Skip to content

Commit ffdb471

Browse files
authored
Rollup merge of #117914 - estebank:issue-85843, r=wesleywiser
On borrow return type, suggest borrowing from arg or owned return type When we encounter a function with a return type that has an anonymous lifetime with no argument to borrow from, besides suggesting the `'static` lifetime we now also suggest changing the arguments to be borrows or changing the return type to be an owned type. ``` error[E0106]: missing lifetime specifier --> $DIR/variadic-ffi-6.rs:7:6 | LL | ) -> &usize { | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` | LL | ) -> &'static usize { | +++++++ help: instead, you are more likely to want to change one of the arguments to be borrowed... | LL | x: &usize, | + help: ...or alternatively, to want to return an owned value | LL - ) -> &usize { LL + ) -> usize { | ``` Fix #85843.
2 parents b2a0175 + eee4cc6 commit ffdb471

19 files changed

+450
-55
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

+259-12
Large diffs are not rendered by default.

src/tools/tidy/src/ui_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
1111
const ENTRY_LIMIT: usize = 900;
1212
// FIXME: The following limits should be reduced eventually.
1313
const ISSUES_ENTRY_LIMIT: usize = 1852;
14-
const ROOT_ENTRY_LIMIT: usize = 867;
14+
const ROOT_ENTRY_LIMIT: usize = 866;
1515

1616
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
1717
"rs", // test source files

tests/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ LL | fn elision<T: Fn() -> &i32>() {
55
| ^ expected named lifetime parameter
66
|
77
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8-
help: consider using the `'static` lifetime
8+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
99
|
1010
LL | fn elision<T: Fn() -> &'static i32>() {
1111
| +++++++
12+
help: instead, you are more likely to want to return an owned value
13+
|
14+
LL - fn elision<T: Fn() -> &i32>() {
15+
LL + fn elision<T: Fn() -> i32>() {
16+
|
1217

1318
error: aborting due to 1 previous error
1419

tests/ui/associated-types/bound-lifetime-in-return-only.elision.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ LL | fn elision(_: fn() -> &i32) {
55
| ^ expected named lifetime parameter
66
|
77
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8-
help: consider using the `'static` lifetime
8+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
99
|
1010
LL | fn elision(_: fn() -> &'static i32) {
1111
| +++++++
12+
help: instead, you are more likely to want to return an owned value
13+
|
14+
LL - fn elision(_: fn() -> &i32) {
15+
LL + fn elision(_: fn() -> i32) {
16+
|
1217

1318
error: aborting due to 1 previous error
1419

tests/ui/c-variadic/variadic-ffi-6.stderr

+10-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@ LL | ) -> &usize {
55
| ^ expected named lifetime parameter
66
|
77
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8-
help: consider using the `'static` lifetime
8+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
99
|
1010
LL | ) -> &'static usize {
1111
| +++++++
12+
help: instead, you are more likely to want to change one of the arguments to be borrowed...
13+
|
14+
LL | x: &usize,
15+
| +
16+
help: ...or alternatively, you might want to return an owned value
17+
|
18+
LL - ) -> &usize {
19+
LL + ) -> usize {
20+
|
1221

1322
error: aborting due to 1 previous error
1423

tests/ui/foreign-fn-return-lifetime.fixed

-8
This file was deleted.

tests/ui/foreign-fn-return-lifetime.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// run-rustfix
2-
31
extern "C" {
42
pub fn g(_: &u8) -> &u8; // OK
53
pub fn f() -> &u8; //~ ERROR missing lifetime specifier

tests/ui/foreign-fn-return-lifetime.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
error[E0106]: missing lifetime specifier
2-
--> $DIR/foreign-fn-return-lifetime.rs:5:19
2+
--> $DIR/foreign-fn-return-lifetime.rs:3:19
33
|
44
LL | pub fn f() -> &u8;
55
| ^ expected named lifetime parameter
66
|
77
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8-
help: consider using the `'static` lifetime
8+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
99
|
1010
LL | pub fn f() -> &'static u8;
1111
| +++++++
12+
help: instead, you are more likely to want to return an owned value
13+
|
14+
LL - pub fn f() -> &u8;
15+
LL + pub fn f() -> u8;
16+
|
1217

1318
error: aborting due to 1 previous error
1419

tests/ui/generic-associated-types/issue-70304.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
1111
| ^^ expected named lifetime parameter
1212
|
1313
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
14-
help: consider using the `'static` lifetime
14+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
1515
|
1616
LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'static>> {
1717
| ~~~~~~~

tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | fn d() -> impl Fn() -> (impl Debug + '_) {
55
| ^^ expected named lifetime parameter
66
|
77
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8-
help: consider using the `'static` lifetime
8+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
99
|
1010
LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
1111
| ~~~~~~~

tests/ui/issues/issue-13497.stderr

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ LL | &str
55
| ^ expected named lifetime parameter
66
|
77
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8-
help: consider using the `'static` lifetime
8+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
99
|
1010
LL | &'static str
1111
| +++++++
12+
help: instead, you are more likely to want to return an owned value
13+
|
14+
LL | String
15+
| ~~~~~~
1216

1317
error: aborting due to 1 previous error
1418

tests/ui/lifetimes/issue-26638.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,18 @@ LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
1717
| ^ expected named lifetime parameter
1818
|
1919
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
20-
help: consider using the `'static` lifetime
20+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
2121
|
2222
LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &'static str { iter() }
2323
| +++++++
24+
help: instead, you are more likely to want to change the argument to be borrowed...
25+
|
26+
LL | fn parse_type_2(iter: &fn(&u8)->&u8) -> &str { iter() }
27+
| +
28+
help: ...or alternatively, you might want to return an owned value
29+
|
30+
LL | fn parse_type_2(iter: fn(&u8)->&u8) -> String { iter() }
31+
| ~~~~~~
2432

2533
error[E0106]: missing lifetime specifier
2634
--> $DIR/issue-26638.rs:10:22
@@ -29,10 +37,14 @@ LL | fn parse_type_3() -> &str { unimplemented!() }
2937
| ^ expected named lifetime parameter
3038
|
3139
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
32-
help: consider using the `'static` lifetime
40+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
3341
|
3442
LL | fn parse_type_3() -> &'static str { unimplemented!() }
3543
| +++++++
44+
help: instead, you are more likely to want to return an owned value
45+
|
46+
LL | fn parse_type_3() -> String { unimplemented!() }
47+
| ~~~~~~
3648

3749
error[E0308]: mismatched types
3850
--> $DIR/issue-26638.rs:1:69

tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr

+26-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ LL | fn f() -> &isize {
55
| ^ expected named lifetime parameter
66
|
77
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8-
help: consider using the `'static` lifetime
8+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
99
|
1010
LL | fn f() -> &'static isize {
1111
| +++++++
12+
help: instead, you are more likely to want to return an owned value
13+
|
14+
LL - fn f() -> &isize {
15+
LL + fn f() -> isize {
16+
|
1217

1318
error[E0106]: missing lifetime specifier
1419
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33
@@ -41,10 +46,19 @@ LL | fn i(_x: isize) -> &isize {
4146
| ^ expected named lifetime parameter
4247
|
4348
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
44-
help: consider using the `'static` lifetime
49+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
4550
|
4651
LL | fn i(_x: isize) -> &'static isize {
4752
| +++++++
53+
help: instead, you are more likely to want to change the argument to be borrowed...
54+
|
55+
LL | fn i(_x: &isize) -> &isize {
56+
| +
57+
help: ...or alternatively, you might want to return an owned value
58+
|
59+
LL - fn i(_x: isize) -> &isize {
60+
LL + fn i(_x: isize) -> isize {
61+
|
4862

4963
error[E0106]: missing lifetime specifier
5064
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:34:24
@@ -53,10 +67,19 @@ LL | fn j(_x: StaticStr) -> &isize {
5367
| ^ expected named lifetime parameter
5468
|
5569
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
56-
help: consider using the `'static` lifetime
70+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
5771
|
5872
LL | fn j(_x: StaticStr) -> &'static isize {
5973
| +++++++
74+
help: instead, you are more likely to want to change the argument to be borrowed...
75+
|
76+
LL | fn j(_x: &StaticStr) -> &isize {
77+
| +
78+
help: ...or alternatively, you might want to return an owned value
79+
|
80+
LL - fn j(_x: StaticStr) -> &isize {
81+
LL + fn j(_x: StaticStr) -> isize {
82+
|
6083

6184
error[E0106]: missing lifetime specifier
6285
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:40:49

tests/ui/self/elision/nested-item.stderr

+10-1
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,19 @@ LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() {
2121
| ^ expected named lifetime parameter
2222
|
2323
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
24-
help: consider using the `'static` lifetime
24+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
2525
|
2626
LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &'static () {
2727
| +++++++
28+
help: instead, you are more likely to want to change the argument to be borrowed...
29+
|
30+
LL | fn wrap(self: &Wrap<{ fn bar(&self) {} }>) -> &() {
31+
| +
32+
help: ...or alternatively, you might want to return an owned value
33+
|
34+
LL - fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() {
35+
LL + fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> () {
36+
|
2837

2938
error[E0412]: cannot find type `Wrap` in this scope
3039
--> $DIR/nested-item.rs:5:15

tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr

+60-6
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@ LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
55
| ^ expected named lifetime parameter
66
|
77
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8-
help: consider using the `'static` lifetime
8+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
99
|
1010
LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&'static ()> { x.next() }
1111
| +++++++
12+
help: consider introducing a named lifetime parameter
13+
|
14+
LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
15+
| ++++ ~~~ ~~~
16+
help: alternatively, you might want to return an owned value
17+
|
18+
LL - fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
19+
LL + fn g(mut x: impl Iterator<Item = &()>) -> Option<()> { x.next() }
20+
|
1221

1322
error[E0106]: missing lifetime specifier
1423
--> $DIR/impl-trait-missing-lifetime-gated.rs:19:60
@@ -17,10 +26,19 @@ LL | async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next()
1726
| ^ expected named lifetime parameter
1827
|
1928
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
20-
help: consider using the `'static` lifetime
29+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
2130
|
2231
LL | async fn i(mut x: impl Iterator<Item = &()>) -> Option<&'static ()> { x.next() }
2332
| +++++++
33+
help: consider introducing a named lifetime parameter
34+
|
35+
LL | async fn i<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
36+
| ++++ ~~~ ~~~
37+
help: alternatively, you might want to return an owned value
38+
|
39+
LL - async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
40+
LL + async fn i(mut x: impl Iterator<Item = &()>) -> Option<()> { x.next() }
41+
|
2442

2543
error[E0106]: missing lifetime specifier
2644
--> $DIR/impl-trait-missing-lifetime-gated.rs:27:58
@@ -29,10 +47,19 @@ LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next()
2947
| ^^ expected named lifetime parameter
3048
|
3149
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
32-
help: consider using the `'static` lifetime
50+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
3351
|
3452
LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
3553
| ~~~~~~~
54+
help: consider introducing a named lifetime parameter
55+
|
56+
LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
57+
| ++++ ~~~ ~~~
58+
help: alternatively, you might want to return an owned value
59+
|
60+
LL - fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
61+
LL + fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
62+
|
3663

3764
error[E0106]: missing lifetime specifier
3865
--> $DIR/impl-trait-missing-lifetime-gated.rs:37:64
@@ -41,10 +68,19 @@ LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.n
4168
| ^^ expected named lifetime parameter
4269
|
4370
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
44-
help: consider using the `'static` lifetime
71+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
4572
|
4673
LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
4774
| ~~~~~~~
75+
help: consider introducing a named lifetime parameter
76+
|
77+
LL | async fn i<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
78+
| ++++ ~~~ ~~~
79+
help: alternatively, you might want to return an owned value
80+
|
81+
LL - async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
82+
LL + async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
83+
|
4884

4985
error[E0106]: missing lifetime specifier
5086
--> $DIR/impl-trait-missing-lifetime-gated.rs:47:37
@@ -53,10 +89,19 @@ LL | fn g(mut x: impl Foo) -> Option<&()> { x.next() }
5389
| ^ expected named lifetime parameter
5490
|
5591
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
56-
help: consider using the `'static` lifetime
92+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
5793
|
5894
LL | fn g(mut x: impl Foo) -> Option<&'static ()> { x.next() }
5995
| +++++++
96+
help: consider introducing a named lifetime parameter
97+
|
98+
LL | fn g<'a>(mut x: impl Foo) -> Option<&'a ()> { x.next() }
99+
| ++++ ~~~
100+
help: alternatively, you might want to return an owned value
101+
|
102+
LL - fn g(mut x: impl Foo) -> Option<&()> { x.next() }
103+
LL + fn g(mut x: impl Foo) -> Option<()> { x.next() }
104+
|
60105

61106
error[E0106]: missing lifetime specifier
62107
--> $DIR/impl-trait-missing-lifetime-gated.rs:58:41
@@ -65,10 +110,19 @@ LL | fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
65110
| ^ expected named lifetime parameter
66111
|
67112
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
68-
help: consider using the `'static` lifetime
113+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
69114
|
70115
LL | fn g(mut x: impl Foo<()>) -> Option<&'static ()> { x.next() }
71116
| +++++++
117+
help: consider introducing a named lifetime parameter
118+
|
119+
LL | fn g<'a>(mut x: impl Foo<()>) -> Option<&'a ()> { x.next() }
120+
| ++++ ~~~
121+
help: alternatively, you might want to return an owned value
122+
|
123+
LL - fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
124+
LL + fn g(mut x: impl Foo<()>) -> Option<()> { x.next() }
125+
|
72126

73127
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
74128
--> $DIR/impl-trait-missing-lifetime-gated.rs:6:35

0 commit comments

Comments
 (0)