Rollup merge of #115844 - oli-obk:opaque_lifetime_ambiguity, r=jackh726
Paper over an accidental regression r? types cc https://github.com/rust-lang/rust/issues/115781 (do not close issue until beta backport has been performed) The PR reasons are explained with comments in the source. In order to keep the diff simple, this PR effectively reverts https://github.com/rust-lang/rust/pull/113661, but only for RPITs. I will submit a follow up PR that fixes this correctly instead of just disabling the newly added check for RPITs. This PR should be significantly easier to review for beta backport
This commit is contained in:
commit
9362604518
@ -461,7 +461,15 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
}
|
||||
match origin {
|
||||
// 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:
|
||||
// ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
|
||||
// They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.
|
||||
|
13
tests/ui/impl-trait/lifetime-ambiguity-regression.rs
Normal file
13
tests/ui/impl-trait/lifetime-ambiguity-regression.rs
Normal 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() {}
|
@ -8,7 +8,7 @@ fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {}
|
||||
//~^ ERROR captures lifetime that does not appear in bounds
|
||||
|
||||
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>> {}
|
||||
//~^ ERROR expected generic lifetime parameter, found `'a`
|
||||
|
||||
|
@ -17,19 +17,7 @@ LL |
|
||||
LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
|
||||
| ^^
|
||||
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
--> $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
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0700, E0792.
|
||||
For more information about an error, try `rustc --explain E0700`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user