Closed eggyal closed 3 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
*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.
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?
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?
Can it really be an implementation detail if its effect is user facing ?
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”.
Okay, thanks again. Will open an issue as advised. Closing here.
In short "uses" really means "could determine variance of".
Related issues:
Yes, that's a helpful clarification. Perhaps that could be added into the explanation of E0392?
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:
Is this a bug, or is there some obscure reason for it?