When suggesting lifetimes, propose adding the new lifetime to all arguments

This commit is contained in:
Esteban Küber 2020-01-27 12:41:49 -08:00
parent 70dbf5526d
commit 7e1464336a
7 changed files with 37 additions and 24 deletions

View File

@ -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 {

View File

@ -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) =

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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