Skip to content

Commit 57cea32

Browse files
authored
Rollup merge of rust-lang#120248 - WaffleLapkin:bonk-ptr-object-casts, r=compiler-errors,oli-obk,lnicola
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. Before this PR the rules were as follows: > When casting `*const X<dyn A>` -> `*const Y<dyn B>`, principal traits in `A` and `B` must refer to the same trait definition (or no trait). With this PR the rules are changed to > When casting `*const X<dyn Src>` -> `*const Y<dyn Dst>` > - if `Dst` has a principal trait `DstP`, > - `Src` must have a principal trait `SrcP` > - `dyn SrcP` and `dyn DstP` must be the same type (modulo the trait object lifetime, `dyn T+'a` -> `dyn T+'b` is allowed) > - Auto traits in `Dst` must be a subset of auto traits in `Src` > - Not adhering to this is currently a FCW (warn-by-default + `FutureReleaseErrorReportInDeps`), instead of an error > - if `Src` has a principal trait `Dst` must as well > - this restriction will be removed in a follow up PR 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 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`
2 parents e466bf5 + 297850a commit 57cea32

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

alloc/src/boxed.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2374,7 +2374,7 @@ impl dyn Error + Send {
23742374
let err: Box<dyn Error> = self;
23752375
<dyn Error>::downcast(err).map_err(|s| unsafe {
23762376
// Reapply the `Send` marker.
2377-
Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send))
2377+
mem::transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
23782378
})
23792379
}
23802380
}
@@ -2387,8 +2387,8 @@ impl dyn Error + Send + Sync {
23872387
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
23882388
let err: Box<dyn Error> = self;
23892389
<dyn Error>::downcast(err).map_err(|s| unsafe {
2390-
// Reapply the `Send + Sync` marker.
2391-
Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send + Sync))
2390+
// Reapply the `Send + Sync` markers.
2391+
mem::transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
23922392
})
23932393
}
23942394
}

0 commit comments

Comments
 (0)