Skip to content

Commit 0277184

Browse files
committed
Paper over an accidental regression
1 parent df63c5f commit 0277184

File tree

4 files changed

+24
-15
lines changed

4 files changed

+24
-15
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,15 @@ fn check_opaque_meets_bounds<'tcx>(
461461
}
462462
match origin {
463463
// Checked when type checking the function containing them.
464-
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
464+
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {
465+
// HACK: this should also fall through to the hidden type check below, but the original
466+
// implementation had a bug where equivalent lifetimes are not identical. This caused us
467+
// to reject existing stable code that is otherwise completely fine. The real fix is to
468+
// compare the hidden types via our type equivalence/relation infra instead of doing an
469+
// identity check.
470+
let _ = infcx.take_opaque_types();
471+
return Ok(());
472+
}
465473
// Nested opaque types occur only in associated types:
466474
// ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
467475
// They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! This test shows a situation where through subtle compiler changes we can
2+
//! suddenly infer a different lifetime in the hidden type, and thus not meet
3+
//! the opaque type bounds anymore. In this case `'a` and `'b` are equal, so
4+
//! picking either is fine, but then we'll fail an identity check of the hidden
5+
//! type and the expected hidden type.
6+
7+
// check-pass
8+
9+
fn test<'a: 'b, 'b: 'a>() -> impl IntoIterator<Item = (&'a u8, impl Into<(&'b u8, &'a u8)>)> {
10+
None::<(_, (_, _))>
11+
}
12+
13+
fn main() {}

tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {}
88
//~^ ERROR captures lifetime that does not appear in bounds
99

1010
type WithLt<'a> = impl Sized + 'a;
11-
//~^ ERROR concrete type differs from previous defining opaque type use
11+
1212
fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
1313
//~^ ERROR expected generic lifetime parameter, found `'a`
1414

tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr

+1-13
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,7 @@ LL |
1717
LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
1818
| ^^
1919

20-
error: concrete type differs from previous defining opaque type use
21-
--> $DIR/nested-tait-hrtb.rs:10:19
22-
|
23-
LL | type WithLt<'a> = impl Sized + 'a;
24-
| ^^^^^^^^^^^^^^^ expected `&'a str`, got `{type error}`
25-
|
26-
note: previous use here
27-
--> $DIR/nested-tait-hrtb.rs:12:17
28-
|
29-
LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
30-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31-
32-
error: aborting due to 3 previous errors
20+
error: aborting due to 2 previous errors
3321

3422
Some errors have detailed explanations: E0700, E0792.
3523
For more information about an error, try `rustc --explain E0700`.

0 commit comments

Comments
 (0)