mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Rollup merge of #102945 - compiler-errors:placeholder-region-outlives, r=lcnr
Do not register placeholder `RegionOutlives` obligations when `considering_regions` is false
**NOTE:** I'm kinda just putting this up for discussion. I'm not certain this is correct...?
This was introduced in [`608625d`](608625dae9 (diff-6e54b18681342ec725d75591dbf384ad08cd73df29db00485fe51b4e90f76ff7R361)
).
Interestingly, we only check `data.has_placeholders()` for `RegionOutlives`, and not for `TypeOutlives`... why? For the record, that different treatment between `RegionOutlives` and `TypeOutlives` is why the fix "The compiling succeeds when all `'a : 'b` are replaced with `&'a () : 'b`" in #100689 _"works"_, but it seems like an implementation detail considering this.
Also, why do we care about placeholder regions being registered if `considering_regions` is false? It doesn't seem to affect any UI tests, for example.
r? `@lcnr`
Fixes #102899
Fixes #100689
This commit is contained in:
commit
d02a221d31
@ -355,7 +355,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::RegionOutlives(data) => {
|
ty::PredicateKind::RegionOutlives(data) => {
|
||||||
if infcx.considering_regions || data.has_placeholders() {
|
if infcx.considering_regions {
|
||||||
infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
|
infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
src/test/ui/higher-rank-trait-bounds/issue-100689.rs
Normal file
29
src/test/ui/higher-rank-trait-bounds/issue-100689.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
struct Foo<'a> {
|
||||||
|
foo: &'a mut usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Bar<'a> {
|
||||||
|
type FooRef<'b>
|
||||||
|
where
|
||||||
|
'a: 'b;
|
||||||
|
fn uwu(foo: Foo<'a>, f: impl for<'b> FnMut(Self::FooRef<'b>));
|
||||||
|
}
|
||||||
|
impl<'a> Bar<'a> for () {
|
||||||
|
type FooRef<'b>
|
||||||
|
=
|
||||||
|
&'b Foo<'a>
|
||||||
|
where
|
||||||
|
'a : 'b,
|
||||||
|
;
|
||||||
|
|
||||||
|
fn uwu(
|
||||||
|
foo: Foo<'a>,
|
||||||
|
mut f: impl for<'b> FnMut(&'b Foo<'a>), //relevant part
|
||||||
|
) {
|
||||||
|
f(&foo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
32
src/test/ui/higher-rank-trait-bounds/issue-102899.rs
Normal file
32
src/test/ui/higher-rank-trait-bounds/issue-102899.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
pub trait BufferTrait<'buffer> {
|
||||||
|
type Subset<'channel>
|
||||||
|
where
|
||||||
|
'buffer: 'channel;
|
||||||
|
|
||||||
|
fn for_each_subset<F>(&self, f: F)
|
||||||
|
where
|
||||||
|
F: for<'channel> Fn(Self::Subset<'channel>);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SomeBuffer<'buffer> {
|
||||||
|
samples: &'buffer [()],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'buffer> BufferTrait<'buffer> for SomeBuffer<'buffer> {
|
||||||
|
type Subset<'subset> = Subset<'subset> where 'buffer: 'subset;
|
||||||
|
|
||||||
|
fn for_each_subset<F>(&self, _f: F)
|
||||||
|
where
|
||||||
|
F: for<'subset> Fn(Subset<'subset>),
|
||||||
|
{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Subset<'subset> {
|
||||||
|
buffer: &'subset [()],
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user