Skip to content

Commit 3c00c96

Browse files
committed
Auto merge of #158705 - ShoyuVanilla:search-graph-depth-fixup, r=lcnr
Use `LowerAvailableDepth::No` for normalizes-to goal itself instead of its nested goals Might fix perf regressions in #157718 (comment)
2 parents 3659db0 + ed57bc8 commit 3c00c96

4 files changed

Lines changed: 31 additions & 37 deletions

File tree

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_type_ir::inherent::*;
88
use rustc_type_ir::region_constraint::RegionConstraint;
99
use rustc_type_ir::relate::Relate;
1010
use rustc_type_ir::relate::solver_relating::RelateExt;
11-
use rustc_type_ir::search_graph::{CandidateHeadUsages, IncreaseDepthForNested, PathKind};
11+
use rustc_type_ir::search_graph::{CandidateHeadUsages, LowerAvailableDepth, PathKind};
1212
use rustc_type_ir::solve::{
1313
AccessedOpaques, ExternalRegionConstraints, FetchEligibleAssocItemResponse, MaybeInfo,
1414
NoSolutionOrRerunNonErased, OpaqueTypesJank, QueryResultOrRerunNonErased, RerunCondition,
@@ -484,7 +484,7 @@ where
484484
stalled_on: Option<GoalStalledOn<I>>,
485485
) -> Result<GoalEvaluation<I>, NoSolutionOrRerunNonErased> {
486486
let (normalization_nested_goals, goal_evaluation) =
487-
self.evaluate_goal_raw(source, goal, stalled_on, IncreaseDepthForNested::Yes)?;
487+
self.evaluate_goal_raw(source, goal, stalled_on, LowerAvailableDepth::Yes)?;
488488
assert!(normalization_nested_goals.is_empty());
489489
Ok(goal_evaluation)
490490
}
@@ -576,7 +576,7 @@ where
576576
source: GoalSource,
577577
goal: Goal<I, I::Predicate>,
578578
stalled_on: Option<GoalStalledOn<I>>,
579-
increase_depth_for_nested: IncreaseDepthForNested,
579+
increase_depth_for_nested: LowerAvailableDepth,
580580
) -> Result<(NestedNormalizationGoals<I>, GoalEvaluation<I>), NoSolutionOrRerunNonErased> {
581581
if let RerunStalled::WontMakeProgress(stalled_certainty) =
582582
self.rerunning_stalled_goal_may_make_progress(stalled_on.as_ref())
@@ -601,7 +601,7 @@ where
601601
&mut self,
602602
source: GoalSource,
603603
goal: Goal<I, I::Predicate>,
604-
increase_depth_for_nested: IncreaseDepthForNested,
604+
increase_depth_for_nested: LowerAvailableDepth,
605605
) -> Result<(NestedNormalizationGoals<I>, GoalEvaluation<I>), NoSolutionOrRerunNonErased> {
606606
// We only care about one entry per `OpaqueTypeKey` here,
607607
// so we only canonicalize the lookup table and ignore

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ mod free_alias;
33
mod inherent;
44
mod opaque_types;
55

6-
use rustc_type_ir::search_graph::IncreaseDepthForNested;
6+
use rustc_type_ir::search_graph::LowerAvailableDepth;
77
use rustc_type_ir::solve::QueryResultOrRerunNonErased;
88
use rustc_type_ir::{self as ty, Interner, ProjectionPredicate};
99
use tracing::{instrument, trace};
@@ -72,14 +72,12 @@ where
7272
GoalSource::TypeRelating,
7373
normalizes_to,
7474
None,
75-
// We don't increase depth for nested goals for this `NormalizesTo` goal, as
76-
// evaluating `NormalizesTo` is an extra step only exists in the new solver
77-
// that behaves like a function call rather than an independent nested goal
78-
// evaluation, so increasing the depth may end up regressions which hit the
79-
// recursion limits for crates compiled well with the old solver. Furthermore,
80-
// those nested goals from `NormalizesTo` will be evaluated again as the
81-
// caller's nested goals with increased depths anyway.
82-
IncreaseDepthForNested::No,
75+
// We don't lower thr available depth for this `NormalizesTo` goal, as evaluating
76+
// it is an extra step only exists in the new solver that behaves like a function
77+
// call rather than an independent nested goal evaluation. So, decreasing the
78+
// available depth may end up regressions which hit the recursion limits for crates
79+
// compiled well with the old solver.
80+
LowerAvailableDepth::No,
8381
)?;
8482

8583
trace!(?nested_goals);

compiler/rustc_type_ir/src/search_graph/mod.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,16 @@ impl CandidateHeadUsages {
262262
}
263263
}
264264

265+
/// Whether evaluating a given goal should be done with a lower available depth from
266+
/// its parent goal.
267+
///
268+
/// Normally, it should be `Yes`, but among rustc's predicate goals, `normalizes-to`
269+
/// goals are exceptions. They act like functions that used for normalizing associated
270+
/// terms while evaluating projection goals with fully unconstrained expected term.
271+
/// We don't want to lower the available depths for those function-like goals, otherwise
272+
/// we will encounter recursion limit overflows more often.
265273
#[derive(Debug, Clone, Copy)]
266-
pub enum IncreaseDepthForNested {
274+
pub enum LowerAvailableDepth {
267275
Yes,
268276
No,
269277
}
@@ -280,11 +288,12 @@ impl AvailableDepth {
280288
fn allowed_depth_for_nested<D: Delegate>(
281289
root_depth: AvailableDepth,
282290
stack: &Stack<D::Cx>,
291+
lower_available_depth: LowerAvailableDepth,
283292
) -> Option<AvailableDepth> {
284293
if let Some(last) = stack.last() {
285-
match last.increase_depth_for_nested {
286-
IncreaseDepthForNested::Yes => {}
287-
IncreaseDepthForNested::No => {
294+
match lower_available_depth {
295+
LowerAvailableDepth::Yes => {}
296+
LowerAvailableDepth::No => {
288297
return Some(last.available_depth);
289298
}
290299
}
@@ -754,7 +763,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
754763
available_depth,
755764
min_reached_available_depth: available_depth,
756765
provisional_result: None,
757-
increase_depth_for_nested: IncreaseDepthForNested::Yes,
758766
heads: Default::default(),
759767
encountered_overflow: false,
760768
usages: None,
@@ -775,12 +783,14 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
775783
cx: X,
776784
input: X::Input,
777785
step_kind_from_parent: PathKind,
778-
increase_depth_for_nested: IncreaseDepthForNested,
786+
lower_available_depth: LowerAvailableDepth,
779787
inspect: &mut D::ProofTreeBuilder,
780788
) -> X::Result {
781-
let Some(available_depth) =
782-
AvailableDepth::allowed_depth_for_nested::<D>(self.root_depth, &self.stack)
783-
else {
789+
let Some(available_depth) = AvailableDepth::allowed_depth_for_nested::<D>(
790+
self.root_depth,
791+
&self.stack,
792+
lower_available_depth,
793+
) else {
784794
return self.handle_overflow(cx, input);
785795
};
786796

@@ -832,7 +842,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
832842
available_depth,
833843
provisional_result: None,
834844
min_reached_available_depth: available_depth,
835-
increase_depth_for_nested,
836845
heads: Default::default(),
837846
encountered_overflow: false,
838847
usages: None,
@@ -1430,7 +1439,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
14301439
// We can keep these goals from previous iterations as they are only
14311440
// ever read after finalizing this evaluation.
14321441
min_reached_available_depth: stack_entry.min_reached_available_depth,
1433-
increase_depth_for_nested: stack_entry.increase_depth_for_nested,
14341442
heads: stack_entry.heads,
14351443
nested_goals: stack_entry.nested_goals,
14361444
// We reset these two fields when rerunning this goal. We could

compiler/rustc_type_ir/src/search_graph/stack.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use derive_where::derive_where;
44
use rustc_index::IndexVec;
55

66
use crate::search_graph::{
7-
AvailableDepth, CandidateHeadUsages, Cx, CycleHeads, HeadUsages, IncreaseDepthForNested,
8-
NestedGoals, PathKind,
7+
AvailableDepth, CandidateHeadUsages, Cx, CycleHeads, HeadUsages, NestedGoals, PathKind,
98
};
109

1110
rustc_index::newtype_index! {
@@ -33,17 +32,6 @@ pub(super) struct StackEntry<X: Cx> {
3332
/// If there's no nested goal, this is equal to the `available_depth`.
3433
pub min_reached_available_depth: AvailableDepth,
3534

36-
/// Whether evaluating nested goals of a given goal should increase the depth.
37-
///
38-
/// Normally, it should be `Yes`, but among rustc's predicate goals, `normalizes-to`
39-
/// goals are exceptions. They act like functions that used for normalizing associated
40-
/// terms while evaluating projection goals and since their expected terms are always fully
41-
/// unconstrained intentionally, they often return ambiguous nested goals to the caller's
42-
/// context. As these nested goals are evaluated again in the caller's context, we don't
43-
/// want to increase depths when they are evaluated as nested goals for `normalizes-to`
44-
/// goals, otherwise we will encounter recursion limit overflows more often.
45-
pub increase_depth_for_nested: IncreaseDepthForNested,
46-
4735
/// Starts out as `None` and gets set when rerunning this
4836
/// goal in case we encounter a cycle.
4937
pub provisional_result: Option<X::Result>,

0 commit comments

Comments
 (0)