diff options
| author | bors <bors@rust-lang.org> | 2025-05-15 15:31:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-05-15 15:31:24 +0000 |
| commit | c4e05e53d19b550a358ee8b2e29ecd5a11075800 (patch) | |
| tree | 8778851085c74c43bc319b87a1f3ba417e02fec7 /tests | |
| parent | d163a28381c297a56417d4a5dfe88c6c65429265 (diff) | |
| parent | 257f68777f469bdd26d4763dc0cbd99c99b74e1d (diff) | |
| download | rust-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.rs | 38 |
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>(&()); +} |
