Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggest introducing an explicit lifetime if it does not exist #101445

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2395,19 +2395,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
type_param_span: Option<(Span, bool)>,
bound_kind: GenericKind<'tcx>,
sub: S,
add_lt_sugg: Option<(Span, String)>,
) {
let msg = "consider adding an explicit lifetime bound";
if let Some((sp, has_lifetimes)) = type_param_span {
let suggestion =
if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) };
err.span_suggestion_verbose(
sp,
&format!("{}...", msg),
suggestion,
let mut suggestions = vec![(sp, suggestion)];
if let Some(add_lt_sugg) = add_lt_sugg {
suggestions.push(add_lt_sugg);
}
err.multipart_suggestion_verbose(
format!("{msg}..."),
suggestions,
Applicability::MaybeIncorrect, // Issue #41966
);
} else {
let consider = format!("{} `{}: {}`...", msg, bound_kind, sub,);
let consider = format!("{} `{}: {}`...", msg, bound_kind, sub);
err.help(&consider);
}
}
Expand All @@ -2423,7 +2427,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
};
let mut sugg =
vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))];
if let Some(lt) = add_lt_sugg {
if let Some(lt) = add_lt_sugg.clone() {
sugg.push(lt);
sugg.rotate_right(1);
}
Expand Down Expand Up @@ -2529,7 +2533,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// for the bound is not suitable for suggestions when `-Zverbose` is set because it
// uses `Debug` output, so we handle it specially here so that suggestions are
// always correct.
binding_suggestion(&mut err, type_param_span, bound_kind, name);
binding_suggestion(&mut err, type_param_span, bound_kind, name, None);
err
}

Expand All @@ -2542,7 +2546,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"{} may not live long enough",
labeled_user_string
);
binding_suggestion(&mut err, type_param_span, bound_kind, "'static");
binding_suggestion(&mut err, type_param_span, bound_kind, "'static", None);
err
}

Expand Down Expand Up @@ -2576,7 +2580,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
new_binding_suggestion(&mut err, type_param_span);
}
_ => {
binding_suggestion(&mut err, type_param_span, bound_kind, new_lt);
binding_suggestion(
&mut err,
type_param_span,
bound_kind,
new_lt,
add_lt_sugg,
);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fn no_restriction<T>(x: &()) -> &() {
with_restriction::<T>(x) //~ ERROR the parameter type `T` may not live long enough
}

fn with_restriction<'b, T: 'b>(x: &'b ()) -> &'b () {
x
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0311]: the parameter type `T` may not live long enough
--> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5
|
LL | with_restriction::<T>(x)
| ^^^^^^^^^^^^^^^^^^^^^
|
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
--> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:1:25
|
LL | fn no_restriction<T>(x: &()) -> &() {
| ^^^
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5
|
LL | with_restriction::<T>(x)
| ^^^^^^^^^^^^^^^^^^^^^
help: consider adding an explicit lifetime bound...
|
LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
| +++ ++++

error: aborting due to previous error

Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ LL | | });
| |______^
help: consider adding an explicit lifetime bound...
|
LL | fn func<T: Test + 'a>(foo: &Foo, t: T) {
| ++++
LL | fn func<'a, T: Test + 'a>(foo: &Foo, t: T) {
| +++ ++++

error: aborting due to previous error

Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ LL | | }
| |_____^
help: consider adding an explicit lifetime bound...
|
LL | G: Get<T> + 'a,
| ++++
LL ~ fn bar<'a, G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
LL | where
LL ~ G: Get<T> + 'a,
|

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:52:5
Expand All @@ -74,8 +76,8 @@ LL | | }
| |_____^
help: consider adding an explicit lifetime bound...
|
LL | fn qux<'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ++++
LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| +++ ++++

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:61:9
Expand All @@ -101,8 +103,8 @@ LL | | }
| |_________^
help: consider adding an explicit lifetime bound...
|
LL | fn qux<'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
| ++++
LL | fn qux<'c, 'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
| +++ ++++

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:73:5
Expand Down Expand Up @@ -130,8 +132,8 @@ LL | | }
| |_____^
help: consider adding an explicit lifetime bound...
|
LL | fn bat<'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
| ++++
LL | fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
| +++ ++++

error[E0621]: explicit lifetime required in the type of `dest`
--> $DIR/missing-lifetimes-in-signature.rs:73:5
Expand Down