Paper over an accidental regression

This commit is contained in:
Oli Scherer 2023-09-14 15:16:48 +00:00
parent df63c5f140
commit 0277184977
4 changed files with 24 additions and 15 deletions

View File

@ -461,7 +461,15 @@ fn check_opaque_meets_bounds<'tcx>(
} }
match origin { match origin {
// Checked when type checking the function containing them. // Checked when type checking the function containing them.
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {} hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {
// HACK: this should also fall through to the hidden type check below, but the original
// implementation had a bug where equivalent lifetimes are not identical. This caused us
// to reject existing stable code that is otherwise completely fine. The real fix is to
// compare the hidden types via our type equivalence/relation infra instead of doing an
// identity check.
let _ = infcx.take_opaque_types();
return Ok(());
}
// Nested opaque types occur only in associated types: // Nested opaque types occur only in associated types:
// ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; ` // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
// They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`. // They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.

View File

@ -0,0 +1,13 @@
//! This test shows a situation where through subtle compiler changes we can
//! suddenly infer a different lifetime in the hidden type, and thus not meet
//! the opaque type bounds anymore. In this case `'a` and `'b` are equal, so
//! picking either is fine, but then we'll fail an identity check of the hidden
//! type and the expected hidden type.
// check-pass
fn test<'a: 'b, 'b: 'a>() -> impl IntoIterator<Item = (&'a u8, impl Into<(&'b u8, &'a u8)>)> {
None::<(_, (_, _))>
}
fn main() {}

View File

@ -8,7 +8,7 @@ fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {}
//~^ ERROR captures lifetime that does not appear in bounds //~^ ERROR captures lifetime that does not appear in bounds
type WithLt<'a> = impl Sized + 'a; type WithLt<'a> = impl Sized + 'a;
//~^ ERROR concrete type differs from previous defining opaque type use
fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {} fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
//~^ ERROR expected generic lifetime parameter, found `'a` //~^ ERROR expected generic lifetime parameter, found `'a`

View File

@ -17,19 +17,7 @@ LL |
LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {} LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
| ^^ | ^^
error: concrete type differs from previous defining opaque type use error: aborting due to 2 previous errors
--> $DIR/nested-tait-hrtb.rs:10:19
|
LL | type WithLt<'a> = impl Sized + 'a;
| ^^^^^^^^^^^^^^^ expected `&'a str`, got `{type error}`
|
note: previous use here
--> $DIR/nested-tait-hrtb.rs:12:17
|
LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0700, E0792. Some errors have detailed explanations: E0700, E0792.
For more information about an error, try `rustc --explain E0700`. For more information about an error, try `rustc --explain E0700`.