Repository navigation
Description
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
Labels
Type
Projects
- StatusShow more project fieldsIdea
Activity
Annotate raw pointer target types
mikeyhew commentedon Dec 23, 2017
@arielb1 thanks for editing with the detailed explanation!
Auto merge of #46914 - mikeyhew:raw_pointer_self, r=arielb1
Add an explicit type to silence a future compatibility warning
SimonSapin commentedon Jan 4, 2018
(Emphasis added.)
I feel that this latter case is overly zealous. A pervasive pattern in Servo’s DOM can be simplified to this:
As of 0a3761e the
handle_mutcall causes atyvar_behind_raw_pointerwarning which does not seem justified:handle_mutis an inherent method ofRootedGuard<T>and so will always be picked before any method ofTthrough auto-deref.arbitrary_self_typeswon’t change that as far as I can tell.Please consider not warning in this case. This example is easy enough to fix (for example by replacing
null_mut()withnull_mut::<JSObject>()), but Servo has 1871 instances of this warning and adding as many type annotation would be a huge pain if they indeed don’t actually remove any ambiguity.Auto merge of #19683 - servo:rustup, r=<try>
(Do not merge )Work around a maybe-false-positive warning
(Do not merge) Work around a maybe-false-positive warning
Auto merge of #19683 - servo:rustup, r=<try>
mikeyhew commentedon Jan 4, 2018
@SimonSapin
During method lookup,
Tis*mut _. That_could theoretically resolve to a type that has a methodfn handle_mut(self: &mut RootedGuard<*mut Self>), which would result an an ambiguity on method lookup. Not to say that defining methods like this is very useful, but that's what's currently allowed witharbitrary_self_types.It's unfortunate that the type information from this function call isn't available during the earlier method lookup. I don't know much about how type inference works in the compiler, but it would be nice if cases like this could be improved.
@arielb1 any thoughts on a possible solution here?
Auto merge of #19683 - servo:rustup, r=<try>
nikomatsakis commentedon Jan 4, 2018
So, my thoughts are these:
There is really not much we can do to get more type information. We already do basically exhaust what remedies we have.
To get more, we'd have to do some big refactorings on the way that method lookup works. I'd like to do this, but it seems pretty distinct from this PR. We'd basically have to make method dispatch "delayable" until more type information is available.
I am a bit nervous about making this change however. I feel like we've seen a fair amount of code affected, though I don't have a real sample. Were any crater runs done to provide actual measurements?
At the worst, we could do the change only behind a feature-gate, and then use an epoch to enable access to custom self types.
39 remaining items
xdispatch: Eliminate the compiler warning "tyvar_behind_raw_pointer"
vext01 commentedon Jun 18, 2020
I've just encountered the same issue on today's nightly:
Gives:
As @arielb1 says, you can fix it by adding type annotations:
But I think the error message was confusing. I'd have known what to do if it had said:
nikomatsakis commentedon Jun 18, 2020
It's probably time to move towards closing this compatibility lint, and maybe we can improve the diagnostics at the same time.
orowith2os commentedon Nov 7, 2023
It appears I've come across this issue, though I don't get why it's happening despite me providing type annotations:
lcnr commentedon Nov 10, 2023
it happens because the type of
raw_pointer_array.cast()is*const _, i.e. a type variable behind a raw pointer. The lint is then emitted while selecting the method forreadorowith2os commentedon Nov 10, 2023
It seems reasonable for it to infer from
.read()that I want the type of.cast()to be*const [u8; 4]. If I'm not mistaken, this also happens in some similar capacity in type inference elsewhere too.[-]Tracking issue for the `tyvar_behind_raw_pointer` compatibility lint[/-][+]Tracking issue for future-incompatibility lint `tyvar_behind_raw_pointer`[/+]Fix for new rustc warnings
zachs18 commentedon Sep 17, 2026
(I was reminded of this by the mention in
cast_slice's tracking issue)If we allow dispatchable non-method trait functions (zulip chat link), then we can get the "best of both worlds" IMO:
let x: T = ptr.cast().read();work on all editionscode example
(this code compiles under this branch)