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

Incorrect lint: needless_lifetimes #5787

Closed
vmalloc opened this issue Jul 12, 2020 · 6 comments · Fixed by #10222
Closed

Incorrect lint: needless_lifetimes #5787

vmalloc opened this issue Jul 12, 2020 · 6 comments · Fixed by #10222
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have T-async-await Type: Issues related to async/await

Comments

@vmalloc
Copy link
Contributor

vmalloc commented Jul 12, 2020

I tried this code:

pub async fn send<'a>(&self, client: &'a Client) -> Result<Request<'a>> {
       ...
        Ok(Request::new(client, self.request_id))
    }

Clippy complains that this violates "needless_lifetimes". However trying to elide them cannot succeed due to the &self reference:

pub async fn send(&self, client: &Client) -> Result<Request<'_>> {
       ...
        Ok(Request::new(client, self.request_id))
    }

Fails:

pub async fn send<'a>(&self, client: &Client) -> Result<Request<'_>> {
   |                           -----                      -------------------------
   |                           |
   |                           this parameter and the return type are declared with different lifetimes...
...
Ok(Request::new(client, self.order_id))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...but data from `client` is returned here

I'm not sure if there is actually an option for elision here at all...

Meta

  • cargo clippy -V: clippy 0.0.212 (bb37a0f 2020-06-16)
  • rustc -Vv:
rustc 1.44.1 (c7087fe00 2020-06-17)
binary: rustc
commit-hash: c7087fe00d2ba919df1d813c040a5d47e43b0fe7
commit-date: 2020-06-17
host: x86_64-apple-darwin
release: 1.44.1
LLVM version: 9.0

Thanks in advance!

@vmalloc vmalloc added the C-bug Category: Clippy is not doing the correct thing label Jul 12, 2020
@flip1995 flip1995 added the T-async-await Type: Issues related to async/await label Jul 13, 2020
@piegamesde
Copy link

I can reproduce this, even without self:

pub async fn wrap_something<'a>(
    to_wrap: &'a mut Wrapped,
    unrelated: &Unrelated,
) -> Wrapper<'a> {

As far as I can tell, there is no possibility of eliding this, as the type system doesn't know from which of the arguments it should borrow without explicit lifetimes.

@mahkoh
Copy link

mahkoh commented Nov 30, 2020

Parameter lifetimes cannot be elided in async functions:

pub async fn transaction<'a>(con: &'a mut PgClient) -> Result<Transaction<'a>> {

// does not compile
pub async fn transaction(con: &mut PgClient) -> Result<Transaction> {

Note that this only applies to async functions.

@cppforliving
Copy link

It seems to be a duplicate of #4746

@flip1995
Copy link
Member

flip1995 commented Dec 4, 2020

Copying my comment from the other issue:

Reproducer: Playground

use std::sync::MutexGuard;

struct Foo;

impl Foo {
    // doesn't get linted without async
    pub async fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> {
        guard
    }
}

This is a self contained reproducer.

@phansch phansch added the I-false-positive Issue: The lint was triggered on code it shouldn't have label Dec 18, 2020
@HyeonuPark
Copy link

HyeonuPark commented Jan 20, 2021

I've reduced it further.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1556b5afa098a4f6578bb3999d82e9d4

async fn foo<'a>(_x: &i32, y: &'a str) -> &'a str {
    y
}
warning: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
 --> src/lib.rs:1:1
  |
1 | async fn foo<'a>(_x: &i32, y: &'a str) -> &'a str {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(clippy::needless_lifetimes)]` on by default
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes

And this doesn't triggers it.

async fn foo<'a, 'b>(_x: &'b i32, y: &'a str) -> &'a str {
    y
}

@tofay
Copy link

tofay commented Jan 20, 2021

In the async case, _x's lifetime is being ignored as it's hitting this check:

} else if let LifetimeName::Param(ParamName::Fresh(_)) = lt.name {
// Fresh lifetimes generated should be ignored.

The lint then only has 'a in the input and output lifetimes, and assumes 'a can be elided.

Alexendoo added a commit to Alexendoo/rust-clippy that referenced this issue Jan 22, 2023
Alexendoo added a commit to Alexendoo/rust-clippy that referenced this issue Jan 23, 2023
Alexendoo added a commit to Alexendoo/rust-clippy that referenced this issue Jan 31, 2023
@bors bors closed this as completed in b5a4fa1 Jan 31, 2023
J-ZhengLi pushed a commit to TogetherGame/rust-clippy that referenced this issue Aug 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have T-async-await Type: Issues related to async/await
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants