Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PhantomData<fn()> is unstable in const fn #69459

Closed
WaffleLapkin opened this issue Feb 25, 2020 · 5 comments
Closed

PhantomData<fn()> is unstable in const fn #69459

WaffleLapkin opened this issue Feb 25, 2020 · 5 comments
Labels
A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@WaffleLapkin
Copy link
Member

WaffleLapkin commented Feb 25, 2020

I tried this code:

use core::marker::PhantomData;

const fn test() {
    let _: PhantomData<fn()> = PhantomData;
}

(playground)

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.

Meta

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
@WaffleLapkin WaffleLapkin added the C-bug Category: This is a bug. label Feb 25, 2020
@RustyYato
Copy link
Contributor

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.

@Centril Centril added C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue. A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. and removed C-bug Category: This is a bug. labels Feb 25, 2020
@WaffleLapkin
Copy link
Member Author

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

@WaffleLapkin
Copy link
Member Author

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
    }
}

(playgrond)

@jonas-schievink
Copy link
Contributor

Duplicate of #67649

@jonas-schievink jonas-schievink marked this as a duplicate of #67649 May 7, 2020
@RustyYato
Copy link
Contributor

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)
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants