I tried this code:
use core::marker::PhantomData;
const fn test() {
let _: PhantomData<fn()> = PhantomData;
}
I expected it to work, but it doesn't work.
Error:
error[E0723]: function pointers in const fn are unstable
--> src/lib.rs:4:32
|
4 | let _: PhantomData<fn()> = PhantomData;
| ^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
I use PhantomData<fn(T) -> T> to make type invariant over T & mark that I don't own T. I see no reason for this code to be unstable.
rustc --version --verbose:
rustc 1.43.0-nightly (433aae93e 2020-02-14)
binary: rustc
commit-hash: 433aae93e4ef866a1fdfefad136b32ed89acd3e7
commit-date: 2020-02-14
host: x86_64-unknown-linux-gnu
release: 1.43.0-nightly
LLVM version: 9.0
To add to this, the only stable way to achieve const friendly non-owning invariance is with PhantomData<*mut T> which means that you must implement Send and Sync manually. This is unfortunate.
There is a similar issue with PhantomData<dyn Fn(T)> (I was trying to find a workaround...):
error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
--> src/dimensions.rs:94:14
|
94 | Self(PhantomData)
| ^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
I've found a workaround for my case (generic struct with PhantomData inside + const fn new) 馃帀
pub struct Generic<T>(core::marker::PhantomData<fn(T) -> T>);
impl<T> Generic<T> {
const NEW: Self = Self(core::marker::PhantomData);
}
impl<T> Generic<T> {
pub const fn new() -> Self {
Self::NEW
}
}
Duplicate of https://github.com/rust-lang/rust/issues/67649
Here is another workaround,
struct Invariant<T>(fn(T) -> T);
pub struct Generic<T>(core::marker::PhantomData<Invariant<T>>);
impl<T> Generic<T> {
pub const fn new() -> Self {
Self(PhantomData)
}
}