rustc_next_trait_solver/solve/eval_ctxt/
fast_path.rs1use rustc_type_ir::inherent::*;
9use rustc_type_ir::solve::{
10 Certainty, ComputeGoalFastPathOutcome, Goal, GoalStalledOn, GoalStalledOnOpaques, MaybeInfo,
11 SucceededInErased,
12};
13use rustc_type_ir::{InferCtxtLike, Interner};
14
15use crate::delegate::SolverDelegate;
16use crate::solve::eval_ctxt::{RerunDecision, should_rerun_after_erased_canonicalization};
17use crate::solve::{GoalEvaluation, HasChanged};
18
19#[derive(#[automatically_derived]
impl ::core::fmt::Debug for RerunStalled {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
RerunStalled::WontMakeProgress(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"WontMakeProgress", &__self_0),
RerunStalled::MayMakeProgress =>
::core::fmt::Formatter::write_str(f, "MayMakeProgress"),
}
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for RerunStalled {
#[inline]
fn clone(&self) -> RerunStalled {
let _: ::core::clone::AssertParamIsClone<MaybeInfo>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for RerunStalled { }Copy)]
20pub(super) enum RerunStalled {
21 WontMakeProgress(MaybeInfo),
22 MayMakeProgress,
23}
24
25#[inline(never)]
30pub(super) fn rerunning_stalled_goal_may_make_progress<D, I>(
31 delegate: &D,
32 stalled_on: Option<&GoalStalledOn<I>>,
33) -> RerunStalled
34where
35 D: SolverDelegate<Interner = I>,
36 I: Interner,
37{
38 inlined_rerunning_stalled_goal_may_make_progress(delegate, stalled_on)
39}
40
41#[inline(always)]
43pub(super) fn inlined_rerunning_stalled_goal_may_make_progress<D, I>(
44 delegate: &D,
45 stalled_on: Option<&GoalStalledOn<I>>,
46) -> RerunStalled
47where
48 D: SolverDelegate<Interner = I>,
49 I: Interner,
50{
51 use RerunStalled::*;
52
53 if delegate.disable_trait_solver_fast_paths() {
55 return MayMakeProgress;
56 }
57
58 let Some(&GoalStalledOn { ref opaques, ref stalled_vars, ref sub_roots, stalled_maybe_info }) =
60 stalled_on
61 else {
62 return MayMakeProgress;
63 };
64
65 if stalled_vars.iter().any(|value| delegate.ty_or_const_infer_var_changed(*value)) {
68 return MayMakeProgress;
69 }
70
71 if sub_roots.iter().any(|&vid| !delegate.is_sub_unification_table_root_var(vid)) {
74 return MayMakeProgress;
75 }
76
77 match opaques {
78 GoalStalledOnOpaques::No => {}
79 &GoalStalledOnOpaques::Yes {
80 num_opaques_in_storage,
81 ref previously_succeeded_in_erased,
82 } => {
83 if delegate
86 .opaque_types_storage_num_entries()
87 .needs_reevaluation(num_opaques_in_storage)
88 {
89 let mut previous_erased_run_is_still_valid = false;
94
95 if let &SucceededInErased::Yes { accessed_opaques } = previously_succeeded_in_erased
96 {
97 match should_rerun_after_erased_canonicalization(
98 accessed_opaques,
99 delegate.typing_mode_raw(),
100 &delegate.clone_opaque_types_lookup_table(),
101 ) {
102 RerunDecision::Yes => {}
103 RerunDecision::EagerlyPropagateToParent => {
104 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("we never retry stalled queries if the parent was erased")));
}unreachable!("we never retry stalled queries if the parent was erased")
105 }
106 RerunDecision::No => {
107 previous_erased_run_is_still_valid = true;
108 }
109 }
110 }
111
112 if !previous_erased_run_is_still_valid {
113 return MayMakeProgress;
114 }
115 }
116 }
117 }
118
119 WontMakeProgress(stalled_maybe_info)
122}
123
124#[cold]
132#[inline(never)]
133pub(super) fn compute_goal_fast_path_cold<D, I>(
134 delegate: &D,
135 goal: Goal<I, I::Predicate>,
136 origin_span: I::Span,
137) -> Option<GoalEvaluation<I>>
138where
139 D: SolverDelegate<Interner = I>,
140 I: Interner,
141{
142 compute_goal_fast_path(delegate, goal, origin_span)
143}
144
145pub fn compute_goal_fast_path<D, I>(
148 delegate: &D,
149 goal: Goal<I, I::Predicate>,
150 origin_span: I::Span,
151) -> Option<GoalEvaluation<I>>
152where
153 D: SolverDelegate<Interner = I>,
154 I: Interner,
155{
156 if delegate.disable_trait_solver_fast_paths() {
157 return None;
158 }
159
160 match delegate.compute_goal_fast_path(goal, origin_span) {
161 ComputeGoalFastPathOutcome::NoFastPath => None,
162 ComputeGoalFastPathOutcome::TriviallyHolds => Some(GoalEvaluation {
163 goal,
164 certainty: Certainty::Yes,
165 has_changed: HasChanged::No,
166 stalled_on: None,
167 }),
168 ComputeGoalFastPathOutcome::TriviallyStalled { stalled_on } => Some(GoalEvaluation {
169 goal,
170 certainty: Certainty::AMBIGUOUS,
171 has_changed: HasChanged::No,
172 stalled_on: Some(stalled_on),
173 }),
174 }
175}