about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/traits/mod.rs
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-10-17 12:31:48 -0400
committerMichael Goulet <michael@errs.io>2024-10-17 12:32:31 -0400
commit8ff8f78e4ca8a898697412a3895cb3070f161d1e (patch)
treef2664d190dc5941da58aa25b3162501c7bb28b7e /compiler/rustc_trait_selection/src/traits/mod.rs
parent3a85d3fa785d95a7b7bcf4f160b67bffba7afd4a (diff)
downloadrust-8ff8f78e4ca8a898697412a3895cb3070f161d1e.tar.gz
rust-8ff8f78e4ca8a898697412a3895cb3070f161d1e.zip
Dont consider predicates that may hold as impossible in is_impossible_associated_item
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/mod.rs')
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs26
1 files changed, 14 insertions, 12 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 0fb795fc184..834363b849c 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -562,11 +562,20 @@ fn is_impossible_associated_item(
 
     let generics = tcx.generics_of(trait_item_def_id);
     let predicates = tcx.predicates_of(trait_item_def_id);
+
+    // Be conservative in cases where we have `W<T: ?Sized>` and a method like `Self: Sized`,
+    // since that method *may* have some substitutions where the predicates hold.
+    //
+    // This replicates the logic we use in coherence.
+    let infcx =
+        tcx.infer_ctxt().ignoring_regions().with_next_trait_solver(true).intercrate(true).build();
+    let param_env = ty::ParamEnv::empty();
+    let fresh_args = infcx.fresh_args_for_item(tcx.def_span(impl_def_id), impl_def_id);
+
     let impl_trait_ref = tcx
         .impl_trait_ref(impl_def_id)
         .expect("expected impl to correspond to trait")
-        .instantiate_identity();
-    let param_env = tcx.param_env(impl_def_id);
+        .instantiate(tcx, fresh_args);
 
     let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id };
     let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| {
@@ -580,16 +589,9 @@ fn is_impossible_associated_item(
         })
     });
 
-    let infcx = tcx.infer_ctxt().ignoring_regions().build();
-    for obligation in predicates_for_trait {
-        // Ignore overflow error, to be conservative.
-        if let Ok(result) = infcx.evaluate_obligation(&obligation)
-            && !result.may_apply()
-        {
-            return true;
-        }
-    }
-    false
+    let ocx = ObligationCtxt::new(&infcx);
+    ocx.register_obligations(predicates_for_trait);
+    !ocx.select_where_possible().is_empty()
 }
 
 pub fn provide(providers: &mut Providers) {