diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index a433ae8ed676a..a85f787b67789 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -5,8 +5,9 @@ use rustc::bug; use rustc::session::Session; use rustc::ty::{self, DefIdTree}; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_feature::BUILTIN_ATTRIBUTES; +use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -1447,3 +1448,74 @@ crate fn show_candidates( } } } + +crate fn report_missing_lifetime_specifiers( + sess: &Session, + span: Span, + count: usize, +) -> DiagnosticBuilder<'_> { + struct_span_err!(sess, span, E0106, "missing lifetime specifier{}", pluralize!(count)) +} + +crate fn add_missing_lifetime_specifiers_label( + err: &mut DiagnosticBuilder<'_>, + span: Span, + count: usize, + lifetime_names: &FxHashSet, + snippet: Option<&str>, + missing_named_lifetime_spots: &[&hir::Generics<'_>], +) { + if count > 1 { + err.span_label(span, format!("expected {} lifetime parameters", count)); + } else { + let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| { + err.span_suggestion( + span, + "consider using the named lifetime", + sugg, + Applicability::MaybeIncorrect, + ); + }; + let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg| { + err.span_label(span, "expected named lifetime parameter"); + + if let Some(generics) = missing_named_lifetime_spots.iter().last() { + let mut introduce_suggestion = vec![]; + introduce_suggestion.push(match &generics.params { + [] => (generics.span, "<'lifetime>".to_string()), + [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()), + }); + introduce_suggestion.push((span, sugg)); + err.multipart_suggestion( + "consider introducing a named lifetime parameter", + introduce_suggestion, + Applicability::MaybeIncorrect, + ); + } + }; + + match (lifetime_names.len(), lifetime_names.iter().next(), snippet) { + (1, Some(name), Some("&")) => { + suggest_existing(err, format!("&{} ", name)); + } + (1, Some(name), Some("'_")) => { + suggest_existing(err, name.to_string()); + } + (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => { + suggest_existing(err, format!("{}<{}>", snippet, name)); + } + (0, _, Some("&")) => { + suggest_new(err, "&'lifetime ".to_string()); + } + (0, _, Some("'_")) => { + suggest_new(err, "'lifetime".to_string()); + } + (0, _, Some(snippet)) if !snippet.ends_with(">") => { + suggest_new(err, format!("{}<'lifetime>", snippet)); + } + _ => { + err.span_label(span, "expected lifetime parameter"); + } + } + } +} diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 60a0049f5da37..96406bc9a8c81 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -11,6 +11,7 @@ #![feature(crate_visibility_modifier)] #![feature(label_break_value)] #![feature(nll)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![recursion_limit = "256"] pub use rustc_hir::def::{Namespace, PerNS}; diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 5fae8f3318743..1c667d1467de0 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -5,14 +5,16 @@ //! used between functions, and they operate in a purely top-down //! way. Therefore, we break lifetime name resolution into a separate pass. +use crate::diagnostics::{ + add_missing_lifetime_specifiers_label, report_missing_lifetime_specifiers, +}; use rustc::hir::map::Map; use rustc::lint; use rustc::middle::resolve_lifetime::*; -use rustc::session::Session; use rustc::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; use rustc::{bug, span_bug}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; @@ -183,6 +185,10 @@ struct LifetimeContext<'a, 'tcx> { xcrate_object_lifetime_defaults: DefIdMap>, lifetime_uses: &'a mut DefIdMap>, + + /// When encountering an undefined named lifetime, we will suggest introducing it in these + /// places. + missing_named_lifetime_spots: Vec<&'tcx hir::Generics<'tcx>>, } #[derive(Debug)] @@ -342,6 +348,7 @@ fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap { labels_in_fn: vec![], xcrate_object_lifetime_defaults: Default::default(), lifetime_uses: &mut Default::default(), + missing_named_lifetime_spots: vec![], }; for (_, item) in &krate.items { visitor.visit_item(item); @@ -384,9 +391,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { match item.kind { hir::ItemKind::Fn(ref sig, ref generics, _) => { + self.missing_named_lifetime_spots.push(generics); self.visit_early_late(None, &sig.decl, generics, |this| { intravisit::walk_item(this, item); }); + self.missing_named_lifetime_spots.pop(); } hir::ItemKind::ExternCrate(_) @@ -417,6 +426,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::Trait(_, _, ref generics, ..) | hir::ItemKind::TraitAlias(ref generics, ..) | hir::ItemKind::Impl { ref generics, .. } => { + self.missing_named_lifetime_spots.push(generics); + // Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name". // This is not true for other kinds of items.x let track_lifetime_uses = match item.kind { @@ -454,6 +465,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { this.check_lifetime_params(old_scope, &generics.params); intravisit::walk_item(this, item); }); + self.missing_named_lifetime_spots.pop(); } } } @@ -686,6 +698,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { use self::hir::TraitItemKind::*; + self.missing_named_lifetime_spots.push(&trait_item.generics); match trait_item.kind { Method(ref sig, _) => { let tcx = self.tcx; @@ -737,10 +750,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { intravisit::walk_trait_item(self, trait_item); } } + self.missing_named_lifetime_spots.pop(); } fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { use self::hir::ImplItemKind::*; + self.missing_named_lifetime_spots.push(&impl_item.generics); match impl_item.kind { Method(ref sig, _) => { let tcx = self.tcx; @@ -824,6 +839,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { intravisit::walk_impl_item(self, impl_item); } } + self.missing_named_lifetime_spots.pop(); } fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { @@ -1309,6 +1325,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let LifetimeContext { tcx, map, lifetime_uses, .. } = self; let labels_in_fn = take(&mut self.labels_in_fn); let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); + let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots); let mut this = LifetimeContext { tcx: *tcx, map: map, @@ -1317,7 +1334,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { is_in_fn_syntax: self.is_in_fn_syntax, labels_in_fn, xcrate_object_lifetime_defaults, - lifetime_uses: lifetime_uses, + lifetime_uses, + missing_named_lifetime_spots, }; debug!("entering scope {:?}", this.scope); f(self.scope, &mut this); @@ -1325,6 +1343,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { debug!("exiting scope {:?}", this.scope); self.labels_in_fn = this.labels_in_fn; self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults; + self.missing_named_lifetime_spots = this.missing_named_lifetime_spots; } /// helper method to determine the span to remove when suggesting the @@ -1807,15 +1826,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.insert_lifetime(lifetime_ref, def); } else { - struct_span_err!( + let mut err = struct_span_err!( self.tcx.sess, lifetime_ref.span, E0261, "use of undeclared lifetime name `{}`", lifetime_ref - ) - .span_label(lifetime_ref.span, "undeclared lifetime") - .emit(); + ); + err.span_label(lifetime_ref.span, "undeclared lifetime"); + if !self.is_in_fn_syntax { + for generics in &self.missing_named_lifetime_spots { + let (span, sugg) = match &generics.params { + [] => (generics.span, format!("<{}>", lifetime_ref)), + [param, ..] => (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)), + }; + err.span_suggestion( + span, + &format!("consider introducing lifetime `{}` here", lifetime_ref), + sugg, + Applicability::MaybeIncorrect, + ); + } + } + err.emit(); } } @@ -2369,6 +2402,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { 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, ); } @@ -2864,34 +2898,3 @@ fn insert_late_bound_lifetimes( } } } - -fn report_missing_lifetime_specifiers( - sess: &Session, - span: Span, - count: usize, -) -> DiagnosticBuilder<'_> { - struct_span_err!(sess, span, E0106, "missing lifetime specifier{}", pluralize!(count)) -} - -fn add_missing_lifetime_specifiers_label( - err: &mut DiagnosticBuilder<'_>, - span: Span, - count: usize, - lifetime_names: &FxHashSet, - snippet: Option<&str>, -) { - if count > 1 { - err.span_label(span, format!("expected {} lifetime parameters", count)); - } else if let (1, Some(name), Some("&")) = - (lifetime_names.len(), lifetime_names.iter().next(), snippet) - { - err.span_suggestion( - span, - "consider using the named lifetime", - format!("&{} ", name), - Applicability::MaybeIncorrect, - ); - } else { - err.span_label(span, "expected lifetime parameter"); - } -} diff --git a/src/test/ui/error-codes/E0106.rs b/src/test/ui/error-codes/E0106.rs index d6537d123637c..cc3438727a817 100644 --- a/src/test/ui/error-codes/E0106.rs +++ b/src/test/ui/error-codes/E0106.rs @@ -16,7 +16,7 @@ struct Buzz<'a, 'b>(&'a str, &'b str); struct Quux { baz: Baz, //~^ ERROR E0106 - //~| expected lifetime parameter + //~| expected named lifetime parameter buzz: Buzz, //~^ ERROR E0106 //~| expected 2 lifetime parameters diff --git a/src/test/ui/error-codes/E0106.stderr b/src/test/ui/error-codes/E0106.stderr index cea9581e70138..e01e0a6f54b07 100644 --- a/src/test/ui/error-codes/E0106.stderr +++ b/src/test/ui/error-codes/E0106.stderr @@ -2,25 +2,49 @@ error[E0106]: missing lifetime specifier --> $DIR/E0106.rs:2:8 | LL | x: &bool, - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | struct Foo<'lifetime> { +LL | x: &'lifetime bool, + | error[E0106]: missing lifetime specifier --> $DIR/E0106.rs:7:7 | LL | B(&bool), - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | enum Bar<'lifetime> { +LL | A(u8), +LL | B(&'lifetime bool), + | error[E0106]: missing lifetime specifier --> $DIR/E0106.rs:10:14 | LL | type MyStr = &str; - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | type MyStr<'lifetime> = &'lifetime str; + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/E0106.rs:17:10 | LL | baz: Baz, - | ^^^ expected lifetime parameter + | ^^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | struct Quux<'lifetime> { +LL | baz: Baz<'lifetime>, + | error[E0106]: missing lifetime specifiers --> $DIR/E0106.rs:20:11 diff --git a/src/test/ui/error-codes/E0261.stderr b/src/test/ui/error-codes/E0261.stderr index 3bf5e9d815485..0eab2dc0ee05f 100644 --- a/src/test/ui/error-codes/E0261.stderr +++ b/src/test/ui/error-codes/E0261.stderr @@ -2,11 +2,15 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/E0261.rs:1:12 | LL | fn foo(x: &'a str) { } - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/E0261.rs:5:9 | +LL | struct Foo { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | x: &'a str, | ^^ undeclared lifetime diff --git a/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr b/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr index 5c64bf6539c91..bbf3ea8a89f23 100644 --- a/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr +++ b/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr @@ -2,103 +2,207 @@ error[E0261]: use of undeclared lifetime name `'x` --> $DIR/feature-gate-in_band_lifetimes.rs:3:12 | LL | fn foo(x: &'x u8) -> &'x u8 { x } - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'x` here: `<'x>` error[E0261]: use of undeclared lifetime name `'x` --> $DIR/feature-gate-in_band_lifetimes.rs:3:23 | LL | fn foo(x: &'x u8) -> &'x u8 { x } - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'x` here: `<'x>` error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:15:12 | LL | impl<'a> X<'b> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'b` here: `'b,` error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:17:27 | LL | fn inner_2(&self) -> &'b u8 { | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b, 'a> X<'b> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn inner_2<'b>(&self) -> &'b u8 { + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:23:8 | LL | impl X<'b> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'b` here: `<'b>` error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:25:27 | LL | fn inner_3(&self) -> &'b u8 { | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b> X<'b> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | fn inner_3<'b>(&self) -> &'b u8 { + | ^^^^ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:33:9 | LL | impl Y<&'a u8> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:35:25 | LL | fn inner(&self) -> &'a u8 { | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | impl<'a> Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'a` here + | +LL | fn inner<'a>(&self) -> &'a u8 { + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:43:27 | LL | fn any_lifetime() -> &'b u8; | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | trait MyTrait<'b, 'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn any_lifetime<'b>() -> &'b u8; + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:45:27 | LL | fn borrowed_lifetime(&'b self) -> &'b u8; | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | trait MyTrait<'b, 'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8; + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:45:40 | LL | fn borrowed_lifetime(&'b self) -> &'b u8; | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | trait MyTrait<'b, 'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8; + | ^^^^ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:50:14 | LL | impl MyTrait<'a> for Y<&'a u8> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:50:25 | LL | impl MyTrait<'a> for Y<&'a u8> { - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:53:31 | LL | fn my_lifetime(&self) -> &'a u8 { self.0 } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | impl<'a> MyTrait<'a> for Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'a` here + | +LL | fn my_lifetime<'a>(&self) -> &'a u8 { self.0 } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:55:27 | LL | fn any_lifetime() -> &'b u8 { &0 } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b> MyTrait<'a> for Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | fn any_lifetime<'b>() -> &'b u8 { &0 } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:57:27 | LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b> MyTrait<'a> for Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:57:40 | LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b> MyTrait<'a> for Y<&'a u8> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 } + | ^^^^ error: aborting due to 17 previous errors diff --git a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr index 81137e81dc489..fc2ce1cb866bb 100644 --- a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr +++ b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr @@ -3,12 +3,30 @@ error[E0261]: use of undeclared lifetime name `'b` | LL | + Deref>; | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | trait Iterable<'b> { + | ^^^^ +help: consider introducing lifetime `'b` here + | +LL | type Iter<'b, 'a>: Iterator> + | ^^^ error[E0261]: use of undeclared lifetime name `'undeclared` --> $DIR/generic_associated_type_undeclared_lifetimes.rs:12:41 | LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; | ^^^^^^^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'undeclared` here + | +LL | trait Iterable<'undeclared> { + | ^^^^^^^^^^^^^ +help: consider introducing lifetime `'undeclared` here + | +LL | fn iter<'undeclared, 'a>(&'a self) -> Self::Iter<'undeclared>; + | ^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr index 492ca872187e0..14c53f906654b 100644 --- a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr +++ b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr @@ -2,13 +2,23 @@ error[E0106]: missing lifetime specifier --> $DIR/assoc-type.rs:11:19 | LL | type Output = &i32; - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | type Output<'lifetime> = &'lifetime i32; + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/assoc-type.rs:16:20 | LL | type Output = &'_ i32; - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | type Output<'lifetime> = &'lifetime i32; + | ^^^^^^^^^^^ ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr index 9579abb76b32f..5f101a24c1d43 100644 --- a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr +++ b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr @@ -2,7 +2,12 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-61124-anon-lifetime-in-struct-declaration.rs:8:19 | LL | struct Heartbreak(Betrayal); - | ^^^^^^^^ expected lifetime parameter + | ^^^^^^^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | struct Heartbreak<'lifetime>(Betrayal<'lifetime>); + | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr index a270dd03926dc..fe656f7af7e01 100644 --- a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr +++ b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr @@ -1,12 +1,16 @@ error[E0261]: use of undeclared lifetime name `'test` --> $DIR/no_in_band_in_struct.rs:5:9 | +LL | struct Foo { + | - help: consider introducing lifetime `'test` here: `<'test>` LL | x: &'test u32, | ^^^^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'test` --> $DIR/no_in_band_in_struct.rs:9:10 | +LL | enum Bar { + | - help: consider introducing lifetime `'test` here: `<'test>` LL | Baz(&'test u32), | ^^^^^ undeclared lifetime diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr index c307066be6b46..bfb20ade035cf 100644 --- a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr @@ -1,6 +1,8 @@ error[E0261]: use of undeclared lifetime name `'test` --> $DIR/no_introducing_in_band_in_locals.rs:5:13 | +LL | fn foo(x: &u32) { + | - help: consider introducing lifetime `'test` here: `<'test>` LL | let y: &'test u32 = x; | ^^^^^ undeclared lifetime diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index c85ce0eb3a75e..8a627bc0bd4de 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -2,17 +2,25 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-19707.rs:3:28 | LL | type Foo = fn(&u8, &u8) -> &u8; - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: consider introducing a named lifetime parameter + | +LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8; + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-19707.rs:5:27 | LL | fn bar &u8>(f: &F) {} - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: consider introducing a named lifetime parameter + | +LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {} + | ^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr index 6d7c1b0c43fce..85d5d9cc42e9a 100644 --- a/src/test/ui/issues/issue-26638.stderr +++ b/src/test/ui/issues/issue-26638.stderr @@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-26638.rs:1:62 | LL | fn parse_type(iter: Box+'static>) -> &str { iter.next() } - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from +help: consider introducing a named lifetime parameter + | +LL | fn parse_type<'lifetime>(iter: Box+'static>) -> &'lifetime str { iter.next() } + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-26638.rs:4:40 diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index c53129b7f2967..c940227764099 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -2,25 +2,37 @@ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:9:24 | LL | fn f(a: &S, b: i32) -> &i32 { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from +help: consider introducing a named lifetime parameter + | +LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:14:34 | LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` +help: consider introducing a named lifetime parameter + | +LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/issue-30255.rs:19:44 | LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` +help: consider introducing a named lifetime parameter + | +LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &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 3f7c3934a0ba2..1d5eeac23f96a 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 @@ -10,17 +10,25 @@ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33 | LL | fn g(_x: &isize, _y: &isize) -> &isize { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y` +help: consider introducing a named lifetime parameter + | +LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize { + | ^^^^^^^^^^^ ^^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19 | LL | fn h(_x: &Foo) -> &isize { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from +help: consider introducing a named lifetime parameter + | +LL | fn h<'lifetime>(_x: &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 a4e0d71a3fa6b..2990ab8682434 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 @@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/ex1b-return-no-names-if-else.rs:1:29 | LL | fn foo(x: &i32, y: &i32) -> &i32 { - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` +help: consider introducing a named lifetime parameter + | +LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 { + | ^^^^^^^^^^^ ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr index 67fd8d7a13eb1..c9f235c4f7df7 100644 --- a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr @@ -1,6 +1,8 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/method-call-lifetime-args-unresolved.rs:2:15 | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | 0.clone::<'a>(); | ^^ undeclared lifetime diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr index 03fb764ee0384..4b9f49423cbf4 100644 --- a/src/test/ui/parser/trait-object-trait-parens.stderr +++ b/src/test/ui/parser/trait-object-trait-parens.stderr @@ -33,6 +33,9 @@ LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>; error[E0261]: use of undeclared lifetime name `'a` --> $DIR/trait-object-trait-parens.rs:11:31 | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` +... LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>; | ^^ undeclared lifetime diff --git a/src/test/ui/proc-macro/item-error.stderr b/src/test/ui/proc-macro/item-error.stderr index e801c26c43b9c..01eadbe252e9f 100644 --- a/src/test/ui/proc-macro/item-error.stderr +++ b/src/test/ui/proc-macro/item-error.stderr @@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/item-error.rs:10:8 | LL | a: &u64 - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | struct A<'lifetime> { +LL | a: &'lifetime u64 + | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-enums-anon.stderr b/src/test/ui/regions/regions-in-enums-anon.stderr index ae06e7653dbeb..41655a210b3c0 100644 --- a/src/test/ui/regions/regions-in-enums-anon.stderr +++ b/src/test/ui/regions/regions-in-enums-anon.stderr @@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/regions-in-enums-anon.rs:4:9 | LL | Bar(&isize) - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | enum Foo<'lifetime> { +LL | Bar(&'lifetime isize) + | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-enums.stderr b/src/test/ui/regions/regions-in-enums.stderr index cfed9feba4b82..66537653291c7 100644 --- a/src/test/ui/regions/regions-in-enums.stderr +++ b/src/test/ui/regions/regions-in-enums.stderr @@ -1,12 +1,16 @@ error[E0261]: use of undeclared lifetime name `'foo` --> $DIR/regions-in-enums.rs:13:9 | +LL | enum No0 { + | - help: consider introducing lifetime `'foo` here: `<'foo>` LL | X5(&'foo usize) | ^^^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-in-enums.rs:17:9 | +LL | enum No1 { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | X6(&'a usize) | ^^ undeclared lifetime diff --git a/src/test/ui/regions/regions-in-structs-anon.stderr b/src/test/ui/regions/regions-in-structs-anon.stderr index a1d4ebb597b4c..fbe8036880f48 100644 --- a/src/test/ui/regions/regions-in-structs-anon.stderr +++ b/src/test/ui/regions/regions-in-structs-anon.stderr @@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/regions-in-structs-anon.rs:4:8 | LL | x: &isize - | ^ expected lifetime parameter + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | struct Foo<'lifetime> { +LL | x: &'lifetime isize + | error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-structs.stderr b/src/test/ui/regions/regions-in-structs.stderr index 8314942759d1a..5dfdc2ee93b43 100644 --- a/src/test/ui/regions/regions-in-structs.stderr +++ b/src/test/ui/regions/regions-in-structs.stderr @@ -1,12 +1,17 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-in-structs.rs:10:9 | +LL | struct StructDecl { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | a: &'a isize, | ^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-in-structs.rs:11:9 | +LL | struct StructDecl { + | - help: consider introducing lifetime `'a` here: `<'a>` +LL | a: &'a isize, LL | b: &'a isize, | ^^ undeclared lifetime diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr index 5f6a48a35f368..79ebef41dccd6 100644 --- a/src/test/ui/regions/regions-name-undeclared.stderr +++ b/src/test/ui/regions/regions-name-undeclared.stderr @@ -3,34 +3,67 @@ error[E0261]: use of undeclared lifetime name `'b` | LL | fn m4(&self, arg: &'b isize) { } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b, 'a> Foo<'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn m4<'b>(&self, arg: &'b isize) { } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/regions-name-undeclared.rs:16:12 | LL | fn m5(&'b self) { } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b, 'a> Foo<'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn m5<'b>(&'b self) { } + | ^^^^ error[E0261]: use of undeclared lifetime name `'b` --> $DIR/regions-name-undeclared.rs:17:27 | LL | fn m6(&self, arg: Foo<'b>) { } | ^^ undeclared lifetime + | +help: consider introducing lifetime `'b` here + | +LL | impl<'b, 'a> Foo<'a> { + | ^^^ +help: consider introducing lifetime `'b` here + | +LL | fn m6<'b>(&self, arg: Foo<'b>) { } + | ^^^^ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:25:22 | LL | type X = Option<&'a isize>; - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:27:13 | +LL | enum E { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | E1(&'a isize) | ^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:30:13 | +LL | struct S { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | f: &'a isize | ^^ undeclared lifetime @@ -38,13 +71,17 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:32:14 | LL | fn f(a: &'a isize) { } - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:40:17 | LL | fn fn_types(a: &'a isize, - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'b` --> $DIR/regions-name-undeclared.rs:42:36 @@ -61,6 +98,9 @@ LL | ... &'b isize)>, error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:46:17 | +LL | fn fn_types(a: &'a isize, + | - help: consider introducing lifetime `'a` here: `<'a>` +... LL | c: &'a isize) | ^^ undeclared lifetime diff --git a/src/test/ui/regions/regions-undeclared.stderr b/src/test/ui/regions/regions-undeclared.stderr index 495aec3fde5f1..6bfde5524ac49 100644 --- a/src/test/ui/regions/regions-undeclared.stderr +++ b/src/test/ui/regions/regions-undeclared.stderr @@ -7,12 +7,17 @@ LL | static c_x: &'blk isize = &22; error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:4:10 | +LL | enum EnumDecl { + | - help: consider introducing lifetime `'a` here: `<'a>` LL | Foo(&'a isize), | ^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:5:10 | +LL | enum EnumDecl { + | - help: consider introducing lifetime `'a` here: `<'a>` +LL | Foo(&'a isize), LL | Bar(&'a isize), | ^^ undeclared lifetime @@ -20,11 +25,15 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:8:15 | LL | fn fnDecl(x: &'a isize, - | ^^ undeclared lifetime + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:9:15 | +LL | fn fnDecl(x: &'a isize, + | - help: consider introducing lifetime `'a` here: `<'a>` LL | y: &'a isize) | ^^ undeclared lifetime diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr index 171c00ba7b813..5b665e181412a 100644 --- a/src/test/ui/rfc1623.stderr +++ b/src/test/ui/rfc1623.stderr @@ -2,7 +2,7 @@ error[E0106]: missing lifetime specifier --> $DIR/rfc1623.rs:8:42 | LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 @@ -10,7 +10,7 @@ error[E0106]: missing lifetime specifier --> $DIR/rfc1623.rs:10:39 | LL | &(non_elidable as fn(&u8, &u8) -> &u8); - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 9fb9a07166f84..0a028e44919a6 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -2,9 +2,18 @@ error[E0106]: missing lifetime specifier --> $DIR/unboxed-closure-sugar-lifetime-elision.rs:26:39 | LL | let _: dyn Foo(&isize, &usize) -> &usize; - | ^ expected lifetime parameter + | ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: consider introducing a named lifetime parameter + | +LL | fn main<'lifetime>() { +LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>, +LL | dyn Foo(&isize) -> &isize >(); +LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>, +LL | dyn Foo(&isize) -> (&isize, &isize) >(); +LL | + ... error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr index b20c23ade2b78..04df2e4570396 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr @@ -2,7 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/dyn-trait-underscore-in-struct.rs:9:24 | LL | x: Box, - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | struct Foo<'lifetime> { +LL | x: Box, + | error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound --> $DIR/dyn-trait-underscore-in-struct.rs:9:12 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 ed61bdfdddab3..cf820249c80af 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier --> $DIR/in-fn-return-illegal.rs:5:30 | LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` +help: consider introducing a named lifetime parameter + | +LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } } + | ^^^^^^^^^^^ ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/in-struct.stderr b/src/test/ui/underscore-lifetime/in-struct.stderr index 6bbdc71195a50..e01b39a4b64f4 100644 --- a/src/test/ui/underscore-lifetime/in-struct.stderr +++ b/src/test/ui/underscore-lifetime/in-struct.stderr @@ -2,13 +2,25 @@ error[E0106]: missing lifetime specifier --> $DIR/in-struct.rs:6:9 | LL | x: &'_ u32, - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | struct Foo<'lifetime> { +LL | x: &'lifetime u32, + | error[E0106]: missing lifetime specifier --> $DIR/in-struct.rs:10:14 | LL | Variant(&'_ u32), - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | enum Bar<'lifetime> { +LL | Variant(&'lifetime u32), + | error: aborting due to 2 previous errors diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index ef9e7e39df0bc..517904ee62869 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -14,7 +14,7 @@ error[E0106]: missing lifetime specifier --> $DIR/underscore-lifetime-binders.rs:2:17 | LL | struct Baz<'a>(&'_ &'a u8); - | ^^ expected lifetime parameter + | ^^ help: consider using the named lifetime: `'a` error[E0106]: missing lifetime specifier --> $DIR/underscore-lifetime-binders.rs:10:33 @@ -28,9 +28,13 @@ error[E0106]: missing lifetime specifier --> $DIR/underscore-lifetime-binders.rs:16:35 | LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } - | ^^ expected lifetime parameter + | ^^ expected named lifetime parameter | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` +help: consider introducing a named lifetime parameter + | +LL | fn foo2<'lifetime>(_: &'_ u8, y: &'_ u8) -> &'lifetime u8 { y } + | ^^^^^^^^^^^ ^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/src/test/ui/where-clauses/where-lifetime-resolution.stderr b/src/test/ui/where-clauses/where-lifetime-resolution.stderr index 0081ae07163b3..49799a93017eb 100644 --- a/src/test/ui/where-clauses/where-lifetime-resolution.stderr +++ b/src/test/ui/where-clauses/where-lifetime-resolution.stderr @@ -1,6 +1,9 @@ error[E0261]: use of undeclared lifetime name `'a` --> $DIR/where-lifetime-resolution.rs:6:38 | +LL | fn f() where + | - help: consider introducing lifetime `'a` here: `<'a>` +LL | for<'a> dyn Trait1<'a>: Trait1<'a>, // OK LL | (dyn for<'a> Trait1<'a>): Trait1<'a>, | ^^ undeclared lifetime @@ -13,6 +16,9 @@ LL | for<'a> dyn for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>, error[E0261]: use of undeclared lifetime name `'b` --> $DIR/where-lifetime-resolution.rs:8:52 | +LL | fn f() where + | - help: consider introducing lifetime `'b` here: `<'b>` +... LL | for<'a> dyn for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>, | ^^ undeclared lifetime