Auto merge of #4266 - uHOOCCOOHu:fix/async_fn_lifetime, r=flip1995
Ignore generated fresh lifetimes in elision check <!-- Thank you for making Clippy better! We're collecting our changelog from pull request descriptions. If your PR only updates to the latest nightly, you can leave the `changelog` entry as `none`. Otherwise, please write a short comment explaining your change. If your PR fixes an issue, you can add "fixes #issue_number" into this PR description. This way the issue will be automatically closed when your PR is merged. If you added a new lint, here's a checklist for things that will be checked during review or continuous integration. - [ ] Followed [lint naming conventions][lint_naming] - [ ] Added passing UI tests (including committed `.stderr` file) - [ ] `cargo test` passes locally - [ ] Executed `util/dev update_lints` - [ ] Added lint documentation - [ ] Run `cargo fmt` Note that you can skip the above if you are just opening a WIP PR in order to get feedback. Delete this line and everything above before opening your PR --> fixes #3988 changelog: Ignore generated fresh lifetimes in elision check. **HELP**: It seems `tests/ui` are compiled under edition 2015, and I don't know how to add tests for this properly. Here is the test input it had already passed: ```rust #![feature(async_await)] #![allow(dead_code)] async fn sink1<'a>(_: &'a str) {} // lint async fn sink1_elided(_: &str) {} // ok async fn one_to_one<'a>(s: &'a str) -> &'a str { s } // lint async fn one_to_one_elided(s: &str) -> &str { s } // ok async fn all_to_one<'a>(a: &'a str, _b: &'a str) -> &'a str { a } // ok // async fn unrelated(_: &str, _: &str) {} // Not allowed in async fn // #3988 struct Foo; impl Foo { pub async fn foo(&mut self) {} // ok } // rust-lang/rust#61115 async fn print(s: &str) { // ok println!("{}", s); } fn main() {} ```
This commit is contained in:
commit
d71e9c4f10
@ -283,6 +283,8 @@ impl<'v, 't> RefVisitor<'v, 't> {
|
||||
if let Some(ref lt) = *lifetime {
|
||||
if lt.name == LifetimeName::Static {
|
||||
self.lts.push(RefLt::Static);
|
||||
} else if let LifetimeName::Param(ParamName::Fresh(_)) = lt.name {
|
||||
// Fresh lifetimes generated should be ignored.
|
||||
} else if lt.is_elided() {
|
||||
self.lts.push(RefLt::Unnamed);
|
||||
} else {
|
||||
|
@ -2,5 +2,5 @@ max_width = 120
|
||||
comment_width = 100
|
||||
match_block_trailing_comma = true
|
||||
wrap_comments = true
|
||||
|
||||
edition = "2018"
|
||||
error_on_line_overflow = true
|
||||
|
@ -313,7 +313,7 @@ fn mcarton_sees_all() {
|
||||
}
|
||||
|
||||
#[clippy::cognitive_complexity = "0"]
|
||||
fn try() -> Result<i32, &'static str> {
|
||||
fn try_() -> Result<i32, &'static str> {
|
||||
match 5 {
|
||||
5 => Ok(5),
|
||||
_ => return Err("bla"),
|
||||
@ -322,14 +322,14 @@ fn try() -> Result<i32, &'static str> {
|
||||
|
||||
#[clippy::cognitive_complexity = "0"]
|
||||
fn try_again() -> Result<i32, &'static str> {
|
||||
let _ = try!(Ok(42));
|
||||
let _ = try!(Ok(43));
|
||||
let _ = try!(Ok(44));
|
||||
let _ = try!(Ok(45));
|
||||
let _ = try!(Ok(46));
|
||||
let _ = try!(Ok(47));
|
||||
let _ = try!(Ok(48));
|
||||
let _ = try!(Ok(49));
|
||||
let _ = r#try!(Ok(42));
|
||||
let _ = r#try!(Ok(43));
|
||||
let _ = r#try!(Ok(44));
|
||||
let _ = r#try!(Ok(45));
|
||||
let _ = r#try!(Ok(46));
|
||||
let _ = r#try!(Ok(47));
|
||||
let _ = r#try!(Ok(48));
|
||||
let _ = r#try!(Ok(49));
|
||||
match 5 {
|
||||
5 => Ok(5),
|
||||
_ => return Err("bla"),
|
||||
|
@ -216,7 +216,7 @@ LL | | }
|
||||
error: the function has a cognitive complexity of 1
|
||||
--> $DIR/cognitive_complexity.rs:316:1
|
||||
|
|
||||
LL | / fn try() -> Result<i32, &'static str> {
|
||||
LL | / fn try_() -> Result<i32, &'static str> {
|
||||
LL | | match 5 {
|
||||
LL | | 5 => Ok(5),
|
||||
LL | | _ => return Err("bla"),
|
||||
@ -230,9 +230,9 @@ error: the function has a cognitive complexity of 1
|
||||
--> $DIR/cognitive_complexity.rs:324:1
|
||||
|
|
||||
LL | / fn try_again() -> Result<i32, &'static str> {
|
||||
LL | | let _ = try!(Ok(42));
|
||||
LL | | let _ = try!(Ok(43));
|
||||
LL | | let _ = try!(Ok(44));
|
||||
LL | | let _ = r#try!(Ok(42));
|
||||
LL | | let _ = r#try!(Ok(43));
|
||||
LL | | let _ = r#try!(Ok(44));
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
|
@ -7,7 +7,7 @@ use alloc::collections::linked_list::LinkedList;
|
||||
|
||||
trait Foo {
|
||||
type Baz = LinkedList<u8>;
|
||||
fn foo(LinkedList<u8>);
|
||||
fn foo(_: LinkedList<u8>);
|
||||
const BAR: Option<LinkedList<u8>>;
|
||||
}
|
||||
|
||||
|
@ -8,10 +8,10 @@ LL | type Baz = LinkedList<u8>;
|
||||
= help: a VecDeque might work
|
||||
|
||||
error: I see you're using a LinkedList! Perhaps you meant some other data structure?
|
||||
--> $DIR/dlist.rs:10:12
|
||||
--> $DIR/dlist.rs:10:15
|
||||
|
|
||||
LL | fn foo(LinkedList<u8>);
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | fn foo(_: LinkedList<u8>);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: a VecDeque might work
|
||||
|
||||
|
@ -215,10 +215,10 @@ fn if_same_then_else() -> Result<&'static str, ()> {
|
||||
};
|
||||
|
||||
if true {
|
||||
try!(Ok("foo"));
|
||||
r#try!(Ok("foo"));
|
||||
} else {
|
||||
//~ ERROR same body as `if` block
|
||||
try!(Ok("foo"));
|
||||
r#try!(Ok("foo"));
|
||||
}
|
||||
|
||||
if true {
|
||||
|
@ -197,7 +197,7 @@ error: this `if` has identical blocks
|
||||
LL | } else {
|
||||
| ____________^
|
||||
LL | | //~ ERROR same body as `if` block
|
||||
LL | | try!(Ok("foo"));
|
||||
LL | | r#try!(Ok("foo"));
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
@ -206,7 +206,7 @@ note: same as this
|
||||
|
|
||||
LL | if true {
|
||||
| _____________^
|
||||
LL | | try!(Ok("foo"));
|
||||
LL | | r#try!(Ok("foo"));
|
||||
LL | | } else {
|
||||
| |_____^
|
||||
|
||||
|
38
tests/ui/issue_4266.rs
Normal file
38
tests/ui/issue_4266.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// compile-flags: --edition 2018
|
||||
#![feature(async_await)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
async fn sink1<'a>(_: &'a str) {} // lint
|
||||
async fn sink1_elided(_: &str) {} // ok
|
||||
|
||||
// lint
|
||||
async fn one_to_one<'a>(s: &'a str) -> &'a str {
|
||||
s
|
||||
}
|
||||
|
||||
// ok
|
||||
async fn one_to_one_elided(s: &str) -> &str {
|
||||
s
|
||||
}
|
||||
|
||||
// ok
|
||||
async fn all_to_one<'a>(a: &'a str, _b: &'a str) -> &'a str {
|
||||
a
|
||||
}
|
||||
|
||||
// async fn unrelated(_: &str, _: &str) {} // Not allowed in async fn
|
||||
|
||||
// #3988
|
||||
struct Foo;
|
||||
impl Foo {
|
||||
// ok
|
||||
pub async fn foo(&mut self) {}
|
||||
}
|
||||
|
||||
// rust-lang/rust#61115
|
||||
// ok
|
||||
async fn print(s: &str) {
|
||||
println!("{}", s);
|
||||
}
|
||||
|
||||
fn main() {}
|
18
tests/ui/issue_4266.stderr
Normal file
18
tests/ui/issue_4266.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
|
||||
--> $DIR/issue_4266.rs:5:1
|
||||
|
|
||||
LL | async fn sink1<'a>(_: &'a str) {} // lint
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::needless-lifetimes` implied by `-D warnings`
|
||||
|
||||
error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
|
||||
--> $DIR/issue_4266.rs:9:1
|
||||
|
|
||||
LL | / async fn one_to_one<'a>(s: &'a str) -> &'a str {
|
||||
LL | | s
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -4,9 +4,9 @@
|
||||
use std::io;
|
||||
|
||||
fn try_macro<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> {
|
||||
try!(s.write(b"test"));
|
||||
r#try!(s.write(b"test"));
|
||||
let mut buf = [0u8; 4];
|
||||
try!(s.read(&mut buf));
|
||||
r#try!(s.read(&mut buf));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: handle written amount returned or use `Write::write_all` instead
|
||||
--> $DIR/unused_io_amount.rs:7:5
|
||||
|
|
||||
LL | try!(s.write(b"test"));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | r#try!(s.write(b"test"));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::unused-io-amount` implied by `-D warnings`
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
@ -10,8 +10,8 @@ LL | try!(s.write(b"test"));
|
||||
error: handle read amount returned or use `Read::read_exact` instead
|
||||
--> $DIR/unused_io_amount.rs:9:5
|
||||
|
|
||||
LL | try!(s.read(&mut buf));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | r#try!(s.read(&mut buf));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user