Skip to content

Commit

Permalink
Paper over an accidental regression
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Sep 14, 2023
1 parent df63c5f commit 0277184
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 15 deletions.
10 changes: 9 additions & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/impl-trait/lifetime-ambiguity-regression.rs
Original file line number Diff line number Diff line change
@@ -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() {}
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down
14 changes: 1 addition & 13 deletions tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

0 comments on commit 0277184

Please sign in to comment.