@@ -29,11 +29,20 @@ fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 {
2929 x
3030}
3131
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 {
3436 x
3537}
3638
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+
3746// No error; multiple input refs
3847async fn func < ' a > ( args : & [ & ' a str ] ) -> Option < & ' a str > {
3948 args. get ( 0 ) . cloned ( )
@@ -44,11 +53,20 @@ fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 {
4453 x
4554}
4655
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 , ( ) > {
4960 Ok ( x)
5061}
5162
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+
5270// No error; two input refs.
5371fn deep_reference_2 < ' a > ( x : Result < & ' a u8 , & ' a u8 > ) -> & ' a u8 {
5472 x. unwrap ( )
@@ -129,11 +147,20 @@ impl X {
129147 & self . x
130148 }
131149
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 {
134154 & self . x
135155 }
136156
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+
137164 fn distinct_self_and_in < ' s , ' t > ( & ' s self , _x : & ' t u8 ) { }
138165
139166 // No error; same lifetimes on two params.
@@ -167,8 +194,19 @@ fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {
167194 unimplemented ! ( )
168195}
169196
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 {
172210 unimplemented ! ( )
173211}
174212
@@ -203,8 +241,19 @@ fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {
203241 unimplemented ! ( )
204242}
205243
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 {
208257 unimplemented ! ( )
209258}
210259
@@ -419,12 +468,31 @@ mod issue7296 {
419468 }
420469}
421470
422- mod false_negative {
471+ mod pr_9743_false_negative_fix {
423472 #![ allow( unused) ]
424473
425474 fn foo < ' a > ( x : & ' a u8 , y : & ' _ u8 ) { }
426475
427476 fn bar < ' a > ( x : & ' a u8 , y : & ' _ u8 , z : & ' _ u8 ) { }
428477}
429478
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+
430498fn main ( ) { }
0 commit comments