diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2020-01-27 12:41:49 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2020-02-05 10:32:01 -0800 |
| commit | 7e1464336a627ecb962f4eb38173fbfbfdd2ccf0 (patch) | |
| tree | 1118175cf8ccb8ebe81d2eba85ff64db625938a6 /src | |
| parent | 70dbf5526d37ad031fca57ddde55bf8757bfc326 (diff) | |
| download | rust-7e1464336a627ecb962f4eb38173fbfbfdd2ccf0.tar.gz rust-7e1464336a627ecb962f4eb38173fbfbfdd2ccf0.zip | |
When suggesting lifetimes, propose adding the new lifetime to all arguments
Diffstat (limited to 'src')
7 files changed, 37 insertions, 24 deletions
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index fafceb1f97c..56fb6600405 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -19,7 +19,7 @@ use syntax::ast::{self, Ident, Path}; use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; -use crate::lifetimes::{HRLTSpanType, MissingLifetimeSpot}; +use crate::lifetimes::{ElisionFailureInfo, HRLTSpanType, MissingLifetimeSpot}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; @@ -1467,11 +1467,13 @@ crate fn report_missing_lifetime_specifiers( crate fn add_missing_lifetime_specifiers_label( err: &mut DiagnosticBuilder<'_>, + source_map: &SourceMap, span: Span, count: usize, lifetime_names: &FxHashSet<ast::Ident>, snippet: Option<&str>, missing_named_lifetime_spots: &[MissingLifetimeSpot<'_>], + params: &[ElisionFailureInfo], ) { if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); @@ -1514,6 +1516,14 @@ crate fn add_missing_lifetime_specifiers_label( (*span, suggestion.to_string()) } }); + for param in params { + if let Ok(snippet) = source_map.span_to_snippet(param.span) { + if snippet.starts_with("&") && !snippet.starts_with("&'") { + introduce_suggestion + .push((param.span, format!("&'lifetime {}", &snippet[1..]))); + } + } + } introduce_suggestion.push((span, sugg.to_string())); err.multipart_suggestion(msg, introduce_suggestion, Applicability::MaybeIncorrect); if should_break { diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 022f83af815..97d314c8f65 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -280,14 +280,14 @@ enum Elide { } #[derive(Clone, Debug)] -struct ElisionFailureInfo { +crate struct ElisionFailureInfo { /// Where we can find the argument pattern. parent: Option<hir::BodyId>, /// The index of the argument in the original definition. index: usize, lifetime_count: usize, have_bound_regions: bool, - span: Span, + crate span: Span, } type ScopeRef<'a> = &'a Scope<'a>; @@ -2441,11 +2441,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if add_label { add_missing_lifetime_specifiers_label( &mut err, + self.tcx.sess.source_map(), span, lifetime_refs.len(), &lifetime_names, self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()), &self.missing_named_lifetime_spots, + error.map(|p| &p[..]).unwrap_or(&[]), ); } @@ -2488,7 +2490,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut spans = vec![]; for (i, info) in elided_params.into_iter().enumerate() { - let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = info; + let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = + info; spans.push(span); let help_name = if let Some(ident) = diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index 1be066caa87..f8917b7bdd0 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -11,8 +11,8 @@ LL | type Foo = fn(&u8, &u8) -> &u8; | ^^^ ^^^ help: consider introducing a named lifetime parameter | -LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8; - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | type Foo<'lifetime> = fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8; + | ^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-19707.rs:5:27 @@ -28,12 +28,12 @@ LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {} = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing a Higher-Ranked lifetime | -LL | fn bar<F: for<'lifetime> Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {} - | ^^^^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn bar<F: for<'lifetime> Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {} + | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {} - | ^^^^^^^^^^ ^^^^^^^^^^ +LL | fn bar<'lifetime, F: Fn(&'lifetime u8, &'lifetime u8) -> &'lifetime u8>(f: &F) {} + | ^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index e2b57a20325..fbe715de932 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -11,8 +11,8 @@ LL | fn f(a: &S, b: i32) -> &i32 { | ^^ help: consider introducing a named lifetime parameter | -LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn f<'lifetime>(a: &'lifetime S, b: i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:14:34 @@ -27,8 +27,8 @@ LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { | ^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn g<'lifetime>(a: &'lifetime S, b: bool, c: &'lifetime i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:19:44 @@ -43,8 +43,8 @@ LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | ^^^^^ ^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn h<'lifetime>(a: &'lifetime bool, b: bool, c: &'lifetime S, d: &'lifetime i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index d1b597804cd..01236e3c773 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -19,8 +19,8 @@ LL | fn g(_x: &isize, _y: &isize) -> &isize { | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | -LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn g<'lifetime>(_x: &'lifetime isize, _y: &'lifetime isize) -> &'lifetime isize { + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19 @@ -35,8 +35,8 @@ LL | fn h(_x: &Foo) -> &isize { | ^^^^ help: consider introducing a named lifetime parameter | -LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn h<'lifetime>(_x: &'lifetime Foo) -> &'lifetime isize { + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20 diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index 52a980a61da..bea1a8bf2c1 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -11,8 +11,8 @@ LL | fn foo(x: &i32, y: &i32) -> &i32 { | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 { - | ^^^^^^^^^^^ ^^^^^^^^^^ +LL | fn foo<'lifetime>(x: &'lifetime i32, y: &'lifetime i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr index 801504627c0..97014dae2b9 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -11,8 +11,8 @@ LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | -LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } } - | ^^^^^^^^^^^ ^^^^^^^^^ +LL | fn foo<'lifetime>(x: &'lifetime u32, y: &'lifetime u32) -> &'lifetime u32 { loop { } } + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^ error: aborting due to previous error |
