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 functions #67441

Closed
9999years opened this issue Dec 20, 2019 · 31 comments · Fixed by #131120
Closed

Tracking issue for const Option functions #67441

9999years opened this issue Dec 20, 2019 · 31 comments · Fixed by #131120
Labels
A-const-eval Area: Constant evaluation (MIR interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. Libs-Tracked Libs issues that are tracked on the team's project board. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@9999years
Copy link
Contributor

9999years commented Dec 20, 2019

Current candidates with feature = const_option:

impl<T> Option<T> {
    pub const fn as_mut(&mut self) -> Option<&mut T>;
    pub const fn expect(self, msg: &str) -> T;
    pub const fn unwrap(self) -> T;
    pub const unsafe fn unwrap_unchecked(self) -> T;
    pub const fn take(&mut self) -> Option<T>;
    pub const fn replace(&mut self, value: T) -> Option<T>;
}

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

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

impl<T, E> Option<Result<T, E>> {
    pub const fn transpose(self) -> Result<Option<T>, E>
}

impl<T> Option<Option<T>> {
    pub const fn flatten(self) -> Option<T>;
}

See also the meta-tracking issue for const fns, #57563.

Blocked on:

Also see the corresponding Result tracking issue: #82814.

@JohnTitor JohnTitor added the C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC label Dec 20, 2019
@Centril Centril added A-const-eval Area: Constant evaluation (MIR interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Dec 20, 2019
Manishearth added a commit to Manishearth/rust that referenced this issue Jul 17, 2020
Make some Option methods const

Tracking issue: rust-lang#67441

Constantify the following methods of `Option`:
- `as_ref`
- `is_some`
- `is_none`
- `iter` (not sure about this one, but it is possible, and will be useful when const traits are a thing)

cc @rust-lang/wg-const-eval @rust-lang/libs
Manishearth added a commit to Manishearth/rust that referenced this issue Jul 17, 2020
Make some Option methods const

Tracking issue: rust-lang#67441

Constantify the following methods of `Option`:
- `as_ref`
- `is_some`
- `is_none`
- `iter` (not sure about this one, but it is possible, and will be useful when const traits are a thing)

cc @rust-lang/wg-const-eval @rust-lang/libs
@KodrAus KodrAus added the Libs-Tracked Libs issues that are tracked on the team's project board. label Jul 30, 2020
bors added a commit to rust-lang-ci/rust that referenced this issue Jul 31, 2020
…=oli-obk

Make `Option::unwrap` unstably const

This is lumped into the `const_option` feature gate (rust-lang#67441), which enables a potpourri of `Option` methods.

cc @rust-lang/wg-const-eval

r? @oli-obk
RalfJung added a commit to RalfJung/rust that referenced this issue Sep 19, 2020
Stabilize some Option methods as const

Stabilize the following methods of `Option` as const:
 - `is_some`
 - `is_none`
 - `as_ref`

These methods are currently const under the unstable feature `const_option` (tracking issue: rust-lang#67441).
I believe these methods to be eligible for stabilization because of the stabilization of rust-lang#49146 (Allow if and match in constants) and the trivial implementations, see also:  [PR#75463](rust-lang#75463).

Related: rust-lang#76225
RalfJung added a commit to RalfJung/rust that referenced this issue Sep 21, 2020
Stabilize some Option methods as const

Stabilize the following methods of `Option` as const:
 - `is_some`
 - `is_none`
 - `as_ref`

These methods are currently const under the unstable feature `const_option` (tracking issue: rust-lang#67441).
I believe these methods to be eligible for stabilization because of the stabilization of rust-lang#49146 (Allow if and match in constants) and the trivial implementations, see also:  [PR#75463](rust-lang#75463).

Related: rust-lang#76225
@peter-lyons-kehl
Copy link
Contributor

Yes for constantifying Option.expect.

However, as per https://doc.rust-lang.org/nightly/src/core/option.rs.html, Option.expect(self, msg: &str) calls (private) fn expect_failed(msg: &str), which uses panic!("{}", msg). Using panic! with more than one argument is not const-friendly:

    --> library/core/src/macros/mod.rs:18:38
     |
7    | / macro_rules! panic {
8    | |     () => (
9    | |         $crate::panic!("explicit panic")
10   | |     );
...    |
18   | |         $crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+))
     | |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation (#2)
19   | |     );
20   | | }
     | |_- in this expansion of `panic!` (#1)
...
761  | /     macro_rules! format_args {
762  | |         ($fmt:expr) => {{ /* compiler built-in */ }};
763  | |         ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
764  | |     }
     | |_____- in this expansion of `$crate::format_args!` (#2)
     | 
    ::: library/core/src/option.rs:1294:5
     |
1294 |       panic!("{}", msg)
     |       ----------------- in this macro invocation (#1)

Since that is not specific to Option, is there any discussion/plan/tracking issue on making panic const-friendly? Isn't it reasonable to assume that any panic is a panic? Or, can panic fail (for example, if formatting fails) and not panic?

@memoryruins
Copy link
Contributor

@peter-kehl the tracking issue for panicking in constants is #51999

@davidhewitt
Copy link
Contributor

FYI anyone looking at .unwrap_or - I just naively tried to add this, but given that T may impl Drop, this is currently unsupported.

I wonder if it would be feasible for the compiler to allow use of .unwrap_or for types that do impl drop - e.g. only fail when trying to const-evaluate .unwrap_or for T: impl Drop.

@jhpratt
Copy link
Member

jhpratt commented Mar 13, 2021

@davidhewitt Given that neither const trait impls nor const trait bounds are usable on stable, it would be quite unintuitive if this were. Even on nightly, const traits have yet to be RFC accepted.

@davidhewitt
Copy link
Contributor

Sorry, I typo'd above - I meant to say only allow types which don't impl Drop.

We probably wouldn't want this in the function signature (should just be const fn unwrap_or(default: T)). The compiler could be aware that in some paths inside the function default is disposed of, and so reject substitutions during const evaluation for T which impl Drop.

TBH it sounds messy and slightly leaks information about the function implementation, so I'm unconvinced it's worth the effort. Just musing of a way to allow some forms of const unwrap_or before const impl Trait / const Drop is ready.

@jhpratt
Copy link
Member

jhpratt commented Mar 13, 2021

Yeah, I figured it was a typo and responded accordingly.

I still think it would be awkward to have this magically work for some types but not others, especially if this isn't in the function signature. I'd much rather wait for const trait impls to be RFC approved and land on stable, as that would allow way more than just this. Just look at the blockers on #82814 and realize that having const trait impls would allow ~80% of them (just guessing, I haven't bothered to actually calculate a percentage).

@jhpratt
Copy link
Member

jhpratt commented Apr 13, 2021

If/when #51999 is stabilized, Option::expect and Option::unwrap should be unblocked (I haven't checked this, it's just from reading source code).

@CodesInChaos
Copy link

@jhpratt Option::expect passes more than one argument to panic! (and the second argument isn't const), so it'll need more work than the minimal version of const panics considered for stabilization at the moment.

@mbartlett21
Copy link
Contributor

replace, take, and copied would also be some more that can be done.

Can @9999years add these to the list at the top?

Manishearth added a commit to Manishearth/rust that referenced this issue Oct 4, 2021
…-replace, r=joshtriplett

const fn for option copied, take & replace

Tracking issue: [rust-lang#67441](rust-lang#67441)

Adding const fn for the copied, take and replace method of Option. Also adding necessary unit test.

It's my first contribution so I am pretty sure I don't know what I'm doing but there's a first for everything!
Manishearth added a commit to Manishearth/rust that referenced this issue Oct 4, 2021
…-replace, r=joshtriplett

const fn for option copied, take & replace

Tracking issue: [rust-lang#67441](rust-lang#67441)

Adding const fn for the copied, take and replace method of Option. Also adding necessary unit test.

It's my first contribution so I am pretty sure I don't know what I'm doing but there's a first for everything!
@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Oct 1, 2024
@rfcbot
Copy link

rfcbot commented Oct 1, 2024

🔔 This is now entering its final comment period, as per the review above. 🔔

tgross35 added a commit to tgross35/rust that referenced this issue Oct 1, 2024
This makes the following API stable in const contexts:

    impl<T> Option<T> {
        pub const fn as_mut(&mut self) -> Option<&mut T>;
        pub const fn expect(self, msg: &str) -> T;
        pub const fn unwrap(self) -> T;
        pub const unsafe fn unwrap_unchecked(self) -> T;
        pub const fn take(&mut self) -> Option<T>;
        pub const fn replace(&mut self, value: T) -> Option<T>;
    }

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

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

    impl<T, E> Option<Result<T, E>> {
        pub const fn transpose(self) -> Result<Option<T>, E>
    }

    impl<T> Option<Option<T>> {
        pub const fn flatten(self) -> Option<T>;
    }

The following functions make use of the unstable
`const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang#67441>
@tgross35
Copy link
Contributor

tgross35 commented Oct 1, 2024

Candidate PR: #131120

@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Oct 11, 2024
@rfcbot
Copy link

rfcbot commented Oct 11, 2024

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

tgross35 added a commit to tgross35/rust that referenced this issue Oct 12, 2024
This makes the following API stable in const contexts:

    impl<T> Option<T> {
        pub const fn as_mut(&mut self) -> Option<&mut T>;
        pub const fn expect(self, msg: &str) -> T;
        pub const fn unwrap(self) -> T;
        pub const unsafe fn unwrap_unchecked(self) -> T;
        pub const fn take(&mut self) -> Option<T>;
        pub const fn replace(&mut self, value: T) -> Option<T>;
    }

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

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

    impl<T, E> Option<Result<T, E>> {
        pub const fn transpose(self) -> Result<Option<T>, E>
    }

    impl<T> Option<Option<T>> {
        pub const fn flatten(self) -> Option<T>;
    }

The following functions make use of the unstable
`const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang#67441>
tgross35 added a commit to tgross35/rust that referenced this issue Oct 12, 2024
…=RalfJung

Stabilize `const_option`

This makes the following API stable in const contexts:

```rust
impl<T> Option<T> {
    pub const fn as_mut(&mut self) -> Option<&mut T>;
    pub const fn expect(self, msg: &str) -> T;
    pub const fn unwrap(self) -> T;
    pub const unsafe fn unwrap_unchecked(self) -> T;
    pub const fn take(&mut self) -> Option<T>;
    pub const fn replace(&mut self, value: T) -> Option<T>;
}

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

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

impl<T, E> Option<Result<T, E>> {
    pub const fn transpose(self) -> Result<Option<T>, E>
}

impl<T> Option<Option<T>> {
    pub const fn flatten(self) -> Option<T>;
}
```

The following functions make use of the unstable `const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang#67441>
tgross35 added a commit to tgross35/rust that referenced this issue Oct 13, 2024
…=RalfJung

Stabilize `const_option`

This makes the following API stable in const contexts:

```rust
impl<T> Option<T> {
    pub const fn as_mut(&mut self) -> Option<&mut T>;
    pub const fn expect(self, msg: &str) -> T;
    pub const fn unwrap(self) -> T;
    pub const unsafe fn unwrap_unchecked(self) -> T;
    pub const fn take(&mut self) -> Option<T>;
    pub const fn replace(&mut self, value: T) -> Option<T>;
}

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

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

impl<T, E> Option<Result<T, E>> {
    pub const fn transpose(self) -> Result<Option<T>, E>
}

impl<T> Option<Option<T>> {
    pub const fn flatten(self) -> Option<T>;
}
```

The following functions make use of the unstable `const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang#67441>
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Oct 13, 2024
Rollup merge of rust-lang#131120 - tgross35:stabilize-const_option, r=RalfJung

Stabilize `const_option`

This makes the following API stable in const contexts:

```rust
impl<T> Option<T> {
    pub const fn as_mut(&mut self) -> Option<&mut T>;
    pub const fn expect(self, msg: &str) -> T;
    pub const fn unwrap(self) -> T;
    pub const unsafe fn unwrap_unchecked(self) -> T;
    pub const fn take(&mut self) -> Option<T>;
    pub const fn replace(&mut self, value: T) -> Option<T>;
}

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

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

impl<T, E> Option<Result<T, E>> {
    pub const fn transpose(self) -> Result<Option<T>, E>
}

impl<T> Option<Option<T>> {
    pub const fn flatten(self) -> Option<T>;
}
```

The following functions make use of the unstable `const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang#67441>
@RalfJung
Copy link
Member

This actually made it into 1.83. :-) That will be quite the release in terms of const.

RalfJung pushed a commit to RalfJung/miri that referenced this issue Oct 14, 2024
This makes the following API stable in const contexts:

    impl<T> Option<T> {
        pub const fn as_mut(&mut self) -> Option<&mut T>;
        pub const fn expect(self, msg: &str) -> T;
        pub const fn unwrap(self) -> T;
        pub const unsafe fn unwrap_unchecked(self) -> T;
        pub const fn take(&mut self) -> Option<T>;
        pub const fn replace(&mut self, value: T) -> Option<T>;
    }

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

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

    impl<T, E> Option<Result<T, E>> {
        pub const fn transpose(self) -> Result<Option<T>, E>
    }

    impl<T> Option<Option<T>> {
        pub const fn flatten(self) -> Option<T>;
    }

The following functions make use of the unstable
`const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang/rust#67441>
RalfJung pushed a commit to RalfJung/miri that referenced this issue Oct 14, 2024
Stabilize `const_option`

This makes the following API stable in const contexts:

```rust
impl<T> Option<T> {
    pub const fn as_mut(&mut self) -> Option<&mut T>;
    pub const fn expect(self, msg: &str) -> T;
    pub const fn unwrap(self) -> T;
    pub const unsafe fn unwrap_unchecked(self) -> T;
    pub const fn take(&mut self) -> Option<T>;
    pub const fn replace(&mut self, value: T) -> Option<T>;
}

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

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

impl<T, E> Option<Result<T, E>> {
    pub const fn transpose(self) -> Result<Option<T>, E>
}

impl<T> Option<Option<T>> {
    pub const fn flatten(self) -> Option<T>;
}
```

The following functions make use of the unstable `const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang/rust#67441>
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 14, 2024
Fix two const-hacks

Fix two pieces of code marked `FIXME(const-hack)` related to const_option rust-lang#67441.
compiler-errors added a commit to compiler-errors/rust that referenced this issue Oct 15, 2024
Fix two const-hacks

Fix two pieces of code marked `FIXME(const-hack)` related to const_option rust-lang#67441.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 15, 2024
Fix two const-hacks

Fix two pieces of code marked `FIXME(const-hack)` related to const_option rust-lang#67441.
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Oct 15, 2024
Rollup merge of rust-lang#131706 - GKFX:fix-const-hacks, r=tgross35

Fix two const-hacks

Fix two pieces of code marked `FIXME(const-hack)` related to const_option rust-lang#67441.
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Oct 17, 2024
flip1995 pushed a commit to flip1995/rust-clippy that referenced this issue Oct 18, 2024
This makes the following API stable in const contexts:

    impl<T> Option<T> {
        pub const fn as_mut(&mut self) -> Option<&mut T>;
        pub const fn expect(self, msg: &str) -> T;
        pub const fn unwrap(self) -> T;
        pub const unsafe fn unwrap_unchecked(self) -> T;
        pub const fn take(&mut self) -> Option<T>;
        pub const fn replace(&mut self, value: T) -> Option<T>;
    }

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

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

    impl<T, E> Option<Result<T, E>> {
        pub const fn transpose(self) -> Result<Option<T>, E>
    }

    impl<T> Option<Option<T>> {
        pub const fn flatten(self) -> Option<T>;
    }

The following functions make use of the unstable
`const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang/rust#67441>
flip1995 pushed a commit to flip1995/rust-clippy that referenced this issue Oct 18, 2024
Stabilize `const_option`

This makes the following API stable in const contexts:

```rust
impl<T> Option<T> {
    pub const fn as_mut(&mut self) -> Option<&mut T>;
    pub const fn expect(self, msg: &str) -> T;
    pub const fn unwrap(self) -> T;
    pub const unsafe fn unwrap_unchecked(self) -> T;
    pub const fn take(&mut self) -> Option<T>;
    pub const fn replace(&mut self, value: T) -> Option<T>;
}

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

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

impl<T, E> Option<Result<T, E>> {
    pub const fn transpose(self) -> Result<Option<T>, E>
}

impl<T> Option<Option<T>> {
    pub const fn flatten(self) -> Option<T>;
}
```

The following functions make use of the unstable `const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang/rust#67441>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation (MIR interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. Libs-Tracked Libs issues that are tracked on the team's project board. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.