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

Match does not understand lifetimes of enum variants #88423

Open
jamesmunns opened this issue Aug 28, 2021 · 2 comments
Open

Match does not understand lifetimes of enum variants #88423

jamesmunns opened this issue Aug 28, 2021 · 2 comments
Labels
A-borrow-checker Area: The borrow checker A-patterns Relating to patterns and pattern matching C-enhancement Category: An issue proposing an enhancement or a PR with one. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@jamesmunns
Copy link
Member

jamesmunns commented Aug 28, 2021

I tried this code:

use std::borrow::Cow;

enum Example<'a> {
    TotallyOwned{ foo: u32, bar: u32 },
    MaybeBorrowed(Cow<'a, [u8]>),
}

impl<'a> Example<'a> {
    fn to_owned(self) -> Example<'static> {
        match self {
            Example::MaybeBorrowed(p) => Example::MaybeBorrowed(Cow::Owned(p.into_owned())),
            
            // Doesn't work!
            a @ Example::TotallyOwned { .. } => a, //~ ERROR lifetime may not live long enough
            
            // Does work, but verbose!
            // Example::TotallyOwned { foo, bar } => Example::TotallyOwned { foo, bar }
        }
    }
}

I expected the match arm a @ Example::TotallyOwned { .. } => a to work, as this variant is completely owned.

Instead, I needed to completely destruct the enum variant, and create a new one, to "make Rust understand" I was creating a fully owned enum instance.

I can understand why this error exists: namely if I am returning a rebound instance of the original enum, it still is bound to the 'a lifetime, however in the case of the TotallyOwned variant, this lifetime is "meaningless", which (someday?) rustc may be able to see.

Since this is more of an "improvement request" kind of issue, let me know if there is a better place to open this, or if this is the sort of thing that would require an RFC.

Meta

This presents in the current stable (1.54.0), as well as the current nightly (2021-08-27), though is likely true for all versions

Backtrace

<backtrace>

@jamesmunns jamesmunns added the C-bug Category: This is a bug. label Aug 28, 2021
@digama0
Copy link
Contributor

digama0 commented Sep 1, 2021

This seems like something that needs an RFC to change, because justifying this expansion requires a to have something additional to its type to remember that it is actually of a particular variant. That is, at the point a is used it definitely has type Example<'a>, which does not coerce to Example<'static>, so in that sense this is "not a bug", and I'm not a fan of poking holes in the type system to accommodate tricks like this.

A thread on https://internals.rust-lang.org might be a good place to test the waters re: popular support for an RFC along these lines.

@samestep
Copy link
Contributor

Ran into this today when trying to implement std::error::Error for a lexer; my Token<'a> enum has a few dozen variants but only one uses 'a, so this bug requires me to write out each token variant in my match in order to convert to Token<'static>.

@fmease fmease added A-borrow-checker Area: The borrow checker T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-patterns Relating to patterns and pattern matching C-enhancement Category: An issue proposing an enhancement or a PR with one. T-lang Relevant to the language team, which will review and decide on the PR/issue. and removed needs-triage-legacy T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Apr 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker A-patterns Relating to patterns and pattern matching C-enhancement Category: An issue proposing an enhancement or a PR with one. 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

5 participants