Skip to content

bizarre error message for one of the universal constructor syntaxes #108224

Open
@ijackson

Description

@ijackson

I tried this code:

#![allow(dead_code)]
#![allow(unused_variables)]
enum Enum<'l, F> {
    Tuple(&'l F),
    Struct { f: &'l F },
}
fn main(){
    let v = 42u32;
    let t = Enum::<u32>::Struct { f: &v };
}

I expected to see this happen: it compiles.

Instead, this happened (on the playground, with stable and with nightly):

error[E0109]: lifetime arguments are not allowed on variant `Struct`
 --> src/main.rs:9:26
  |
9 |     let t = Enum::<u32>::Struct { f: &v };
  |                          ^^^^^^
  |                          |
  |                          lifetime argument not allowed
  |                          not allowed on variant `Struct`
  |
  = note: enum variants can't have type parameters

error[E0107]: this enum takes 1 lifetime argument but 0 lifetime arguments were supplied
 --> src/main.rs:9:13
  |
9 |     let t = Enum::<u32>::Struct { f: &v };
  |             ^^^^ expected 1 lifetime argument
  |
note: enum defined here, with 1 lifetime parameter: `'l`
 --> src/main.rs:3:6
  |
3 | enum Enum<'l, F> {
  |      ^^^^ --
help: add missing lifetime argument
  |
9 |     let t = Enum::<'l, u32>::Struct { f: &v };
  |                    +++

It's not 100% clear to me that this syntax, with the generics applied to the enum type rather than the variant, is intended to be accepted. I think it probably ought to be, though. On this point I found #69363/#69356. The Reference doesn't seem to discuss it.

Also, the error messages are nonsensical, and the suggestion doesn't compile.

Variations:

    let t = Enum::<'l, u32>::Tuple { 0: &v }; // use of undeclared lifetime name `'l`  [obviously]
    let t = Enum::<u32>::Tuple { 0: &v }; //  lifetime arguments are not allowed on variant `Tuple`
    let t = Enum::<'_, u32>::Tuple { 0: &v }; // //  lifetime arguments are not allowed on variant `Tuple`
    let t = Enum::<u32>::Tuple(&v);; // compiles, but of course you can't use this for a named-fields variant
    let t = Enum::Struct::<u32> { f: &v }; // compiles
    let t = Enum::Tuple::<u32> { 0: &v }; // compiles

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions