diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index e99c5eacbd8..2891df3ed2d 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -66,7 +66,7 @@ impl<'tcx> At<'_, 'tcx> { let value = self .normalize(value) .into_value_registering_obligations(self.infcx, &mut *fulfill_cx); - let errors = fulfill_cx.select_where_possible(self.infcx); + let errors = fulfill_cx.select_all_or_error(self.infcx); let value = self.infcx.resolve_vars_if_possible(value); if errors.is_empty() { Ok(value) } else { Err(errors) } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index c6e41e57f0c..224a7271472 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -59,12 +59,13 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, ) -> Result>, NoSolution> { - let normalize_op = |ty| { - let ty = ocx.normalize(&ObligationCause::dummy(), param_env, ty); + let normalize_op = |ty| -> Result<_, NoSolution> { + let ty = ocx + .deeply_normalize(&ObligationCause::dummy(), param_env, ty) + .map_err(|_| NoSolution)?; if !ocx.select_all_or_error().is_empty() { return Err(NoSolution); } - let ty = ocx.infcx.resolve_vars_if_possible(ty); let ty = OpportunisticRegionResolver::new(&ocx.infcx).fold_ty(ty); Ok(ty) }; diff --git a/tests/ui/traits/next-solver/normalize-in-implied_outlives_bounds.rs b/tests/ui/traits/next-solver/normalize-in-implied_outlives_bounds.rs new file mode 100644 index 00000000000..1dca19d28e9 --- /dev/null +++ b/tests/ui/traits/next-solver/normalize-in-implied_outlives_bounds.rs @@ -0,0 +1,46 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +// Minimized example from `rustc_type_ir` that demonstrates a missing deep normalization +// in the new solver when computing the implies outlives bounds of an impl. + +use std::marker::PhantomData; +use std::ops::Deref; + +pub struct SearchGraph::Cx> { + d: PhantomData, + x: PhantomData, +} + +pub trait Delegate { + type Cx; +} + +struct SearchGraphDelegate { + _marker: PhantomData, +} + +impl Delegate for SearchGraphDelegate +where + D: SolverDelegate, +{ + type Cx = D::Interner; +} + +pub trait SolverDelegate { + type Interner; +} + +struct EvalCtxt<'a, D, I> +where + D: SolverDelegate, +{ + search_graph: &'a SearchGraph>, +} + +impl<'a, D, I> EvalCtxt<'a, D, ::Interner> +where + D: SolverDelegate +{} + +fn main() {}