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

Tracking Issue for const_option_ext #91930

Open
1 of 3 tasks
fee1-dead opened this issue Dec 14, 2021 · 15 comments
Open
1 of 3 tasks

Tracking Issue for const_option_ext #91930

fee1-dead opened this issue Dec 14, 2021 · 15 comments
Labels
C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-const_trait_impl `#![feature(const_trait_impl)]` T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@fee1-dead
Copy link
Member

fee1-dead commented Dec 14, 2021

Feature gate: #![feature(const_option_ext)]

This is a tracking issue for option methods mostly requiring const_trait_impl to work.

as_pin_ref, as_pin_mut, unwrap_unchecked do not require const_trait_impl.

Option::<&mut T>::copied does not require const_trait_impl as well, but it requires const_mut_refs.

Public API

// core::option

impl<T> Option<T> {
    pub const fn contains<U>(&self, x: &U) -> bool
    where
        U: ~const PartialEq<T>;
    pub const fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>>;
    pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>>;
    pub const fn unwrap_or(self, default: T) -> T
    where
        T: ~const Drop;
    pub const fn unwrap_or_else<F>(self, f: F) -> T
    where
        F: ~const FnOnce() -> T,
        F: ~const Drop;
    pub const unsafe fn unwrap_unchecked(self) -> T;
    pub const fn map<U, F>(self, f: F) -> Option<U>
    where
        F: ~const FnOnce(T) -> U,
        F: ~const Drop;
    pub const fn inspect<F>(self, f: F) -> Self
    where
        F: ~const FnOnce(&T),
        F: ~const Drop;
    pub const fn map_or<U, F>(self, default: U, f: F) -> U
    where
        F: ~const FnOnce(T) -> U,
        F: ~const Drop,
        U: ~const Drop;
    pub const fn map_or_else<U, D, F>(self, default: D, f: F) -> U
    where
        D: ~const FnOnce() -> U,
        D: ~const Drop,
        F: ~const FnOnce(T) -> U,
        F: ~const Drop;
    pub const fn ok_or<E>(self, err: E) -> Result<T, E>
    where
        E: ~const Drop;
    pub const fn and<U>(self, optb: Option<U>) -> Option<U>
    where
        T: ~const Drop,
        U: ~const Drop;
    pub const fn and_then<U, F>(self, f: F) -> Option<U>
    where
        F: ~const FnOnce(T) -> Option<U>,
        F: ~const Drop;
    pub const fn filter<P>(self, predicate: P) -> Self
    where
        T: ~const Drop,
        P: ~const FnOnce(&T) -> bool,
        P: ~const Drop;
    pub const fn or(self, optb: Option<T>) -> Option<T>
    where
        T: ~const Drop;
    pub const fn or_else<F>(self, f: F) -> Option<T>
    where
        F: ~const FnOnce() -> Option<T>,
        F: ~const Drop;
    pub const fn xor(self, optb: Option<T>) -> Option<T>
    where
        T: ~const Drop;
    pub const fn insert(&mut self, value: T) -> &mut T
    where
        T: ~const Drop;
    pub const fn get_or_insert(&mut self, value: T) -> &mut T
    where
        T: ~const Drop;
    pub const fn get_or_insert_default(&mut self) -> &mut T
    where
        T: ~const Default;
    pub const fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
    where
        F: ~const FnOnce() -> T,
        F: ~const Drop;
    pub const fn zip<U>(self, other: Option<U>) -> Option<(T, U)>
    where
        T: ~const Drop,
        U: ~const Drop;
    pub const fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R>
    where
        F: ~const FnOnce(T, U) -> R,
        F: ~const Drop,
        T: ~const Drop,
        U: ~const Drop;
    pub const fn unwrap_or_default(self) -> T
    where
        T: ~const Default;
    pub const fn as_deref(&self) -> Option<&T::Target>
    where
        T: ~const Deref;
    pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target>
    where
        T: ~const DerefMut;
}

impl<T: Copy> Option<&mut T> {
    pub const fn copied(self) -> Option<T>
}

Steps / History

Unresolved Questions

  • None yet.
@fee1-dead fee1-dead added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. labels Dec 14, 2021
@PvdBerg1998
Copy link

Out of interest as I found this in std: where can I find details about the ~const syntax?

@fee1-dead
Copy link
Member Author

Out of interest as I found this in std: where can I find details about the ~const syntax?

You can find the most recent proposal on Rust Internals

@Clockwork-Muse
Copy link

What about things like expect() or unwrap()?

Current workaround:

/// Obtains an Instant using seconds and an adjustment in nanoseconds since '1970-01-01 00:00:00.000000000Z'.
///
/// # Parameters
///  - `epoch_seconds`: the seconds since the epoch.
///  - `nano_adjustment`: the adjustment amount from the given second.
///
/// # Panics
/// - if the adjusted amount of seconds would overflow the instant.
pub const fn of_epoch_second_and_adjustment(
    epoch_seconds: i64,
    nano_adjustment: i64,
) -> Instant {
    match Instant::of_epoch_second_and_adjustment_checked(epoch_seconds, nano_adjustment) {
        Some(i) => i,
        _ => panic!("nano adjustment would overflow instant"),
    }
}

@cyqsimon
Copy link
Contributor

In #94317 I noticed this feature is WIP for similar methods, but I don't understand it enough to be confident that what I wrote was correct. Please help me verify, thanks.

@BratSinot
Copy link

Greetings!

Any way to do such thing in stable?

pub const FOO: usize = option_env!("FOO")
    .unwrap_or("123456")
    .parse()
    .unwrap();

@fee1-dead
Copy link
Member Author

fee1-dead commented Apr 5, 2022

Parsing an integer is not converted to const code yet I believe. So you can't do this yet even in nightly.

@DunnAnDusted
Copy link

Hi, I followed the link from the unwrap_or() method, but don't see it included among the methods noted, is this exclusion a mistake...?

@frederikhors
Copy link

I'm new to Rust. I'm using rust 1.60.0.

I'm trying to use this code:

pub const VERSION: &'static str = option_env!("VERSION").unwrap_or_else(|| "dev");

but I'm getting this error:

the trait bound `[closure@src\constants.rs:4:81: 4:89]: ~const FnOnce<()>` is not satisfied
the trait `~const FnOnce<()>` is not implemented for `[closure@src\constants.rs:4:81: 4:89]`
wrap the `[closure@src\constants.rs:4:81: 4:89]` in a closure with no arguments: `|| { /* code */ }`rustcE0277
constants.rs(4, 66): the trait `FnOnce<()>` is implemented for `[closure@src\constants.rs:4:81: 4:89]`, but that implementation is not `const`
option.rs(797, 12): required by a bound in `Option::<T>::unwrap_or_else`

Can you help me understand what's wrong with it?

@fee1-dead
Copy link
Member Author

You could use .unwrap_or:

pub const VERSION: &'static str = option_env!("VERSION").unwrap_or("dev");

Ideally the errors message should be improved. I will work on that.

@frederikhors
Copy link

unwrap_or doesn't work.

@fee1-dead
Copy link
Member Author

Hmm. Are you using nightly? If you aren't using nightly, none of these would work.

@frederikhors
Copy link

1.60.

@frederikhors
Copy link

I fixed with:

pub const VERSION: &'static str = match option_env!("VERSION") {
    Some(v) => v,
    None => "dev",
};

@poliorcetics
Copy link
Contributor

poliorcetics commented Jul 27, 2022

Is it possible to stabilize the methods that do not depend on ~const ?

impl<T> Option<T> {
    pub const fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>>;
    pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>>;

    pub const unsafe fn unwrap_unchecked(self) -> T;
}

impl<T: Copy> Option<&mut T> {
    pub const fn copied(self) -> Option<T>
}

@fee1-dead
Copy link
Member Author

@poliorcetics Yes. Feel free to open a PR.

@fee1-dead fee1-dead added the F-const_trait_impl `#![feature(const_trait_impl)]` label Mar 24, 2023
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 20, 2024
Make Option::as_[mut_]slice const

These two functions can both be made `const`. I have added them to the `const_option_ext` feature, rust-lang#91930. I don't believe there is anything blocking stabilization of `as_slice`, but `as_mut_slice` contains mutable references so depends on `const_mut_refs`.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 20, 2024
Make Option::as_[mut_]slice const

These two functions can both be made `const`. I have added them to the `const_option_ext` feature, rust-lang#91930. I don't believe there is anything blocking stabilization of `as_slice`, but `as_mut_slice` contains mutable references so depends on `const_mut_refs`.
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jun 20, 2024
Rollup merge of rust-lang#126711 - GKFX:const-option-as-slice, r=oli-obk

Make Option::as_[mut_]slice const

These two functions can both be made `const`. I have added them to the `const_option_ext` feature, rust-lang#91930. I don't believe there is anything blocking stabilization of `as_slice`, but `as_mut_slice` contains mutable references so depends on `const_mut_refs`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-const_trait_impl `#![feature(const_trait_impl)]` T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants