Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_type_ir::inherent::*;
use rustc_type_ir::region_constraint::RegionConstraint;
use rustc_type_ir::relate::Relate;
use rustc_type_ir::relate::solver_relating::RelateExt;
use rustc_type_ir::search_graph::{CandidateHeadUsages, IncreaseDepthForNested, PathKind};
use rustc_type_ir::search_graph::{CandidateHeadUsages, LowerAvailableDepth, PathKind};
use rustc_type_ir::solve::{
AccessedOpaques, ExternalRegionConstraints, FetchEligibleAssocItemResponse, MaybeInfo,
NoSolutionOrRerunNonErased, OpaqueTypesJank, QueryResultOrRerunNonErased, RerunCondition,
Expand Down Expand Up @@ -484,7 +484,7 @@ where
stalled_on: Option<GoalStalledOn<I>>,
) -> Result<GoalEvaluation<I>, NoSolutionOrRerunNonErased> {
let (normalization_nested_goals, goal_evaluation) =
self.evaluate_goal_raw(source, goal, stalled_on, IncreaseDepthForNested::Yes)?;
self.evaluate_goal_raw(source, goal, stalled_on, LowerAvailableDepth::Yes)?;
assert!(normalization_nested_goals.is_empty());
Ok(goal_evaluation)
}
Expand Down Expand Up @@ -576,7 +576,7 @@ where
source: GoalSource,
goal: Goal<I, I::Predicate>,
stalled_on: Option<GoalStalledOn<I>>,
increase_depth_for_nested: IncreaseDepthForNested,
increase_depth_for_nested: LowerAvailableDepth,
) -> Result<(NestedNormalizationGoals<I>, GoalEvaluation<I>), NoSolutionOrRerunNonErased> {
if let RerunStalled::WontMakeProgress(stalled_certainty) =
self.rerunning_stalled_goal_may_make_progress(stalled_on.as_ref())
Expand All @@ -601,7 +601,7 @@ where
&mut self,
source: GoalSource,
goal: Goal<I, I::Predicate>,
increase_depth_for_nested: IncreaseDepthForNested,
increase_depth_for_nested: LowerAvailableDepth,
) -> Result<(NestedNormalizationGoals<I>, GoalEvaluation<I>), NoSolutionOrRerunNonErased> {
// We only care about one entry per `OpaqueTypeKey` here,
// so we only canonicalize the lookup table and ignore
Expand Down
16 changes: 7 additions & 9 deletions compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod free_alias;
mod inherent;
mod opaque_types;

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

trace!(?nested_goals);
Expand Down
30 changes: 19 additions & 11 deletions compiler/rustc_type_ir/src/search_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,16 @@ impl CandidateHeadUsages {
}
}

/// Whether evaluating a given goal should be done with a lower available depth from
/// its parent goal.
///
/// Normally, it should be `Yes`, but among rustc's predicate goals, `normalizes-to`
/// goals are exceptions. They act like functions that used for normalizing associated
/// terms while evaluating projection goals with fully unconstrained expected term.
/// We don't want to lower the available depths for those function-like goals, otherwise
/// we will encounter recursion limit overflows more often.
#[derive(Debug, Clone, Copy)]
pub enum IncreaseDepthForNested {
pub enum LowerAvailableDepth {
Yes,
No,
}
Expand All @@ -280,11 +288,12 @@ impl AvailableDepth {
fn allowed_depth_for_nested<D: Delegate>(
root_depth: AvailableDepth,
stack: &Stack<D::Cx>,
lower_available_depth: LowerAvailableDepth,
) -> Option<AvailableDepth> {
if let Some(last) = stack.last() {
match last.increase_depth_for_nested {
IncreaseDepthForNested::Yes => {}
IncreaseDepthForNested::No => {
match lower_available_depth {
LowerAvailableDepth::Yes => {}
LowerAvailableDepth::No => {
return Some(last.available_depth);
}
}
Expand Down Expand Up @@ -754,7 +763,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
available_depth,
min_reached_available_depth: available_depth,
provisional_result: None,
increase_depth_for_nested: IncreaseDepthForNested::Yes,
heads: Default::default(),
encountered_overflow: false,
usages: None,
Expand All @@ -775,12 +783,14 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
cx: X,
input: X::Input,
step_kind_from_parent: PathKind,
increase_depth_for_nested: IncreaseDepthForNested,
lower_available_depth: LowerAvailableDepth,
inspect: &mut D::ProofTreeBuilder,
) -> X::Result {
let Some(available_depth) =
AvailableDepth::allowed_depth_for_nested::<D>(self.root_depth, &self.stack)
else {
let Some(available_depth) = AvailableDepth::allowed_depth_for_nested::<D>(
self.root_depth,
&self.stack,
lower_available_depth,
) else {
return self.handle_overflow(cx, input);
};

Expand Down Expand Up @@ -832,7 +842,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
available_depth,
provisional_result: None,
min_reached_available_depth: available_depth,
increase_depth_for_nested,
heads: Default::default(),
encountered_overflow: false,
usages: None,
Expand Down Expand Up @@ -1430,7 +1439,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
// We can keep these goals from previous iterations as they are only
// ever read after finalizing this evaluation.
min_reached_available_depth: stack_entry.min_reached_available_depth,
increase_depth_for_nested: stack_entry.increase_depth_for_nested,
heads: stack_entry.heads,
nested_goals: stack_entry.nested_goals,
// We reset these two fields when rerunning this goal. We could
Expand Down
14 changes: 1 addition & 13 deletions compiler/rustc_type_ir/src/search_graph/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use derive_where::derive_where;
use rustc_index::IndexVec;

use crate::search_graph::{
AvailableDepth, CandidateHeadUsages, Cx, CycleHeads, HeadUsages, IncreaseDepthForNested,
NestedGoals, PathKind,
AvailableDepth, CandidateHeadUsages, Cx, CycleHeads, HeadUsages, NestedGoals, PathKind,
};

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

/// Whether evaluating nested goals of a given goal should increase the depth.
///
/// Normally, it should be `Yes`, but among rustc's predicate goals, `normalizes-to`
/// goals are exceptions. They act like functions that used for normalizing associated
/// terms while evaluating projection goals and since their expected terms are always fully
/// unconstrained intentionally, they often return ambiguous nested goals to the caller's
/// context. As these nested goals are evaluated again in the caller's context, we don't
/// want to increase depths when they are evaluated as nested goals for `normalizes-to`
/// goals, otherwise we will encounter recursion limit overflows more often.
pub increase_depth_for_nested: IncreaseDepthForNested,

/// Starts out as `None` and gets set when rerunning this
/// goal in case we encounter a cycle.
pub provisional_result: Option<X::Result>,
Expand Down
Loading