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:
Matthias Krüger 2022-10-17 17:15:50 +02:00 committed by GitHub
commit d02a221d31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 1 deletions

View File

@ -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));
} }

View 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() {}

View 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() {}