Skip to content

Commit d861bd4

Browse files
committed
When suggesting lifetimes, propose adding the new lifetime to all arguments
1 parent 91a3172 commit d861bd4

File tree

7 files changed

+37
-24
lines changed

7 files changed

+37
-24
lines changed

src/librustc_resolve/diagnostics.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use syntax::print::pprust;
1919
use syntax::util::lev_distance::find_best_match_for_name;
2020

2121
use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
22-
use crate::lifetimes::{HRLTSpanType, MissingLifetimeSpot};
22+
use crate::lifetimes::{ElisionFailureInfo, HRLTSpanType, MissingLifetimeSpot};
2323
use crate::path_names_to_string;
2424
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind};
2525
use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot};
@@ -1462,11 +1462,13 @@ crate fn report_missing_lifetime_specifiers(
14621462

14631463
crate fn add_missing_lifetime_specifiers_label(
14641464
err: &mut DiagnosticBuilder<'_>,
1465+
source_map: &SourceMap,
14651466
span: Span,
14661467
count: usize,
14671468
lifetime_names: &FxHashSet<ast::Ident>,
14681469
snippet: Option<&str>,
14691470
missing_named_lifetime_spots: &[MissingLifetimeSpot<'_>],
1471+
params: &[ElisionFailureInfo],
14701472
) {
14711473
if count > 1 {
14721474
err.span_label(span, format!("expected {} lifetime parameters", count));
@@ -1509,6 +1511,14 @@ crate fn add_missing_lifetime_specifiers_label(
15091511
(*span, suggestion.to_string())
15101512
}
15111513
});
1514+
for param in params {
1515+
if let Ok(snippet) = source_map.span_to_snippet(param.span) {
1516+
if snippet.starts_with("&") && !snippet.starts_with("&'") {
1517+
introduce_suggestion
1518+
.push((param.span, format!("&'lifetime {}", &snippet[1..])));
1519+
}
1520+
}
1521+
}
15121522
introduce_suggestion.push((span, sugg.to_string()));
15131523
err.multipart_suggestion(msg, introduce_suggestion, Applicability::MaybeIncorrect);
15141524
if should_break {

src/librustc_resolve/lifetimes.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -280,14 +280,14 @@ enum Elide {
280280
}
281281

282282
#[derive(Clone, Debug)]
283-
struct ElisionFailureInfo {
283+
crate struct ElisionFailureInfo {
284284
/// Where we can find the argument pattern.
285285
parent: Option<hir::BodyId>,
286286
/// The index of the argument in the original definition.
287287
index: usize,
288288
lifetime_count: usize,
289289
have_bound_regions: bool,
290-
span: Span,
290+
crate span: Span,
291291
}
292292

293293
type ScopeRef<'a> = &'a Scope<'a>;
@@ -2441,11 +2441,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
24412441
if add_label {
24422442
add_missing_lifetime_specifiers_label(
24432443
&mut err,
2444+
self.tcx.sess.source_map(),
24442445
span,
24452446
lifetime_refs.len(),
24462447
&lifetime_names,
24472448
self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()),
24482449
&self.missing_named_lifetime_spots,
2450+
error.map(|p| &p[..]).unwrap_or(&[]),
24492451
);
24502452
}
24512453

@@ -2488,7 +2490,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
24882490
let mut spans = vec![];
24892491

24902492
for (i, info) in elided_params.into_iter().enumerate() {
2491-
let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = info;
2493+
let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } =
2494+
info;
24922495

24932496
spans.push(span);
24942497
let help_name = if let Some(ident) =

src/test/ui/issues/issue-19707.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ LL | type Foo = fn(&u8, &u8) -> &u8;
1111
| ^^^ ^^^
1212
help: consider introducing a named lifetime parameter
1313
|
14-
LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8;
15-
| ^^^^^^^^^^^ ^^^^^^^^^^
14+
LL | type Foo<'lifetime> = fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8;
15+
| ^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^
1616

1717
error[E0106]: missing lifetime specifier
1818
--> $DIR/issue-19707.rs:5:27
@@ -28,12 +28,12 @@ LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {}
2828
= note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html
2929
help: consider introducing a Higher-Ranked lifetime
3030
|
31-
LL | fn bar<F: for<'lifetime> Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {}
32-
| ^^^^^^^^^^^^^^ ^^^^^^^^^^
31+
LL | fn bar<F: for<'lifetime> Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {}
32+
| ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^
3333
help: consider introducing a named lifetime parameter
3434
|
35-
LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {}
36-
| ^^^^^^^^^^ ^^^^^^^^^^
35+
LL | fn bar<'lifetime, F: Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {}
36+
| ^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^
3737

3838
error: aborting due to 2 previous errors
3939

src/test/ui/issues/issue-30255.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ LL | fn f(a: &S, b: i32) -> &i32 {
1111
| ^^
1212
help: consider introducing a named lifetime parameter
1313
|
14-
LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 {
15-
| ^^^^^^^^^^^ ^^^^^^^^^^
14+
LL | fn f<'lifetime>(a: &'lifetime S, b: i32) -> &'lifetime i32 {
15+
| ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^
1616

1717
error[E0106]: missing lifetime specifier
1818
--> $DIR/issue-30255.rs:14:34
@@ -27,8 +27,8 @@ LL | fn g(a: &S, b: bool, c: &i32) -> &i32 {
2727
| ^^ ^^^^
2828
help: consider introducing a named lifetime parameter
2929
|
30-
LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 {
31-
| ^^^^^^^^^^^ ^^^^^^^^^^
30+
LL | fn g<'lifetime>(a: &'lifetime S, b: bool, c: &'lifetime i32) -> &'lifetime i32 {
31+
| ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^
3232

3333
error[E0106]: missing lifetime specifier
3434
--> $DIR/issue-30255.rs:19:44
@@ -43,8 +43,8 @@ LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 {
4343
| ^^^^^ ^^ ^^^^
4444
help: consider introducing a named lifetime parameter
4545
|
46-
LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 {
47-
| ^^^^^^^^^^^ ^^^^^^^^^^
46+
LL | fn h<'lifetime>(a: &'lifetime bool, b: bool, c: &'lifetime S, d: &'lifetime i32) -> &'lifetime i32 {
47+
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^
4848

4949
error: aborting due to 3 previous errors
5050

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ LL | fn g(_x: &isize, _y: &isize) -> &isize {
1919
| ^^^^^^ ^^^^^^
2020
help: consider introducing a named lifetime parameter
2121
|
22-
LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize {
23-
| ^^^^^^^^^^^ ^^^^^^^^^^
22+
LL | fn g<'lifetime>(_x: &'lifetime isize, _y: &'lifetime isize) -> &'lifetime isize {
23+
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^
2424

2525
error[E0106]: missing lifetime specifier
2626
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19
@@ -35,8 +35,8 @@ LL | fn h(_x: &Foo) -> &isize {
3535
| ^^^^
3636
help: consider introducing a named lifetime parameter
3737
|
38-
LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize {
39-
| ^^^^^^^^^^^ ^^^^^^^^^^
38+
LL | fn h<'lifetime>(_x: &'lifetime Foo) -> &'lifetime isize {
39+
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^
4040

4141
error[E0106]: missing lifetime specifier
4242
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20

src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ LL | fn foo(x: &i32, y: &i32) -> &i32 {
1111
| ^^^^ ^^^^
1212
help: consider introducing a named lifetime parameter
1313
|
14-
LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 {
15-
| ^^^^^^^^^^^ ^^^^^^^^^^
14+
LL | fn foo<'lifetime>(x: &'lifetime i32, y: &'lifetime i32) -> &'lifetime i32 {
15+
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^
1616

1717
error: aborting due to previous error
1818

src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } }
1111
| ^^^^ ^^^^
1212
help: consider introducing a named lifetime parameter
1313
|
14-
LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } }
15-
| ^^^^^^^^^^^ ^^^^^^^^^
14+
LL | fn foo<'lifetime>(x: &'lifetime u32, y: &'lifetime u32) -> &'lifetime u32 { loop { } }
15+
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^
1616

1717
error: aborting due to previous error
1818

0 commit comments

Comments
 (0)