Skip to content

Commit

Permalink
Rollup merge of #117414 - compiler-errors:tait-forevert, r=oli-obk
Browse files Browse the repository at this point in the history
Don't normalize to an un-revealed opaque when we hit the recursion limit

Currently, we will normalize `Opaque := Option<&Opaque>` to something like `Option<&Option<&Option<&...Opaque>>>`, hitting a limit and bottoming out in an unnormalized opaque after the recursion limit gets hit.

Unfortunately, during `layout_of`, we'll simply recurse and try again if the type normalizes to something different than the type:
https://github.com/rust-lang/rust/blob/e6e931dda5fffbae0fd87c5b1af753cc95556880/compiler/rustc_ty_utils/src/layout.rs#L58-L60

That means then we'll try to normalize `Option<&Option<&Option<&...Opaque>>>` again, substituting `Opaque` into itself even deeper. Eventually this will get to the point that we're just stack-overflowing on a really deep type before even hitting an opaque again.

To fix this, we just bottom out into `ty::Error` instead of the unrevealed opaque type.

Fixes #117412

r? `@oli-obk`
  • Loading branch information
matthiaskrgr authored Oct 30, 2023
2 parents 3e95c6a + c91f60e commit c5aec96
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 7 deletions.
11 changes: 4 additions & 7 deletions compiler/rustc_trait_selection/src/traits/query/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,17 +230,14 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
Reveal::All => {
let args = data.args.try_fold_with(self)?;
let recursion_limit = self.interner().recursion_limit();

if !recursion_limit.value_within_limit(self.anon_depth) {
// A closure or coroutine may have itself as in its upvars.
// This should be checked handled by the recursion check for opaque
// types, but we may end up here before that check can happen.
// In that case, we delay a bug to mark the trip, and continue without
// revealing the opaque.
self.infcx
let guar = self
.infcx
.err_ctxt()
.build_overflow_error(&ty, self.cause.span, true)
.delay_as_bug();
return ty.try_super_fold_with(self);
return Ok(Ty::new_error(self.interner(), guar));
}

let generic_ty = self.interner().type_of(data.def_id);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![feature(type_alias_impl_trait)]

type T = impl Copy;
//~^ ERROR cannot resolve opaque type

static STATIC: T = None::<&'static T>;

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0720]: cannot resolve opaque type
--> $DIR/infinite-cycle-involving-weak.rs:3:10
|
LL | type T = impl Copy;
| ^^^^^^^^^ cannot resolve opaque type

error: aborting due to previous error

For more information about this error, try `rustc --explain E0720`.

0 comments on commit c5aec96

Please sign in to comment.