about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-05-15 15:31:24 +0000
committerbors <bors@rust-lang.org>2025-05-15 15:31:24 +0000
commitc4e05e53d19b550a358ee8b2e29ecd5a11075800 (patch)
tree8778851085c74c43bc319b87a1f3ba417e02fec7 /tests
parentd163a28381c297a56417d4a5dfe88c6c65429265 (diff)
parent257f68777f469bdd26d4763dc0cbd99c99b74e1d (diff)
downloadrust-c4e05e53d19b550a358ee8b2e29ecd5a11075800.tar.gz
rust-c4e05e53d19b550a358ee8b2e29ecd5a11075800.zip
Auto merge of #136988 - compiler-errors:impossible_predicates, r=lcnr
Use the new solver in the `impossible_predicates`

The old solver is unsound for many reasons. One of which was weaponized by `@lcnr` in #140212, where the old solver was incompletely considering a dyn vtable method to be impossible and replacing its vtable entry with a null value. This null function could be called post-mono.

The new solver is expected to be less incomplete due to its correct handling of higher-ranked aliases in relate. This PR switches the `impossible_predicates` query to use the new solver, which patches this UB.

r? lcnr
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/traits/vtable/impossible-method.rs38
1 files changed, 38 insertions, 0 deletions
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>(&());
+}