Auto merge of #142774 - lcnr:search_graph-2, r=oli-obk
`evaluate_goal` avoid unnecessary step
based on rust-lang/rust#142617.
This does not mess with the debug logging for the trait solver and is a very nice cleanup for rust-lang/rust#142735. E.g. for
```rust
#[derive(Clone)]
struct Wrapper<T>(T);
#[derive(Clone)]
struct Nested; // using a separate type to avoid the fast paths
fn is_clone<T: Clone>() {}
fn main() {
is_clone::<Wrapper<Nested>>();
}
```
We get the following proof tree with `RUSTC_LOG=rustc_type_ir::search_graph=debug,rustc_next_trait_solver=debug`
```
rustc_next_trait_solver::solve::eval_ctxt::evaluate_root_goal goal=Goal { param_env: ParamEnv { caller_bounds: [] }, predicate: Binder { value: TraitPredicate(<Wrapper<Nested> as std::clone::Clone>, polarity:Positive), bound_vars: [] } }, generate_proof_tree=No, span=src/main.rs:7:5: 7:34 (#0), stalled_on=None
rustc_type_ir::search_graph::evaluate_goal input=CanonicalQueryInput { canonical: Canonical { value: QueryInput { goal: Goal { param_env: ParamEnv { caller_bounds: [] }, predicate: Binder { value: TraitPredicate(<Wrapper<Nested> as std::clone::Clone>, polarity:Positive), bound_vars: [] } }, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] }, typing_mode: Analysis { defining_opaque_types_and_generators: [] } }, step_kind_from_parent=Unknown
rustc_next_trait_solver::solve::eval_ctxt::probe::enter source=Impl(DefId(0:10 ~ main[21d2]::{impl#0}))
rustc_next_trait_solver::solve::eval_ctxt::add_goal source=ImplWhereBound, goal=Goal { param_env: ParamEnv { caller_bounds: [] }, predicate: Binder { value: TraitPredicate(<_ as std::marker::Sized>, polarity:Positive), bound_vars: [] } }
rustc_next_trait_solver::solve::eval_ctxt::add_goal source=ImplWhereBound, goal=Goal { param_env: ParamEnv { caller_bounds: [] }, predicate: Binder { value: TraitPredicate(<_ as std::clone::Clone>, polarity:Positive), bound_vars: [] } }
rustc_type_ir::search_graph::evaluate_goal input=CanonicalQueryInput { canonical: Canonical { value: QueryInput { goal: Goal { param_env: ParamEnv { caller_bounds: [] }, predicate: Binder { value: TraitPredicate(<Nested as std::clone::Clone>, polarity:Positive), bound_vars: [] } }, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] }, typing_mode: Analysis { defining_opaque_types_and_generators: [] } }, step_kind_from_parent=Unknown
0ms DEBUG rustc_type_ir::search_graph global cache hit, required_depth=0
0ms DEBUG rustc_type_ir::search_graph return=Ok(Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: [], opaque_types: [], normalization_nested_goals: NestedNormalizationGoals([]) }) }, max_universe: U0, variables: [] })
rustc_next_trait_solver::solve::eval_ctxt::probe::enter source=BuiltinImpl(Misc)
rustc_next_trait_solver::solve::trait_goals::merge_trait_candidates candidates=[Candidate { source: Impl(DefId(0:10 ~ main[21d2]::{impl#0})), result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: [], opaque_types: [], normalization_nested_goals: NestedNormalizationGoals([]) }) }, max_universe: U0, variables: [] } }]
0ms DEBUG rustc_next_trait_solver::solve::trait_goals return=Ok((Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: [], opaque_types: [], normalization_nested_goals: NestedNormalizationGoals([]) }) }, max_universe: U0, variables: [] }, Some(Misc)))
0ms DEBUG rustc_type_ir::search_graph insert global cache, evaluation_result=EvaluationResult { encountered_overflow: false, required_depth: 1, heads: CycleHeads { heads: {} }, nested_goals: NestedGoals { nested_goals: {} }, result: Ok(Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: [], opaque_types: [], normalization_nested_goals: NestedNormalizationGoals([]) }) }, max_universe: U0, variables: [] }) }
0ms DEBUG rustc_type_ir::search_graph return=Ok(Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: [], opaque_types: [], normalization_nested_goals: NestedNormalizationGoals([]) }) }, max_universe: U0, variables: [] })
```
This commit is contained in:
@@ -37,7 +37,7 @@ pub struct InspectGoal<'a, 'tcx> {
|
||||
orig_values: Vec<ty::GenericArg<'tcx>>,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
result: Result<Certainty, NoSolution>,
|
||||
evaluation_kind: inspect::CanonicalGoalEvaluationKind<TyCtxt<'tcx>>,
|
||||
evaluation_kind: inspect::GoalEvaluationKind<TyCtxt<'tcx>>,
|
||||
normalizes_to_term_hack: Option<NormalizesToTermHack<'tcx>>,
|
||||
source: GoalSource,
|
||||
}
|
||||
@@ -393,8 +393,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
||||
let mut candidates = vec![];
|
||||
let last_eval_step = match &self.evaluation_kind {
|
||||
// An annoying edge case in case the recursion limit is 0.
|
||||
inspect::CanonicalGoalEvaluationKind::Overflow => return vec![],
|
||||
inspect::CanonicalGoalEvaluationKind::Evaluation { final_revision } => final_revision,
|
||||
inspect::GoalEvaluationKind::Overflow => return vec![],
|
||||
inspect::GoalEvaluationKind::Evaluation { final_revision } => final_revision,
|
||||
};
|
||||
|
||||
let mut nested_goals = vec![];
|
||||
@@ -426,10 +426,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
||||
) -> Self {
|
||||
let infcx = <&SolverDelegate<'tcx>>::from(infcx);
|
||||
|
||||
let inspect::GoalEvaluation { uncanonicalized_goal, orig_values, evaluation } = root;
|
||||
let inspect::GoalEvaluation { uncanonicalized_goal, orig_values, kind, result } = root;
|
||||
// If there's a normalizes-to goal, AND the evaluation result with the result of
|
||||
// constraining the normalizes-to RHS and computing the nested goals.
|
||||
let result = evaluation.result.and_then(|ok| {
|
||||
let result = result.and_then(|ok| {
|
||||
let nested_goals_certainty =
|
||||
term_hack_and_nested_certainty.map_or(Ok(Certainty::Yes), |(_, c)| c)?;
|
||||
Ok(ok.value.certainty.and(nested_goals_certainty))
|
||||
@@ -441,7 +441,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
||||
orig_values,
|
||||
goal: eager_resolve_vars(infcx, uncanonicalized_goal),
|
||||
result,
|
||||
evaluation_kind: evaluation.kind,
|
||||
evaluation_kind: kind,
|
||||
normalizes_to_term_hack: term_hack_and_nested_certainty.map(|(n, _)| n),
|
||||
source,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user