Skip to content

Tracking issue for future-incompatibility lint tyvar_behind_raw_pointer #46906

Open
@mikeyhew

Description

@mikeyhew

This is the summary issue for the tyvar_behind_raw_pointer future-compatibility warning and other related errors. The goal of this page is describe why this change was made and how you can fix code that is affected by it. It also provides a place to ask questions or register a complaint if you feel the change should not be made. For more information on the policy around future-compatibility warnings, see our breaking change policy guidelines.

What is the warning for?

This warning occurs when you call a method on a value whose type is a raw pointer to an unknown type (aka *const _ or *mut _), or a type that dereferences to one of these.

The most common case for this is casts, for example:

        let s = libc::getenv(k.as_ptr()) as *const _;
        s.is_null()

This can be fixed by giving a type annotation to the cast:

        let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
        s.is_null()

The reason that this is going to become an error is because we are working on enabling arbitrary self types. Using that, you should be able to write functions such as:

#![feature(arbitrary_self_types)]

struct MyType;

impl MyType {
    fn is_null(self: *mut Self) -> bool {
        println!("?");
        true
    }
}

While that case is obviously silly, we can't prevent a sibling crate from implementing it, and such a function would make a call to s.is_null() when the type of s is an *mut _ ambiguous. Therefore, to avoid that potential breakage, you have to annotate the type of your raw pointer before the point of the method call.

After you fix these warnings, if you are working with raw pointers on nightly, you might want to check out #![feature(arbitrary_self_types)] yourself! It even works with trait objects:

#![feature(arbitrary_self_types, dyn_trait)]
trait Foo {
    fn example(self: *mut Self);
}

struct S;
impl Foo for S {
    fn example(self: *mut Self) {
        println!("Hello, I'm at {:?}", self);
    }
}

fn foo(foo: *mut dyn Foo) {
    foo.example();
}

fn main() {
    // This is 100% safe and not UB, even through I am calling `foo`
    // with a null pointer - this is a *raw* null pointer, and these are
    // always ok.
    foo(0 as *mut S);
}

While I'm at it, arbitrary_self_types also works for smart pointers, such as Rc<T> or Arc<T> (however, unfortunately we still have not figured out the best way to make it work with smart pointers to trait objects, so you can't yet create dyn Bar trait objects. We are planning on making it eventually work, so stay tuned!).

#![feature(arbitrary_self_types)]

use std::rc::Rc;

trait Bar {
    fn example(self: &Rc<Self>);
}

struct S;
impl Bar for S {
    fn example(self: &Rc<Self>) {
        println!("Hi I'm called on an Rc.");
        let _x = self.clone(); // You can call Rc::clone on Self!
    }
}

fn main() {
    Rc::new(S).example();
}

When will this warning become a hard error?

At the beginning of each 6-week release cycle, the Rust compiler team will review the set of outstanding future compatibility warnings and nominate some of them for Final Comment Period. Toward the end of the cycle, we will review any comments and make a final determination whether to convert the warning into a hard error or remove it entirely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.C-future-incompatibilityCategory: Future-incompatibility lintsC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    Status

    Idea

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions