Skip to content

Commit 4275ef6

Browse files
committed
Auto merge of #79689 - Vooblin:patch1, r=tmandry
Update tests of "unused_lifetimes" lint for async functions and corresponding source code Before this PR the following code would cause an error: ``` #![deny(unused_lifetimes)] async fn f<'a>(_: &'a i32) {} fn main() {} ``` It was happening because of the desugaring of return type in async functions. As a result of the desugaring, the return type contains all lifetimes involved in the function signature. And these lifetimes were interpreted separately from the same in the function scope => so they are unused. Now, all lifetimes from the return type are interpreted as used. It is also not perfect, but at least this lint doesn't cause wrong errors now. This PR connected to issues #78522, #77217
2 parents d03fe84 + 64f11b9 commit 4275ef6

File tree

3 files changed

+65
-64
lines changed

3 files changed

+65
-64
lines changed

compiler/rustc_resolve/src/late/lifetimes.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -644,17 +644,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
644644
} else {
645645
bug!();
646646
};
647-
if let hir::ParamName::Plain(param_name) = name {
648-
if param_name.name == kw::UnderscoreLifetime {
649-
// Pick the elided lifetime "definition" if one exists
650-
// and use it to make an elision scope.
651-
self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
652-
elision = Some(reg);
653-
} else {
654-
lifetimes.insert(name, reg);
655-
}
647+
// We cannot predict what lifetimes are unused in opaque type.
648+
self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
649+
if let hir::ParamName::Plain(Ident {
650+
name: kw::UnderscoreLifetime,
651+
..
652+
}) = name
653+
{
654+
// Pick the elided lifetime "definition" if one exists
655+
// and use it to make an elision scope.
656+
elision = Some(reg);
656657
} else {
657-
self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
658658
lifetimes.insert(name, reg);
659659
}
660660
}
+42-37
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,47 @@
1-
// edition:2018
1+
// Check "unused_lifetimes" lint on both async and sync functions
22

3-
// Avoid spurious warnings of unused lifetime. The below async functions
4-
// are desugered to have an unused lifetime
5-
// but we don't want to warn about that as there's nothing they can do about it.
3+
// edition:2018
64

75
#![deny(unused_lifetimes)]
8-
#![allow(dead_code)]
9-
10-
pub async fn october(s: &str) {
11-
println!("{}", s);
12-
}
13-
14-
pub async fn async_fn(&mut ref s: &mut[i32]) {
15-
println!("{:?}", s);
16-
}
17-
18-
macro_rules! foo_macro {
19-
() => {
20-
pub async fn async_fn_in_macro(&mut ref _s: &mut[i32]) {}
21-
};
22-
}
23-
24-
foo_macro!();
25-
26-
pub async fn func_with_unused_lifetime<'a>(s: &'a str) {
27-
//~^ ERROR lifetime parameter `'a` never used
28-
println!("{}", s);
29-
}
30-
31-
pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
32-
//~^ ERROR lifetime parameter `'a` never used
33-
//~^^ ERROR lifetime parameter `'b` never used
34-
println!("{}", s);
35-
}
36-
37-
pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) {
38-
//~^ ERROR lifetime parameter `'c` never used
39-
println!("{}", s);
40-
}
6+
7+
8+
// Async part with unused lifetimes
9+
//
10+
// Even wrong cases don't cause errors because async functions are desugared with all lifetimes
11+
// involved in the signature. So, we cannot predict what lifetimes are unused in async function.
12+
async fn async_wrong_without_args<'a>() {}
13+
14+
async fn async_wrong_1_lifetime<'a>(_: &i32) {}
15+
16+
async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
17+
18+
async fn async_right_1_lifetime<'a>(_: &'a i32) {}
19+
20+
async fn async_right_2_lifetimes<'a, 'b>(_: &'a i32, _: &'b i32) {}
21+
22+
async fn async_right_trait_bound_lifetime<'a, I>(_: I)
23+
where
24+
I: Iterator<Item = &'a i32>
25+
{}
26+
27+
28+
// Sync part with unused lifetimes
29+
//
30+
// These functions are compiled as supposed
31+
fn wrong_without_args<'a>() {} //~ ERROR lifetime parameter `'a` never used
32+
33+
fn wrong_1_lifetime<'a>(_: &i32) {} //~ ERROR lifetime parameter `'a` never used
34+
35+
fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} //~ ERROR lifetime parameter `'b` never used
36+
37+
fn right_1_lifetime<'a>(_: &'a i32) {}
38+
39+
fn right_2_lifetimes<'a, 'b>(_: &'a i32, _: &'b i32) {}
40+
41+
fn right_trait_bound_lifetime<'a, I>(_: I)
42+
where
43+
I: Iterator<Item = &'a i32>
44+
{}
45+
4146

4247
fn main() {}
+13-17
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,28 @@
11
error: lifetime parameter `'a` never used
2-
--> $DIR/unused-lifetime.rs:26:40
2+
--> $DIR/unused-lifetime.rs:31:23
33
|
4-
LL | pub async fn func_with_unused_lifetime<'a>(s: &'a str) {
5-
| ^^
4+
LL | fn wrong_without_args<'a>() {}
5+
| -^^- help: elide the unused lifetime
66
|
77
note: the lint level is defined here
8-
--> $DIR/unused-lifetime.rs:7:9
8+
--> $DIR/unused-lifetime.rs:5:9
99
|
1010
LL | #![deny(unused_lifetimes)]
1111
| ^^^^^^^^^^^^^^^^
1212

1313
error: lifetime parameter `'a` never used
14-
--> $DIR/unused-lifetime.rs:31:44
14+
--> $DIR/unused-lifetime.rs:33:21
1515
|
16-
LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
17-
| ^^
16+
LL | fn wrong_1_lifetime<'a>(_: &i32) {}
17+
| -^^- help: elide the unused lifetime
1818

1919
error: lifetime parameter `'b` never used
20-
--> $DIR/unused-lifetime.rs:31:48
20+
--> $DIR/unused-lifetime.rs:35:26
2121
|
22-
LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
23-
| ^^
22+
LL | fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
23+
| --^^
24+
| |
25+
| help: elide the unused lifetime
2426

25-
error: lifetime parameter `'c` never used
26-
--> $DIR/unused-lifetime.rs:37:54
27-
|
28-
LL | pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) {
29-
| ^^
30-
31-
error: aborting due to 4 previous errors
27+
error: aborting due to 3 previous errors
3228

0 commit comments

Comments
 (0)