about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-10-30 21:03:40 +0100
committerGitHub <noreply@github.com>2023-10-30 21:03:40 +0100
commitc5aec964405a9b5d769e74a8869326d321d5008f (patch)
tree00f56e54746c55f625926bab929788bde20c5d09
parent3e95c6ab036a705ce166695351c61ae74b984244 (diff)
parentc91f60e22fccbd1ee7701b2a1b88457985f9df0b (diff)
downloadrust-c5aec964405a9b5d769e74a8869326d321d5008f.tar.gz
rust-c5aec964405a9b5d769e74a8869326d321d5008f.zip
Rollup merge of #117414 - compiler-errors:tait-forevert, r=oli-obk
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`
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs8
-rw-r--r--tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr9
3 files changed, 21 insertions, 7 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index c761d0d103e..2e31b560b38 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -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);
diff --git a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs
new file mode 100644
index 00000000000..6609d4eb5a2
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs
@@ -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() {}
diff --git a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr
new file mode 100644
index 00000000000..50ae6f38641
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr
@@ -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`.