Skip to content

Commit 4017434

Browse files
Auto merge of #145934 - lcnr:test-return-sized-obligations, r=<try>
[DO NOT MERGE] `-Znext-solver` test `Certainty::Yes` when only ambiguous goals are "trivial"
2 parents b2dd217 + 2f21f9a commit 4017434

File tree

5 files changed

+111
-75
lines changed

5 files changed

+111
-75
lines changed

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ use std::iter;
1414
use rustc_index::IndexVec;
1515
use rustc_type_ir::data_structures::HashSet;
1616
use rustc_type_ir::inherent::*;
17+
use rustc_type_ir::lang_items::TraitSolverLangItem;
1718
use rustc_type_ir::relate::solver_relating::RelateExt;
1819
use rustc_type_ir::{
19-
self as ty, Canonical, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable,
20+
self as ty, Canonical, CanonicalVarValues, ClauseKind, InferCtxtLike, Interner, TypeFoldable,
2021
};
2122
use tracing::{debug, instrument, trace};
2223

@@ -133,6 +134,43 @@ where
133134
),
134135
)
135136
}
137+
(_, Certainty::Yes) => {
138+
let goals = std::mem::take(&mut self.nested_goals);
139+
// As we return all ambiguous nested goals, we can ignore the certainty
140+
// returned by `self.try_evaluate_added_goals()`.
141+
if goals.is_empty() {
142+
assert!(matches!(goals_certainty, Certainty::Yes));
143+
}
144+
if goals.iter().all(|(_, g, _)| {
145+
let Some(clause) = g.predicate.as_clause() else {
146+
return false;
147+
};
148+
match clause.kind().skip_binder() {
149+
ClauseKind::Trait(pred) => {
150+
let def_id = pred.def_id();
151+
(self.cx().is_lang_item(def_id, TraitSolverLangItem::Sized)
152+
|| self
153+
.cx()
154+
.is_lang_item(def_id, TraitSolverLangItem::MetaSized))
155+
&& self.resolve_vars_if_possible(pred).self_ty().is_ty_var()
156+
}
157+
ClauseKind::WellFormed(arg) => {
158+
self.resolve_vars_if_possible(arg).is_infer()
159+
}
160+
_ => false,
161+
}
162+
}) {
163+
(
164+
Certainty::Yes,
165+
NestedNormalizationGoals(
166+
goals.into_iter().map(|(s, g, _)| (s, g)).collect(),
167+
),
168+
)
169+
} else {
170+
let certainty = shallow_certainty.and(goals_certainty);
171+
(certainty, NestedNormalizationGoals::empty())
172+
}
173+
}
136174
_ => {
137175
let certainty = shallow_certainty.and(goals_certainty);
138176
(certainty, NestedNormalizationGoals::empty())

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 28 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,7 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
171171
&self,
172172
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
173173
span: <Self::Interner as Interner>::Span,
174-
) -> (
175-
Result<
176-
(NestedNormalizationGoals<Self::Interner>, GoalEvaluation<Self::Interner>),
177-
NoSolution,
178-
>,
179-
inspect::GoalEvaluation<Self::Interner>,
180-
);
174+
) -> (Result<GoalEvaluation<Self::Interner>, NoSolution>, inspect::GoalEvaluation<Self::Interner>);
181175
}
182176

183177
impl<D, I> SolverDelegateEvalExt for D
@@ -221,16 +215,13 @@ where
221215
&self,
222216
goal: Goal<I, I::Predicate>,
223217
span: I::Span,
224-
) -> (
225-
Result<(NestedNormalizationGoals<I>, GoalEvaluation<I>), NoSolution>,
226-
inspect::GoalEvaluation<I>,
227-
) {
218+
) -> (Result<GoalEvaluation<I>, NoSolution>, inspect::GoalEvaluation<I>) {
228219
let (result, proof_tree) = EvalCtxt::enter_root(
229220
self,
230221
self.cx().recursion_limit(),
231222
GenerateProofTree::Yes,
232223
span,
233-
|ecx| ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal, None),
224+
|ecx| ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal, None),
234225
);
235226
(result, proof_tree.unwrap())
236227
}
@@ -411,26 +402,6 @@ where
411402
goal: Goal<I, I::Predicate>,
412403
stalled_on: Option<GoalStalledOn<I>>,
413404
) -> Result<GoalEvaluation<I>, NoSolution> {
414-
let (normalization_nested_goals, goal_evaluation) =
415-
self.evaluate_goal_raw(goal_evaluation_kind, source, goal, stalled_on)?;
416-
assert!(normalization_nested_goals.is_empty());
417-
Ok(goal_evaluation)
418-
}
419-
420-
/// Recursively evaluates `goal`, returning the nested goals in case
421-
/// the nested goal is a `NormalizesTo` goal.
422-
///
423-
/// As all other goal kinds do not return any nested goals and
424-
/// `NormalizesTo` is only used by `AliasRelate`, all other callsites
425-
/// should use [`EvalCtxt::evaluate_goal`] which discards that empty
426-
/// storage.
427-
pub(super) fn evaluate_goal_raw(
428-
&mut self,
429-
goal_evaluation_kind: GoalEvaluationKind,
430-
source: GoalSource,
431-
goal: Goal<I, I::Predicate>,
432-
stalled_on: Option<GoalStalledOn<I>>,
433-
) -> Result<(NestedNormalizationGoals<I>, GoalEvaluation<I>), NoSolution> {
434405
// If we have run this goal before, and it was stalled, check that any of the goal's
435406
// args have changed. Otherwise, we don't need to re-run the goal because it'll remain
436407
// stalled, since it'll canonicalize the same way and evaluation is pure.
@@ -441,15 +412,13 @@ where
441412
.opaque_types_storage_num_entries()
442413
.needs_reevaluation(stalled_on.num_opaques)
443414
{
444-
return Ok((
445-
NestedNormalizationGoals::empty(),
446-
GoalEvaluation {
447-
goal,
448-
certainty: Certainty::Maybe(stalled_on.stalled_cause),
449-
has_changed: HasChanged::No,
450-
stalled_on: Some(stalled_on),
451-
},
452-
));
415+
return Ok(GoalEvaluation {
416+
goal,
417+
certainty: Certainty::Maybe(stalled_on.stalled_cause),
418+
has_changed: HasChanged::No,
419+
stalled_on: Some(stalled_on),
420+
nested_goals: NestedNormalizationGoals::empty(),
421+
});
453422
}
454423

455424
// We only care about one entry per `OpaqueTypeKey` here,
@@ -477,7 +446,7 @@ where
477446
let has_changed =
478447
if !has_only_region_constraints(response) { HasChanged::Yes } else { HasChanged::No };
479448

480-
let (normalization_nested_goals, certainty) =
449+
let (nested_goals, certainty) =
481450
self.instantiate_and_apply_query_response(goal.param_env, &orig_values, response);
482451

483452
// FIXME: We previously had an assert here that checked that recomputing
@@ -536,10 +505,7 @@ where
536505
},
537506
};
538507

539-
Ok((
540-
normalization_nested_goals,
541-
GoalEvaluation { goal, certainty, has_changed, stalled_on },
542-
))
508+
Ok(GoalEvaluation { goal, certainty, has_changed, stalled_on, nested_goals })
543509
}
544510

545511
pub(super) fn compute_goal(&mut self, goal: Goal<I, I::Predicate>) -> QueryResult<I> {
@@ -673,10 +639,13 @@ where
673639
let unconstrained_goal =
674640
goal.with(cx, ty::NormalizesTo { alias: pred.alias, term: unconstrained_rhs });
675641

676-
let (
677-
NestedNormalizationGoals(nested_goals),
678-
GoalEvaluation { goal, certainty, stalled_on, has_changed: _ },
679-
) = self.evaluate_goal_raw(
642+
let GoalEvaluation {
643+
goal,
644+
certainty,
645+
stalled_on,
646+
has_changed: _,
647+
nested_goals: NestedNormalizationGoals(nested_goals),
648+
} = self.evaluate_goal(
680649
GoalEvaluationKind::Nested,
681650
source,
682651
unconstrained_goal,
@@ -733,12 +702,18 @@ where
733702
}
734703
}
735704
} else {
736-
let GoalEvaluation { goal, certainty, has_changed, stalled_on } =
737-
self.evaluate_goal(GoalEvaluationKind::Nested, source, goal, stalled_on)?;
705+
let GoalEvaluation {
706+
goal,
707+
certainty,
708+
has_changed,
709+
stalled_on,
710+
nested_goals: NestedNormalizationGoals(nested_goals),
711+
} = self.evaluate_goal(GoalEvaluationKind::Nested, source, goal, stalled_on)?;
712+
trace!(?nested_goals);
713+
self.nested_goals.extend(nested_goals.into_iter().map(|(s, g)| (s, g, None)));
738714
if has_changed == HasChanged::Yes {
739715
unchanged_certainty = None;
740716
}
741-
742717
match certainty {
743718
Certainty::Yes => {}
744719
Certainty::Maybe(_) => {

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ pub struct GoalEvaluation<I: Interner> {
413413
/// then reevaluating this goal now only needs to resolve `?y` while it would otherwise
414414
/// have to resolve both `?x` and `?y`,
415415
pub goal: Goal<I, I::Predicate>,
416+
pub nested_goals: NestedNormalizationGoals<I>,
416417
pub certainty: Certainty,
417418
pub has_changed: HasChanged,
418419
/// If the [`Certainty`] was `Maybe`, then keep track of whether the goal has changed

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ use rustc_hir::def_id::LocalDefId;
77
use rustc_infer::infer::InferCtxt;
88
use rustc_infer::traits::query::NoSolution;
99
use rustc_infer::traits::{
10-
FromSolverError, PredicateObligation, PredicateObligations, TraitEngine,
10+
FromSolverError, Obligation, ObligationCause, PredicateObligation, PredicateObligations,
11+
TraitEngine,
1112
};
1213
use rustc_middle::ty::{
1314
self, DelayedSet, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
1415
TypingMode,
1516
};
1617
use rustc_next_trait_solver::delegate::SolverDelegate as _;
1718
use rustc_next_trait_solver::solve::{
18-
GoalEvaluation, GoalStalledOn, HasChanged, SolverDelegateEvalExt as _,
19+
GoalEvaluation, GoalStalledOn, HasChanged, NestedNormalizationGoals, SolverDelegateEvalExt as _,
1920
};
2021
use rustc_span::Span;
2122
use thin_vec::ThinVec;
@@ -213,7 +214,13 @@ where
213214

214215
let result = delegate.evaluate_root_goal(goal, obligation.cause.span, stalled_on);
215216
self.inspect_evaluated_obligation(infcx, &obligation, &result);
216-
let GoalEvaluation { goal, certainty, has_changed, stalled_on } = match result {
217+
let GoalEvaluation {
218+
goal,
219+
certainty,
220+
has_changed,
221+
stalled_on,
222+
nested_goals: NestedNormalizationGoals(nested_goals),
223+
} = match result {
217224
Ok(result) => result,
218225
Err(NoSolution) => {
219226
errors.push(E::from_solver_error(
@@ -223,6 +230,18 @@ where
223230
continue;
224231
}
225232
};
233+
for (_, nested_goal) in nested_goals {
234+
self.obligations.register(
235+
Obligation::with_depth(
236+
infcx.tcx,
237+
ObligationCause::misc(obligation.cause.span, obligation.cause.body_id),
238+
obligation.recursion_depth + 1,
239+
nested_goal.param_env,
240+
nested_goal.predicate,
241+
),
242+
None,
243+
);
244+
}
226245

227246
// We've resolved the goal in `evaluate_root_goal`, avoid redoing this work
228247
// in the next iteration. This does not resolve the inference variables

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_middle::ty::{TyCtxt, VisitorResult, try_visit};
2020
use rustc_middle::{bug, ty};
2121
use rustc_next_trait_solver::resolve::eager_resolve_vars;
2222
use rustc_next_trait_solver::solve::inspect::{self, instantiate_canonical_state};
23-
use rustc_next_trait_solver::solve::{MaybeCause, SolverDelegateEvalExt as _};
23+
use rustc_next_trait_solver::solve::{GoalEvaluation, MaybeCause, SolverDelegateEvalExt as _};
2424
use rustc_span::Span;
2525
use tracing::instrument;
2626

@@ -249,23 +249,26 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
249249
// `InspectGoal::new` so that the goal has the right result (and maintains
250250
// the impression that we don't do this normalizes-to infer hack at all).
251251
let (nested, proof_tree) = infcx.evaluate_root_goal_for_proof_tree(goal, span);
252-
let nested_goals_result = nested.and_then(|(nested, _)| {
253-
normalizes_to_term_hack.constrain_and(
254-
infcx,
255-
span,
256-
proof_tree.uncanonicalized_goal.param_env,
257-
|ocx| {
258-
ocx.register_obligations(nested.0.into_iter().map(|(_, goal)| {
259-
Obligation::new(
260-
infcx.tcx,
261-
ObligationCause::dummy_with_span(span),
262-
goal.param_env,
263-
goal.predicate,
264-
)
265-
}));
266-
},
267-
)
268-
});
252+
let nested_goals_result =
253+
nested.and_then(|GoalEvaluation { nested_goals, .. }| {
254+
normalizes_to_term_hack.constrain_and(
255+
infcx,
256+
span,
257+
proof_tree.uncanonicalized_goal.param_env,
258+
|ocx| {
259+
ocx.register_obligations(nested_goals.0.into_iter().map(
260+
|(_, goal)| {
261+
Obligation::new(
262+
infcx.tcx,
263+
ObligationCause::dummy_with_span(span),
264+
goal.param_env,
265+
goal.predicate,
266+
)
267+
},
268+
));
269+
},
270+
)
271+
});
269272
(proof_tree, nested_goals_result)
270273
});
271274
InspectGoal::new(

0 commit comments

Comments
 (0)