diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index 80b4d3be172ef..e0640538ec28d 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -156,6 +156,27 @@ where delegate.create_next_universe(); } + compute_query_response_instantiation_values_in_universe( + delegate, + original_values, + response, + span, + prev_universe, + ) +} + +fn compute_query_response_instantiation_values_in_universe( + delegate: &D, + original_values: &[I::GenericArg], + response: &Canonical, + span: I::Span, + prev_universe: ty::UniverseIndex, +) -> CanonicalVarValues +where + D: SolverDelegate, + I: Interner, + T: ResponseT, +{ let var_values = response.value.var_values(); assert_eq!(original_values.len(), var_values.len()); @@ -343,6 +364,7 @@ pub fn instantiate_canonical_state( delegate: &D, span: I::Span, param_env: I::ParamEnv, + prev_universe: ty::UniverseIndex, orig_values: &mut Vec, state: inspect::CanonicalState, ) -> T @@ -353,14 +375,23 @@ where { // In case any fresh inference variables have been created between `state` // and the previous instantiation, extend `orig_values` for it. + let max_universe = prev_universe + state.max_universe.index(); + while delegate.universe() < max_universe { + delegate.create_next_universe(); + } orig_values.extend( state.value.var_values.var_values.as_slice()[orig_values.len()..] .iter() - .map(|&arg| delegate.fresh_var_for_kind_with_span(arg, span)), + .map(|&arg| delegate.fresh_var_for_kind(arg, span, max_universe)), ); - let instantiation = - compute_query_response_instantiation_values(delegate, orig_values, &state, span); + let instantiation = compute_query_response_instantiation_values_in_universe( + delegate, + orig_values, + &state, + span, + prev_universe, + ); let inspect::State { var_values, data } = delegate.instantiate_canonical(state, instantiation); diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 2ebb0fb851a4c..cceed3cd33d4f 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -25,10 +25,11 @@ pub trait SolverDelegate: Deref + Sized { span: ::Span, ) -> Option; - fn fresh_var_for_kind_with_span( + fn fresh_var_for_kind( &self, arg: ::GenericArg, span: ::Span, + universe: ty::UniverseIndex, ) -> ::GenericArg; // FIXME: Uplift the leak check into this crate. diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index fe573025c87f4..4d1517a94fa1a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -1789,6 +1789,7 @@ pub(super) fn evaluate_root_goal_for_proof_tree, let (orig_values, canonical_goal) = canonicalize_goal(delegate, goal, &opaque_types, typing_mode.into()); + let max_input_universe = canonical_goal.canonical.max_universe; let (canonical_result, final_revision) = delegate.cx().evaluate_root_goal_for_proof_tree_raw(canonical_goal); @@ -1796,6 +1797,7 @@ pub(super) fn evaluate_root_goal_for_proof_tree, let proof_tree = inspect::GoalEvaluation { uncanonicalized_goal: goal, orig_values, + max_input_universe, final_revision, result: canonical_result, }; diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index e0877829b25f3..f2d1f7cfc31ae 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -197,17 +197,18 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< } } - fn fresh_var_for_kind_with_span( + fn fresh_var_for_kind( &self, arg: ty::GenericArg<'tcx>, span: Span, + universe: ty::UniverseIndex, ) -> ty::GenericArg<'tcx> { match arg.kind() { ty::GenericArgKind::Lifetime(_) => { - self.next_region_var(RegionVariableOrigin::Misc(span)).into() + self.next_region_var_in_universe(RegionVariableOrigin::Misc(span), universe).into() } - ty::GenericArgKind::Type(_) => self.next_ty_var(span).into(), - ty::GenericArgKind::Const(_) => self.next_const_var(span).into(), + ty::GenericArgKind::Type(_) => self.next_ty_var_in_universe(span, universe).into(), + ty::GenericArgKind::Const(_) => self.next_const_var_in_universe(span, universe).into(), } } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 7bf41d343ecf4..87f83c6559b68 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -32,6 +32,7 @@ pub struct InspectGoal<'a, 'tcx> { infcx: &'a SolverDelegate<'tcx>, depth: usize, orig_values: Vec>, + max_input_universe: ty::UniverseIndex, goal: Goal<'tcx, ty::Predicate<'tcx>>, result: Result, final_revision: &'tcx inspect::Probe>, @@ -102,7 +103,14 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { match **step { inspect::ProbeStep::AddGoal(source, goal) => instantiated_goals.push(( source, - instantiate_canonical_state(infcx, span, param_env, &mut orig_values, goal), + instantiate_canonical_state( + infcx, + span, + param_env, + self.goal.max_input_universe, + &mut orig_values, + goal, + ), )), inspect::ProbeStep::RecordImplArgs { .. } => {} inspect::ProbeStep::MakeCanonicalResponse { .. } @@ -110,8 +118,14 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { } } - let () = - instantiate_canonical_state(infcx, span, param_env, &mut orig_values, self.final_state); + let () = instantiate_canonical_state( + infcx, + span, + param_env, + self.goal.max_input_universe, + &mut orig_values, + self.final_state, + ); instantiated_goals .into_iter() @@ -139,6 +153,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { infcx, span, param_env, + self.goal.max_input_universe, &mut orig_values, impl_args, ); @@ -147,6 +162,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { infcx, span, param_env, + self.goal.max_input_universe, &mut orig_values, self.final_state, ); @@ -321,8 +337,13 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { ) -> Self { let infcx = <&SolverDelegate<'tcx>>::from(infcx); - let inspect::GoalEvaluation { uncanonicalized_goal, orig_values, final_revision, result } = - root; + let inspect::GoalEvaluation { + uncanonicalized_goal, + orig_values, + max_input_universe, + final_revision, + result, + } = root; // If there's a normalizes-to goal, AND the evaluation result with the result of // constraining the normalizes-to RHS and computing the nested goals. let result = result.map(|ok| ok.value.certainty); @@ -331,6 +352,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { infcx, depth, orig_values, + max_input_universe, goal: eager_resolve_vars(&**infcx, uncanonicalized_goal), result, final_revision, diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs index 20432687e5f6b..042fe2ba83cb7 100644 --- a/compiler/rustc_type_ir/src/solve/inspect.rs +++ b/compiler/rustc_type_ir/src/solve/inspect.rs @@ -49,6 +49,7 @@ pub type CanonicalState = Canonical>; pub struct GoalEvaluation { pub uncanonicalized_goal: Goal, pub orig_values: Vec, + pub max_input_universe: crate::UniverseIndex, pub final_revision: I::Probe, pub result: QueryResult, } diff --git a/tests/ui/traits/non_lifetime_binders/foreach-partial-eq-next-solver.rs b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq-next-solver.rs new file mode 100644 index 0000000000000..a48dd465750c6 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq-next-solver.rs @@ -0,0 +1,14 @@ +//@ compile-flags: -Znext-solver=globally + +#![allow(incomplete_features)] +#![feature(non_lifetime_binders)] + +fn auto_trait() +where + for T: PartialEq + PartialOrd, +{} + +fn main() { + auto_trait(); + //~^ ERROR can't compare `T` with `T` +} diff --git a/tests/ui/traits/non_lifetime_binders/foreach-partial-eq-next-solver.stderr b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq-next-solver.stderr new file mode 100644 index 0000000000000..dc4dedd75c320 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq-next-solver.stderr @@ -0,0 +1,19 @@ +error[E0277]: can't compare `T` with `T` + --> $DIR/foreach-partial-eq-next-solver.rs:12:5 + | +LL | auto_trait(); + | ^^^^^^^^^^^^ no implementation for `T < T` and `T > T` + | + = help: the trait `PartialOrd` is not implemented for `T` +note: required by a bound in `auto_trait` + --> $DIR/foreach-partial-eq-next-solver.rs:8:27 + | +LL | fn auto_trait() + | ---------- required by a bound in this function +LL | where +LL | for T: PartialEq + PartialOrd, + | ^^^^^^^^^^ required by this bound in `auto_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.