Skip to content

Incorrect 'never used' warning for struct when only use is in pattern match #52325

Description

@stearnsc

I ran across this implementing a one-time-use struct for a diesel query.
I incorrectly get a warning:

warning: struct is never used: `Foo`

when compiling

trait SomeTrait {}

struct Foo {
    s: String
}

impl SomeTrait for Foo {}

fn main() {
    let Foo { s } = get_thing();
    println!("{}", s);
}

fn get_thing<T: SomeTrait>() -> T {
    unimplemented!()
}

I got this is on 1.27.0 stable, and verified still exists on 1.29.0-nightly (2018-07-10). I didn't find another issue that looked like the same thing, so hopefully this isn't a duplicate :).

Activity

  1. stearnsc commented on Jul 12, 2018

    @stearnsc
    Author

    Looks like the warning goes away if the trait impl constructs the struct, which I imagine happens almost always. In my case, the struct was deriving a trait instead of impl'ing something manually. My actual use was something more like:

    fn get_something() -> Result<f64, Error> {
        #[derive(QueryableByName)]
        struct Foo { #[sql_type = "Double"] f: f64 }
        let Foo { f } = sql_query("<my query>").get_result(conn)?;
        ...
    }
    
  2. csmoe commented on Jul 12, 2018

    @csmoe
    Contributor

    let Foo { s } = get_thing(); You're assigning s with pattern matching here, the Foo isn't' used indeed.

  3. zackmdavis commented on Jul 13, 2018

    @zackmdavis
    Contributor

    @stearnsc Thanks for the report! You are right that the issue is that the lint is firing because the struct isn't constructed even if it's used as a match pattern. The message wording was changed for unused enum variants not too long ago for exactly this reason; perhaps we should do the same for structs as well. (Unless someone objects to the consonance of "struct is never constructed"??) Pull request: #52332.

  4. added a commit that references this issue on Jul 13, 2018
  5. stearnsc commented on Jul 13, 2018

    @stearnsc
    Author

    Thank's for the explanation! Is the consensus view that the warning is "correct" then, in that there ought to be a warning for this case? This use of structs doesn't seem particularly hacky or weird to me, so it feels weird that my code should require a fair number of #[allow(dead_code)]s sprinkled throughout in order to compile without warnings.

    Or, maybe rephrasing a bit, should the "bug" be considered that the linter doesn't check derived code to see if a struct is constructed?

    I haven't looked directly at the derived output, but I'm assuming somewhere in there my type is being explicitly constructed.

  6. zackmdavis commented on Jul 22, 2018

    @zackmdavis
    Contributor

    @stearnsc I'm not aware of this having been debated enough for there to be a consensus view. The dead-code analysis lives in src/librustc/middle/dead.rs if you're curious how it works.

  7. added a commit that references this issue on Jul 31, 2018
  8. added a commit that references this issue on Aug 1, 2018
  9. added a commit that references this issue on Aug 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions