Repository: rust
Issue: Tracking issue for future-incompatibility lint `tyvar_behind_raw_pointer`
Labels: A-lints,T-lang,T-compiler,C-future-incompatibility,C-tracking-issue

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](https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md).

**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:
```Rust
        let s = libc::getenv(k.as_ptr()) as *const _;
        s.is_null()
```

This can be fixed by giving a type annotation to the cast:
```Rust
        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:

```Rust
#![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:
```Rust
#![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!).

```Rust
#![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.