You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Auto merge of rust-lang#120248 - WaffleLapkin:bonk-ptr-object-casts, r=<try>
Make casts of pointers to trait objects stricter
This is an attempt to `fix` rust-lang#120222 and rust-lang#120217.
This is done by adding restrictions on casting pointers to trait objects. Currently the restriction is
> When casting `*const X<dyn A>` -> `*const Y<dyn B>`, if `B` has a principal trait, `dyn A + 'erased: Unsize<dyn B + 'erased>` must hold
This ensures that
1. Principal trait's generic arguments match (no `*const dyn Tr<A>` -> `*const dyn Tr<B>` casts, which are a problem for [rust-lang#120222](rust-lang#120222))
2. Principal trait's lifetime arguments match (no `*const dyn Tr<'a>` -> `*const dyn Tr<'b>` casts, which are a problem for [rust-lang#120217](rust-lang#120217))
3. No auto traits can be _added_ (this is a problem for arbitrary self types, see [this comment](rust-lang#120248 (comment)))
Some notes:
- We only care about the metadata/last field, so you can still cast `*const dyn T` to `*const WithHeader<dyn T>`, etc
- The lifetime of the trait object itself (`dyn A + 'lt`) is not checked, so you can still cast `*mut FnOnce() + '_` to `*mut FnOnce() + 'static`, etc
- This feels fishy, but I couldn't come up with a reason it must be checked
- The new checks are only done if `B` has a principal, so you can still do any kinds of cast, if the target only has auto traits
- This is because auto traits are not enough to get unsoundness issues that this PR fixes
- ...and so it makes sense to minimize breakage
The plan is to, ~~once the checks are properly implemented~~, run crate to determine how much damage does this do.
The diagnostics are currently not great, to say the least, but as far as I can tell this correctly fixes the issues.
cc `@oli-obk` `@compiler-errors` `@lcnr`
error[E0277]: the trait bound `dyn Trait<'_>: Unsize<dyn Trait<'_> + Send>` is not satisfied
2
+
--> $DIR/ptr-to-trait-obj-add-auto.rs:6:5
3
+
|
4
+
LL | x as _
5
+
| ^^^^^^ the trait `Unsize<dyn Trait<'_> + Send>` is not implemented for `dyn Trait<'_>`
6
+
|
7
+
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
8
+
9
+
error: aborting due to 1 previous error
10
+
11
+
For more information about this error, try `rustc --explain E0277`.
error[E0277]: the trait bound `dyn A: Unsize<dyn B>` is not satisfied
2
+
--> $DIR/ptr-to-trait-obj-different-args.rs:19:27
3
+
|
4
+
LL | let b: *const dyn B = a as _;
5
+
| ^^^^^^ the trait `Unsize<dyn B>` is not implemented for `dyn A`
6
+
|
7
+
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
8
+
9
+
error[E0277]: the trait bound `dyn Trait<X>: Unsize<dyn Trait<Y>>` is not satisfied
10
+
--> $DIR/ptr-to-trait-obj-different-args.rs:22:34
11
+
|
12
+
LL | let y: *const dyn Trait<Y> = x as _;
13
+
| ^^^^^^ the trait `Unsize<dyn Trait<Y>>` is not implemented for `dyn Trait<X>`
14
+
|
15
+
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
16
+
17
+
error[E0277]: the trait bound `dyn Trait<X>: Unsize<dyn Trait<T>>` is not satisfied
18
+
--> $DIR/ptr-to-trait-obj-different-args.rs:28:34
19
+
|
20
+
LL | let _: *const dyn Trait<T> = x as _;
21
+
| ^^^^^^ the trait `Unsize<dyn Trait<T>>` is not implemented for `dyn Trait<X>`
22
+
|
23
+
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
24
+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
error[E0277]: the trait bound `dyn Trait<T>: Unsize<dyn Trait<X>>` is not satisfied
30
+
--> $DIR/ptr-to-trait-obj-different-args.rs:29:34
31
+
|
32
+
LL | let _: *const dyn Trait<X> = t as _;
33
+
| ^^^^^^ the trait `Unsize<dyn Trait<X>>` is not implemented for `dyn Trait<T>`
34
+
|
35
+
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
36
+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
error[E0277]: the trait bound `dyn Assocked<Assoc = u8>: Unsize<dyn Assocked<Assoc = u32>>` is not satisfied
42
+
--> $DIR/ptr-to-trait-obj-different-args.rs:37:5
43
+
|
44
+
LL | x as _
45
+
| ^^^^^^ the trait `Unsize<dyn Assocked<Assoc = u32>>` is not implemented for `dyn Assocked<Assoc = u8>`
46
+
|
47
+
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
48
+
49
+
error: aborting due to 5 previous errors
50
+
51
+
For more information about this error, try `rustc --explain E0277`.
0 commit comments