about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-03-19 17:53:43 +0000
committerMichael Goulet <michael@errs.io>2025-04-23 18:04:25 +0000
commit257f68777f469bdd26d4763dc0cbd99c99b74e1d (patch)
tree07ac0b5e8b6931c5ccf470de705404cfcf84752b
parentbe181dd75c83d72fcc95538e235768bc367b76b9 (diff)
downloadrust-257f68777f469bdd26d4763dc0cbd99c99b74e1d.tar.gz
rust-257f68777f469bdd26d4763dc0cbd99c99b74e1d.zip
Use the new solver in the impossible_predicates
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs14
-rw-r--r--tests/ui/traits/vtable/impossible-method.rs38
2 files changed, 43 insertions, 9 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 0987c5b42d8..7a744dfc2ad 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -690,8 +690,11 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
 /// used during analysis.
 pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause<'tcx>>) -> bool {
     debug!("impossible_predicates(predicates={:?})", predicates);
-    let (infcx, param_env) =
-        tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized());
+    let (infcx, param_env) = tcx
+        .infer_ctxt()
+        .with_next_trait_solver(true)
+        .build_with_typing_env(ty::TypingEnv::fully_monomorphized());
+
     let ocx = ObligationCtxt::new(&infcx);
     let predicates = ocx.normalize(&ObligationCause::dummy(), param_env, predicates);
     for predicate in predicates {
@@ -704,13 +707,6 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
         return true;
     }
 
-    // Leak check for any higher-ranked trait mismatches.
-    // We only need to do this in the old solver, since the new solver already
-    // leak-checks.
-    if !infcx.next_trait_solver() && infcx.leak_check(ty::UniverseIndex::ROOT, None).is_err() {
-        return true;
-    }
-
     false
 }
 
diff --git a/tests/ui/traits/vtable/impossible-method.rs b/tests/ui/traits/vtable/impossible-method.rs
new file mode 100644
index 00000000000..ff7910cfac8
--- /dev/null
+++ b/tests/ui/traits/vtable/impossible-method.rs
@@ -0,0 +1,38 @@
+//@ run-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+trait Id {
+    type This<'a>;
+}
+impl<T> Id for T {
+    type This<'a> = T;
+}
+
+trait Trait<T> {}
+impl<T: Id> Trait<for<'a> fn(T::This<'a>)> for T {}
+
+trait Method<T: Id> {
+    fn call_me(&self)
+    where
+        T: Trait<for<'a> fn(T::This<'a>)>;
+}
+
+impl<T, U> Method<U> for T {
+    fn call_me(&self) {
+        println!("method was reachable");
+    }
+}
+
+fn generic<T: Id>(x: &dyn Method<T>) {
+    // Proving `T: Trait<for<'a> fn(T::This<'a>)>` holds.
+    x.call_me();
+}
+
+fn main() {
+    // Proving `u32: Trait<fn(u32)>` fails due to incompleteness.
+    // We don't add the method to the vtable of `dyn Method`, so
+    // calling it causes UB.
+    generic::<u32>(&());
+}