From 01eec5317dfcce8f936fb7d6020b86676edf887d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jul 2023 23:35:44 +0000 Subject: [PATCH] Don't normalize projections referencing type error --- .../src/solve/normalize.rs | 5 ++++- .../dont-try-normalizing-proj-with-errors.rs | 19 +++++++++++++++++++ ...nt-try-normalizing-proj-with-errors.stderr | 9 +++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/new-solver/dont-try-normalizing-proj-with-errors.rs create mode 100644 tests/ui/traits/new-solver/dont-try-normalizing-proj-with-errors.stderr diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index c0ee1a576e5fb..9a28d6fd9a9b3 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -70,7 +70,10 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { // keep the projection unnormalized. This is the case for projections // with a `T: Trait` where-clause and opaque types outside of the defining // scope. - let result = if infcx.predicate_may_hold(&obligation) { + // HACK: if alias_ty references errors, then there's a possibility that the + // normalized type may remain unconstrained. In that case, let's just bail. + // See `dont-try-normalizing-proj-with-errors.rs` in the test suite. + let result = if infcx.predicate_may_hold(&obligation) && !alias.references_error() { self.fulfill_cx.register_predicate_obligation(infcx, obligation); let errors = self.fulfill_cx.select_all_or_error(infcx); if !errors.is_empty() { diff --git a/tests/ui/traits/new-solver/dont-try-normalizing-proj-with-errors.rs b/tests/ui/traits/new-solver/dont-try-normalizing-proj-with-errors.rs new file mode 100644 index 0000000000000..7a47c03c16e65 --- /dev/null +++ b/tests/ui/traits/new-solver/dont-try-normalizing-proj-with-errors.rs @@ -0,0 +1,19 @@ +// compile-flags: -Ztrait-solver=next + +trait Mirror { + type Assoc: ?Sized; +} + +struct Wrapper(T); +impl Mirror for Wrapper { + type Assoc = T; +} + +fn mirror(_: W) -> Box { todo!() } + +fn type_error() -> TypeError { todo!() } +//~^ ERROR cannot find type `TypeError` in this scope + +fn main() { + let x = mirror(type_error()); +} diff --git a/tests/ui/traits/new-solver/dont-try-normalizing-proj-with-errors.stderr b/tests/ui/traits/new-solver/dont-try-normalizing-proj-with-errors.stderr new file mode 100644 index 0000000000000..93e4074f115cc --- /dev/null +++ b/tests/ui/traits/new-solver/dont-try-normalizing-proj-with-errors.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `TypeError` in this scope + --> $DIR/dont-try-normalizing-proj-with-errors.rs:14:20 + | +LL | fn type_error() -> TypeError { todo!() } + | ^^^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`.