Skip to content

Incorrect needless_lifetimes warning for impl Trait based code #2944

@vitalyd

Description

@vitalyd

Given the following code:

#![crate_type = "lib"]
#![allow(unused)]
use std::collections::{HashMap, HashSet};

struct MyMap {
    inner: HashMap<u32, HashSet<String>>,
}

impl MyMap {
    fn iter<'a>(&'a self, key: u32) -> Option<impl Iterator<Item = impl AsRef<str> + 'a>> {
        self.inner.get(&key).map(|set| set.iter())
    }
}

fn main() {}

Playground

clippy reports the following:

 Checking playground v0.0.1 (file:///playground)
warning: explicit lifetimes given in parameter types where they could be elided
  --> src/main.rs:10:5
   |
10 | /     fn iter<'a>(&'a self, key: u32) -> Option<impl Iterator<Item = impl AsRef<str> + 'a>> {
11 | |         self.inner.get(&key).map(|set| set.iter())
12 | |     }
   | |_____^
   |
   = note: #[warn(needless_lifetimes)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#needless_lifetimes

    Finished dev [unoptimized + debuginfo] target(s) in 1.40s

But if you take its suggestion and remove 'a from iter(), you get the following compiler error:

 Compiling playground v0.0.1 (file:///playground)
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/lib.rs:11:20
   |
11 |         self.inner.get(&key).map(|set| set.iter())
   |                    ^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 10:5...
  --> src/lib.rs:10:5
   |
10 | /     fn iter(&self, key: u32) -> Option<impl Iterator<Item = impl AsRef<str>>> {
11 | |         self.inner.get(&key).map(|set| set.iter())
12 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:11:9
   |
11 |         self.inner.get(&key).map(|set| set.iter())
   |         ^^^^^^^^^^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that return value is valid for the call
  --> src/lib.rs:10:40
   |
10 |     fn iter(&self, key: u32) -> Option<impl Iterator<Item = impl AsRef<str>>> {
   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0495`.
error: Could not compile `playground`.

To learn more, run the command again with --verbose.

It's possible this is a dupe of an existing issue but a cursory search revealed a few old (and closed) impl Trait related bugs, and I didn't find anything current.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions