Rust: "variant is never constructed" lint appears to be incorrect?

Created on 10 Sep 2019  路  5Comments  路  Source: rust-lang/rust

This code (playground) causes a "variant is never constructed" lint, even though the variant is constructed in the FromStr implementation:

use std::str::FromStr;

enum Foo {
    A { inner: () },
    B,
}

impl FromStr for Foo {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, ()> {
        match s {
            "a" => Ok(Self::A { inner: () }),
            "b" => Ok(Self::B),
            _ => Err(()),
        }
    }
}
warning: variant is never constructed: `A`
 --> src/lib.rs:4:5
  |
4 |     A { inner: () },
  |     ^^^^^^^^^^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

Changing Self for the type name in from_str for Foo (playground) compiles with the "field is never used" lint I would expect from this code.

Tested on rustc 1.39.0-nightly (0b36e9dea 2019-09-09)


This issue has been assigned to @jakubadamw via this comment.


A-lint C-bug T-compiler

Most helpful comment

The problem seems to manifest itself when variants with named fields are constructed using Self::.

Here is a minimal example (playground):

#[derive(Debug)]
enum Foo {
    A { data: u32 },
}

impl Foo {
    fn new() -> Self {
        Self::A { data: 0 }
    }
}

fn main() {
    println!("created: {:?}", Foo::new());
}

All 5 comments

This is correct. Your snippet is treated as a library, where the enum Foo is not reachable, because it is not public.
If you write pub enum Foo the error will go away.

Behavoir inteded and therefore this can be closed.

The bug is that it doesn't trigger for B.

If the lint triggered for all variants, then it would just say:

   Compiling playground v0.0.1 (/playground)
warning: enum is never used: `Foo`
 --> src/lib.rs:3:1
  |
3 | enum Foo {
  | ^^^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

The problem seems to manifest itself when variants with named fields are constructed using Self::.

Here is a minimal example (playground):

#[derive(Debug)]
enum Foo {
    A { data: u32 },
}

impl Foo {
    fn new() -> Self {
        Self::A { data: 0 }
    }
}

fn main() {
    println!("created: {:?}", Foo::new());
}

@rustbot claim

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Leo1003 picture Leo1003  路  898Comments

withoutboats picture withoutboats  路  308Comments

nikomatsakis picture nikomatsakis  路  259Comments

nikomatsakis picture nikomatsakis  路  236Comments

nikomatsakis picture nikomatsakis  路  331Comments