From bd379dedc8ad9fe7ef9f438abe77bc1d6749e73f Mon Sep 17 00:00:00 2001 From: rabindra789 Date: Sun, 16 Aug 2026 12:30:47 +0530 Subject: [PATCH] mir: accept ambiguous unsize coercion validation results The MIR validator currently treats ambiguous and old-solver cycle results as definite failures when checking Unsize coercions. This can ICE on valid post-monomorphization MIR. Only definite trait evaluation errors should make this validation fail; ambiguity and cycle results are deliberately accepted. Add a regression test for the post-monomorphization cycle case. --- compiler/rustc_mir_transform/src/validate.rs | 9 +++++-- .../validate/validate-unsize-cast-cycle.rs | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 tests/ui/mir/validate/validate-unsize-cast-cycle.rs diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index b9c55439f0597..fa60509ba1be7 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -598,7 +598,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { crate::util::relate_types(self.tcx, self.typing_env, variance, src, dest) } - /// Check that the given predicate definitely holds in the param-env of this MIR body. + /// Check that the given predicate is not provably false in the param-env of this MIR body. + /// + /// We deliberately accept ambiguous and cycle results, such as post-monomorphization cycles, + /// mirroring the behavior of `impossible_clauses` which also only rejects definite failures. + /// See . fn predicate_must_hold_modulo_regions( &self, pred: impl Upcast, ty::Predicate<'tcx>>, @@ -622,7 +626,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { param_env, pred, )); - ocx.evaluate_obligations_error_on_ambiguity().no_errors() + let errors = ocx.try_evaluate_obligations(); + errors.as_slice().iter().all(|error| !error.is_true_error()) } } diff --git a/tests/ui/mir/validate/validate-unsize-cast-cycle.rs b/tests/ui/mir/validate/validate-unsize-cast-cycle.rs new file mode 100644 index 0000000000000..625c1dda4a44f --- /dev/null +++ b/tests/ui/mir/validate/validate-unsize-cast-cycle.rs @@ -0,0 +1,27 @@ +// Regression test for . +// +// This must be a full build test: `check-pass` only emits metadata and +// therefore does not run the post-mono MIR validator that this ICEs in. +//@ build-pass + +trait Apply { + type Output: Trait; +} +struct Identity; +impl Apply for Identity { + type Output = T; +} + +struct Thing(A); + +trait Trait {} + +impl Trait for Thing where ::Output: Trait {} + +fn weird(x: A) -> impl Trait { + Thing(x) +} + +fn main() { + let _ = Box::new(weird(Identity)) as Box; +}