-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-dyn-traitArea: trait objects, vtable layoutArea: trait objects, vtable layoutA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.A-raw-pointersArea: raw pointers, MaybeUninit, NonNullArea: raw pointers, MaybeUninit, NonNullC-future-incompatibilityCategory: Future-incompatibility lintsCategory: Future-incompatibility lintsC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-arbitrary_self_types`#![feature(arbitrary_self_types)]``#![feature(arbitrary_self_types)]`F-derive_coerce_pointeeFeature: RFC 3621's oft-renamed implementationFeature: RFC 3621's oft-renamed implementationT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
This is a tracking issue for the ptr_cast_add_auto_to_object
lint, which was added in #120248.
This lint detects casts of raw pointers to trait objects, which add auto traits. Adding auto traits to trait objects may cause UB when #![feature(arbitrary_self_types)]
is used.
Example
#![feature(arbitrary_self_types)]
trait Trait {
fn f(self: *const Self)
where
Self: Send;
}
impl Trait for *const () {
fn f(self: *const Self) {
unreachable!()
}
}
fn main() {
let unsend: *const () = &();
let unsend: *const dyn Trait = &unsend;
let send_bad: *const (dyn Trait + Send) = unsend as _;
send_bad.f(); // this crashes, since vtable for `*const ()` does not have an entry for `f`
//~^ warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on
}
In case your usage is sound (e.g. because the trait doesn't have auto trait bounds), you can replace cast with a transmute to suppress the warning:
trait Cat {}
impl Cat for *const () {}
fn main() {
let unsend: *const () = &();
let unsend: *const dyn Cat = &unsend;
let _send: *const (dyn Cat + Send) = unsafe {
// Safety:
// - Both types are pointers, to the same trait object (and thus have the same vtable)
// - `Cat` does not have methods with `Send` bounds
std::mem::transmute::<*const dyn Cat, *const (dyn Cat + Send)>(unsend)
};
// meow
}
Metadata
Metadata
Assignees
Labels
A-dyn-traitArea: trait objects, vtable layoutArea: trait objects, vtable layoutA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.A-raw-pointersArea: raw pointers, MaybeUninit, NonNullArea: raw pointers, MaybeUninit, NonNullC-future-incompatibilityCategory: Future-incompatibility lintsCategory: Future-incompatibility lintsC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-arbitrary_self_types`#![feature(arbitrary_self_types)]``#![feature(arbitrary_self_types)]`F-derive_coerce_pointeeFeature: RFC 3621's oft-renamed implementationFeature: RFC 3621's oft-renamed implementationT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.