Skip to content

Commit 3009b2c

Browse files
committed
initial info dump
1 parent 8d1fa47 commit 3009b2c

File tree

11 files changed

+944
-417
lines changed

11 files changed

+944
-417
lines changed

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ pub enum CodegenObligationError {
981981
FulfillmentError,
982982
}
983983

984-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)]
984+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
985985
pub enum DefiningAnchor {
986986
/// `DefId` of the item.
987987
Bind(LocalDefId),

compiler/rustc_middle/src/traits/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
9292
pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
9393
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;
9494

95-
#[derive(Copy, Clone, Debug, HashStable, PartialEq, Eq)]
95+
#[derive(Copy, Clone, Debug, Hash, HashStable, PartialEq, Eq)]
9696
pub struct NoSolution;
9797

9898
impl<'tcx> From<TypeError<'tcx>> for NoSolution {

compiler/rustc_middle/src/traits/solve.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ use crate::ty::{
1111
TypeVisitor,
1212
};
1313

14+
pub mod inspect;
15+
1416
pub type EvaluationCache<'tcx> = Cache<CanonicalInput<'tcx>, QueryResult<'tcx>>;
1517

1618
/// A goal is a statement, i.e. `predicate`, we want to prove
1719
/// given some assumptions, i.e. `param_env`.
1820
///
1921
/// Most of the time the `param_env` contains the `where`-bounds of the function
2022
/// we're currently typechecking while the `predicate` is some trait bound.
21-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)]
23+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
2224
pub struct Goal<'tcx, P> {
2325
pub predicate: P,
2426
pub param_env: ty::ParamEnv<'tcx>,
@@ -39,15 +41,15 @@ impl<'tcx, P> Goal<'tcx, P> {
3941
}
4042
}
4143

42-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)]
44+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
4345
pub struct Response<'tcx> {
4446
pub certainty: Certainty,
4547
pub var_values: CanonicalVarValues<'tcx>,
4648
/// Additional constraints returned by this query.
4749
pub external_constraints: ExternalConstraints<'tcx>,
4850
}
4951

50-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)]
52+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
5153
pub enum Certainty {
5254
Yes,
5355
Maybe(MaybeCause),
@@ -86,7 +88,7 @@ impl Certainty {
8688
}
8789

8890
/// Why we failed to evaluate a goal.
89-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)]
91+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
9092
pub enum MaybeCause {
9193
/// We failed due to ambiguity. This ambiguity can either
9294
/// be a true ambiguity, i.e. there are multiple different answers,
@@ -96,20 +98,20 @@ pub enum MaybeCause {
9698
Overflow,
9799
}
98100

99-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)]
101+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
100102
pub struct QueryInput<'tcx, T> {
101103
pub goal: Goal<'tcx, T>,
102104
pub anchor: DefiningAnchor,
103105
pub predefined_opaques_in_body: PredefinedOpaques<'tcx>,
104106
}
105107

106108
/// Additional constraints returned on success.
107-
#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)]
109+
#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default)]
108110
pub struct PredefinedOpaquesData<'tcx> {
109111
pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
110112
}
111113

112-
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
114+
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
113115
pub struct PredefinedOpaques<'tcx>(pub(crate) Interned<'tcx, PredefinedOpaquesData<'tcx>>);
114116

115117
impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> {
@@ -132,7 +134,7 @@ pub type CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>;
132134
/// solver, merge the two responses again.
133135
pub type QueryResult<'tcx> = Result<CanonicalResponse<'tcx>, NoSolution>;
134136

135-
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
137+
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
136138
pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>);
137139

138140
impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
@@ -144,7 +146,7 @@ impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
144146
}
145147

146148
/// Additional constraints returned on success.
147-
#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)]
149+
#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default)]
148150
pub struct ExternalConstraintsData<'tcx> {
149151
// FIXME: implement this.
150152
pub region_constraints: QueryRegionConstraints<'tcx>,
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
use super::{CanonicalInput, Certainty, Goal, NoSolution, QueryInput, QueryResult};
2+
use crate::ty;
3+
use std::fmt::{Debug, Write};
4+
5+
#[derive(Eq, PartialEq, Hash, HashStable)]
6+
pub struct GoalEvaluation<'tcx> {
7+
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
8+
pub canonicalized_goal: Option<CanonicalInput<'tcx>>,
9+
10+
/// To handle coinductive cycles we can end up re-evaluating a goal
11+
/// multiple times with different results for a nested goal. Each rerun
12+
/// is represented as an entry in this vec.
13+
pub evaluation_steps: Vec<GoalEvaluationStep<'tcx>>,
14+
15+
pub cache_hit: bool,
16+
17+
pub result: Option<QueryResult<'tcx>>,
18+
}
19+
impl Debug for GoalEvaluation<'_> {
20+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21+
ProofTreeFormatter { f, on_newline: true }.format_goal_evaluation(self)
22+
}
23+
}
24+
25+
#[derive(Eq, PartialEq, Hash, HashStable)]
26+
pub struct AddedGoalsEvaluation<'tcx> {
27+
pub evaluations: Vec<Vec<GoalEvaluation<'tcx>>>,
28+
pub result: Option<Result<Certainty, NoSolution>>,
29+
}
30+
impl Debug for AddedGoalsEvaluation<'_> {
31+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32+
ProofTreeFormatter { f, on_newline: true }.format_nested_goal_evaluation(self)
33+
}
34+
}
35+
36+
#[derive(Eq, PartialEq, Hash, HashStable)]
37+
pub struct GoalEvaluationStep<'tcx> {
38+
pub instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>,
39+
40+
pub nested_goal_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
41+
pub candidates: Vec<GoalCandidate<'tcx>>,
42+
43+
pub result: Option<QueryResult<'tcx>>,
44+
}
45+
impl Debug for GoalEvaluationStep<'_> {
46+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47+
ProofTreeFormatter { f, on_newline: true }.format_evaluation_step(self)
48+
}
49+
}
50+
51+
#[derive(Eq, PartialEq, Hash, HashStable)]
52+
pub struct GoalCandidate<'tcx> {
53+
pub nested_goal_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
54+
pub candidates: Vec<GoalCandidate<'tcx>>,
55+
56+
pub name: Option<String>,
57+
pub result: Option<QueryResult<'tcx>>,
58+
}
59+
impl Debug for GoalCandidate<'_> {
60+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61+
ProofTreeFormatter { f, on_newline: true }.format_candidate(self)
62+
}
63+
}
64+
65+
struct ProofTreeFormatter<'a, 'b> {
66+
f: &'a mut (dyn Write + 'b),
67+
on_newline: bool,
68+
}
69+
70+
impl Write for ProofTreeFormatter<'_, '_> {
71+
fn write_str(&mut self, s: &str) -> std::fmt::Result {
72+
for line in s.split_inclusive("\n") {
73+
if self.on_newline {
74+
self.f.write_str(" ")?;
75+
}
76+
self.on_newline = line.ends_with("\n");
77+
self.f.write_str(line)?;
78+
}
79+
80+
Ok(())
81+
}
82+
}
83+
84+
impl ProofTreeFormatter<'_, '_> {
85+
fn nested(&mut self) -> ProofTreeFormatter<'_, '_> {
86+
ProofTreeFormatter { f: self, on_newline: true }
87+
}
88+
89+
fn format_goal_evaluation(&mut self, goal: &GoalEvaluation<'_>) -> std::fmt::Result {
90+
let f = &mut *self.f;
91+
writeln!(f, "GOAL: {:?}", goal.uncanonicalized_goal)?;
92+
writeln!(f, "CANONICALIZED: {:?}", goal.canonicalized_goal)?;
93+
94+
match goal.cache_hit {
95+
true => writeln!(f, "CACHE HIT: {:?}", goal.result),
96+
false => {
97+
for (n, step) in goal.evaluation_steps.iter().enumerate() {
98+
let f = &mut *self.f;
99+
writeln!(f, "REVISION {n}: {:?}", step.result.unwrap())?;
100+
let mut f = self.nested();
101+
f.format_evaluation_step(step)?;
102+
}
103+
104+
let f = &mut *self.f;
105+
writeln!(f, "RESULT: {:?}", goal.result.unwrap())
106+
}
107+
}
108+
}
109+
110+
fn format_evaluation_step(
111+
&mut self,
112+
evaluation_step: &GoalEvaluationStep<'_>,
113+
) -> std::fmt::Result {
114+
let f = &mut *self.f;
115+
writeln!(f, "INSTANTIATED: {:?}", evaluation_step.instantiated_goal)?;
116+
117+
for candidate in &evaluation_step.candidates {
118+
let mut f = self.nested();
119+
f.format_candidate(candidate)?;
120+
}
121+
for nested_goal_evaluation in &evaluation_step.nested_goal_evaluations {
122+
let mut f = self.nested();
123+
f.format_nested_goal_evaluation(nested_goal_evaluation)?;
124+
}
125+
126+
Ok(())
127+
}
128+
129+
fn format_candidate(&mut self, candidate: &GoalCandidate<'_>) -> std::fmt::Result {
130+
let f = &mut *self.f;
131+
132+
match (candidate.name.as_ref(), candidate.result) {
133+
(Some(name), Some(result)) => writeln!(f, "CANDIDATE {}: {:?}", name, result,)?,
134+
(None, None) => writeln!(f, "MISC PROBE")?,
135+
(None, Some(_)) => unreachable!("unexpected probe with no name but a result"),
136+
(Some(_), None) => unreachable!("unexpected probe with a name but no candidate"),
137+
};
138+
139+
let mut f = self.nested();
140+
for candidate in &candidate.candidates {
141+
f.format_candidate(candidate)?;
142+
}
143+
for nested_evaluations in &candidate.nested_goal_evaluations {
144+
f.format_nested_goal_evaluation(nested_evaluations)?;
145+
}
146+
147+
Ok(())
148+
}
149+
150+
fn format_nested_goal_evaluation(
151+
&mut self,
152+
nested_goal_evaluation: &AddedGoalsEvaluation<'_>,
153+
) -> std::fmt::Result {
154+
let f = &mut *self.f;
155+
writeln!(f, "TRY_EVALUATE_ADDED_GOALS: {:?}", nested_goal_evaluation.result.unwrap())?;
156+
157+
for (n, revision) in nested_goal_evaluation.evaluations.iter().enumerate() {
158+
let f = &mut *self.f;
159+
writeln!(f, "REVISION {n}")?;
160+
let mut f = self.nested();
161+
for goal_evaluation in revision {
162+
f.format_goal_evaluation(goal_evaluation)?;
163+
}
164+
}
165+
166+
Ok(())
167+
}
168+
}

compiler/rustc_trait_selection/src/solve/alias_relate.rs

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
109109
direction: ty::AliasRelationDirection,
110110
invert: Invert,
111111
) -> QueryResult<'tcx> {
112-
self.probe(|ecx| {
113-
ecx.normalizes_to_inner(param_env, alias, other, direction, invert)?;
114-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
115-
})
112+
self.probe_candidate(
113+
|ecx| {
114+
ecx.normalizes_to_inner(param_env, alias, other, direction, invert)?;
115+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
116+
},
117+
|| "normalizes-to".into(),
118+
)
116119
}
117120

118121
fn normalizes_to_inner(
@@ -153,18 +156,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
153156
alias_rhs: ty::AliasTy<'tcx>,
154157
direction: ty::AliasRelationDirection,
155158
) -> QueryResult<'tcx> {
156-
self.probe(|ecx| {
157-
match direction {
158-
ty::AliasRelationDirection::Equate => {
159-
ecx.eq(param_env, alias_lhs, alias_rhs)?;
160-
}
161-
ty::AliasRelationDirection::Subtype => {
162-
ecx.sub(param_env, alias_lhs, alias_rhs)?;
159+
self.probe_candidate(
160+
|ecx| {
161+
match direction {
162+
ty::AliasRelationDirection::Equate => {
163+
ecx.eq(param_env, alias_lhs, alias_rhs)?;
164+
}
165+
ty::AliasRelationDirection::Subtype => {
166+
ecx.sub(param_env, alias_lhs, alias_rhs)?;
167+
}
163168
}
164-
}
165169

166-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
167-
})
170+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
171+
},
172+
|| "substs relate".into(),
173+
)
168174
}
169175

170176
fn assemble_bidirectional_normalizes_to_candidate(
@@ -174,22 +180,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
174180
rhs: ty::Term<'tcx>,
175181
direction: ty::AliasRelationDirection,
176182
) -> QueryResult<'tcx> {
177-
self.probe(|ecx| {
178-
ecx.normalizes_to_inner(
179-
param_env,
180-
lhs.to_alias_ty(ecx.tcx()).unwrap(),
181-
rhs,
182-
direction,
183-
Invert::No,
184-
)?;
185-
ecx.normalizes_to_inner(
186-
param_env,
187-
rhs.to_alias_ty(ecx.tcx()).unwrap(),
188-
lhs,
189-
direction,
190-
Invert::Yes,
191-
)?;
192-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
193-
})
183+
self.probe_candidate(
184+
|ecx| {
185+
ecx.normalizes_to_inner(
186+
param_env,
187+
lhs.to_alias_ty(ecx.tcx()).unwrap(),
188+
rhs,
189+
direction,
190+
Invert::No,
191+
)?;
192+
ecx.normalizes_to_inner(
193+
param_env,
194+
rhs.to_alias_ty(ecx.tcx()).unwrap(),
195+
lhs,
196+
direction,
197+
Invert::Yes,
198+
)?;
199+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
200+
},
201+
|| "bidir normalizes-to".into(),
202+
)
194203
}
195204
}

0 commit comments

Comments
 (0)