rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.96k stars 12.69k forks source link

`*mut` "uses" type params, but `*const` (and therefore `NonNull`) does not #118976

Closed eggyal closed 3 months ago

eggyal commented 10 months ago

Update(fmease): See https://github.com/rust-lang/rust/issues/118976#issuecomment-1863691682 and https://github.com/rust-lang/rust/issues/118976#issuecomment-1864232472.


As first mentioned on URLO, and demonstrated on quick playground:

struct Foo<T>(*mut Self); // works
struct Bar<T>(*const Self); // error[E0392]: parameter `T` is never used

Is this a bug, or is there some obscure reason for it?

Darksonn commented 10 months ago

Note that the use of Self is not the problem:

struct Foo<T>(*mut Foo<T>); // works
struct Bar<T>(*const Bar<T>); // error[E0392]: parameter `T` is never used
fmease commented 10 months ago

*mut is invariant over its pointee type while *const is covariant over it. Foo is invariant over T because invariance “overrules” bivariance (all to-be-inferred terms start out as bivariant). Bar is bivariant over T (i.e., T is “unused”) since covariance gets “overruled” by bivariance. Sorry for the super technical explanation. I don't really see a bug though :thinking:

Similar example:

struct Foo<T: 'static>(&'static mut Foo<T>); // works
struct Bar<T: 'static>(&'static Bar<T>); // errors

You can remedy this with PhantomData and a wrapper type that renders T invariant, e.g., struct Bar<T>(*const Bar<T>, PhantomData<*mut T>); should be just fine.

eggyal commented 10 months ago

Ah, thank you. I had thought it might be variance-related and did refresh my memory with a read of the chapters on subtyping in the reference and nomicon but neither mention "bivariance" at all nor how variance relates to whether a type parameter is deemed to be "used" in a type definition.

Perhaps this is already documented somewhere that I missed, but if not maybe this is a documentation bug?

fmease commented 10 months ago

The rustc dev guide mentions bivariance but that one isn't really user-facing as its name suggests. Not sure why the Reference and the Nomicon don't mention it, maybe because it's considered to be an implementation detail?

eggyal commented 10 months ago

Can it really be an implementation detail if its effect is user facing ?

fmease commented 10 months ago

Yeah, makes sense. Probably worth opening an issue over at the Reference and/or the Nomicon. It's an implementation detail insofar that rustc never mentions bivariance in any error messages for example and only talks about generic parameters “that must be used”.

eggyal commented 10 months ago

Okay, thanks again. Will open an issue as advised. Closing here.

QuineDot commented 10 months ago

In short "uses" really means "could determine variance of".

Related issues:

eggyal commented 10 months ago

Yes, that's a helpful clarification. Perhaps that could be added into the explanation of E0392?