diff options
| author | bors <bors@rust-lang.org> | 2022-05-20 15:40:33 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-05-20 15:40:33 +0000 |
| commit | b5caa5a8421f84cb7664f999b7635801bcf3f96a (patch) | |
| tree | 641380c4a3f31c8369c7d07644d6f2f28b260851 /src | |
| parent | 22ee39504a702f75485582d02060495a01254de1 (diff) | |
| parent | 563916d698380f3773da38b1ebff00ef2842e781 (diff) | |
Auto merge of #96833 - cjgillot:ast-lifetimes-single, r=petrochenkov
Lint single-use lifetimes during AST resolution This PR rewrites `single_use_lifetime` and `unused_lifetime` lints to be based on the AST. We have more information at our disposal, so we can reduce the amount of false positives. Remaining false positive: single-use lifetimes in argument-position impl-trait. I'm waiting for https://github.com/rust-lang/rust/issues/96529 to be fixed to have a clean and proper solution here. Closes https://github.com/rust-lang/rust/issues/54079 Closes https://github.com/rust-lang/rust/issues/55057 Closes https://github.com/rust-lang/rust/issues/55058 Closes https://github.com/rust-lang/rust/issues/60554 Closes https://github.com/rust-lang/rust/issues/69952 r? `@petrochenkov`
Diffstat (limited to 'src')
12 files changed, 98 insertions, 36 deletions
diff --git a/src/test/ui/async-await/unused-lifetime.rs b/src/test/ui/async-await/unused-lifetime.rs index 5bd6ae8d3a4..6cfd36ba9e8 100644 --- a/src/test/ui/async-await/unused-lifetime.rs +++ b/src/test/ui/async-await/unused-lifetime.rs @@ -1,19 +1,15 @@ // Check "unused_lifetimes" lint on both async and sync functions +// Both cases should be diagnosed the same way. // edition:2018 #![deny(unused_lifetimes)] +async fn async_wrong_without_args<'a>() {} //~ ERROR lifetime parameter `'a` never used -// Async part with unused lifetimes -// -// Even wrong cases don't cause errors because async functions are desugared with all lifetimes -// involved in the signature. So, we cannot predict what lifetimes are unused in async function. -async fn async_wrong_without_args<'a>() {} +async fn async_wrong_1_lifetime<'a>(_: &i32) {} //~ ERROR lifetime parameter `'a` never used -async fn async_wrong_1_lifetime<'a>(_: &i32) {} - -async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} +async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} //~ ERROR lifetime parameter `'b` never used async fn async_right_1_lifetime<'a>(_: &'a i32) {} @@ -24,10 +20,6 @@ where I: Iterator<Item = &'a i32> {} - -// Sync part with unused lifetimes -// -// These functions are compiled as supposed fn wrong_without_args<'a>() {} //~ ERROR lifetime parameter `'a` never used fn wrong_1_lifetime<'a>(_: &i32) {} //~ ERROR lifetime parameter `'a` never used diff --git a/src/test/ui/async-await/unused-lifetime.stderr b/src/test/ui/async-await/unused-lifetime.stderr index 4e90f43fdd0..5c00501a62f 100644 --- a/src/test/ui/async-await/unused-lifetime.stderr +++ b/src/test/ui/async-await/unused-lifetime.stderr @@ -1,28 +1,48 @@ error: lifetime parameter `'a` never used - --> $DIR/unused-lifetime.rs:31:23 + --> $DIR/unused-lifetime.rs:8:35 | -LL | fn wrong_without_args<'a>() {} - | -^^- help: elide the unused lifetime +LL | async fn async_wrong_without_args<'a>() {} + | -^^- help: elide the unused lifetime | note: the lint level is defined here - --> $DIR/unused-lifetime.rs:5:9 + --> $DIR/unused-lifetime.rs:6:9 | LL | #![deny(unused_lifetimes)] | ^^^^^^^^^^^^^^^^ error: lifetime parameter `'a` never used - --> $DIR/unused-lifetime.rs:33:21 + --> $DIR/unused-lifetime.rs:10:33 + | +LL | async fn async_wrong_1_lifetime<'a>(_: &i32) {} + | -^^- help: elide the unused lifetime + +error: lifetime parameter `'b` never used + --> $DIR/unused-lifetime.rs:12:38 + | +LL | async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} + | --^^ + | | + | help: elide the unused lifetime + +error: lifetime parameter `'a` never used + --> $DIR/unused-lifetime.rs:23:23 + | +LL | fn wrong_without_args<'a>() {} + | -^^- help: elide the unused lifetime + +error: lifetime parameter `'a` never used + --> $DIR/unused-lifetime.rs:25:21 | LL | fn wrong_1_lifetime<'a>(_: &i32) {} | -^^- help: elide the unused lifetime error: lifetime parameter `'b` never used - --> $DIR/unused-lifetime.rs:35:26 + --> $DIR/unused-lifetime.rs:27:26 | LL | fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} | --^^ | | | help: elide the unused lifetime -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors diff --git a/src/test/ui/single-use-lifetime/fn-types.stderr b/src/test/ui/single-use-lifetime/fn-types.stderr index 584c889506b..9290c21620e 100644 --- a/src/test/ui/single-use-lifetime/fn-types.stderr +++ b/src/test/ui/single-use-lifetime/fn-types.stderr @@ -11,6 +11,11 @@ note: the lint level is defined here | LL | #![deny(single_use_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^ +help: elide the single-use lifetime + | +LL - a: for<'a> fn(&'a u32), +LL + a: fn(&u32), + | error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types --> $DIR/fn-types.rs:12:22 diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs index ff9d6bd01c6..7919ef820f6 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs @@ -19,4 +19,15 @@ fn left<'x, 'y>(foo: Double<'x, 'y>) -> &'x u32 { foo.f } //~ ERROR `'y` only us fn right<'x, 'y>(foo: Double<'x, 'y>) -> &'y u32 { foo.f } //~ ERROR `'x` only used once //~^ HELP elide the single-use lifetime -fn main() { } +pub trait Tfv<'a> {} + +// Do NOT lint in an HRTB. +pub fn g<T: for<'a> Tfv<'a>>() {} + +// Do NOT lint for trait bounds. +pub fn h<'a, S>(_: S) +where + S: Tfv<'a>, +{} + +fn main() {} diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs b/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs index 7b7ff08da7c..1ade01eed36 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs @@ -14,4 +14,10 @@ fn b<'a>() -> &'a u32 { &22 } +pub trait Tfv<'a> {} +impl Tfv<'_> for () {} + +// Do NOT lint if used in return type. +pub fn i<'a>() -> impl Tfv<'a> {} + fn main() {} diff --git a/src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.stderr b/src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.stderr index 35fd782e133..cf34a1ca299 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.stderr @@ -11,6 +11,11 @@ note: the lint level is defined here | LL | #![deny(single_use_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^ +help: elide the single-use lifetime + | +LL - impl<'f> Foo<'f> { +LL + impl Foo<'_> { + | error: aborting due to previous error diff --git a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.rs b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.rs index e7bdbb2207a..eecd715efc1 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.rs @@ -9,6 +9,7 @@ struct Foo<'f> { } impl<'f> Foo<'f> { //~ ERROR `'f` only used once + //~^ HELP elide the single-use lifetime fn inherent_a<'a>(&self, data: &'a u32) { //~ ERROR `'a` only used once //~^ HELP elide the single-use lifetime } diff --git a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.stderr b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.stderr index b8b78cd87b0..846c1bf41a2 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-argument.stderr @@ -1,10 +1,10 @@ -error: lifetime parameter `'a` only used once - --> $DIR/one-use-in-inherent-method-argument.rs:12:19 +error: lifetime parameter `'f` only used once + --> $DIR/one-use-in-inherent-method-argument.rs:11:6 | -LL | fn inherent_a<'a>(&self, data: &'a u32) { - | ^^ -- ...is used only here - | | - | this lifetime... +LL | impl<'f> Foo<'f> { + | ^^ -- ...is used only here + | | + | this lifetime... | note: the lint level is defined here --> $DIR/one-use-in-inherent-method-argument.rs:1:9 @@ -13,17 +13,23 @@ LL | #![deny(single_use_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^ help: elide the single-use lifetime | -LL - fn inherent_a<'a>(&self, data: &'a u32) { -LL + fn inherent_a(&self, data: &u32) { +LL - impl<'f> Foo<'f> { +LL + impl Foo<'_> { | -error: lifetime parameter `'f` only used once - --> $DIR/one-use-in-inherent-method-argument.rs:11:6 +error: lifetime parameter `'a` only used once + --> $DIR/one-use-in-inherent-method-argument.rs:13:19 | -LL | impl<'f> Foo<'f> { - | ^^ -- ...is used only here - | | - | this lifetime... +LL | fn inherent_a<'a>(&self, data: &'a u32) { + | ^^ -- ...is used only here + | | + | this lifetime... + | +help: elide the single-use lifetime + | +LL - fn inherent_a<'a>(&self, data: &'a u32) { +LL + fn inherent_a(&self, data: &u32) { + | error: aborting due to 2 previous errors diff --git a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-return.stderr b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-return.stderr index da9e2534611..790fcaa409c 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-inherent-method-return.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-inherent-method-return.stderr @@ -11,6 +11,11 @@ note: the lint level is defined here | LL | #![deny(single_use_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^ +help: elide the single-use lifetime + | +LL - impl<'f> Foo<'f> { +LL + impl Foo<'_> { + | error: aborting due to previous error diff --git a/src/test/ui/single-use-lifetime/one-use-in-struct.rs b/src/test/ui/single-use-lifetime/one-use-in-struct.rs index 9082aa68ed2..9cad942e7a2 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-struct.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-struct.rs @@ -4,7 +4,8 @@ // // check-pass -#![deny(single_use_lifetimes)] +// Use forbid to verify that `automatically_derived` is handled correctly. +#![forbid(single_use_lifetimes)] #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.rs b/src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.rs index 6a66c17538a..1848fc91c62 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.rs @@ -18,4 +18,9 @@ impl<'f> Iterator for Foo<'f> { } } -fn main() { } +trait Bar<'a> { + // But we should not warn here. + fn bar(x: Foo<'a>); +} + +fn main() {} diff --git a/src/test/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.stderr b/src/test/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.stderr index c16b244fafd..b50975a189e 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.stderr +++ b/src/test/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.stderr @@ -11,6 +11,11 @@ note: the lint level is defined here | LL | #![deny(single_use_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^ +help: elide the single-use lifetime + | +LL - impl<'f> Foo<'f> { +LL + impl Foo<'_> { + | error: aborting due to previous error |
