Skip to content

canonicalize in inspect, work towards intercrate_ambiguity_causes support #114810

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 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
6 changes: 0 additions & 6 deletions compiler/rustc_middle/src/traits/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,3 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
self.opaque_types.visit_with(visitor)
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)]
pub enum IsNormalizesToHack {
Yes,
No,
}
69 changes: 38 additions & 31 deletions compiler/rustc_middle/src/traits/solve/inspect.rs
Original file line number Diff line number Diff line change
@@ -1,70 +1,82 @@
use super::{
CanonicalInput, Certainty, Goal, IsNormalizesToHack, NoSolution, QueryInput, QueryResult,
};
use super::{CanonicalInput, Certainty, Goal, NoSolution, QueryResult};
use crate::infer::canonical::{Canonical, CanonicalVarValues};
use crate::ty;
use format::ProofTreeFormatter;
use std::fmt::{Debug, Write};

mod format;

#[derive(Debug, Clone, Eq, PartialEq, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct State<'tcx, T> {
pub var_values: CanonicalVarValues<'tcx>,
pub data: T,
}
pub type CanonicalState<'tcx, T> = Canonical<'tcx, State<'tcx, T>>;

#[derive(Eq, PartialEq, Debug, Hash, HashStable)]
pub enum CacheHit {
Provisional,
Global,
}

#[derive(Debug, PartialEq, Eq, Hash, HashStable)]
pub enum IsNormalizesToHack {
Yes,
No,
}

#[derive(Eq, PartialEq, Hash, HashStable)]
pub struct GoalEvaluation<'tcx> {
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
pub canonicalized_goal: CanonicalInput<'tcx>,
pub struct RootGoalEvaluation<'tcx> {
pub goal: Goal<'tcx, ty::Predicate<'tcx>>,
pub orig_values: Vec<ty::GenericArg<'tcx>>,
pub evaluation: CanonicalGoalEvaluation<'tcx>,
pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
}

pub kind: GoalEvaluationKind<'tcx>,
#[derive(Eq, PartialEq, Hash, HashStable)]
pub struct NestedGoalEvaluation<'tcx> {
pub goal: CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>,
pub orig_values: CanonicalState<'tcx, Vec<ty::GenericArg<'tcx>>>,
pub is_normalizes_to_hack: IsNormalizesToHack,
pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
pub evaluation: CanonicalGoalEvaluation<'tcx>,
pub returned_goals: Vec<CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
}

#[derive(Eq, PartialEq, Hash, HashStable)]
pub struct CanonicalGoalEvaluation<'tcx> {
pub goal: CanonicalInput<'tcx>,
pub data: GoalEvaluationData<'tcx>,
pub result: QueryResult<'tcx>,
}

#[derive(Eq, PartialEq, Hash, HashStable)]
pub enum GoalEvaluationKind<'tcx> {
pub enum GoalEvaluationData<'tcx> {
CacheHit(CacheHit),
Uncached { revisions: Vec<GoalEvaluationStep<'tcx>> },
}
impl Debug for GoalEvaluation<'_> {
impl Debug for RootGoalEvaluation<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ProofTreeFormatter::new(f).format_goal_evaluation(self)
ProofTreeFormatter::new(f).format_root_goal_evaluation(self)
}
}

#[derive(Eq, PartialEq, Hash, HashStable)]
pub struct AddedGoalsEvaluation<'tcx> {
pub evaluations: Vec<Vec<GoalEvaluation<'tcx>>>,
pub evaluations: Vec<Vec<NestedGoalEvaluation<'tcx>>>,
pub result: Result<Certainty, NoSolution>,
}
impl Debug for AddedGoalsEvaluation<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ProofTreeFormatter::new(f).format_nested_goal_evaluation(self)
}
}

#[derive(Eq, PartialEq, Hash, HashStable)]
pub struct GoalEvaluationStep<'tcx> {
pub instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>,

pub nested_goal_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
pub added_goals_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
pub candidates: Vec<GoalCandidate<'tcx>>,

pub result: QueryResult<'tcx>,
}
impl Debug for GoalEvaluationStep<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ProofTreeFormatter::new(f).format_evaluation_step(self)
}
}

#[derive(Eq, PartialEq, Hash, HashStable)]
pub struct GoalCandidate<'tcx> {
pub nested_goal_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
pub added_goals_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
pub candidates: Vec<GoalCandidate<'tcx>>,
pub kind: CandidateKind<'tcx>,
}
Expand All @@ -83,8 +95,3 @@ pub enum CandidateKind<'tcx> {
/// the source type upholds all of the target type's object bounds.
UpcastProbe,
}
impl Debug for GoalCandidate<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ProofTreeFormatter::new(f).format_candidate(self)
}
}
107 changes: 67 additions & 40 deletions compiler/rustc_middle/src/traits/solve/inspect/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,57 +39,84 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
func(&mut ProofTreeFormatter { f: &mut Indentor { f: self.f, on_newline: true } })
}

pub(super) fn format_goal_evaluation(&mut self, goal: &GoalEvaluation<'_>) -> std::fmt::Result {
let goal_text = match goal.is_normalizes_to_hack {
IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
IsNormalizesToHack::No => "GOAL",
};

writeln!(self.f, "{}: {:?}", goal_text, goal.uncanonicalized_goal)?;
writeln!(self.f, "CANONICALIZED: {:?}", goal.canonicalized_goal)?;

match &goal.kind {
GoalEvaluationKind::CacheHit(CacheHit::Global) => {
writeln!(self.f, "GLOBAL CACHE HIT: {:?}", goal.result)
}
GoalEvaluationKind::CacheHit(CacheHit::Provisional) => {
writeln!(self.f, "PROVISIONAL CACHE HIT: {:?}", goal.result)
}
GoalEvaluationKind::Uncached { revisions } => {
for (n, step) in revisions.iter().enumerate() {
writeln!(self.f, "REVISION {n}: {:?}", step.result)?;
self.nested(|this| this.format_evaluation_step(step))?;
pub(super) fn format_root_goal_evaluation(
&mut self,
eval: &RootGoalEvaluation<'_>,
) -> std::fmt::Result {
writeln!(self.f, "ROOT GOAL: {:?}", eval.goal)?;
self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))?;
if eval.returned_goals.len() > 0 {
writeln!(self.f, "NESTED GOALS ADDED TO CALLER: [")?;
self.nested(|this| {
for goal in eval.returned_goals.iter() {
writeln!(this.f, "ADDED GOAL: {goal:?},")?;
}
writeln!(self.f, "RESULT: {:?}", goal.result)
}
}?;
Ok(())
})?;

writeln!(self.f, "]")
} else {
Ok(())
}
}

if goal.returned_goals.len() > 0 {
pub(super) fn format_nested_goal_evaluation(
&mut self,
eval: &NestedGoalEvaluation<'_>,
) -> std::fmt::Result {
let goal_text = match eval.is_normalizes_to_hack {
IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
IsNormalizesToHack::No => "NESTED GOAL",
};
writeln!(self.f, "{}: {:?}", goal_text, eval.goal)?;
self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))?;
if eval.returned_goals.len() > 0 {
writeln!(self.f, "NESTED GOALS ADDED TO CALLER: [")?;
self.nested(|this| {
for goal in goal.returned_goals.iter() {
for goal in eval.returned_goals.iter() {
writeln!(this.f, "ADDED GOAL: {goal:?},")?;
}
Ok(())
})?;

writeln!(self.f, "]")?;
writeln!(self.f, "]")
} else {
Ok(())
}
}

Ok(())
pub(super) fn format_canonical_goal_evaluation(
&mut self,
eval: &CanonicalGoalEvaluation<'_>,
) -> std::fmt::Result {
writeln!(self.f, "GOAL: {:?}", eval.goal)?;

match &eval.data {
GoalEvaluationData::CacheHit(CacheHit::Global) => {
writeln!(self.f, "GLOBAL CACHE HIT: {:?}", eval.result)
}
GoalEvaluationData::CacheHit(CacheHit::Provisional) => {
writeln!(self.f, "PROVISIONAL CACHE HIT: {:?}", eval.result)
}
GoalEvaluationData::Uncached { revisions } => {
for (n, step) in revisions.iter().enumerate() {
writeln!(self.f, "REVISION {n}: {:?}", step.result)?;
self.format_evaluation_step(step)?;
}
writeln!(self.f, "RESULT: {:?}", eval.result)
}
}
}

pub(super) fn format_evaluation_step(
&mut self,
evaluation_step: &GoalEvaluationStep<'_>,
) -> std::fmt::Result {
writeln!(self.f, "INSTANTIATED: {:?}", evaluation_step.instantiated_goal)?;

for candidate in &evaluation_step.candidates {
self.nested(|this| this.format_candidate(candidate))?;
}
for nested in &evaluation_step.nested_goal_evaluations {
self.nested(|this| this.format_nested_goal_evaluation(nested))?;
for nested in &evaluation_step.added_goals_evaluations {
self.nested(|this| this.format_added_goals_evaluation(nested))?;
}

Ok(())
Expand All @@ -115,24 +142,24 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
for candidate in &candidate.candidates {
this.format_candidate(candidate)?;
}
for nested in &candidate.nested_goal_evaluations {
this.format_nested_goal_evaluation(nested)?;
for nested in &candidate.added_goals_evaluations {
this.format_added_goals_evaluation(nested)?;
}
Ok(())
})
}

pub(super) fn format_nested_goal_evaluation(
pub(super) fn format_added_goals_evaluation(
&mut self,
nested_goal_evaluation: &AddedGoalsEvaluation<'_>,
added_goals_evaluation: &AddedGoalsEvaluation<'_>,
) -> std::fmt::Result {
writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", nested_goal_evaluation.result)?;
writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", added_goals_evaluation.result)?;

for (n, revision) in nested_goal_evaluation.evaluations.iter().enumerate() {
writeln!(self.f, "REVISION {n}")?;
for (n, iterations) in added_goals_evaluation.evaluations.iter().enumerate() {
writeln!(self.f, "ITERATION {n}")?;
self.nested(|this| {
for goal_evaluation in revision {
this.format_goal_evaluation(goal_evaluation)?;
for goal_evaluation in iterations {
this.format_nested_goal_evaluation(goal_evaluation)?;
}
Ok(())
})?;
Expand Down
Loading