diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b379711e28720..ae58e5f947c00 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -201,7 +201,12 @@ impl<'tcx> InferCtxtInner<'tcx> { } #[inline] - fn type_variables(&mut self) -> type_variable::TypeVariableTable<'_, 'tcx> { + pub fn instantiate_const_var(&mut self, var: ConstVid, value: ty::Const<'tcx>) { + self.const_unification_table().union_value(var, ConstVariableValue::Known { value }) + } + + #[inline] + pub fn type_variables(&mut self) -> type_variable::TypeVariableTable<'_, 'tcx> { self.type_variable_storage.with_log(&mut self.undo_log) } diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs index e94ad4aa539b6..90180af3b167f 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect.rs @@ -58,8 +58,6 @@ pub struct GoalEvaluation<'tcx> { pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>, pub kind: GoalEvaluationKind<'tcx>, pub evaluation: CanonicalGoalEvaluation<'tcx>, - /// The nested goals from instantiating the query response. - pub returned_goals: Vec>>, } #[derive(Eq, PartialEq)] diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs index 54db8dbd33606..89c5eb517e565 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs @@ -48,20 +48,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> { }, }; writeln!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?; - self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))?; - if eval.returned_goals.len() > 0 { - writeln!(self.f, "NESTED GOALS ADDED TO CALLER: [")?; - self.nested(|this| { - for goal in eval.returned_goals.iter() { - writeln!(this.f, "ADDED GOAL: {goal:?},")?; - } - Ok(()) - })?; - - writeln!(self.f, "]") - } else { - Ok(()) - } + self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation)) } pub(super) fn format_canonical_goal_evaluation( diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index db1aee1190359..914665ac545c5 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -107,21 +107,22 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> Canonicalizer<'a, Infc // universes `n`, this algorithm compresses them in place so that: // // - the new universe indices are as small as possible - // - we only create a new universe if we would otherwise put a placeholder in - // the same compressed universe as an existential which cannot name it + // - we create a new universe if we would otherwise + // 1. put existentials from a different universe into the same one + // 2. put a placeholder in the same universe as an existential which cannot name it // // Let's walk through an example: // - var_infos: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 0 // - var_infos: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 1 // - var_infos: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 1, next_orig_uv: 2 // - var_infos: [E0, U1, E5, U1, E1, E6, U6], curr_compressed_uv: 1, next_orig_uv: 5 - // - var_infos: [E0, U1, E1, U1, E1, E6, U6], curr_compressed_uv: 1, next_orig_uv: 6 - // - var_infos: [E0, U1, E1, U1, E1, E2, U2], curr_compressed_uv: 2, next_orig_uv: - + // - var_infos: [E0, U1, E2, U1, E1, E6, U6], curr_compressed_uv: 2, next_orig_uv: 6 + // - var_infos: [E0, U1, E1, U1, E1, E3, U3], curr_compressed_uv: 2, next_orig_uv: - // // This algorithm runs in `O(n²)` where `n` is the number of different universe // indices in the input. This should be fine as `n` is expected to be small. let mut curr_compressed_uv = ty::UniverseIndex::ROOT; - let mut existential_in_new_uv = false; + let mut existential_in_new_uv = None; let mut next_orig_uv = Some(ty::UniverseIndex::ROOT); while let Some(orig_uv) = next_orig_uv.take() { let mut update_uv = |var: &mut CanonicalVarInfo, orig_uv, is_existential| { @@ -130,14 +131,25 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> Canonicalizer<'a, Infc Ordering::Less => (), // Already updated Ordering::Equal => { if is_existential { - existential_in_new_uv = true; - } else if existential_in_new_uv { + if existential_in_new_uv.is_some_and(|uv| uv < orig_uv) { + // Condition 1. + // + // We already put an existential from a outer universe + // into the current compressed universe, so we need to + // create a new one. + curr_compressed_uv = curr_compressed_uv.next_universe(); + } + + existential_in_new_uv = next_orig_uv; + } else if existential_in_new_uv.is_some() { + // Condition 2. + // // `var` is a placeholder from a universe which is not nameable // by an existential which we already put into the compressed // universe `curr_compressed_uv`. We therefore have to create a // new universe for `var`. curr_compressed_uv = curr_compressed_uv.next_universe(); - existential_in_new_uv = false; + existential_in_new_uv = None; } *var = var.with_updated_universe(curr_compressed_uv); diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index ecdae2521b933..0189002c9ced9 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -191,22 +191,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { param_env: ty::ParamEnv<'tcx>, original_values: Vec>, response: CanonicalResponse<'tcx>, - ) -> Result<(Certainty, Vec>>), NoSolution> { + ) -> Certainty { let substitution = Self::compute_query_response_substitution(self.infcx, &original_values, &response); let Response { var_values, external_constraints, certainty } = response.substitute(self.tcx(), &substitution); - let nested_goals = - Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values)?; + Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values); let ExternalConstraintsData { region_constraints, opaque_types } = external_constraints.deref(); self.register_region_constraints(region_constraints); - self.register_opaque_types(param_env, opaque_types)?; - - Ok((certainty, nested_goals)) + self.register_new_opaque_types(param_env, opaque_types); + certainty } /// This returns the substitutions to instantiate the bound variables of @@ -299,26 +297,61 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { param_env: ty::ParamEnv<'tcx>, original_values: &[ty::GenericArg<'tcx>], var_values: CanonicalVarValues<'tcx>, - ) -> Result>>, NoSolution> { + ) { assert_eq!(original_values.len(), var_values.len()); - - let mut nested_goals = vec![]; for (&orig, response) in iter::zip(original_values, var_values.var_values) { - nested_goals.extend( - infcx + EvalCtxt::unify_var_value(infcx, param_env, orig, response); + } + } + + fn unify_var_value( + infcx: &InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + orig: ty::GenericArg<'tcx>, + response: ty::GenericArg<'tcx>, + ) { + let orig = infcx.shallow_resolve(orig); + match (orig.unpack(), response.unpack()) { + (ty::GenericArgKind::Lifetime(orig), ty::GenericArgKind::Lifetime(response)) => { + let InferOk { value: (), obligations } = infcx .at(&ObligationCause::dummy(), param_env) .eq(DefineOpaqueTypes::No, orig, response) - .map(|InferOk { value: (), obligations }| { - obligations.into_iter().map(|o| Goal::from(o)) - }) - .map_err(|e| { - debug!(?e, "failed to equate"); - NoSolution - })?, - ); + .unwrap(); + assert!(obligations.is_empty()); + } + (ty::GenericArgKind::Type(orig), ty::GenericArgKind::Type(response)) => { + if let ty::Infer(ty::TyVar(orig)) = *orig.kind() + && !response.is_ty_or_numeric_infer() + { + infcx.inner.borrow_mut().type_variables().instantiate(orig, response); + } else { + let InferOk { value: (), obligations } = infcx + .at(&ObligationCause::dummy(), param_env) + .eq(DefineOpaqueTypes::No, orig, response) + .unwrap(); + assert!(obligations.is_empty()); + } + } + (ty::GenericArgKind::Const(orig), ty::GenericArgKind::Const(response)) => { + if let ty::ConstKind::Infer(ty::InferConst::Var(orig)) = orig.kind() + && !response.is_ct_infer() + { + infcx.inner.borrow_mut().instantiate_const_var(orig, response); + } else { + let InferOk { value: (), obligations } = infcx + .at(&ObligationCause::dummy(), param_env) + .eq(DefineOpaqueTypes::No, orig, response) + .unwrap(); + assert!(obligations.is_empty()); + } + } + ( + ty::GenericArgKind::Lifetime(_) + | ty::GenericArgKind::Type(_) + | ty::GenericArgKind::Const(_), + _, + ) => unreachable!(), } - - Ok(nested_goals) } fn register_region_constraints(&mut self, region_constraints: &QueryRegionConstraints<'tcx>) { @@ -330,21 +363,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - for member_constraint in ®ion_constraints.member_constraints { - // FIXME: Deal with member constraints :< - let _ = member_constraint; - } + assert!(region_constraints.member_constraints.is_empty()); } - fn register_opaque_types( + fn register_new_opaque_types( &mut self, param_env: ty::ParamEnv<'tcx>, opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)], - ) -> Result<(), NoSolution> { + ) { for &(key, ty) in opaque_types { - self.insert_hidden_type(key, param_env, ty)?; + self.insert_hidden_type(key, param_env, ty).unwrap(); } - Ok(()) } } @@ -368,14 +397,13 @@ impl<'tcx> inspect::ProofTreeBuilder<'tcx> { param_env: ty::ParamEnv<'tcx>, original_values: &[ty::GenericArg<'tcx>], state: inspect::CanonicalState<'tcx, T>, - ) -> Result<(Vec>>, T), NoSolution> { + ) -> T { let substitution = EvalCtxt::compute_query_response_substitution(infcx, original_values, &state); let inspect::State { var_values, data } = state.substitute(infcx.tcx, &substitution); - let nested_goals = - EvalCtxt::unify_query_var_values(infcx, param_env, original_values, var_values)?; - Ok((nested_goals, data)) + EvalCtxt::unify_query_var_values(infcx, param_env, original_values, var_values); + data } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 76c50a111027d..5923badfaf56d 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -140,10 +140,7 @@ pub trait InferCtxtEvalExt<'tcx> { &self, goal: Goal<'tcx, ty::Predicate<'tcx>>, generate_proof_tree: GenerateProofTree, - ) -> ( - Result<(bool, Certainty, Vec>>), NoSolution>, - Option>, - ); + ) -> (Result<(bool, Certainty), NoSolution>, Option>); } impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> { @@ -152,10 +149,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> { &self, goal: Goal<'tcx, ty::Predicate<'tcx>>, generate_proof_tree: GenerateProofTree, - ) -> ( - Result<(bool, Certainty, Vec>>), NoSolution>, - Option>, - ) { + ) -> (Result<(bool, Certainty), NoSolution>, Option>) { EvalCtxt::enter_root(self, generate_proof_tree, |ecx| { ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal) }) @@ -337,7 +331,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { goal_evaluation_kind: GoalEvaluationKind, source: GoalSource, goal: Goal<'tcx, ty::Predicate<'tcx>>, - ) -> Result<(bool, Certainty, Vec>>), NoSolution> { + ) -> Result<(bool, Certainty), NoSolution> { let (orig_values, canonical_goal) = self.canonicalize_goal(goal); let mut goal_evaluation = self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind); @@ -355,26 +349,13 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { Ok(response) => response, }; - let (certainty, has_changed, nested_goals) = match self - .instantiate_response_discarding_overflow( - goal.param_env, - source, - orig_values, - canonical_response, - ) { - Err(e) => { - self.inspect.goal_evaluation(goal_evaluation); - return Err(e); - } - Ok(response) => response, - }; - goal_evaluation.returned_goals(&nested_goals); + let (certainty, has_changed) = self.instantiate_response_discarding_overflow( + goal.param_env, + source, + orig_values, + canonical_response, + ); self.inspect.goal_evaluation(goal_evaluation); - - if !has_changed && !nested_goals.is_empty() { - bug!("an unchanged goal shouldn't have any side-effects on instantiation"); - } - // FIXME: We previously had an assert here that checked that recomputing // a goal after applying its constraints did not change its response. // @@ -385,7 +366,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { // Once we have decided on how to handle trait-system-refactor-initiative#75, // we should re-add an assert here. - Ok((has_changed, certainty, nested_goals)) + Ok((has_changed, certainty)) } fn instantiate_response_discarding_overflow( @@ -394,7 +375,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { source: GoalSource, original_values: Vec>, response: CanonicalResponse<'tcx>, - ) -> Result<(Certainty, bool, Vec>>), NoSolution> { + ) -> (Certainty, bool) { // The old solver did not evaluate nested goals when normalizing. // It returned the selection constraints allowing a `Projection` // obligation to not hold in coherence while avoiding the fatal error @@ -415,14 +396,14 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { }; if response.value.certainty == Certainty::OVERFLOW && !keep_overflow_constraints() { - Ok((Certainty::OVERFLOW, false, Vec::new())) + (Certainty::OVERFLOW, false) } else { let has_changed = !response.value.var_values.is_identity_modulo_regions() || !response.value.external_constraints.opaque_types.is_empty(); - let (certainty, nested_goals) = - self.instantiate_and_apply_query_response(param_env, original_values, response)?; - Ok((certainty, has_changed, nested_goals)) + let certainty = + self.instantiate_and_apply_query_response(param_env, original_values, response); + (certainty, has_changed) } } @@ -546,12 +527,11 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ty::NormalizesTo { alias: goal.predicate.alias, term: unconstrained_rhs }, ); - let (_, certainty, instantiate_goals) = self.evaluate_goal( + let (_, certainty) = self.evaluate_goal( GoalEvaluationKind::Nested { is_normalizes_to_hack: IsNormalizesToHack::Yes }, GoalSource::Misc, unconstrained_goal, )?; - self.nested_goals.goals.extend(with_misc_source(instantiate_goals)); // Finally, equate the goal's RHS with the unconstrained var. // We put the nested goals from this into goals instead of @@ -582,12 +562,11 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } for (source, goal) in goals.goals.drain(..) { - let (has_changed, certainty, instantiate_goals) = self.evaluate_goal( + let (has_changed, certainty) = self.evaluate_goal( GoalEvaluationKind::Nested { is_normalizes_to_hack: IsNormalizesToHack::No }, source, goal, )?; - self.nested_goals.goals.extend(with_misc_source(instantiate_goals)); if has_changed { unchanged_certainty = None; } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 315df06be417c..7b904af9102a8 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -67,37 +67,26 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> { } let candidate = candidates.pop().unwrap(); - let (certainty, nested_goals) = ecx - .instantiate_and_apply_query_response( - trait_goal.param_env, - orig_values, - candidate.result, - ) - .map_err(|_| SelectionError::Unimplemented)?; + let certainty = ecx.instantiate_and_apply_query_response( + trait_goal.param_env, + orig_values, + candidate.result, + ); - Ok(Some((candidate, certainty, nested_goals))) + Ok(Some((candidate, certainty))) }); - let (candidate, certainty, nested_goals) = match result { - Ok(Some((candidate, certainty, nested_goals))) => (candidate, certainty, nested_goals), + let (candidate, certainty) = match result { + Ok(Some((candidate, certainty))) => (candidate, certainty), Ok(None) => return Ok(None), Err(e) => return Err(e), }; - let nested_obligations: Vec<_> = nested_goals - .into_iter() - .map(|goal| { - Obligation::new(self.tcx, ObligationCause::dummy(), goal.param_env, goal.predicate) - }) - .collect(); - let goal = self.resolve_vars_if_possible(trait_goal); match (certainty, candidate.source) { // Rematching the implementation will instantiate the same nested goals that // would have caused the ambiguity, so we can still make progress here regardless. - (_, CandidateSource::Impl(def_id)) => { - rematch_impl(self, goal, def_id, nested_obligations) - } + (_, CandidateSource::Impl(def_id)) => rematch_impl(self, goal, def_id), // If an unsize goal is ambiguous, then we can manually rematch it to make // selection progress for coercion during HIR typeck. If it is *not* ambiguous, @@ -110,20 +99,20 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> { | (Certainty::Yes, CandidateSource::BuiltinImpl(src @ BuiltinImplSource::Misc)) if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) => { - rematch_unsize(self, goal, nested_obligations, src, certainty) + rematch_unsize(self, goal, src, certainty) } // Technically some builtin impls have nested obligations, but if // `Certainty::Yes`, then they should've all been verified and don't // need re-checking. (Certainty::Yes, CandidateSource::BuiltinImpl(src)) => { - Ok(Some(ImplSource::Builtin(src, nested_obligations))) + Ok(Some(ImplSource::Builtin(src, Vec::new()))) } // It's fine not to do anything to rematch these, since there are no // nested obligations. (Certainty::Yes, CandidateSource::ParamEnv(_) | CandidateSource::AliasBound) => { - Ok(Some(ImplSource::Param(nested_obligations))) + Ok(Some(ImplSource::Param(Vec::new()))) } (Certainty::Maybe(_), _) => Ok(None), @@ -193,19 +182,16 @@ fn rematch_impl<'tcx>( infcx: &InferCtxt<'tcx>, goal: Goal<'tcx, ty::TraitPredicate<'tcx>>, impl_def_id: DefId, - mut nested: Vec>, ) -> SelectionResult<'tcx, Selection<'tcx>> { let args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); let impl_trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(infcx.tcx, args); - nested.extend( - infcx - .at(&ObligationCause::dummy(), goal.param_env) - .eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref) - .map_err(|_| SelectionError::Unimplemented)? - .into_obligations(), - ); + let mut nested = infcx + .at(&ObligationCause::dummy(), goal.param_env) + .eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref) + .map_err(|_| SelectionError::Unimplemented)? + .into_obligations(); nested.extend( infcx.tcx.predicates_of(impl_def_id).instantiate(infcx.tcx, args).into_iter().map( @@ -222,11 +208,11 @@ fn rematch_impl<'tcx>( fn rematch_unsize<'tcx>( infcx: &InferCtxt<'tcx>, goal: Goal<'tcx, ty::TraitPredicate<'tcx>>, - mut nested: Vec>, source: BuiltinImplSource, certainty: Certainty, ) -> SelectionResult<'tcx, Selection<'tcx>> { let tcx = infcx.tcx; + let mut nested = vec![]; let a_ty = structurally_normalize(goal.predicate.self_ty(), infcx, goal.param_env, &mut nested); let b_ty = structurally_normalize( goal.predicate.trait_ref.args.type_at(1), diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index f08622816ec28..4b86a22ff02f6 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -2,7 +2,6 @@ use std::mem; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::solve::MaybeCause; -use rustc_infer::traits::Obligation; use rustc_infer::traits::{ query::NoSolution, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, PredicateObligation, SelectionError, TraitEngine, @@ -48,11 +47,11 @@ impl<'tcx> FulfillmentCtxt<'tcx> { &self, infcx: &InferCtxt<'tcx>, obligation: &PredicateObligation<'tcx>, - result: &Result<(bool, Certainty, Vec>>), NoSolution>, + result: &Result<(bool, Certainty), NoSolution>, ) { if let Some(inspector) = infcx.obligation_inspector.get() { let result = match result { - Ok((_, c, _)) => Ok(*c), + Ok((_, c)) => Ok(*c), Err(NoSolution) => Err(NoSolution), }; (inspector)(infcx, &obligation, result); @@ -80,13 +79,13 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { .evaluate_root_goal(obligation.clone().into(), GenerateProofTree::IfEnabled) .0 { - Ok((_, Certainty::Maybe(MaybeCause::Ambiguity), _)) => { + Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => { FulfillmentErrorCode::Ambiguity { overflow: false } } - Ok((_, Certainty::Maybe(MaybeCause::Overflow), _)) => { + Ok((_, Certainty::Maybe(MaybeCause::Overflow))) => { FulfillmentErrorCode::Ambiguity { overflow: true } } - Ok((_, Certainty::Yes, _)) => { + Ok((_, Certainty::Yes)) => { bug!("did not expect successful goal when collecting ambiguity errors") } Err(_) => { @@ -117,7 +116,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { let goal = obligation.clone().into(); let result = infcx.evaluate_root_goal(goal, GenerateProofTree::IfEnabled).0; self.inspect_evaluated_obligation(infcx, &obligation, &result); - let (changed, certainty, nested_goals) = match result { + let (changed, certainty) = match result { Ok(result) => result, Err(NoSolution) => { errors.push(FulfillmentError { @@ -175,16 +174,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { continue; } }; - // Push any nested goals that we get from unifying our canonical response - // with our obligation onto the fulfillment context. - self.obligations.extend(nested_goals.into_iter().map(|goal| { - Obligation::new( - infcx.tcx, - obligation.cause.clone(), - goal.param_env, - goal.predicate, - ) - })); has_changed |= changed; match certainty { Certainty::Yes => {} diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index f33d0f397ce9e..7fd524dbd809d 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -63,21 +63,12 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { infcx.probe(|_| { let mut instantiated_goals = vec![]; for goal in &self.nested_goals { - let goal = match ProofTreeBuilder::instantiate_canonical_state( + let goal = ProofTreeBuilder::instantiate_canonical_state( infcx, self.goal.goal.param_env, self.goal.orig_values, *goal, - ) { - Ok((_goals, goal)) => goal, - Err(NoSolution) => { - warn!( - "unexpected failure when instantiating {:?}: {:?}", - goal, self.nested_goals - ); - return ControlFlow::Continue(()); - } - }; + ); instantiated_goals.push(goal); } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs index b587a93b24c4f..f7b310a7abe27 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs @@ -87,7 +87,6 @@ struct WipGoalEvaluation<'tcx> { pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>, pub kind: WipGoalEvaluationKind<'tcx>, pub evaluation: Option>, - pub returned_goals: Vec>>, } impl<'tcx> WipGoalEvaluation<'tcx> { @@ -103,7 +102,6 @@ impl<'tcx> WipGoalEvaluation<'tcx> { } }, evaluation: self.evaluation.unwrap().finalize(), - returned_goals: self.returned_goals, } } } @@ -312,7 +310,6 @@ impl<'tcx> ProofTreeBuilder<'tcx> { } }, evaluation: None, - returned_goals: vec![], }) } @@ -369,17 +366,6 @@ impl<'tcx> ProofTreeBuilder<'tcx> { } } - pub fn returned_goals(&mut self, goals: &[Goal<'tcx, ty::Predicate<'tcx>>]) { - if let Some(this) = self.as_mut() { - match this { - DebugSolver::GoalEvaluation(evaluation) => { - assert!(evaluation.returned_goals.is_empty()); - evaluation.returned_goals.extend(goals); - } - _ => unreachable!(), - } - } - } pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<'tcx>) { if let Some(this) = self.as_mut() { match (this, *goal_evaluation.state.unwrap()) { diff --git a/tests/ui/impl-trait/issue-103181-1.next.stderr b/tests/ui/impl-trait/issue-103181-1.next.stderr index e6804588d0b4e..83410dfc6ea90 100644 --- a/tests/ui/impl-trait/issue-103181-1.next.stderr +++ b/tests/ui/impl-trait/issue-103181-1.next.stderr @@ -1,10 +1,3 @@ -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) error[E0046]: not all trait items implemented, missing: `Error` --> $DIR/issue-103181-1.rs:11:5 | @@ -14,13 +7,6 @@ LL | } LL | impl HttpBody for () { | ^^^^^^^^^^^^^^^^^^^^ missing `Error` in implementation -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [!0, &RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:34 ~ issue_103181_1[ac79]::hyper::{impl#2}::'a), 'a) }) ()], def_id: DefId(0:47 ~ issue_103181_1[ac79]::hyper::Service::Response) }) error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0046`.