@@ -29,11 +29,20 @@ fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 {
29
29
x
30
30
}
31
31
32
- // No error; multiple input refs.
33
- fn multiple_in_and_out_2 < ' a , ' b > ( x : & ' a u8 , _y : & ' b u8 ) -> & ' a u8 {
32
+ // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
33
+ // fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8
34
+ // ^^^
35
+ fn multiple_in_and_out_2a < ' a , ' b > ( x : & ' a u8 , _y : & ' b u8 ) -> & ' a u8 {
34
36
x
35
37
}
36
38
39
+ // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
40
+ // fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8
41
+ // ^^^
42
+ fn multiple_in_and_out_2b < ' a , ' b > ( _x : & ' a u8 , y : & ' b u8 ) -> & ' b u8 {
43
+ y
44
+ }
45
+
37
46
// No error; multiple input refs
38
47
async fn func < ' a > ( args : & [ & ' a str ] ) -> Option < & ' a str > {
39
48
args. get ( 0 ) . cloned ( )
@@ -44,11 +53,20 @@ fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 {
44
53
x
45
54
}
46
55
47
- // No error.
48
- fn deep_reference_1 < ' a , ' b > ( x : & ' a u8 , _y : & ' b u8 ) -> Result < & ' a u8 , ( ) > {
56
+ // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
57
+ // fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()>
58
+ // ^^^
59
+ fn deep_reference_1a < ' a , ' b > ( x : & ' a u8 , _y : & ' b u8 ) -> Result < & ' a u8 , ( ) > {
49
60
Ok ( x)
50
61
}
51
62
63
+ // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
64
+ // fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()>
65
+ // ^^^
66
+ fn deep_reference_1b < ' a , ' b > ( _x : & ' a u8 , y : & ' b u8 ) -> Result < & ' b u8 , ( ) > {
67
+ Ok ( y)
68
+ }
69
+
52
70
// No error; two input refs.
53
71
fn deep_reference_2 < ' a > ( x : Result < & ' a u8 , & ' a u8 > ) -> & ' a u8 {
54
72
x. unwrap ( )
@@ -129,11 +147,20 @@ impl X {
129
147
& self . x
130
148
}
131
149
132
- // No error; multiple input refs.
133
- fn self_and_in_out < ' s , ' t > ( & ' s self , _x : & ' t u8 ) -> & ' s u8 {
150
+ // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
151
+ // fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8
152
+ // ^^^
153
+ fn self_and_in_out_1 < ' s , ' t > ( & ' s self , _x : & ' t u8 ) -> & ' s u8 {
134
154
& self . x
135
155
}
136
156
157
+ // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
158
+ // fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8
159
+ // ^^^^^
160
+ fn self_and_in_out_2 < ' s , ' t > ( & ' s self , x : & ' t u8 ) -> & ' t u8 {
161
+ x
162
+ }
163
+
137
164
fn distinct_self_and_in < ' s , ' t > ( & ' s self , _x : & ' t u8 ) { }
138
165
139
166
// No error; same lifetimes on two params.
@@ -167,8 +194,19 @@ fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {
167
194
unimplemented ! ( )
168
195
}
169
196
170
- // No warning; two input lifetimes.
171
- fn struct_with_lt4 < ' a , ' b > ( _foo : & ' a Foo < ' b > ) -> & ' a str {
197
+ // Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
198
+ // valid:
199
+ // fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str
200
+ // ^^
201
+ fn struct_with_lt4a < ' a , ' b > ( _foo : & ' a Foo < ' b > ) -> & ' a str {
202
+ unimplemented ! ( )
203
+ }
204
+
205
+ // Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
206
+ // valid:
207
+ // fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str
208
+ // ^^^^
209
+ fn struct_with_lt4b < ' a , ' b > ( _foo : & ' a Foo < ' b > ) -> & ' b str {
172
210
unimplemented ! ( )
173
211
}
174
212
@@ -203,8 +241,19 @@ fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {
203
241
unimplemented ! ( )
204
242
}
205
243
206
- // No warning; two input lifetimes.
207
- fn alias_with_lt4 < ' a , ' b > ( _foo : & ' a FooAlias < ' b > ) -> & ' a str {
244
+ // Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
245
+ // valid:
246
+ // fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str
247
+ // ^^
248
+ fn alias_with_lt4a < ' a , ' b > ( _foo : & ' a FooAlias < ' b > ) -> & ' a str {
249
+ unimplemented ! ( )
250
+ }
251
+
252
+ // Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
253
+ // valid:
254
+ // fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str
255
+ // ^^^^^^^^^
256
+ fn alias_with_lt4b < ' a , ' b > ( _foo : & ' a FooAlias < ' b > ) -> & ' b str {
208
257
unimplemented ! ( )
209
258
}
210
259
@@ -419,12 +468,31 @@ mod issue7296 {
419
468
}
420
469
}
421
470
422
- mod false_negative {
471
+ mod pr_9743_false_negative_fix {
423
472
#![ allow( unused) ]
424
473
425
474
fn foo < ' a > ( x : & ' a u8 , y : & ' _ u8 ) { }
426
475
427
476
fn bar < ' a > ( x : & ' a u8 , y : & ' _ u8 , z : & ' _ u8 ) { }
428
477
}
429
478
479
+ mod pr_9743_output_lifetime_checks {
480
+ #![ allow( unused) ]
481
+
482
+ // lint: only one input
483
+ fn one_input < ' a > ( x : & ' a u8 ) -> & ' a u8 {
484
+ unimplemented ! ( )
485
+ }
486
+
487
+ // lint: multiple inputs, output would not be elided
488
+ fn multiple_inputs_output_not_elided < ' a , ' b > ( x : & ' a u8 , y : & ' b u8 , z : & ' b u8 ) -> & ' b u8 {
489
+ unimplemented ! ( )
490
+ }
491
+
492
+ // don't lint: multiple inputs, output would be elided (which would create an ambiguity)
493
+ fn multiple_inputs_output_would_be_elided < ' a , ' b > ( x : & ' a u8 , y : & ' b u8 , z : & ' b u8 ) -> & ' a u8 {
494
+ unimplemented ! ( )
495
+ }
496
+ }
497
+
430
498
fn main ( ) { }
0 commit comments