about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-02-10 23:49:16 +0000
committerMichael Goulet <michael@errs.io>2024-02-10 23:49:21 +0000
commit5461fd4250c5e535ae653bd6f0f8392dede5b484 (patch)
treec0625355965ac561ef650bba9c1173e080a6468c
parent6cc4843512d613f51ec81aba689180c31b0b28b6 (diff)
downloadrust-5461fd4250c5e535ae653bd6f0f8392dede5b484.tar.gz
rust-5461fd4250c5e535ae653bd6f0f8392dede5b484.zip
Gracefully handle non-WF alias in assemble_alias_bound_candidates_recur
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs8
-rw-r--r--tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs19
-rw-r--r--tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr17
3 files changed, 42 insertions, 2 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 81c0cfea85a..6833d2ae330 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -15,7 +15,7 @@ use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{fast_reject, TypeFoldable};
 use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
-use rustc_span::ErrorGuaranteed;
+use rustc_span::{ErrorGuaranteed, DUMMY_SP};
 use std::fmt::Debug;
 
 pub(super) mod structural_traits;
@@ -612,7 +612,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
             ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
             ty::Alias(ty::Inherent | ty::Weak, _) => {
-                unreachable!("Weak and Inherent aliases should have been normalized away already")
+                self.tcx().sess.dcx().span_delayed_bug(
+                    DUMMY_SP,
+                    format!("could not normalize {self_ty}, it is not WF"),
+                );
+                return;
             }
         };
 
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
new file mode 100644
index 00000000000..229a918cdd2
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
@@ -0,0 +1,19 @@
+// compile-flags: -Znext-solver
+
+#![feature(lazy_type_alias)]
+//~^ WARN the feature `lazy_type_alias` is incomplete
+
+trait Foo {}
+
+type A<T: Foo> = T;
+
+struct W<T>(T);
+
+// For `W<A<usize>>` to be WF, `A<usize>: Sized` must hold. However, when assembling
+// alias bounds for `A<usize>`, we try to normalize it, but it doesn't hold because
+// `usize: Foo` doesn't hold. Therefore we ICE, because we don't expect to still
+// encounter weak types in `assemble_alias_bound_candidates_recur`.
+fn hello(_: W<A<usize>>) {}
+//~^ ERROR the type `W<A<usize>>` is not well-formed
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
new file mode 100644
index 00000000000..5df27ac3bc6
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
@@ -0,0 +1,17 @@
+warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/alias-bounds-when-not-wf.rs:3:12
+   |
+LL | #![feature(lazy_type_alias)]
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: the type `W<A<usize>>` is not well-formed
+  --> $DIR/alias-bounds-when-not-wf.rs:16:13
+   |
+LL | fn hello(_: W<A<usize>>) {}
+   |             ^^^^^^^^^^^
+
+error: aborting due to 1 previous error; 1 warning emitted
+