Use a proper probe for shadowing impl
This commit is contained in:
parent
9105c57b7f
commit
dbd2ca6478
@ -153,6 +153,8 @@ pub enum ProbeKind<'tcx> {
|
|||||||
/// do a probe to find out what projection type(s) may be used to prove that
|
/// do a probe to find out what projection type(s) may be used to prove that
|
||||||
/// the source type upholds all of the target type's object bounds.
|
/// the source type upholds all of the target type's object bounds.
|
||||||
UpcastProjectionCompatibility,
|
UpcastProjectionCompatibility,
|
||||||
|
/// Looking for param-env candidates that satisfy the trait ref for a projection.
|
||||||
|
ShadowedEnvProbing,
|
||||||
/// Try to unify an opaque type with an existing key in the storage.
|
/// Try to unify an opaque type with an existing key in the storage.
|
||||||
OpaqueTypeStorageLookup { result: QueryResult<'tcx> },
|
OpaqueTypeStorageLookup { result: QueryResult<'tcx> },
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,9 @@ pub(super) fn format_probe(&mut self, probe: &Probe<'_>) -> std::fmt::Result {
|
|||||||
ProbeKind::TraitCandidate { source, result } => {
|
ProbeKind::TraitCandidate { source, result } => {
|
||||||
write!(self.f, "CANDIDATE {source:?}: {result:?}")
|
write!(self.f, "CANDIDATE {source:?}: {result:?}")
|
||||||
}
|
}
|
||||||
|
ProbeKind::ShadowedEnvProbing => {
|
||||||
|
write!(self.f, "PROBING FOR IMPLS SHADOWED BY PARAM-ENV CANDIDATE:")
|
||||||
|
}
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
self.nested(|this| {
|
self.nested(|this| {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Code shared by trait and projection goals for candidate assembly.
|
//! Code shared by trait and projection goals for candidate assembly.
|
||||||
|
|
||||||
use crate::solve::GoalSource;
|
use crate::solve::GoalSource;
|
||||||
use crate::solve::{inspect, EvalCtxt, SolverMode};
|
use crate::solve::{EvalCtxt, SolverMode};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
@ -16,7 +16,6 @@
|
|||||||
use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
|
use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
|
||||||
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
|
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
pub(super) mod structural_traits;
|
pub(super) mod structural_traits;
|
||||||
|
|
||||||
@ -792,17 +791,16 @@ fn discard_impls_shadowed_by_env<G: GoalKind<'tcx>>(
|
|||||||
goal: Goal<'tcx, G>,
|
goal: Goal<'tcx, G>,
|
||||||
candidates: &mut Vec<Candidate<'tcx>>,
|
candidates: &mut Vec<Candidate<'tcx>>,
|
||||||
) {
|
) {
|
||||||
// HACK: We temporarily remove the `ProofTreeBuilder` to
|
|
||||||
// avoid adding `Trait` candidates to the candidates used
|
|
||||||
// to prove the current goal.
|
|
||||||
let inspect = mem::replace(&mut self.inspect, inspect::ProofTreeBuilder::new_noop());
|
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> =
|
let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> =
|
||||||
goal.with(tcx, goal.predicate.trait_ref(tcx));
|
goal.with(tcx, goal.predicate.trait_ref(tcx));
|
||||||
let mut trait_candidates_from_env = Vec::new();
|
|
||||||
self.assemble_param_env_candidates(trait_goal, &mut trait_candidates_from_env);
|
let mut trait_candidates_from_env = vec![];
|
||||||
self.assemble_alias_bound_candidates(trait_goal, &mut trait_candidates_from_env);
|
self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
|
||||||
|
ecx.assemble_param_env_candidates(trait_goal, &mut trait_candidates_from_env);
|
||||||
|
ecx.assemble_alias_bound_candidates(trait_goal, &mut trait_candidates_from_env);
|
||||||
|
});
|
||||||
|
|
||||||
if !trait_candidates_from_env.is_empty() {
|
if !trait_candidates_from_env.is_empty() {
|
||||||
let trait_env_result = self.merge_candidates(trait_candidates_from_env);
|
let trait_env_result = self.merge_candidates(trait_candidates_from_env);
|
||||||
match trait_env_result.unwrap().value.certainty {
|
match trait_env_result.unwrap().value.certainty {
|
||||||
@ -831,7 +829,6 @@ fn discard_impls_shadowed_by_env<G: GoalKind<'tcx>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.inspect = inspect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If there are multiple ways to prove a trait or projection goal, we have
|
/// If there are multiple ways to prove a trait or projection goal, we have
|
||||||
|
@ -176,7 +176,8 @@ fn to_selection<'tcx>(
|
|||||||
| ProbeKind::UnsizeAssembly
|
| ProbeKind::UnsizeAssembly
|
||||||
| ProbeKind::UpcastProjectionCompatibility
|
| ProbeKind::UpcastProjectionCompatibility
|
||||||
| ProbeKind::OpaqueTypeStorageLookup { result: _ }
|
| ProbeKind::OpaqueTypeStorageLookup { result: _ }
|
||||||
| ProbeKind::Root { result: _ } => {
|
| ProbeKind::Root { result: _ }
|
||||||
|
| ProbeKind::ShadowedEnvProbing => {
|
||||||
span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
|
span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
use rustc_middle::traits::solve::{inspect, QueryResult};
|
use rustc_middle::traits::solve::{inspect, QueryResult};
|
||||||
use rustc_middle::traits::solve::{Certainty, Goal};
|
use rustc_middle::traits::solve::{Certainty, Goal};
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty;
|
|
||||||
use rustc_middle::ty::TypeFoldable;
|
use rustc_middle::ty::TypeFoldable;
|
||||||
|
use rustc_middle::{bug, ty};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
|
||||||
use crate::solve::eval_ctxt::canonical;
|
use crate::solve::eval_ctxt::canonical;
|
||||||
@ -290,12 +290,25 @@ fn candidates_recur(
|
|||||||
match *step {
|
match *step {
|
||||||
inspect::ProbeStep::AddGoal(source, goal) => nested_goals.push((source, goal)),
|
inspect::ProbeStep::AddGoal(source, goal) => nested_goals.push((source, goal)),
|
||||||
inspect::ProbeStep::NestedProbe(ref probe) => {
|
inspect::ProbeStep::NestedProbe(ref probe) => {
|
||||||
// Nested probes have to prove goals added in their parent
|
match probe.kind {
|
||||||
// but do not leak them, so we truncate the added goals
|
// These never assemble candidates for the goal we're trying to solve.
|
||||||
// afterwards.
|
inspect::ProbeKind::UpcastProjectionCompatibility
|
||||||
let num_goals = nested_goals.len();
|
| inspect::ProbeKind::ShadowedEnvProbing => continue,
|
||||||
self.candidates_recur(candidates, nested_goals, probe);
|
|
||||||
nested_goals.truncate(num_goals);
|
inspect::ProbeKind::NormalizedSelfTyAssembly
|
||||||
|
| inspect::ProbeKind::UnsizeAssembly
|
||||||
|
| inspect::ProbeKind::Root { .. }
|
||||||
|
| inspect::ProbeKind::TryNormalizeNonRigid { .. }
|
||||||
|
| inspect::ProbeKind::TraitCandidate { .. }
|
||||||
|
| inspect::ProbeKind::OpaqueTypeStorageLookup { .. } => {
|
||||||
|
// Nested probes have to prove goals added in their parent
|
||||||
|
// but do not leak them, so we truncate the added goals
|
||||||
|
// afterwards.
|
||||||
|
let num_goals = nested_goals.len();
|
||||||
|
self.candidates_recur(candidates, nested_goals, probe);
|
||||||
|
nested_goals.truncate(num_goals);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
|
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
|
||||||
assert_eq!(shallow_certainty.replace(c), None);
|
assert_eq!(shallow_certainty.replace(c), None);
|
||||||
@ -308,9 +321,10 @@ fn candidates_recur(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match probe.kind {
|
match probe.kind {
|
||||||
inspect::ProbeKind::NormalizedSelfTyAssembly
|
inspect::ProbeKind::UpcastProjectionCompatibility
|
||||||
| inspect::ProbeKind::UnsizeAssembly
|
| inspect::ProbeKind::ShadowedEnvProbing => bug!(),
|
||||||
| inspect::ProbeKind::UpcastProjectionCompatibility => (),
|
|
||||||
|
inspect::ProbeKind::NormalizedSelfTyAssembly | inspect::ProbeKind::UnsizeAssembly => {}
|
||||||
|
|
||||||
// We add a candidate even for the root evaluation if there
|
// We add a candidate even for the root evaluation if there
|
||||||
// is only one way to prove a given goal, e.g. for `WellFormed`.
|
// is only one way to prove a given goal, e.g. for `WellFormed`.
|
||||||
|
Loading…
Reference in New Issue
Block a user