about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-05-07 11:09:21 -0400
committerMichael Goulet <michael@errs.io>2024-05-13 23:58:33 -0400
commitdbd2ca6478dca81dc4ed64f9dec09fb216d34f1a (patch)
tree1e69b1a123de5dddc79edcd512c89956b13f5016
parent9105c57b7f6623310e33f3ee7e48a3114e5190a7 (diff)
downloadrust-dbd2ca6478dca81dc4ed64f9dec09fb216d34f1a.tar.gz
rust-dbd2ca6478dca81dc4ed64f9dec09fb216d34f1a.zip
Use a proper probe for shadowing impl
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect.rs2
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect/format.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs19
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs34
5 files changed, 39 insertions, 22 deletions
diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs
index 2ddcb8aab25..9e944899026 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect.rs
@@ -153,6 +153,8 @@ pub enum ProbeKind<'tcx> {
     /// 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.
     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.
     OpaqueTypeStorageLookup { result: QueryResult<'tcx> },
 }
diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
index e652f0586c4..5b3c50cb973 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
@@ -118,6 +118,9 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
             ProbeKind::TraitCandidate { source, result } => {
                 write!(self.f, "CANDIDATE {source:?}: {result:?}")
             }
+            ProbeKind::ShadowedEnvProbing => {
+                write!(self.f, "PROBING FOR IMPLS SHADOWED BY PARAM-ENV CANDIDATE:")
+            }
         }?;
 
         self.nested(|this| {
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 9a027d7f937..97bea28f06a 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -1,7 +1,7 @@
 //! Code shared by trait and projection goals for candidate assembly.
 
 use crate::solve::GoalSource;
-use crate::solve::{inspect, EvalCtxt, SolverMode};
+use crate::solve::{EvalCtxt, SolverMode};
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::query::NoSolution;
 use rustc_middle::bug;
@@ -16,7 +16,6 @@ use rustc_middle::ty::{fast_reject, TypeFoldable};
 use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
 use rustc_span::{ErrorGuaranteed, DUMMY_SP};
 use std::fmt::Debug;
-use std::mem;
 
 pub(super) mod structural_traits;
 
@@ -792,17 +791,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, G>,
         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 trait_goal: Goal<'tcx, ty::TraitPredicate<'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);
-        self.assemble_alias_bound_candidates(trait_goal, &mut trait_candidates_from_env);
+
+        let mut trait_candidates_from_env = vec![];
+        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() {
             let trait_env_result = self.merge_candidates(trait_candidates_from_env);
             match trait_env_result.unwrap().value.certainty {
@@ -831,7 +829,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 }
             }
         }
-        self.inspect = inspect;
     }
 
     /// If there are multiple ways to prove a trait or projection goal, we have
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index 6fda5f4af25..68c0c8bf09e 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -176,7 +176,8 @@ fn to_selection<'tcx>(
         | ProbeKind::UnsizeAssembly
         | ProbeKind::UpcastProjectionCompatibility
         | ProbeKind::OpaqueTypeStorageLookup { result: _ }
-        | ProbeKind::Root { result: _ } => {
+        | ProbeKind::Root { result: _ }
+        | ProbeKind::ShadowedEnvProbing => {
             span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
         }
     })
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index fd36b7ffd4e..b71a1b339cb 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -18,8 +18,8 @@ use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{inspect, QueryResult};
 use rustc_middle::traits::solve::{Certainty, Goal};
 use rustc_middle::traits::ObligationCause;
-use rustc_middle::ty;
 use rustc_middle::ty::TypeFoldable;
+use rustc_middle::{bug, ty};
 use rustc_span::{Span, DUMMY_SP};
 
 use crate::solve::eval_ctxt::canonical;
@@ -290,12 +290,25 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
             match *step {
                 inspect::ProbeStep::AddGoal(source, goal) => nested_goals.push((source, goal)),
                 inspect::ProbeStep::NestedProbe(ref probe) => {
-                    // 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);
+                    match probe.kind {
+                        // These never assemble candidates for the goal we're trying to solve.
+                        inspect::ProbeKind::UpcastProjectionCompatibility
+                        | inspect::ProbeKind::ShadowedEnvProbing => continue,
+
+                        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 } => {
                     assert_eq!(shallow_certainty.replace(c), None);
@@ -308,9 +321,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
         }
 
         match probe.kind {
-            inspect::ProbeKind::NormalizedSelfTyAssembly
-            | inspect::ProbeKind::UnsizeAssembly
-            | inspect::ProbeKind::UpcastProjectionCompatibility => (),
+            inspect::ProbeKind::UpcastProjectionCompatibility
+            | inspect::ProbeKind::ShadowedEnvProbing => bug!(),
+
+            inspect::ProbeKind::NormalizedSelfTyAssembly | inspect::ProbeKind::UnsizeAssembly => {}
 
             // We add a candidate even for the root evaluation if there
             // is only one way to prove a given goal, e.g. for `WellFormed`.