Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking Issue for ptr_cast_add_auto_to_object future compatibility warning #127323

Open
WaffleLapkin opened this issue Jul 4, 2024 · 2 comments
Labels
A-raw-pointers Area: raw pointers, MaybeUninit, NonNull A-trait-objects Area: trait objects, vtable layout C-future-compatibility Category: Future-compatibility lints C-tracking-issue Category: A tracking issue for an RFC or an unstable feature.

Comments

@WaffleLapkin
Copy link
Member

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
}
@WaffleLapkin WaffleLapkin added C-future-compatibility Category: Future-compatibility lints C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. A-raw-pointers Area: raw pointers, MaybeUninit, NonNull A-trait-objects Area: trait objects, vtable layout labels Jul 4, 2024
@bjorn3
Copy link
Member

bjorn3 commented Jul 4, 2024

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:

Future compatibility warnings are generally made hard errors after a while, right? I don't think we should suggest suppressing a future compatibility warning.

@WaffleLapkin
Copy link
Member Author

@bjorn3 we only will make cases with the warning into errors. transmuteing is, and will be, allowed (although you do actually need to make sure that your code is sound).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-raw-pointers Area: raw pointers, MaybeUninit, NonNull A-trait-objects Area: trait objects, vtable layout C-future-compatibility Category: Future-compatibility lints C-tracking-issue Category: A tracking issue for an RFC or an unstable feature.
Projects
None yet
Development

No branches or pull requests

2 participants