diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8597820073a56..7edf3edfe2b27 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1405,7 +1405,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi(); let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }; - (region, LifetimeSyntax::Hidden) + (region, LifetimeSyntax::Implicit) } }; self.lower_lifetime(®ion, LifetimeSource::Reference, syntax) @@ -1789,7 +1789,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { id, Ident::new(kw::UnderscoreLifetime, span), LifetimeSource::Path { angle_brackets }, - LifetimeSyntax::Hidden, + LifetimeSyntax::Implicit, ) } @@ -2421,7 +2421,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Ident::new(kw::UnderscoreLifetime, self.lower_span(span)), hir::LifetimeKind::ImplicitObjectLifetimeDefault, LifetimeSource::Other, - LifetimeSyntax::Hidden, + LifetimeSyntax::Implicit, ); debug!("elided_dyn_bound: r={:?}", r); self.arena.alloc(r) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 507c94aca8b9a..429086d0a732d 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -842,12 +842,7 @@ pub enum LifetimeRes { /// late resolution. Those lifetimes will be inferred by typechecking. Infer, /// `'static` lifetime. - Static { - /// We do not want to emit `elided_named_lifetimes` - /// when we are inside of a const item or a static, - /// because it would get too annoying. - suppress_elision_warning: bool, - }, + Static, /// Resolution failure. Error, /// HACK: This is used to recover the NodeId of an elided lifetime. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 107aea4e5a401..fde651124e006 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -72,13 +72,13 @@ pub enum LifetimeSource { #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)] pub enum LifetimeSyntax { /// E.g. `&Type`, `ContainsLifetime` - Hidden, + Implicit, /// E.g. `&'_ Type`, `ContainsLifetime<'_>`, `impl Trait + '_`, `impl Trait + use<'_>` - Anonymous, + ExplicitAnonymous, /// E.g. `&'a Type`, `ContainsLifetime<'a>`, `impl Trait + 'a`, `impl Trait + use<'a>` - Named, + ExplicitBound, } impl From for LifetimeSyntax { @@ -88,10 +88,10 @@ impl From for LifetimeSyntax { if name == kw::Empty { unreachable!("A lifetime name should never be empty"); } else if name == kw::UnderscoreLifetime { - LifetimeSyntax::Anonymous + LifetimeSyntax::ExplicitAnonymous } else { debug_assert!(name.as_str().starts_with('\'')); - LifetimeSyntax::Named + LifetimeSyntax::ExplicitBound } } } @@ -102,48 +102,48 @@ impl From for LifetimeSyntax { /// /// ``` /// #[repr(C)] -/// struct S<'a>(&'a u32); // res=Param, name='a, source=Reference, syntax=Named +/// struct S<'a>(&'a u32); // res=Param, name='a, source=Reference, syntax=ExplicitBound /// unsafe extern "C" { -/// fn f1(s: S); // res=Param, name='_, source=Path, syntax=Hidden -/// fn f2(s: S<'_>); // res=Param, name='_, source=Path, syntax=Anonymous -/// fn f3<'a>(s: S<'a>); // res=Param, name='a, source=Path, syntax=Named +/// fn f1(s: S); // res=Param, name='_, source=Path, syntax=Implicit +/// fn f2(s: S<'_>); // res=Param, name='_, source=Path, syntax=ExplicitAnonymous +/// fn f3<'a>(s: S<'a>); // res=Param, name='a, source=Path, syntax=ExplicitBound /// } /// -/// struct St<'a> { x: &'a u32 } // res=Param, name='a, source=Reference, syntax=Named +/// struct St<'a> { x: &'a u32 } // res=Param, name='a, source=Reference, syntax=ExplicitBound /// fn f() { -/// _ = St { x: &0 }; // res=Infer, name='_, source=Path, syntax=Hidden -/// _ = St::<'_> { x: &0 }; // res=Infer, name='_, source=Path, syntax=Anonymous +/// _ = St { x: &0 }; // res=Infer, name='_, source=Path, syntax=Implicit +/// _ = St::<'_> { x: &0 }; // res=Infer, name='_, source=Path, syntax=ExplicitAnonymous /// } /// -/// struct Name<'a>(&'a str); // res=Param, name='a, source=Reference, syntax=Named -/// const A: Name = Name("a"); // res=Static, name='_, source=Path, syntax=Hidden -/// const B: &str = ""; // res=Static, name='_, source=Reference, syntax=Hidden -/// static C: &'_ str = ""; // res=Static, name='_, source=Reference, syntax=Anonymous -/// static D: &'static str = ""; // res=Static, name='static, source=Reference, syntax=Named +/// struct Name<'a>(&'a str); // res=Param, name='a, source=Reference, syntax=ExplicitBound +/// const A: Name = Name("a"); // res=Static, name='_, source=Path, syntax=Implicit +/// const B: &str = ""; // res=Static, name='_, source=Reference, syntax=Implicit +/// static C: &'_ str = ""; // res=Static, name='_, source=Reference, syntax=ExplicitAnonymous +/// static D: &'static str = ""; // res=Static, name='static, source=Reference, syntax=ExplicitBound /// /// trait Tr {} -/// fn tr(_: Box) {} // res=ImplicitObjectLifetimeDefault, name='_, source=Other, syntax=Hidden +/// fn tr(_: Box) {} // res=ImplicitObjectLifetimeDefault, name='_, source=Other, syntax=Implicit /// /// fn capture_outlives<'a>() -> -/// impl FnOnce() + 'a // res=Param, ident='a, source=OutlivesBound, syntax=Named +/// impl FnOnce() + 'a // res=Param, ident='a, source=OutlivesBound, syntax=ExplicitBound /// { /// || {} /// } /// /// fn capture_precise<'a>() -> -/// impl FnOnce() + use<'a> // res=Param, ident='a, source=PreciseCapturing, syntax=Named +/// impl FnOnce() + use<'a> // res=Param, ident='a, source=PreciseCapturing, syntax=ExplicitBound /// { /// || {} /// } /// /// // (commented out because these cases trigger errors) -/// // struct S1<'a>(&'a str); // res=Param, name='a, source=Reference, syntax=Named -/// // struct S2(S1); // res=Error, name='_, source=Path, syntax=Hidden -/// // struct S3(S1<'_>); // res=Error, name='_, source=Path, syntax=Anonymous -/// // struct S4(S1<'a>); // res=Error, name='a, source=Path, syntax=Named +/// // struct S1<'a>(&'a str); // res=Param, name='a, source=Reference, syntax=ExplicitBound +/// // struct S2(S1); // res=Error, name='_, source=Path, syntax=Implicit +/// // struct S3(S1<'_>); // res=Error, name='_, source=Path, syntax=ExplicitAnonymous +/// // struct S4(S1<'a>); // res=Error, name='a, source=Path, syntax=ExplicitBound /// ``` /// -/// Some combinations that cannot occur are `LifetimeSyntax::Hidden` with +/// Some combinations that cannot occur are `LifetimeSyntax::Implicit` with /// `LifetimeSource::OutlivesBound` or `LifetimeSource::PreciseCapturing` /// — there's no way to "elide" these lifetimes. #[derive(Debug, Copy, Clone, HashStable_Generic)] @@ -206,7 +206,7 @@ impl ParamName { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)] pub enum LifetimeKind { /// User-given names or fresh (synthetic) names. Param(LocalDefId), @@ -287,12 +287,8 @@ impl Lifetime { self.ident.name == kw::UnderscoreLifetime } - pub fn is_syntactically_hidden(&self) -> bool { - matches!(self.syntax, LifetimeSyntax::Hidden) - } - - pub fn is_syntactically_anonymous(&self) -> bool { - matches!(self.syntax, LifetimeSyntax::Anonymous) + pub fn is_implicit(&self) -> bool { + matches!(self.syntax, LifetimeSyntax::Implicit) } pub fn is_static(&self) -> bool { @@ -307,28 +303,28 @@ impl Lifetime { match (self.syntax, self.source) { // The user wrote `'a` or `'_`. - (Named | Anonymous, _) => (self.ident.span, format!("{new_lifetime}")), + (ExplicitBound | ExplicitAnonymous, _) => (self.ident.span, format!("{new_lifetime}")), // The user wrote `Path`, and omitted the `'_,`. - (Hidden, Path { angle_brackets: AngleBrackets::Full }) => { + (Implicit, Path { angle_brackets: AngleBrackets::Full }) => { (self.ident.span, format!("{new_lifetime}, ")) } // The user wrote `Path<>`, and omitted the `'_`.. - (Hidden, Path { angle_brackets: AngleBrackets::Empty }) => { + (Implicit, Path { angle_brackets: AngleBrackets::Empty }) => { (self.ident.span, format!("{new_lifetime}")) } // The user wrote `Path` and omitted the `<'_>`. - (Hidden, Path { angle_brackets: AngleBrackets::Missing }) => { + (Implicit, Path { angle_brackets: AngleBrackets::Missing }) => { (self.ident.span.shrink_to_hi(), format!("<{new_lifetime}>")) } // The user wrote `&type` or `&mut type`. - (Hidden, Reference) => (self.ident.span, format!("{new_lifetime} ")), + (Implicit, Reference) => (self.ident.span, format!("{new_lifetime} ")), - (Hidden, source) => { - unreachable!("can't suggest for a hidden lifetime of {source:?}") + (Implicit, source) => { + unreachable!("can't suggest for a implicit lifetime of {source:?}") } } } diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs index 8684adee29c99..1fd793bc1616f 100644 --- a/compiler/rustc_hir/src/hir/tests.rs +++ b/compiler/rustc_hir/src/hir/tests.rs @@ -55,7 +55,7 @@ fn trait_object_roundtrips_impl(syntax: TraitObjectSyntax) { ident: Ident::new(sym::name, DUMMY_SP), kind: LifetimeKind::Static, source: LifetimeSource::Other, - syntax: LifetimeSyntax::Hidden, + syntax: LifetimeSyntax::Implicit, }; let unambig = TyKind::TraitObject::<'_, ()>(&[], TaggedRef::new(<, syntax)); let unambig_to_ambig = unsafe { std::mem::transmute::<_, TyKind<'_, AmbigArg>>(unambig) }; diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 99b42ee548029..10820d9c78c5c 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -251,11 +251,6 @@ lint_duplicate_macro_attribute = lint_duplicate_matcher_binding = duplicate matcher binding -lint_elided_named_lifetime = elided lifetime has a name - .label_elided = this elided lifetime gets resolved as `{$name}` - .label_named = lifetime `{$name}` declared here - .suggestion = consider specifying it explicitly - lint_enum_intrinsics_mem_discriminant = the return value of `mem::discriminant` is unspecified when called with a non-enum type .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum @@ -512,6 +507,28 @@ lint_metavariable_still_repeating = variable `{$name}` is still repeating at thi lint_metavariable_wrong_operator = meta-variable repeats with different Kleene operator +lint_mismatched_lifetime_syntaxes = + lifetime flowing from input to output with different syntax + .label_mismatched_lifetime_syntaxes_inputs = + {$n_inputs -> + [one] this lifetime flows + *[other] these lifetimes flow + } to the output + .label_mismatched_lifetime_syntaxes_outputs = + the elided {$n_outputs -> + [one] lifetime gets + *[other] lifetimes get + } resolved as `{$lifetime_name}` + +lint_mismatched_lifetime_syntaxes_suggestion_explicit = + one option is to consistently use `{$lifetime_name}` + +lint_mismatched_lifetime_syntaxes_suggestion_implicit = + one option is to consistently hide the lifetime + +lint_mismatched_lifetime_syntaxes_suggestion_mixed = + one option is to hide the lifetime for references and use the anonymous lifetime for paths + lint_missing_fragment_specifier = missing fragment specifier lint_missing_unsafe_on_extern = extern blocks should be unsafe diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 40ca9e05d95d6..c59987cabb782 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -10,11 +10,11 @@ use rustc_errors::{ use rustc_middle::middle::stability; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution}; -use rustc_span::{BytePos, kw}; +use rustc_session::lint::BuiltinLintDiag; +use rustc_span::BytePos; use tracing::debug; -use crate::lints::{self, ElidedNamedLifetime}; +use crate::lints; mod check_cfg; @@ -450,16 +450,5 @@ pub(super) fn decorate_lint( BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => { lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag) } - BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => { - match resolution { - ElidedLifetimeResolution::Static => { - ElidedNamedLifetime { span, kind, name: kw::StaticLifetime, declaration: None } - } - ElidedLifetimeResolution::Param(name, declaration) => { - ElidedNamedLifetime { span, kind, name, declaration: Some(declaration) } - } - } - .decorate_lint(diag) - } } } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index b910d6a138e11..10ebe1c17e6e6 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -57,6 +57,7 @@ mod invalid_from_utf8; mod late; mod let_underscore; mod levels; +mod lifetime_style; mod lints; mod macro_expr_fragment_specifier_2024_migration; mod map_unit_fn; @@ -98,6 +99,7 @@ use impl_trait_overcaptures::ImplTraitOvercaptures; use internal::*; use invalid_from_utf8::*; use let_underscore::*; +use lifetime_style::*; use macro_expr_fragment_specifier_2024_migration::*; use map_unit_fn::*; use multiple_supertrait_upcastable::*; @@ -246,6 +248,7 @@ late_lint_methods!( IfLetRescope: IfLetRescope::default(), StaticMutRefs: StaticMutRefs, UnqualifiedLocalImports: UnqualifiedLocalImports, + LifetimeStyle: LifetimeStyle, ] ] ); @@ -353,6 +356,7 @@ fn register_builtins(store: &mut LintStore) { store.register_renamed("unused_tuple_struct_fields", "dead_code"); store.register_renamed("static_mut_ref", "static_mut_refs"); store.register_renamed("temporary_cstring_as_ptr", "dangling_pointers_from_temporaries"); + store.register_renamed("elided_named_lifetimes", "mismatched_lifetime_syntaxes"); // These were moved to tool lints, but rustc still sees them when compiling normally, before // tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use diff --git a/compiler/rustc_lint/src/lifetime_style.rs b/compiler/rustc_lint/src/lifetime_style.rs new file mode 100644 index 0000000000000..afe70ca79a348 --- /dev/null +++ b/compiler/rustc_lint/src/lifetime_style.rs @@ -0,0 +1,454 @@ +use rustc_data_structures::fx::FxIndexMap; +use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::{self as hir, LifetimeSource, LifetimeSyntax}; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::Span; +use tracing::instrument; + +use crate::{LateContext, LateLintPass, LintContext, lints}; + +declare_lint! { + /// The `mismatched_lifetime_syntaxes` lint detects when an + /// elided lifetime uses different syntax between function + /// arguments and return values. + /// + /// The three kinds of syntax are: + /// 1. Explicitly bound lifetimes, such as `'static` or `'a`. + /// 2. The explicitly anonymous lifetime `'_`. + /// 3. Implicit lifetimes, such as `&u8` or `ThisHasALifetimeGeneric`. + /// + /// As an exception, this lint allows references with implicit or + /// explicitly anonymous lifetimes to be paired with paths using + /// explicitly anonymous lifetimes. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(mismatched_lifetime_syntaxes)] + /// + /// pub fn mixing_explicit_bound_with_implicit(v: &'static u8) -> &u8 { + /// v + /// } + /// + /// struct Person<'a> { + /// name: &'a str, + /// } + /// + /// pub fn mixing_implicit_with_explicit_anonymous(v: Person) -> Person<'_> { + /// v + /// } + /// + /// struct Foo; + /// + /// impl Foo { + /// // Lifetime elision results in the output lifetime becoming + /// // `'static`, which is not what was intended. + /// pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 { + /// unsafe { &mut *(x as *mut _) } + /// } + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Lifetime elision is useful because it frees you from having to + /// give each lifetime its own name and show the relation of input + /// and output lifetimes for common cases. However, a lifetime + /// that uses inconsistent syntax between related arguments and + /// return values is more confusing. + /// + /// In certain `unsafe` code, lifetime elision combined with + /// inconsistent lifetime syntax may result in unsound code. + pub MISMATCHED_LIFETIME_SYNTAXES, + Warn, + "detects when an elided lifetime uses different syntax between arguments and return values" +} + +declare_lint_pass!(LifetimeStyle => [MISMATCHED_LIFETIME_SYNTAXES]); + +impl<'tcx> LateLintPass<'tcx> for LifetimeStyle { + #[instrument(skip_all)] + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + _: hir::intravisit::FnKind<'tcx>, + fd: &'tcx hir::FnDecl<'tcx>, + _: &'tcx hir::Body<'tcx>, + _: rustc_span::Span, + _: rustc_span::def_id::LocalDefId, + ) { + let mut input_map = Default::default(); + let mut output_map = Default::default(); + + for input in fd.inputs { + LifetimeInfoCollector::collect(input, &mut input_map); + } + + if let hir::FnRetTy::Return(output) = fd.output { + LifetimeInfoCollector::collect(output, &mut output_map); + } + + report_mismatches(cx, &input_map, &output_map); + } +} + +#[instrument(skip_all)] +fn report_mismatches<'tcx>( + cx: &LateContext<'tcx>, + inputs: &LifetimeInfoMap<'tcx>, + outputs: &LifetimeInfoMap<'tcx>, +) { + for (resolved_lifetime, output_info) in outputs { + if let Some(input_info) = inputs.get(resolved_lifetime) { + let relevant_lifetimes = input_info.iter().chain(output_info); + + // There can only ever be zero or one bound lifetime + // for a given lifetime resolution. + let mut bound_lifetime = None; + + // Categorize lifetimes into source/syntax buckets + let mut n_hidden = 0; + let mut n_elided = 0; + let mut n_named = 0; + + // These are the lifetime instances that are allowed to + // change to a given alternate style. + let mut suggest_change_to_implicit = Vec::new(); + let mut suggest_change_to_mixed_implicit = Vec::new(); + let mut suggest_change_to_mixed_explicit_anonymous = Vec::new(); + let mut suggest_change_to_explicit_anonymous = Vec::new(); + let mut suggest_change_to_explicit_bound = Vec::new(); + + // Some styles prevent using implicit syntax at all. + let mut allow_suggesting_implicit = true; + + // It only makes sense to suggest mixed if we have both sources + let mut saw_a_reference = false; + let mut saw_a_path = false; + + for info in relevant_lifetimes { + use LifetimeSource::*; + use LifetimeSyntax::*; + + let syntax_source = (info.lifetime.syntax, info.lifetime.source); + + if let (ExplicitBound, _) = syntax_source { + bound_lifetime = Some(info); + } + + match syntax_source { + // Ignore any other kind of lifetime + (_, Other) => continue, + + // e.g. `&T` + (Implicit, Reference | OutlivesBound | PreciseCapturing) | + // e.g. `&'_ T` + (ExplicitAnonymous, Reference | OutlivesBound | PreciseCapturing) | + // e.g. `ContainsLifetime<'_>` + (ExplicitAnonymous, Path { .. }) => n_elided += 1, + + // e.g. `ContainsLifetime` + (Implicit, Path { .. }) => n_hidden += 1, + + // e.g. `&'a T` + (ExplicitBound, Reference | OutlivesBound | PreciseCapturing) | + // e.g. `ContainsLifetime<'a>` + (ExplicitBound, Path { .. }) => n_named += 1, + }; + + match syntax_source { + // e.g. `&T` + (Implicit, Reference) => { + suggest_change_to_explicit_anonymous.push(info); + suggest_change_to_explicit_bound.push(info); + } + + // e.g. `&'_ T` + (ExplicitAnonymous, Reference) => { + suggest_change_to_implicit.push(info); + suggest_change_to_mixed_implicit.push(info); + suggest_change_to_explicit_bound.push(info); + } + + // e.g. `ContainsLifetime` + (Implicit, Path { .. }) => { + suggest_change_to_mixed_explicit_anonymous.push(info); + suggest_change_to_explicit_anonymous.push(info); + suggest_change_to_explicit_bound.push(info); + } + + // e.g. `ContainsLifetime<'_>` + (ExplicitAnonymous, Path { .. }) => { + suggest_change_to_explicit_bound.push(info); + } + + // e.g. `&'a T` + (ExplicitBound, Reference) => { + suggest_change_to_implicit.push(info); + suggest_change_to_mixed_implicit.push(info); + suggest_change_to_explicit_anonymous.push(info); + } + + // e.g. `ContainsLifetime<'a>` + (ExplicitBound, Path { .. }) => { + suggest_change_to_mixed_explicit_anonymous.push(info); + suggest_change_to_explicit_anonymous.push(info); + } + + (Implicit, OutlivesBound | PreciseCapturing) => { + panic!("This syntax / source combination is not possible"); + } + + // e.g. `+ '_`, `+ use<'_>` + (ExplicitAnonymous, OutlivesBound | PreciseCapturing) => { + suggest_change_to_explicit_bound.push(info); + } + + // e.g. `+ 'a`, `+ use<'a>` + (ExplicitBound, OutlivesBound | PreciseCapturing) => { + suggest_change_to_mixed_explicit_anonymous.push(info); + suggest_change_to_explicit_anonymous.push(info); + } + + (_, Other) => { + panic!("This syntax / source combination has already been skipped"); + } + } + + if matches!(syntax_source, (_, Path { .. } | OutlivesBound | PreciseCapturing)) { + allow_suggesting_implicit = false; + } + + match syntax_source { + (_, Reference) => saw_a_reference = true, + (_, Path { .. }) => saw_a_path = true, + _ => {} + } + } + + // Check if syntaxes are consistent + let syntax_counts = (n_hidden, n_elided, n_named); + tracing::debug!(?syntax_counts); + + if let (_, 0, 0) | (0, _, 0) | (0, 0, _) = syntax_counts { + // The syntax is consistent, nothing to report. + continue; + } + + let make_implicit_suggestions = + |infos: &[&Info<'_>]| infos.iter().map(|i| i.hiding_span()).collect::>(); + + let inputs = input_info.iter().map(|info| info.reporting_span()).collect(); + let outputs = output_info.iter().map(|info| info.reporting_span()).collect(); + + let explicit_bound_suggestion = bound_lifetime.map(|info| { + build_mismatch_suggestion(info.lifetime_name(), &suggest_change_to_explicit_bound) + }); + + let is_bound_static = bound_lifetime.is_some_and(|info| info.is_static()); + + tracing::debug!(?bound_lifetime, ?explicit_bound_suggestion, ?is_bound_static); + + let should_suggest_mixed = + // Do we have a mixed case? + (saw_a_reference && saw_a_path) && + // Is there anything to change? + (!suggest_change_to_mixed_implicit.is_empty() || + !suggest_change_to_mixed_explicit_anonymous.is_empty()) && + // If we have `'static`, we don't want to remove it + !is_bound_static; + + let mixed_suggestion = should_suggest_mixed.then(|| { + let implicit_suggestions = + make_implicit_suggestions(&suggest_change_to_mixed_implicit); + + let explicit_anonymous_suggestions = suggest_change_to_mixed_explicit_anonymous + .iter() + .map(|info| info.suggestion("'_")) + .collect(); + + lints::MismatchedLifetimeSyntaxesSuggestion::Mixed { + implicit_suggestions, + explicit_anonymous_suggestions, + tool_only: false, + } + }); + + tracing::debug!( + ?suggest_change_to_mixed_implicit, + ?suggest_change_to_mixed_explicit_anonymous, + ?mixed_suggestion, + ); + + let should_suggest_implicit = + // Is there anything to change? + !suggest_change_to_implicit.is_empty() && + // We never want to hide the lifetime in a path (or similar) + allow_suggesting_implicit && + // If we have `'static`, we don't want to remove it + !is_bound_static; + + let implicit_suggestion = should_suggest_implicit.then(|| { + let suggestions = make_implicit_suggestions(&suggest_change_to_implicit); + + lints::MismatchedLifetimeSyntaxesSuggestion::Implicit { + suggestions, + tool_only: false, + } + }); + + tracing::debug!( + ?should_suggest_implicit, + ?suggest_change_to_implicit, + allow_suggesting_implicit, + ?implicit_suggestion, + ); + + let should_suggest_explicit_anonymous = + // Is there anything to change? + !suggest_change_to_explicit_anonymous.is_empty() && + // If we have `'static`, we don't want to remove it + !is_bound_static; + + let explicit_anonymous_suggestion = should_suggest_explicit_anonymous + .then(|| build_mismatch_suggestion("'_", &suggest_change_to_explicit_anonymous)); + + tracing::debug!( + ?should_suggest_explicit_anonymous, + ?suggest_change_to_explicit_anonymous, + ?explicit_anonymous_suggestion, + ); + + let lifetime_name = + bound_lifetime.map(|info| info.lifetime_name()).unwrap_or("'_").to_owned(); + + // We can produce a number of suggestions which may overwhelm + // the user. Instead, we order the suggestions based on Rust + // idioms. The "best" choice is shown to the user and the + // remaining choices are shown to tools only. + let mut suggestions = Vec::new(); + suggestions.extend(explicit_bound_suggestion); + suggestions.extend(mixed_suggestion); + suggestions.extend(implicit_suggestion); + suggestions.extend(explicit_anonymous_suggestion); + + cx.emit_span_lint( + MISMATCHED_LIFETIME_SYNTAXES, + Vec::clone(&inputs), + lints::MismatchedLifetimeSyntaxes { lifetime_name, inputs, outputs, suggestions }, + ); + } + } +} + +fn build_mismatch_suggestion( + lifetime_name: &str, + infos: &[&Info<'_>], +) -> lints::MismatchedLifetimeSyntaxesSuggestion { + let lifetime_name = lifetime_name.to_owned(); + + let suggestions = infos.iter().map(|info| info.suggestion(&lifetime_name)).collect(); + + lints::MismatchedLifetimeSyntaxesSuggestion::Explicit { + lifetime_name, + suggestions, + tool_only: false, + } +} + +#[derive(Debug)] +struct Info<'tcx> { + type_span: Span, + referenced_type_span: Option, + lifetime: &'tcx hir::Lifetime, +} + +impl<'tcx> Info<'tcx> { + fn lifetime_name(&self) -> &str { + self.lifetime.ident.as_str() + } + + fn is_static(&self) -> bool { + self.lifetime.is_static() + } + + /// When reporting a lifetime that is implicit, we expand the span + /// to include the type. Otherwise we end up pointing at nothing, + /// which is a bit confusing. + fn reporting_span(&self) -> Span { + if self.lifetime.is_implicit() { self.type_span } else { self.lifetime.ident.span } + } + + /// When hiding a lifetime in a reference, we want to remove the + /// whitespace after the lifetime. + /// + /// ```rust + /// fn x(a: &'_ u8) {} + /// ``` + /// + /// Should become + /// + /// ```rust + /// fn x(a: &u8) {} + /// ``` + // FIXME: Ideally, we'd also remove the lifetime declaration. + fn hiding_span(&self) -> Span { + let mut span = self.suggestion("'dummy").0; + + if let Some(referenced_type_span) = self.referenced_type_span { + span = span.until(referenced_type_span); + } + + span + } + + fn suggestion(&self, lifetime_name: &str) -> (Span, String) { + self.lifetime.suggestion(lifetime_name) + } +} + +type LifetimeInfoMap<'tcx> = FxIndexMap<&'tcx hir::LifetimeKind, Vec>>; + +struct LifetimeInfoCollector<'a, 'tcx> { + type_span: Span, + referenced_type_span: Option, + map: &'a mut LifetimeInfoMap<'tcx>, +} + +impl<'a, 'tcx> LifetimeInfoCollector<'a, 'tcx> { + fn collect(ty: &'tcx hir::Ty<'tcx>, map: &'a mut LifetimeInfoMap<'tcx>) { + let mut this = Self { type_span: ty.span, referenced_type_span: None, map }; + + intravisit::walk_unambig_ty(&mut this, ty); + } +} + +impl<'a, 'tcx> Visitor<'tcx> for LifetimeInfoCollector<'a, 'tcx> { + #[instrument(skip(self))] + fn visit_lifetime(&mut self, lifetime: &'tcx hir::Lifetime) { + let type_span = self.type_span; + let referenced_type_span = self.referenced_type_span; + + let info = Info { type_span, referenced_type_span, lifetime }; + + self.map.entry(&lifetime.kind).or_default().push(info); + } + + #[instrument(skip(self))] + fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, hir::AmbigArg>) -> Self::Result { + let old_type_span = self.type_span; + let old_referenced_type_span = self.referenced_type_span; + + self.type_span = ty.span; + if let hir::TyKind::Ref(_, ty) = ty.kind { + self.referenced_type_span = Some(ty.ty.span); + } + + intravisit::walk_ty(self, ty); + + self.type_span = old_type_span; + self.referenced_type_span = old_referenced_type_span; + } +} diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 487184b836a43..ae30901509437 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -8,17 +8,17 @@ use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString, ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, Subdiagnostic, SuggestionStyle, }; +use rustc_hir as hir; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::VisitorExt; -use rustc_hir::{self as hir, MissingLifetimeKind}; use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::inhabitedness::InhabitedPredicate; use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_session::Session; use rustc_session::lint::AmbiguityErrorDiag; use rustc_span::edition::Edition; -use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, kw, sym}; +use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym}; use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds}; use crate::errors::{OverruledAttributeSub, RequestedLevel}; @@ -2689,58 +2689,6 @@ pub(crate) struct ElidedLifetimesInPaths { pub subdiag: ElidedLifetimeInPathSubdiag, } -pub(crate) struct ElidedNamedLifetime { - pub span: Span, - pub kind: MissingLifetimeKind, - pub name: Symbol, - pub declaration: Option, -} - -impl LintDiagnostic<'_, G> for ElidedNamedLifetime { - fn decorate_lint(self, diag: &mut rustc_errors::Diag<'_, G>) { - let Self { span, kind, name, declaration } = self; - diag.primary_message(fluent::lint_elided_named_lifetime); - diag.arg("name", name); - diag.span_label(span, fluent::lint_label_elided); - if let Some(declaration) = declaration { - diag.span_label(declaration, fluent::lint_label_named); - } - // FIXME(GrigorenkoPV): this `if` and `return` should be removed, - // but currently this lint's suggestions can conflict with those of `clippy::needless_lifetimes`: - // https://github.com/rust-lang/rust/pull/129840#issuecomment-2323349119 - // HACK: `'static` suggestions will never sonflict, emit only those for now. - if name != kw::StaticLifetime { - return; - } - match kind { - MissingLifetimeKind::Underscore => diag.span_suggestion_verbose( - span, - fluent::lint_suggestion, - format!("{name}"), - Applicability::MachineApplicable, - ), - MissingLifetimeKind::Ampersand => diag.span_suggestion_verbose( - span.shrink_to_hi(), - fluent::lint_suggestion, - format!("{name} "), - Applicability::MachineApplicable, - ), - MissingLifetimeKind::Comma => diag.span_suggestion_verbose( - span.shrink_to_hi(), - fluent::lint_suggestion, - format!("{name}, "), - Applicability::MachineApplicable, - ), - MissingLifetimeKind::Brackets => diag.span_suggestion_verbose( - span.shrink_to_hi(), - fluent::lint_suggestion, - format!("<{name}>"), - Applicability::MachineApplicable, - ), - }; - } -} - #[derive(LintDiagnostic)] #[diag(lint_invalid_crate_type_value)] pub(crate) struct UnknownCrateTypes { @@ -3176,3 +3124,128 @@ pub(crate) struct ReservedMultihash { #[suggestion(code = " ", applicability = "machine-applicable")] pub suggestion: Span, } + +#[derive(Debug)] +pub(crate) struct MismatchedLifetimeSyntaxes { + pub lifetime_name: String, + pub inputs: Vec, + pub outputs: Vec, + + pub suggestions: Vec, +} + +impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for MismatchedLifetimeSyntaxes { + fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { + diag.primary_message(fluent::lint_mismatched_lifetime_syntaxes); + + diag.arg("lifetime_name", self.lifetime_name); + + diag.arg("n_inputs", self.inputs.len()); + for input in self.inputs { + let a = diag.eagerly_translate(fluent::lint_label_mismatched_lifetime_syntaxes_inputs); + diag.span_label(input, a); + } + + diag.arg("n_outputs", self.outputs.len()); + for output in self.outputs { + let a = diag.eagerly_translate(fluent::lint_label_mismatched_lifetime_syntaxes_outputs); + diag.span_label(output, a); + } + + let mut suggestions = self.suggestions.into_iter(); + if let Some(s) = suggestions.next() { + diag.subdiagnostic(s); + + for mut s in suggestions { + s.make_tool_only(); + diag.subdiagnostic(s); + } + } + } +} + +#[derive(Debug)] +pub(crate) enum MismatchedLifetimeSyntaxesSuggestion { + Implicit { + suggestions: Vec, + tool_only: bool, + }, + + Mixed { + implicit_suggestions: Vec, + explicit_anonymous_suggestions: Vec<(Span, String)>, + tool_only: bool, + }, + + Explicit { + lifetime_name: String, + suggestions: Vec<(Span, String)>, + tool_only: bool, + }, +} + +impl MismatchedLifetimeSyntaxesSuggestion { + fn make_tool_only(&mut self) { + use MismatchedLifetimeSyntaxesSuggestion::*; + + let tool_only = match self { + Implicit { tool_only, .. } | Mixed { tool_only, .. } | Explicit { tool_only, .. } => { + tool_only + } + }; + + *tool_only = true; + } +} + +impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { + fn add_to_diag(self, diag: &mut Diag<'_, G>) { + use MismatchedLifetimeSyntaxesSuggestion::*; + + let style = |tool_only| { + if tool_only { SuggestionStyle::CompletelyHidden } else { SuggestionStyle::ShowAlways } + }; + + match self { + Implicit { suggestions, tool_only } => { + let suggestions = suggestions.into_iter().map(|s| (s, String::new())).collect(); + diag.multipart_suggestion_with_style( + fluent::lint_mismatched_lifetime_syntaxes_suggestion_implicit, + suggestions, + Applicability::MachineApplicable, + style(tool_only), + ); + } + + Mixed { implicit_suggestions, explicit_anonymous_suggestions, tool_only } => { + let implicit_suggestions = + implicit_suggestions.into_iter().map(|s| (s, String::new())); + + let suggestions = + implicit_suggestions.chain(explicit_anonymous_suggestions).collect(); + + diag.multipart_suggestion_with_style( + fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed, + suggestions, + Applicability::MachineApplicable, + style(tool_only), + ); + } + + Explicit { lifetime_name, suggestions, tool_only } => { + diag.arg("lifetime_name", lifetime_name); + + let msg = diag.eagerly_translate( + fluent::lint_mismatched_lifetime_syntaxes_suggestion_explicit, + ); + + diag.multipart_suggestion_with_style( + msg, + suggestions, + Applicability::MachineApplicable, + style(tool_only), + ); + } + } + } +} diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 3cea24634feee..4fcdccb756e1b 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -39,7 +39,6 @@ declare_lint_pass! { DUPLICATE_MACRO_ATTRIBUTES, ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, ELIDED_LIFETIMES_IN_PATHS, - ELIDED_NAMED_LIFETIMES, EXPLICIT_BUILTIN_CFGS_IN_FLAGS, EXPORTED_PRIVATE_DEPENDENCIES, FFI_UNWIND_CALLS, @@ -1827,38 +1826,6 @@ declare_lint! { "hidden lifetime parameters in types are deprecated" } -declare_lint! { - /// The `elided_named_lifetimes` lint detects when an elided - /// lifetime ends up being a named lifetime, such as `'static` - /// or some lifetime parameter `'a`. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(elided_named_lifetimes)] - /// struct Foo; - /// impl Foo { - /// pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 { - /// unsafe { &mut *(x as *mut _) } - /// } - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Lifetime elision is quite useful, because it frees you from having - /// to give each lifetime its own name, but sometimes it can produce - /// somewhat surprising resolutions. In safe code, it is mostly okay, - /// because the borrow checker prevents any unsoundness, so the worst - /// case scenario is you get a confusing error message in some other place. - /// But with `unsafe` code, such unexpected resolutions may lead to unsound code. - pub ELIDED_NAMED_LIFETIMES, - Warn, - "detects when an elided lifetime gets resolved to be `'static` or some named parameter" -} - declare_lint! { /// The `bare_trait_objects` lint suggests using `dyn Trait` for trait /// objects. diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index b4069b317bfa1..07bee6b8f064e 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -9,7 +9,7 @@ use rustc_data_structures::stable_hasher::{ use rustc_error_messages::{DiagMessage, MultiSpan}; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefPathHash; -use rustc_hir::{HashStableContext, HirId, ItemLocalId, MissingLifetimeKind}; +use rustc_hir::{HashStableContext, HirId, ItemLocalId}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; pub use rustc_span::edition::Edition; use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym}; @@ -635,12 +635,6 @@ pub enum DeprecatedSinceKind { InVersion(String), } -#[derive(Debug)] -pub enum ElidedLifetimeResolution { - Static, - Param(Symbol, Span), -} - // This could be a closure, but then implementing derive trait // becomes hacky (and it gets allocated). #[derive(Debug)] @@ -653,10 +647,6 @@ pub enum BuiltinLintDiag { }, MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), ElidedLifetimesInPaths(usize, Span, bool, Span), - ElidedNamedLifetimes { - elided: (Span, MissingLifetimeKind), - resolution: ElidedLifetimeResolution, - }, UnknownCrateTypes { span: Span, candidate: Option, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index faee0e7dd5ff9..d38dbc2d6647c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1706,7 +1706,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if ident.name == kw::StaticLifetime { self.record_lifetime_res( lifetime.id, - LifetimeRes::Static { suppress_elision_warning: false }, + LifetimeRes::Static, LifetimeElisionCandidate::Named, ); return; @@ -1854,8 +1854,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if lifetimes_in_scope.is_empty() { self.record_lifetime_res( lifetime.id, - // We are inside a const item, so do not warn. - LifetimeRes::Static { suppress_elision_warning: true }, + LifetimeRes::Static, elision_candidate, ); return; @@ -2202,47 +2201,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { panic!("lifetime {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)") } - match candidate { - LifetimeElisionCandidate::Missing(missing @ MissingLifetime { .. }) => { - debug_assert_eq!(id, missing.id); - match res { - LifetimeRes::Static { suppress_elision_warning } => { - if !suppress_elision_warning { - self.r.lint_buffer.buffer_lint( - lint::builtin::ELIDED_NAMED_LIFETIMES, - missing.id_for_lint, - missing.span, - BuiltinLintDiag::ElidedNamedLifetimes { - elided: (missing.span, missing.kind), - resolution: lint::ElidedLifetimeResolution::Static, - }, - ); - } - } - LifetimeRes::Param { param, binder: _ } => { - let tcx = self.r.tcx(); - self.r.lint_buffer.buffer_lint( - lint::builtin::ELIDED_NAMED_LIFETIMES, - missing.id_for_lint, - missing.span, - BuiltinLintDiag::ElidedNamedLifetimes { - elided: (missing.span, missing.kind), - resolution: lint::ElidedLifetimeResolution::Param( - tcx.item_name(param.into()), - tcx.source_span(param), - ), - }, - ); - } - LifetimeRes::Fresh { .. } - | LifetimeRes::Infer - | LifetimeRes::Error - | LifetimeRes::ElidedAnchor { .. } => {} - } - } - LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => {} - } - match res { LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static { .. } => { if let Some(ref mut candidates) = self.lifetime_elision_candidates { @@ -2760,14 +2718,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .. }) => { self.with_static_rib(def_kind, |this| { - this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Static { - suppress_elision_warning: true, - }), - |this| { - this.visit_ty(ty); - }, - ); + this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| { + this.visit_ty(ty); + }); if let Some(expr) = expr { // We already forbid generic params because of the above item rib, // so it doesn't matter whether this is a trivial constant. @@ -2804,9 +2757,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.visit_generics(generics); this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Static { - suppress_elision_warning: true, - }), + LifetimeRibKind::Elided(LifetimeRes::Static), |this| this.visit_ty(ty), ); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index d4fe446cc9f76..6e70fb8308480 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3276,7 +3276,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { maybe_static = true; in_scope_lifetimes = vec![( Ident::with_dummy_span(kw::StaticLifetime), - (DUMMY_NODE_ID, LifetimeRes::Static { suppress_elision_warning: false }), + (DUMMY_NODE_ID, LifetimeRes::Static), )]; } } else if elided_len == 0 { @@ -3288,7 +3288,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { maybe_static = true; in_scope_lifetimes = vec![( Ident::with_dummy_span(kw::StaticLifetime), - (DUMMY_NODE_ID, LifetimeRes::Static { suppress_elision_warning: false }), + (DUMMY_NODE_ID, LifetimeRes::Static), )]; } } else if num_params == 1 { diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 8ab4d795c4597..1611ca79be2ac 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -585,7 +585,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { matches!( arg, hir::GenericArg::Lifetime(lifetime) - if lifetime.is_syntactically_hidden() + if lifetime.is_implicit() ) }) { self.suggestions.push(( diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed index cd0898dfc3672..3aa04c6154497 100644 --- a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed +++ b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed @@ -77,11 +77,11 @@ fn main() { struct NoIntoIter(); impl NoIntoIter { - fn iter(&self) -> slice::Iter { + fn iter(&self) -> slice::Iter<'_, u8> { unimplemented!() } - fn iter_mut(&mut self) -> slice::IterMut { + fn iter_mut(&mut self) -> slice::IterMut<'_, u8> { unimplemented!() } } diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_iter_loop.rs index 02405280ce423..9918c176d3b9b 100644 --- a/src/tools/clippy/tests/ui/explicit_iter_loop.rs +++ b/src/tools/clippy/tests/ui/explicit_iter_loop.rs @@ -77,11 +77,11 @@ fn main() { struct NoIntoIter(); impl NoIntoIter { - fn iter(&self) -> slice::Iter { + fn iter(&self) -> slice::Iter<'_, u8> { unimplemented!() } - fn iter_mut(&mut self) -> slice::IterMut { + fn iter_mut(&mut self) -> slice::IterMut<'_, u8> { unimplemented!() } } diff --git a/src/tools/clippy/tests/ui/iter_next_loop.rs b/src/tools/clippy/tests/ui/iter_next_loop.rs index 32711c7ef6239..f44d7d576ad07 100644 --- a/src/tools/clippy/tests/ui/iter_next_loop.rs +++ b/src/tools/clippy/tests/ui/iter_next_loop.rs @@ -8,7 +8,7 @@ fn main() { struct Unrelated(&'static [u8]); impl Unrelated { - fn next(&self) -> std::slice::Iter { + fn next(&self) -> std::slice::Iter<'_, u8> { self.0.iter() } } diff --git a/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs b/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs index 5c8c8eb4a43d4..d2497ed4330c2 100644 --- a/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs +++ b/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs @@ -71,7 +71,7 @@ impl S { struct S2([u8]); impl S2 { - fn iter(&self) -> core::slice::Iter { + fn iter(&self) -> core::slice::Iter<'_, u8> { self.0.iter() } } diff --git a/src/tools/clippy/tests/ui/methods.rs b/src/tools/clippy/tests/ui/methods.rs index 2f4004181f6a8..f73fe288b0f8c 100644 --- a/src/tools/clippy/tests/ui/methods.rs +++ b/src/tools/clippy/tests/ui/methods.rs @@ -49,7 +49,7 @@ struct Lt2<'a> { impl<'a> Lt2<'a> { // The lifetime is different, but that’s irrelevant; see issue #734. - pub fn new(s: &str) -> Lt2 { + pub fn new(s: &str) -> Lt2<'_> { unimplemented!() } } diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.fixed b/src/tools/clippy/tests/ui/needless_lifetimes.fixed index e9d811986aa49..ceea4480d0dd9 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.fixed +++ b/src/tools/clippy/tests/ui/needless_lifetimes.fixed @@ -10,7 +10,7 @@ clippy::unnecessary_wraps, dyn_drop, clippy::get_first, - elided_named_lifetimes + mismatched_lifetime_syntaxes, )] extern crate proc_macros; diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs index 0b6eb9755b932..8432f9e6d2f18 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.rs +++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs @@ -10,7 +10,7 @@ clippy::unnecessary_wraps, dyn_drop, clippy::get_first, - elided_named_lifetimes + mismatched_lifetime_syntaxes, )] extern crate proc_macros; diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs index 2d77bf06ff942..65f3f05d6cb0a 100644 --- a/src/tools/clippy/tests/ui/ptr_arg.rs +++ b/src/tools/clippy/tests/ui/ptr_arg.rs @@ -312,7 +312,7 @@ mod issue_9218 { // Inferred to be `&'a str`, afaik. fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str { - //~^ ERROR: elided lifetime has a name + //~^ ERROR: lifetime flowing from input to output with different syntax todo!() } } diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr index 741e60cbd749c..591b1d9b9d777 100644 --- a/src/tools/clippy/tests/ui/ptr_arg.stderr +++ b/src/tools/clippy/tests/ui/ptr_arg.stderr @@ -1,12 +1,3 @@ -error: elided lifetime has a name - --> tests/ui/ptr_arg.rs:314:56 - | -LL | fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str { - | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` - | - = note: `-D elided-named-lifetimes` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(elided_named_lifetimes)]` - error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do --> tests/ui/ptr_arg.rs:13:14 | @@ -240,5 +231,21 @@ error: writing `&String` instead of `&str` involves a new object where a slice w LL | fn good(v1: &String, v2: &String) { | ^^^^^^^ help: change this to: `&str` +error: lifetime flowing from input to output with different syntax + --> tests/ui/ptr_arg.rs:314:36 + | +LL | fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str { + | ^^ ^^ ---- the elided lifetime gets resolved as `'a` + | | | + | | these lifetimes flow to the output + | these lifetimes flow to the output + | + = note: `-D mismatched-lifetime-syntaxes` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(mismatched_lifetime_syntaxes)]` +help: one option is to consistently use `'a` + | +LL | fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &'a str { + | ++ + error: aborting due to 27 previous errors diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs index 4f65a06680d6c..78fc365bd5bb5 100644 --- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs @@ -191,7 +191,7 @@ struct CounterWrapper<'a> { } impl<'a> CounterWrapper<'a> { - fn new(counter: &Counter) -> CounterWrapper { + fn new(counter: &Counter) -> CounterWrapper<'_> { counter.i.fetch_add(1, Ordering::Relaxed); CounterWrapper { counter } } @@ -204,7 +204,7 @@ impl<'a> Drop for CounterWrapper<'a> { } impl Counter { - fn temp_increment(&self) -> Vec { + fn temp_increment(&self) -> Vec> { vec![CounterWrapper::new(self), CounterWrapper::new(self)] } } @@ -480,7 +480,7 @@ impl StateWithBoxedMutexGuard { fn new() -> StateWithBoxedMutexGuard { StateWithBoxedMutexGuard { u: Mutex::new(42) } } - fn lock(&self) -> Box> { + fn lock(&self) -> Box> { Box::new(self.u.lock().unwrap()) } } @@ -507,7 +507,7 @@ impl StateStringWithBoxedMutexGuard { s: Mutex::new("A String".to_owned()), } } - fn lock(&self) -> Box> { + fn lock(&self) -> Box> { Box::new(self.s.lock().unwrap()) } } @@ -686,11 +686,11 @@ struct Guard<'a, T>(MutexGuard<'a, T>); struct Ref<'a, T>(&'a T); impl<'a, T> Guard<'a, T> { - fn guard(&self) -> &MutexGuard { + fn guard(&self) -> &MutexGuard<'_, T> { &self.0 } - fn guard_ref(&self) -> Ref> { + fn guard_ref(&self) -> Ref<'_, MutexGuard<'_, T>> { Ref(&self.0) } diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs index 37bc6f89a20af..bfec8dd4f75d4 100644 --- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs +++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs @@ -40,6 +40,7 @@ fn good_return_explicit_lt_ref<'a>(foo: &'a Foo) -> &'a u32 { &foo.0 } +#[allow(mismatched_lifetime_syntaxes)] fn good_return_implicit_lt_struct(foo: &Foo) -> FooRef { FooRef { foo } } diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr index e813fecf653ac..55ba707d75452 100644 --- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr +++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr @@ -1,5 +1,5 @@ error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:52:11 + --> tests/ui/trivially_copy_pass_by_ref.rs:53:11 | LL | fn bad(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` @@ -11,103 +11,103 @@ LL | #![deny(clippy::trivially_copy_pass_by_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:52:20 + --> tests/ui/trivially_copy_pass_by_ref.rs:53:20 | LL | fn bad(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:52:29 + --> tests/ui/trivially_copy_pass_by_ref.rs:53:29 | LL | fn bad(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:62:12 + --> tests/ui/trivially_copy_pass_by_ref.rs:63:12 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^^ help: consider passing by value instead: `self` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:62:22 + --> tests/ui/trivially_copy_pass_by_ref.rs:63:22 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:62:31 + --> tests/ui/trivially_copy_pass_by_ref.rs:63:31 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:62:40 + --> tests/ui/trivially_copy_pass_by_ref.rs:63:40 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:68:16 + --> tests/ui/trivially_copy_pass_by_ref.rs:69:16 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:68:25 + --> tests/ui/trivially_copy_pass_by_ref.rs:69:25 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:68:34 + --> tests/ui/trivially_copy_pass_by_ref.rs:69:34 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:73:35 + --> tests/ui/trivially_copy_pass_by_ref.rs:74:35 | LL | fn bad_issue7518(self, other: &Self) {} | ^^^^^ help: consider passing by value instead: `Self` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:86:16 + --> tests/ui/trivially_copy_pass_by_ref.rs:87:16 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:86:25 + --> tests/ui/trivially_copy_pass_by_ref.rs:87:25 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:86:34 + --> tests/ui/trivially_copy_pass_by_ref.rs:87:34 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:93:34 + --> tests/ui/trivially_copy_pass_by_ref.rs:94:34 | LL | fn trait_method(&self, _foo: &Foo); | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:126:21 + --> tests/ui/trivially_copy_pass_by_ref.rs:127:21 | LL | fn foo_never(x: &i32) { | ^^^^ help: consider passing by value instead: `i32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:132:15 + --> tests/ui/trivially_copy_pass_by_ref.rs:133:15 | LL | fn foo(x: &i32) { | ^^^^ help: consider passing by value instead: `i32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:160:37 + --> tests/ui/trivially_copy_pass_by_ref.rs:161:37 | LL | fn _unrelated_lifetimes<'a, 'b>(_x: &'a u32, y: &'b u32) -> &'b u32 { | ^^^^^^^ help: consider passing by value instead: `u32` diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed index f15e5e0a5bb42..cccb6bffabb71 100644 --- a/src/tools/clippy/tests/ui/use_self.fixed +++ b/src/tools/clippy/tests/ui/use_self.fixed @@ -69,7 +69,7 @@ mod lifetimes { impl<'a> Foo<'a> { // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) -> // Foo<'b>` - fn foo(s: &str) -> Foo { + fn foo(s: &str) -> Foo<'_> { Foo { foo_str: s } } // cannot replace with `Self`, because that's `Foo<'a>` diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs index b6376938611e7..09288677aa715 100644 --- a/src/tools/clippy/tests/ui/use_self.rs +++ b/src/tools/clippy/tests/ui/use_self.rs @@ -69,7 +69,7 @@ mod lifetimes { impl<'a> Foo<'a> { // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) -> // Foo<'b>` - fn foo(s: &str) -> Foo { + fn foo(s: &str) -> Foo<'_> { Foo { foo_str: s } } // cannot replace with `Self`, because that's `Foo<'a>` diff --git a/src/tools/miri/tests/pass/fat_ptr.rs b/src/tools/miri/tests/pass/fat_ptr.rs index c5603d2cf8045..13608b8f898ea 100644 --- a/src/tools/miri/tests/pass/fat_ptr.rs +++ b/src/tools/miri/tests/pass/fat_ptr.rs @@ -19,11 +19,11 @@ fn fat_ptr_via_local(a: &[u8]) -> &[u8] { x } -fn fat_ptr_from_struct(s: FatPtrContainer) -> &[u8] { +fn fat_ptr_from_struct(s: FatPtrContainer<'_>) -> &[u8] { s.ptr } -fn fat_ptr_to_struct(a: &[u8]) -> FatPtrContainer { +fn fat_ptr_to_struct(a: &[u8]) -> FatPtrContainer<'_> { FatPtrContainer { ptr: a } } diff --git a/tests/ui/associated-types/associated-types-impl-redirect.rs b/tests/ui/associated-types/associated-types-impl-redirect.rs index 65e6a094b77df..2cbe0d7254026 100644 --- a/tests/ui/associated-types/associated-types-impl-redirect.rs +++ b/tests/ui/associated-types/associated-types-impl-redirect.rs @@ -21,7 +21,7 @@ trait Iterator { } trait IteratorExt: Iterator + Sized { - fn by_ref(&mut self) -> ByRef { + fn by_ref(&mut self) -> ByRef<'_, Self> { ByRef(self) } } diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs index f15de0d9a2898..b32323181b5fd 100644 --- a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs +++ b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs @@ -21,11 +21,11 @@ trait SliceExt2 { impl SliceExt2 for [T] { type Item = T; - fn split2

(&self, pred: P) -> Splits where P: FnMut(&T) -> bool { + fn split2

(&self, pred: P) -> Splits<'_, T, P> where P: FnMut(&T) -> bool { loop {} } - fn splitn2

(&self, n: u32, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { + fn splitn2

(&self, n: u32, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { SliceExt2::split2(self, pred); loop {} } diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs index 7e94d3a011f55..6844c5f9adb82 100644 --- a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs +++ b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs @@ -3,32 +3,40 @@ // Test that we normalize associated types that appear in bounds; if // we didn't, the call to `self.split2()` fails to type check. - use std::marker::PhantomData; -struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>); +struct Splits<'a, T, P>(PhantomData<(&'a (), T, P)>); struct SplitsN(PhantomData); trait SliceExt2 { type Item; fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P> - where P: FnMut(&Self::Item) -> bool; + where + P: FnMut(&Self::Item) -> bool; + fn splitn2<'a, P>(&'a self, n: usize, pred: P) -> SplitsN> - where P: FnMut(&Self::Item) -> bool; + where + P: FnMut(&Self::Item) -> bool; } impl SliceExt2 for [T] { type Item = T; - fn split2

(&self, pred: P) -> Splits where P: FnMut(&T) -> bool { + fn split2

(&self, pred: P) -> Splits<'_, T, P> + where + P: FnMut(&T) -> bool, + { loop {} } - fn splitn2

(&self, n: usize, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { + fn splitn2

(&self, n: usize, pred: P) -> SplitsN> + where + P: FnMut(&T) -> bool, + { self.split2(pred); loop {} } } -fn main() { } +fn main() {} diff --git a/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs b/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs index dcfa3532cdfb5..34c269d4d903f 100644 --- a/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs +++ b/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs @@ -20,7 +20,7 @@ trait Iterator { } trait IteratorExt: Iterator + Sized { - fn by_ref(&mut self) -> ByRef { + fn by_ref(&mut self) -> ByRef<'_, Self> { ByRef(self) } } diff --git a/tests/ui/associated-types/cache/elision.rs b/tests/ui/associated-types/cache/elision.rs index 12765fc581108..7ddb32ea87414 100644 --- a/tests/ui/associated-types/cache/elision.rs +++ b/tests/ui/associated-types/cache/elision.rs @@ -14,7 +14,7 @@ pub trait UnicodeStr { impl UnicodeStr for str { #[inline] - fn split_whitespace(&self) -> SplitWhitespace { + fn split_whitespace(&self) -> SplitWhitespace<'_> { unimplemented!() } } diff --git a/tests/ui/associated-types/project-defer-unification.rs b/tests/ui/associated-types/project-defer-unification.rs index b51228ef4117f..a949171db122f 100644 --- a/tests/ui/associated-types/project-defer-unification.rs +++ b/tests/ui/associated-types/project-defer-unification.rs @@ -50,7 +50,7 @@ where P: Pixel + 'static, loop { } } - pub fn pixels_mut(&mut self) -> PixelsMut

{ + pub fn pixels_mut(&mut self) -> PixelsMut<'_, P> { loop { } } } diff --git a/tests/ui/async-await/issues/issue-63388-1.rs b/tests/ui/async-await/issues/issue-63388-1.rs index acfc64baff97d..3a89f3ebfd2b4 100644 --- a/tests/ui/async-await/issues/issue-63388-1.rs +++ b/tests/ui/async-await/issues/issue-63388-1.rs @@ -9,7 +9,7 @@ trait Foo {} impl Xyz { async fn do_sth<'a>( &'a self, foo: &dyn Foo - ) -> &dyn Foo //~ WARNING elided lifetime has a name + ) -> &dyn Foo { foo //~^ ERROR explicit lifetime required in the type of `foo` [E0621] diff --git a/tests/ui/async-await/issues/issue-63388-1.stderr b/tests/ui/async-await/issues/issue-63388-1.stderr index 579caa45bc945..277f7fa6f63ed 100644 --- a/tests/ui/async-await/issues/issue-63388-1.stderr +++ b/tests/ui/async-await/issues/issue-63388-1.stderr @@ -1,14 +1,3 @@ -warning: elided lifetime has a name - --> $DIR/issue-63388-1.rs:12:10 - | -LL | async fn do_sth<'a>( - | -- lifetime `'a` declared here -LL | &'a self, foo: &dyn Foo -LL | ) -> &dyn Foo - | ^ this elided lifetime gets resolved as `'a` - | - = note: `#[warn(elided_named_lifetimes)]` on by default - error[E0621]: explicit lifetime required in the type of `foo` --> $DIR/issue-63388-1.rs:14:9 | @@ -18,6 +7,6 @@ LL | &'a self, foo: &dyn Foo LL | foo | ^^^ lifetime `'a` required -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0621`. diff --git a/tests/ui/borrowck/copy-suggestion-region-vid.fixed b/tests/ui/borrowck/copy-suggestion-region-vid.fixed index 7fe18615408bd..2bc8a74086e38 100644 --- a/tests/ui/borrowck/copy-suggestion-region-vid.fixed +++ b/tests/ui/borrowck/copy-suggestion-region-vid.fixed @@ -7,7 +7,7 @@ pub struct HelperStruct<'n> { } impl DataStruct { - pub fn f(&self) -> HelperStruct { + pub fn f(&self) -> HelperStruct<'_> { let helpers = [vec![], vec![]]; HelperStruct { helpers: helpers.clone(), is_empty: helpers[0].is_empty() } diff --git a/tests/ui/borrowck/copy-suggestion-region-vid.rs b/tests/ui/borrowck/copy-suggestion-region-vid.rs index daafba71ece74..248ce80d22bf7 100644 --- a/tests/ui/borrowck/copy-suggestion-region-vid.rs +++ b/tests/ui/borrowck/copy-suggestion-region-vid.rs @@ -7,7 +7,7 @@ pub struct HelperStruct<'n> { } impl DataStruct { - pub fn f(&self) -> HelperStruct { + pub fn f(&self) -> HelperStruct<'_> { let helpers = [vec![], vec![]]; HelperStruct { helpers, is_empty: helpers[0].is_empty() } diff --git a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr index 177ff20fbf9ea..b5c0515057fba 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr @@ -1,10 +1,17 @@ -warning: elided lifetime has a name - --> $DIR/issue-71348.rs:18:68 +warning: lifetime flowing from input to output with different syntax + --> $DIR/issue-71348.rs:18:40 | LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target - | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` + | ^^ -- ------------------------ the elided lifetimes get resolved as `'a` + | | | + | | the elided lifetimes get resolved as `'a` + | this lifetime flows to the output | - = note: `#[warn(elided_named_lifetimes)]` on by default + = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default +help: one option is to consistently use `'a` + | +LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target + | +++ warning: 1 warning emitted diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr index 8995c4158635f..c491469bcbd2d 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr @@ -1,11 +1,3 @@ -warning: elided lifetime has a name - --> $DIR/issue-71348.rs:18:68 - | -LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target - | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` - | - = note: `#[warn(elided_named_lifetimes)]` on by default - error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/issue-71348.rs:10:24 | @@ -38,5 +30,5 @@ help: add `#![feature(unsized_const_params)]` to the crate attributes to enable LL + #![feature(unsized_const_params)] | -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/type-dependent/issue-71348.rs b/tests/ui/const-generics/type-dependent/issue-71348.rs index 97e786405fe39..c6563c8030590 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.rs +++ b/tests/ui/const-generics/type-dependent/issue-71348.rs @@ -17,7 +17,7 @@ trait Get<'a, const N: &'static str> { impl Foo { fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter - //~^^ WARNING elided lifetime has a name + //[full]~^^ WARNING lifetime flowing from input to output with different syntax where Self: Get<'a, N>, { diff --git a/tests/ui/drop/drop-order-comparisons.e2021.fixed b/tests/ui/drop/drop-order-comparisons.e2021.fixed index 71158cb806213..6cc53bbbab58e 100644 --- a/tests/ui/drop/drop-order-comparisons.e2021.fixed +++ b/tests/ui/drop/drop-order-comparisons.e2021.fixed @@ -548,7 +548,7 @@ impl Events { Ok(LogDrop(self, m)) } /// Return an `Err` value that logs its drop. - fn err(&self, m: u64) -> Result { + fn err(&self, m: u64) -> Result, LogDrop<'_>> { Err(LogDrop(self, m)) } /// Log an event. diff --git a/tests/ui/drop/drop-order-comparisons.rs b/tests/ui/drop/drop-order-comparisons.rs index 0492b3a4db7f9..1741318e65277 100644 --- a/tests/ui/drop/drop-order-comparisons.rs +++ b/tests/ui/drop/drop-order-comparisons.rs @@ -548,7 +548,7 @@ impl Events { Ok(LogDrop(self, m)) } /// Return an `Err` value that logs its drop. - fn err(&self, m: u64) -> Result { + fn err(&self, m: u64) -> Result, LogDrop<'_>> { Err(LogDrop(self, m)) } /// Log an event. diff --git a/tests/ui/drop/drop_order.rs b/tests/ui/drop/drop_order.rs index b96e55a2535a6..34b1a0e8f7546 100644 --- a/tests/ui/drop/drop_order.rs +++ b/tests/ui/drop/drop_order.rs @@ -23,11 +23,11 @@ impl Drop for LoudDrop<'_> { } impl DropOrderCollector { - fn option_loud_drop(&self, n: u32) -> Option { + fn option_loud_drop(&self, n: u32) -> Option> { Some(LoudDrop(self, n)) } - fn loud_drop(&self, n: u32) -> LoudDrop { + fn loud_drop(&self, n: u32) -> LoudDrop<'_> { LoudDrop(self, n) } diff --git a/tests/ui/drop/drop_order_if_let_rescope.rs b/tests/ui/drop/drop_order_if_let_rescope.rs index 27bced5fa62fd..e96ceedd5cb11 100644 --- a/tests/ui/drop/drop_order_if_let_rescope.rs +++ b/tests/ui/drop/drop_order_if_let_rescope.rs @@ -18,7 +18,7 @@ impl Drop for LoudDrop<'_> { } impl DropOrderCollector { - fn option_loud_drop(&self, n: u32) -> Option { + fn option_loud_drop(&self, n: u32) -> Option> { Some(LoudDrop(self, n)) } diff --git a/tests/ui/drop/issue-2735-2.rs b/tests/ui/drop/issue-2735-2.rs index 7a6ed6ea2f8da..66025956e0880 100644 --- a/tests/ui/drop/issue-2735-2.rs +++ b/tests/ui/drop/issue-2735-2.rs @@ -14,7 +14,7 @@ impl<'a> Drop for defer<'a> { } } -fn defer(b: &Cell) -> defer { +fn defer(b: &Cell) -> defer<'_> { defer { b: b } diff --git a/tests/ui/drop/issue-2735-3.rs b/tests/ui/drop/issue-2735-3.rs index 3bb4536537cb9..c9535168653cf 100644 --- a/tests/ui/drop/issue-2735-3.rs +++ b/tests/ui/drop/issue-2735-3.rs @@ -14,7 +14,7 @@ impl<'a> Drop for defer<'a> { } } -fn defer(b: &Cell) -> defer { +fn defer(b: &Cell) -> defer<'_> { defer { b: b } diff --git a/tests/ui/drop/issue-979.rs b/tests/ui/drop/issue-979.rs index 8d98ac4df2336..70052708be6c4 100644 --- a/tests/ui/drop/issue-979.rs +++ b/tests/ui/drop/issue-979.rs @@ -13,7 +13,7 @@ impl<'a> Drop for r<'a> { } } -fn r(b: &Cell) -> r { +fn r(b: &Cell) -> r<'_> { r { b: b } diff --git a/tests/ui/drop/tail-expr-drop-order.rs b/tests/ui/drop/tail-expr-drop-order.rs index f74530fce1e22..a6807b16b5066 100644 --- a/tests/ui/drop/tail-expr-drop-order.rs +++ b/tests/ui/drop/tail-expr-drop-order.rs @@ -28,11 +28,11 @@ impl Drop for LoudDrop<'_> { } impl DropOrderCollector { - fn option_loud_drop(&self, n: u32) -> Option { + fn option_loud_drop(&self, n: u32) -> Option> { Some(LoudDrop(self, n)) } - fn loud_drop(&self, n: u32) -> LoudDrop { + fn loud_drop(&self, n: u32) -> LoudDrop<'_> { LoudDrop(self, n) } diff --git a/tests/ui/generics/generic-no-mangle.fixed b/tests/ui/generics/generic-no-mangle.fixed index 2776848c45fff..e3e41eb9d0db1 100644 --- a/tests/ui/generics/generic-no-mangle.fixed +++ b/tests/ui/generics/generic-no-mangle.fixed @@ -1,5 +1,5 @@ //@ run-rustfix -#![allow(dead_code, elided_named_lifetimes)] +#![allow(dead_code, mismatched_lifetime_syntaxes)] #![deny(no_mangle_generic_items)] pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled diff --git a/tests/ui/generics/generic-no-mangle.rs b/tests/ui/generics/generic-no-mangle.rs index 5314005d31fa1..085f8610a548e 100644 --- a/tests/ui/generics/generic-no-mangle.rs +++ b/tests/ui/generics/generic-no-mangle.rs @@ -1,5 +1,5 @@ //@ run-rustfix -#![allow(dead_code, elided_named_lifetimes)] +#![allow(dead_code, mismatched_lifetime_syntaxes)] #![deny(no_mangle_generic_items)] #[no_mangle] diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs index c368f2650629d..e00a31e26aa23 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs @@ -25,7 +25,7 @@ where impl Inject for RefMutFamily { type I = Self; - fn inject(_: &()) -> ::Out { + fn inject(_: &()) -> >::Out { unimplemented!() } } diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs index a7f38b5c16af2..da7530b4e7a8c 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs @@ -13,7 +13,6 @@ fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - //~| WARNING elided lifetime has a name |x| x } diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr index 31f39eb90041e..40cb6b647d1e9 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/impl-fn-hrtb-bounds.rs:20:38 + --> $DIR/impl-fn-hrtb-bounds.rs:19:38 | LL | fn d() -> impl Fn() -> (impl Debug + '_) { | ^^ expected named lifetime parameter @@ -11,14 +11,6 @@ LL - fn d() -> impl Fn() -> (impl Debug + '_) { LL + fn d() -> impl Fn() -> (impl Debug + 'static) { | -warning: elided lifetime has a name - --> $DIR/impl-fn-hrtb-bounds.rs:14:52 - | -LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { - | -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a` - | - = note: `#[warn(elided_named_lifetimes)]` on by default - error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/impl-fn-hrtb-bounds.rs:4:41 | @@ -55,7 +47,7 @@ note: lifetime declared here LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { | ^^ -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors Some errors have detailed explanations: E0106, E0657. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs index 776bb7278ce15..199cbbf4fcc9b 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs @@ -2,7 +2,6 @@ use std::fmt::Debug; fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - //~^ WARNING elided lifetime has a name |x| x //~^ ERROR expected generic lifetime parameter, found `'_` } diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index 209186db4cc15..6064b09ef0927 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -1,20 +1,11 @@ -warning: elided lifetime has a name - --> $DIR/impl-fn-predefined-lifetimes.rs:4:48 - | -LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - | -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a` - | - = note: `#[warn(elided_named_lifetimes)]` on by default - error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/impl-fn-predefined-lifetimes.rs:6:9 + --> $DIR/impl-fn-predefined-lifetimes.rs:5:9 | LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { | -- this generic parameter must be used with a generic lifetime parameter -LL | LL | |x| x | ^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs index e48441f533d7c..1ac3c593dbe5c 100644 --- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs +++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs @@ -1,7 +1,7 @@ //@ check-pass pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator { - //~^ WARNING elided lifetime has a name + //~^ WARNING lifetime flowing from input to output with different syntax v.into_iter() } diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr index bff3ffd934ac6..01806f3217eaa 100644 --- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr +++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr @@ -1,10 +1,14 @@ -warning: elided lifetime has a name - --> $DIR/rpit-assoc-pair-with-lifetime.rs:3:82 +warning: lifetime flowing from input to output with different syntax + --> $DIR/rpit-assoc-pair-with-lifetime.rs:3:31 | LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator { - | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` + | ^^ this lifetime flows to the output ---- the elided lifetime gets resolved as `'a` | - = note: `#[warn(elided_named_lifetimes)]` on by default + = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default +help: one option is to consistently use `'a` + | +LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator { + | ++ warning: 1 warning emitted diff --git a/tests/ui/issues/issue-2502.rs b/tests/ui/issues/issue-2502.rs index dfc0995104ea6..98a52a3b5a7de 100644 --- a/tests/ui/issues/issue-2502.rs +++ b/tests/ui/issues/issue-2502.rs @@ -14,7 +14,7 @@ impl<'a> font<'a> { } } -fn font(fontbuf: &Vec ) -> font { +fn font(fontbuf: &Vec ) -> font<'_> { font { fontbuf: fontbuf } diff --git a/tests/ui/issues/issue-42552.rs b/tests/ui/issues/issue-42552.rs index 998cde44be015..734921d9b012a 100644 --- a/tests/ui/issues/issue-42552.rs +++ b/tests/ui/issues/issue-42552.rs @@ -1,7 +1,7 @@ //@ run-pass // Regression test for an obscure issue with the projection cache. -fn into_iter(a: &I) -> Groups { +fn into_iter(a: &I) -> Groups<'_, I> { Groups { _a: a } } diff --git a/tests/ui/issues/issue-5708.rs b/tests/ui/issues/issue-5708.rs index ce9ef78ffcd9c..6fa3cfa472454 100644 --- a/tests/ui/issues/issue-5708.rs +++ b/tests/ui/issues/issue-5708.rs @@ -25,7 +25,7 @@ struct Outer<'a> { } impl<'a> Outer<'a> { - fn new(inner: &dyn Inner) -> Outer { + fn new(inner: &dyn Inner) -> Outer<'_> { Outer { inner: inner } diff --git a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed index 2ceaaf0339d92..bcc4abc47e153 100644 --- a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed +++ b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed @@ -28,6 +28,7 @@ impl Greeter1 for FixedGreeter<'_> { struct Greetings(pub Vec); impl Greetings { + #[expect(mismatched_lifetime_syntaxes)] pub fn get(&self, i: usize) -> BoxedGreeter { (Box::new(FixedGreeter(&self.0[i])), Box::new(FixedGreeter(&self.0[i]))) //~^ ERROR lifetime may not live long enough diff --git a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs index e7d427517b5f1..9ca6077f47f35 100644 --- a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs +++ b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs @@ -28,6 +28,7 @@ impl Greeter1 for FixedGreeter<'_> { struct Greetings(pub Vec); impl Greetings { + #[expect(mismatched_lifetime_syntaxes)] pub fn get(&self, i: usize) -> BoxedGreeter { (Box::new(FixedGreeter(&self.0[i])), Box::new(FixedGreeter(&self.0[i]))) //~^ ERROR lifetime may not live long enough diff --git a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr index 24bb9e2ef7d63..2eba3ff418ba5 100644 --- a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr +++ b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs:32:9 + --> $DIR/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs:33:9 | LL | pub fn get(&self, i: usize) -> BoxedGreeter { | - let's call the lifetime of this reference `'1` diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs index 63a2c9be9ebad..d0a8fe795efd0 100644 --- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs +++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs @@ -47,6 +47,5 @@ fn l<'a>(_: &'a str, _: &'a str) -> &str { "" } // This is ok because both `'a` are for the same parameter. fn m<'a>(_: &'a Foo<'a>) -> &str { "" } -//~^ WARNING elided lifetime has a name fn main() {} diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index f835d2655bb01..23ef36888f079 100644 --- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -105,16 +105,6 @@ help: consider using the `'a` lifetime LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" } | ++ -warning: elided lifetime has a name - --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:49:29 - | -LL | fn m<'a>(_: &'a Foo<'a>) -> &str { "" } - | -- ^ this elided lifetime gets resolved as `'a` - | | - | lifetime `'a` declared here - | - = note: `#[warn(elided_named_lifetimes)]` on by default - -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs index 598633d75768e..5dbc0c556fb52 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs @@ -4,12 +4,8 @@ struct Foo { impl Foo { fn foo<'a>(&'a self, x: &i32) -> &i32 { - //~^ WARNING elided lifetime has a name - if true { &self.field } else { x } //~ ERROR explicit lifetime - } - } fn main() { } diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr index 2d5d4fb0e72ec..071bda24ef8de 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr @@ -1,22 +1,11 @@ -warning: elided lifetime has a name - --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:6:36 - | -LL | fn foo<'a>(&'a self, x: &i32) -> &i32 { - | -- ^ this elided lifetime gets resolved as `'a` - | | - | lifetime `'a` declared here - | - = note: `#[warn(elided_named_lifetimes)]` on by default - error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:9:36 + --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:7:36 | LL | fn foo<'a>(&'a self, x: &i32) -> &i32 { | ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32` -... LL | if true { &self.field } else { x } | ^ lifetime `'a` required -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0621`. diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs similarity index 55% rename from tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs rename to tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs index eac7c32a9aac6..1804003d36722 100644 --- a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs @@ -1,10 +1,10 @@ -#![deny(elided_named_lifetimes)] +#![deny(mismatched_lifetime_syntaxes)] struct Foo; impl Foo { pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 { - //~^ ERROR elided lifetime has a name + //~^ ERROR lifetime flowing from input to output with different syntax unsafe { &mut *(x as *mut _) } } } diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr new file mode 100644 index 0000000000000..68e76e78c9dc9 --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr @@ -0,0 +1,20 @@ +error: lifetime flowing from input to output with different syntax + --> $DIR/example-from-issue48686.rs:6:21 + | +LL | pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 { + | ^^^^^^^ ------- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +note: the lint level is defined here + --> $DIR/example-from-issue48686.rs:1:9 + | +LL | #![deny(mismatched_lifetime_syntaxes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: one option is to consistently use `'static` + | +LL | pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 { + | +++++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs new file mode 100644 index 0000000000000..3d5aab5c8295b --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs @@ -0,0 +1,27 @@ +#![deny(mismatched_lifetime_syntaxes)] + +fn ampersand<'a>(x: &'a u8) -> &u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + x +} + +struct Brackets<'a>(&'a u8); + +fn brackets<'a>(x: &'a u8) -> Brackets { + //~^ ERROR lifetime flowing from input to output with different syntax + Brackets(x) +} + +struct Comma<'a, T>(&'a T); + +fn comma<'a>(x: &'a u8) -> Comma { + //~^ ERROR lifetime flowing from input to output with different syntax + Comma(x) +} + +fn underscore<'a>(x: &'a u8) -> &'_ u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + x +} + +fn main() {} diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr new file mode 100644 index 0000000000000..04aa634802bb5 --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr @@ -0,0 +1,60 @@ +error: lifetime flowing from input to output with different syntax + --> $DIR/missing-lifetime-kind.rs:3:22 + | +LL | fn ampersand<'a>(x: &'a u8) -> &u8 { + | ^^ --- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +note: the lint level is defined here + --> $DIR/missing-lifetime-kind.rs:1:9 + | +LL | #![deny(mismatched_lifetime_syntaxes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: one option is to consistently use `'a` + | +LL | fn ampersand<'a>(x: &'a u8) -> &'a u8 { + | ++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/missing-lifetime-kind.rs:10:21 + | +LL | fn brackets<'a>(x: &'a u8) -> Brackets { + | ^^ -------- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn brackets<'a>(x: &'a u8) -> Brackets<'a> { + | ++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/missing-lifetime-kind.rs:17:18 + | +LL | fn comma<'a>(x: &'a u8) -> Comma { + | ^^ --------- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn comma<'a>(x: &'a u8) -> Comma<'a, u8> { + | +++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/missing-lifetime-kind.rs:22:23 + | +LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 { + | ^^ -- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL - fn underscore<'a>(x: &'a u8) -> &'_ u8 { +LL + fn underscore<'a>(x: &'a u8) -> &'a u8 { + | + +error: aborting due to 4 previous errors + diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs new file mode 100644 index 0000000000000..d63a6315ac81b --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs @@ -0,0 +1,17 @@ +#![allow(mismatched_lifetime_syntaxes)] + +#[warn(mismatched_lifetime_syntaxes)] +mod foo { + fn bar(x: &'static u8) -> &u8 { + //~^ WARNING lifetime flowing from input to output with different syntax + x + } + + #[deny(mismatched_lifetime_syntaxes)] + fn baz(x: &'static u8) -> &u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + x + } +} + +fn main() {} diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr new file mode 100644 index 0000000000000..226a83d0363a6 --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr @@ -0,0 +1,38 @@ +warning: lifetime flowing from input to output with different syntax + --> $DIR/not-tied-to-crate.rs:5:16 + | +LL | fn bar(x: &'static u8) -> &u8 { + | ^^^^^^^ --- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +note: the lint level is defined here + --> $DIR/not-tied-to-crate.rs:3:8 + | +LL | #[warn(mismatched_lifetime_syntaxes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: one option is to consistently use `'static` + | +LL | fn bar(x: &'static u8) -> &'static u8 { + | +++++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/not-tied-to-crate.rs:11:16 + | +LL | fn baz(x: &'static u8) -> &u8 { + | ^^^^^^^ --- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +note: the lint level is defined here + --> $DIR/not-tied-to-crate.rs:10:12 + | +LL | #[deny(mismatched_lifetime_syntaxes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: one option is to consistently use `'static` + | +LL | fn baz(x: &'static u8) -> &'static u8 { + | +++++++ + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/lint/elided-named-lifetimes/static.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs similarity index 63% rename from tests/ui/lint/elided-named-lifetimes/static.rs rename to tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs index dc8222c6e6e48..47ae258f138fc 100644 --- a/tests/ui/lint/elided-named-lifetimes/static.rs +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs @@ -1,4 +1,4 @@ -#![deny(elided_named_lifetimes)] +#![deny(mismatched_lifetime_syntaxes)] use std::borrow::Cow; @@ -14,26 +14,26 @@ impl Trait for () { } fn ampersand(x: &'static u8) -> &u8 { - //~^ ERROR elided lifetime has a name + //~^ ERROR lifetime flowing from input to output with different syntax x } struct Brackets<'a>(&'a u8); fn brackets(x: &'static u8) -> Brackets { - //~^ ERROR elided lifetime has a name + //~^ ERROR lifetime flowing from input to output with different syntax Brackets(x) } struct Comma<'a, T>(&'a T); fn comma(x: &'static u8) -> Comma { - //~^ ERROR elided lifetime has a name + //~^ ERROR lifetime flowing from input to output with different syntax Comma(x) } fn underscore(x: &'static u8) -> &'_ u8 { - //~^ ERROR elided lifetime has a name + //~^ ERROR lifetime flowing from input to output with different syntax x } diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr new file mode 100644 index 0000000000000..5efd68d83a66a --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr @@ -0,0 +1,60 @@ +error: lifetime flowing from input to output with different syntax + --> $DIR/static.rs:16:18 + | +LL | fn ampersand(x: &'static u8) -> &u8 { + | ^^^^^^^ --- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +note: the lint level is defined here + --> $DIR/static.rs:1:9 + | +LL | #![deny(mismatched_lifetime_syntaxes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: one option is to consistently use `'static` + | +LL | fn ampersand(x: &'static u8) -> &'static u8 { + | +++++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/static.rs:23:17 + | +LL | fn brackets(x: &'static u8) -> Brackets { + | ^^^^^^^ -------- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL | fn brackets(x: &'static u8) -> Brackets<'static> { + | +++++++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/static.rs:30:14 + | +LL | fn comma(x: &'static u8) -> Comma { + | ^^^^^^^ --------- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL | fn comma(x: &'static u8) -> Comma<'static, u8> { + | ++++++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/static.rs:35:19 + | +LL | fn underscore(x: &'static u8) -> &'_ u8 { + | ^^^^^^^ -- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL - fn underscore(x: &'static u8) -> &'_ u8 { +LL + fn underscore(x: &'static u8) -> &'static u8 { + | + +error: aborting due to 4 previous errors + diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs new file mode 100644 index 0000000000000..ef5b2cc44a9ec --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs @@ -0,0 +1,298 @@ +#![deny(mismatched_lifetime_syntaxes)] + +// +// + +#[derive(Copy, Clone)] +struct ContainsLifetime<'a>(&'a u8); + +struct S(u8); + +fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + v +} + +fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + v +} + +// --- + +fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime) -> ContainsLifetime<'_> { + //~^ ERROR lifetime flowing from input to output with different syntax + v +} + +fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime { + //~^ ERROR lifetime flowing from input to output with different syntax + v +} + +fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime { + //~^ ERROR lifetime flowing from input to output with different syntax + v +} + +fn explicit_bound_path_to_explicit_anonymous_path<'a>( + v: ContainsLifetime<'a>, + //~^ ERROR lifetime flowing from input to output with different syntax +) -> ContainsLifetime<'_> { + v +} + +// --- + +fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(v) +} + +fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(v) +} + +fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(v) +} + +fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(v) +} + +// --- + +fn implicit_path_to_implicit_ref(v: ContainsLifetime) -> &u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + v.0 +} + +fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + v.0 +} + +fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + v.0 +} + +fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + v.0 +} + +impl S { + fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + &self.0 + } + + fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + &self.0 + } + + // --- + + fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(&self.0) + } + + fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(&self.0) + } + + fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(&self.0) + } +} + +// If a function uses the `'static` lifetime, we should not suggest +// replacing it with an explicitly anonymous or implicit +// lifetime. Only suggest using `'static` everywhere. +mod static_suggestions { + #[derive(Copy, Clone)] + struct ContainsLifetime<'a>(&'a u8); + + struct S(u8); + + fn static_ref_to_implicit_ref(v: &'static u8) -> &u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + v + } + + fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + v + } + + fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(v) + } + + fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(v) + } + + impl S { + fn static_ref_to_implicit_ref(&'static self) -> &u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + &self.0 + } + + fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 { + //~^ ERROR lifetime flowing from input to output with different syntax + &self.0 + } + + fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(&self.0) + } + + fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> { + //~^ ERROR lifetime flowing from input to output with different syntax + ContainsLifetime(&self.0) + } + } +} + +/// `impl Trait` uses lifetimes in some additional ways. +mod impl_trait { + #[derive(Copy, Clone)] + struct ContainsLifetime<'a>(&'a u8); + + fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ { + //~^ ERROR lifetime flowing from input to output with different syntax + move || _ = v + } + + fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> { + //~^ ERROR lifetime flowing from input to output with different syntax + move || _ = v + } + + fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ { + //~^ ERROR lifetime flowing from input to output with different syntax + move || _ = v + } + + fn explicit_bound_path_to_impl_trait_precise_capture<'a>( + v: ContainsLifetime<'a>, + //~^ ERROR lifetime flowing from input to output with different syntax + ) -> impl FnOnce() + use<'_> { + move || _ = v + } +} + +/// These tests serve to exercise edge cases of the lint formatting +mod diagnostic_output { + fn multiple_outputs<'a>(v: &'a u8) -> (&u8, &u8) { + //~^ ERROR lifetime flowing from input to output with different syntax + (v, v) + } +} + +/// These usages are expected to **not** trigger the lint +mod acceptable_uses { + #[derive(Copy, Clone)] + struct ContainsLifetime<'a>(&'a u8); + + struct S(u8); + + fn implicit_ref_to_implicit_ref(v: &u8) -> &u8 { + v + } + + fn explicit_anonymous_ref_to_explicit_anonymous_ref(v: &'_ u8) -> &'_ u8 { + v + } + + fn explicit_bound_ref_to_explicit_bound_ref<'a>(v: &'a u8) -> &'a u8 { + v + } + + fn implicit_path_to_implicit_path(v: ContainsLifetime) -> ContainsLifetime { + v + } + + fn explicit_anonymous_path_to_explicit_anonymous_path( + v: ContainsLifetime<'_>, + ) -> ContainsLifetime<'_> { + v + } + + fn explicit_bound_path_to_explicit_bound_path<'a>( + v: ContainsLifetime<'a>, + ) -> ContainsLifetime<'a> { + v + } + + fn explicit_anonymous_ref_to_explicit_anonymous_path(v: &'_ u8) -> ContainsLifetime<'_> { + ContainsLifetime(v) + } + + fn explicit_bound_ref_to_explicit_bound_path<'a>(v: &'a u8) -> ContainsLifetime<'a> { + ContainsLifetime(v) + } + + fn explicit_anonymous_path_to_explicit_anonymous_ref(v: ContainsLifetime<'_>) -> &'_ u8 { + v.0 + } + + fn explicit_bound_path_to_explicit_bound_ref<'a>(v: ContainsLifetime<'a>) -> &'a u8 { + v.0 + } + + // These may be surprising, but ampersands count as enough of a + // visual indicator that a reference exists that we treat + // references with implicit lifetimes the same as if they were + // explcitly anonymous. + fn implicit_ref_to_explicit_anonymous_ref(v: &u8) -> &'_ u8 { + v + } + + fn explicit_anonymous_ref_to_implicit_ref(v: &'_ u8) -> &u8 { + v + } + + fn implicit_ref_to_explicit_anonymous_path(v: &u8) -> ContainsLifetime<'_> { + ContainsLifetime(v) + } + + fn explicit_anonymous_path_to_implicit_ref(v: ContainsLifetime<'_>) -> &u8 { + v.0 + } + + impl S { + fn method_implicit_ref_to_explicit_anonymous_ref(&self) -> &'_ u8 { + &self.0 + } + + fn method_explicit_anonymous_ref_to_implicit_ref(&'_ self) -> &u8 { + &self.0 + } + + fn method_implicit_ref_to_explicit_anonymous_path(&self) -> ContainsLifetime<'_> { + ContainsLifetime(&self.0) + } + } + + // `dyn Trait` has an "embedded" lifetime that we should **not** + // lint about. + fn dyn_trait_does_not_have_a_lifetime_generic(v: &u8) -> &dyn core::fmt::Debug { + v + } +} + +fn main() {} diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr new file mode 100644 index 0000000000000..ae9553197ef70 --- /dev/null +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr @@ -0,0 +1,443 @@ +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:11:47 + | +LL | fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &u8 { + | ^^ --- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +note: the lint level is defined here + --> $DIR/mismatched-lifetime-syntaxes.rs:1:9 + | +LL | #![deny(mismatched_lifetime_syntaxes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: one option is to consistently use `'a` + | +LL | fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &'a u8 { + | ++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:16:57 + | +LL | fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 { + | ^^ -- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL - fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 { +LL + fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'a u8 { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:23:48 + | +LL | fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime) -> ContainsLifetime<'_> { + | ^^^^^^^^^^^^^^^^ -- the elided lifetime gets resolved as `'_` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'_` + | +LL | fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime<'_>) -> ContainsLifetime<'_> { + | ++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:28:65 + | +LL | fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime { + | ^^ ---------------- the elided lifetime gets resolved as `'_` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'_` + | +LL | fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime<'_> { + | ++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:33:65 + | +LL | fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime { + | ^^ ---------------- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime<'a> { + | ++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:39:25 + | +LL | v: ContainsLifetime<'a>, + | ^^ this lifetime flows to the output +LL | +LL | ) -> ContainsLifetime<'_> { + | -- the elided lifetime gets resolved as `'a` + | +help: one option is to consistently use `'a` + | +LL - ) -> ContainsLifetime<'_> { +LL + ) -> ContainsLifetime<'a> { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:47:37 + | +LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime { + | ^^^ ---------------- the elided lifetime gets resolved as `'_` + | | + | this lifetime flows to the output + | +help: one option is to hide the lifetime for references and use the anonymous lifetime for paths + | +LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> { + | ++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:52:48 + | +LL | fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime { + | ^^ ---------------- the elided lifetime gets resolved as `'_` + | | + | this lifetime flows to the output + | +help: one option is to hide the lifetime for references and use the anonymous lifetime for paths + | +LL - fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime { +LL + fn explicit_anonymous_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:57:48 + | +LL | fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime { + | ^^ ---------------- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime<'a> { + | ++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:62:58 + | +LL | fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> { + | ^^ -- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL - fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> { +LL + fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'a> { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:69:37 + | +LL | fn implicit_path_to_implicit_ref(v: ContainsLifetime) -> &u8 { + | ^^^^^^^^^^^^^^^^ --- the elided lifetime gets resolved as `'_` + | | + | this lifetime flows to the output + | +help: one option is to hide the lifetime for references and use the anonymous lifetime for paths + | +LL | fn implicit_path_to_implicit_ref(v: ContainsLifetime<'_>) -> &u8 { + | ++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:74:47 + | +LL | fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 { + | ^^^^^^^^^^^^^^^^ -- the elided lifetime gets resolved as `'_` + | | + | this lifetime flows to the output + | +help: one option is to hide the lifetime for references and use the anonymous lifetime for paths + | +LL - fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 { +LL + fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime<'_>) -> &u8 { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:79:64 + | +LL | fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &u8 { + | ^^ --- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &'a u8 { + | ++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:84:74 + | +LL | fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 { + | ^^ -- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL - fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 { +LL + fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'a u8 { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:90:55 + | +LL | fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &u8 { + | ^^ --- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &'a u8 { + | ++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:95:65 + | +LL | fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 { + | ^^ -- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL - fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 { +LL + fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'a u8 { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:102:56 + | +LL | fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime { + | ^^ ---------------- the elided lifetime gets resolved as `'_` + | | + | this lifetime flows to the output + | +help: one option is to hide the lifetime for references and use the anonymous lifetime for paths + | +LL - fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime { +LL + fn method_explicit_anonymous_ref_to_implicit_path(&self) -> ContainsLifetime<'_> { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:107:56 + | +LL | fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime { + | ^^ ---------------- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime<'a> { + | ++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:112:66 + | +LL | fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> { + | ^^ -- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL - fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> { +LL + fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'a> { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:127:39 + | +LL | fn static_ref_to_implicit_ref(v: &'static u8) -> &u8 { + | ^^^^^^^ --- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL | fn static_ref_to_implicit_ref(v: &'static u8) -> &'static u8 { + | +++++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:132:49 + | +LL | fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 { + | ^^^^^^^ -- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL - fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 { +LL + fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'static u8 { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:137:40 + | +LL | fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime { + | ^^^^^^^ ---------------- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL | fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime<'static> { + | +++++++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:142:50 + | +LL | fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> { + | ^^^^^^^ -- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL - fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> { +LL + fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'static> { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:148:40 + | +LL | fn static_ref_to_implicit_ref(&'static self) -> &u8 { + | ^^^^^^^ --- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL | fn static_ref_to_implicit_ref(&'static self) -> &'static u8 { + | +++++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:153:50 + | +LL | fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 { + | ^^^^^^^ -- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL - fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 { +LL + fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'static u8 { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:158:41 + | +LL | fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime { + | ^^^^^^^ ---------------- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL | fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime<'static> { + | +++++++++ + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:163:51 + | +LL | fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> { + | ^^^^^^^ -- the elided lifetime gets resolved as `'static` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'static` + | +LL - fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> { +LL + fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'static> { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:175:55 + | +LL | fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ { + | ^^ -- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL - fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ { +LL + fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + 'a { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:180:65 + | +LL | fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> { + | ^^ -- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL - fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> { +LL + fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'a> { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:185:72 + | +LL | fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ { + | ^^ -- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL - fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ { +LL + fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + 'a { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:191:29 + | +LL | v: ContainsLifetime<'a>, + | ^^ this lifetime flows to the output +LL | +LL | ) -> impl FnOnce() + use<'_> { + | -- the elided lifetime gets resolved as `'a` + | +help: one option is to consistently use `'a` + | +LL - ) -> impl FnOnce() + use<'_> { +LL + ) -> impl FnOnce() + use<'a> { + | + +error: lifetime flowing from input to output with different syntax + --> $DIR/mismatched-lifetime-syntaxes.rs:200:33 + | +LL | fn multiple_outputs<'a>(v: &'a u8) -> (&u8, &u8) { + | ^^ --- --- the elided lifetimes get resolved as `'a` + | | | + | | the elided lifetimes get resolved as `'a` + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn multiple_outputs<'a>(v: &'a u8) -> (&'a u8, &'a u8) { + | ++ ++ + +error: aborting due to 32 previous errors + diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr deleted file mode 100644 index 2d8c6e996439d..0000000000000 --- a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: elided lifetime has a name - --> $DIR/example-from-issue48686.rs:6:50 - | -LL | pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 { - | ^ this elided lifetime gets resolved as `'static` - | -note: the lint level is defined here - --> $DIR/example-from-issue48686.rs:1:9 - | -LL | #![deny(elided_named_lifetimes)] - | ^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying it explicitly - | -LL | pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 { - | +++++++ - -error: aborting due to 1 previous error - diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs deleted file mode 100644 index 2f9083ed65f6e..0000000000000 --- a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![deny(elided_named_lifetimes)] - -fn ampersand<'a>(x: &'a u8) -> &u8 { - //~^ ERROR elided lifetime has a name - x -} - -struct Brackets<'a>(&'a u8); - -fn brackets<'a>(x: &'a u8) -> Brackets { - //~^ ERROR elided lifetime has a name - Brackets(x) -} - -struct Comma<'a, T>(&'a T); - -fn comma<'a>(x: &'a u8) -> Comma { - //~^ ERROR elided lifetime has a name - Comma(x) -} - -fn underscore<'a>(x: &'a u8) -> &'_ u8 { - //~^ ERROR elided lifetime has a name - x -} - -fn main() {} diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr deleted file mode 100644 index 249ae146b1675..0000000000000 --- a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr +++ /dev/null @@ -1,40 +0,0 @@ -error: elided lifetime has a name - --> $DIR/missing-lifetime-kind.rs:3:32 - | -LL | fn ampersand<'a>(x: &'a u8) -> &u8 { - | -- ^ this elided lifetime gets resolved as `'a` - | | - | lifetime `'a` declared here - | -note: the lint level is defined here - --> $DIR/missing-lifetime-kind.rs:1:9 - | -LL | #![deny(elided_named_lifetimes)] - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: elided lifetime has a name - --> $DIR/missing-lifetime-kind.rs:10:31 - | -LL | fn brackets<'a>(x: &'a u8) -> Brackets { - | -- ^^^^^^^^ this elided lifetime gets resolved as `'a` - | | - | lifetime `'a` declared here - -error: elided lifetime has a name - --> $DIR/missing-lifetime-kind.rs:17:33 - | -LL | fn comma<'a>(x: &'a u8) -> Comma { - | -- ^ this elided lifetime gets resolved as `'a` - | | - | lifetime `'a` declared here - -error: elided lifetime has a name - --> $DIR/missing-lifetime-kind.rs:22:34 - | -LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 { - | -- ^^ this elided lifetime gets resolved as `'a` - | | - | lifetime `'a` declared here - -error: aborting due to 4 previous errors - diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs deleted file mode 100644 index 4f9218130fbc1..0000000000000 --- a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![allow(elided_named_lifetimes)] - -#[warn(elided_named_lifetimes)] -mod foo { - fn bar(x: &'static u8) -> &u8 { - //~^ WARNING elided lifetime has a name - x - } - - #[deny(elided_named_lifetimes)] - fn baz(x: &'static u8) -> &u8 { - //~^ ERROR elided lifetime has a name - x - } -} - -fn main() {} diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr deleted file mode 100644 index 3c01375d50191..0000000000000 --- a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr +++ /dev/null @@ -1,34 +0,0 @@ -warning: elided lifetime has a name - --> $DIR/not-tied-to-crate.rs:5:31 - | -LL | fn bar(x: &'static u8) -> &u8 { - | ^ this elided lifetime gets resolved as `'static` - | -note: the lint level is defined here - --> $DIR/not-tied-to-crate.rs:3:8 - | -LL | #[warn(elided_named_lifetimes)] - | ^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying it explicitly - | -LL | fn bar(x: &'static u8) -> &'static u8 { - | +++++++ - -error: elided lifetime has a name - --> $DIR/not-tied-to-crate.rs:11:31 - | -LL | fn baz(x: &'static u8) -> &u8 { - | ^ this elided lifetime gets resolved as `'static` - | -note: the lint level is defined here - --> $DIR/not-tied-to-crate.rs:10:12 - | -LL | #[deny(elided_named_lifetimes)] - | ^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying it explicitly - | -LL | fn baz(x: &'static u8) -> &'static u8 { - | +++++++ - -error: aborting due to 1 previous error; 1 warning emitted - diff --git a/tests/ui/lint/elided-named-lifetimes/static.stderr b/tests/ui/lint/elided-named-lifetimes/static.stderr deleted file mode 100644 index 7ad08dbf04baf..0000000000000 --- a/tests/ui/lint/elided-named-lifetimes/static.stderr +++ /dev/null @@ -1,52 +0,0 @@ -error: elided lifetime has a name - --> $DIR/static.rs:16:33 - | -LL | fn ampersand(x: &'static u8) -> &u8 { - | ^ this elided lifetime gets resolved as `'static` - | -note: the lint level is defined here - --> $DIR/static.rs:1:9 - | -LL | #![deny(elided_named_lifetimes)] - | ^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying it explicitly - | -LL | fn ampersand(x: &'static u8) -> &'static u8 { - | +++++++ - -error: elided lifetime has a name - --> $DIR/static.rs:23:32 - | -LL | fn brackets(x: &'static u8) -> Brackets { - | ^^^^^^^^ this elided lifetime gets resolved as `'static` - | -help: consider specifying it explicitly - | -LL | fn brackets(x: &'static u8) -> Brackets<'static> { - | +++++++++ - -error: elided lifetime has a name - --> $DIR/static.rs:30:34 - | -LL | fn comma(x: &'static u8) -> Comma { - | ^ this elided lifetime gets resolved as `'static` - | -help: consider specifying it explicitly - | -LL | fn comma(x: &'static u8) -> Comma<'static, u8> { - | ++++++++ - -error: elided lifetime has a name - --> $DIR/static.rs:35:35 - | -LL | fn underscore(x: &'static u8) -> &'_ u8 { - | ^^ this elided lifetime gets resolved as `'static` - | -help: consider specifying it explicitly - | -LL - fn underscore(x: &'static u8) -> &'_ u8 { -LL + fn underscore(x: &'static u8) -> &'static u8 { - | - -error: aborting due to 4 previous errors - diff --git a/tests/ui/macros/format-args-temporaries.rs b/tests/ui/macros/format-args-temporaries.rs index ad9792bc796cf..74714be765344 100644 --- a/tests/ui/macros/format-args-temporaries.rs +++ b/tests/ui/macros/format-args-temporaries.rs @@ -5,7 +5,7 @@ use std::fmt::{self, Display}; struct Mutex; impl Mutex { - fn lock(&self) -> MutexGuard { + fn lock(&self) -> MutexGuard<'_> { MutexGuard(self) } } diff --git a/tests/ui/mir/mir_fat_ptr.rs b/tests/ui/mir/mir_fat_ptr.rs index f2dd9e6fe4064..af9831570d109 100644 --- a/tests/ui/mir/mir_fat_ptr.rs +++ b/tests/ui/mir/mir_fat_ptr.rs @@ -20,11 +20,11 @@ fn fat_ptr_via_local(a: &[u8]) -> &[u8] { x } -fn fat_ptr_from_struct(s: FatPtrContainer) -> &[u8] { +fn fat_ptr_from_struct(s: FatPtrContainer<'_>) -> &[u8] { s.ptr } -fn fat_ptr_to_struct(a: &[u8]) -> FatPtrContainer { +fn fat_ptr_to_struct(a: &[u8]) -> FatPtrContainer<'_> { FatPtrContainer { ptr: a } } diff --git a/tests/ui/nll/issue-53570.rs b/tests/ui/nll/issue-53570.rs index 882ce9e1c3130..cfc1edd217d01 100644 --- a/tests/ui/nll/issue-53570.rs +++ b/tests/ui/nll/issue-53570.rs @@ -22,7 +22,7 @@ struct Scratchpad<'a> { } impl<'a> Scratchpad<'a> { - fn get>(&self) -> Ref<[T]> + fn get>(&self) -> Ref<'_, [T]> where T: 'a { Ref::map(self.buffers.borrow(), |x| T::unwrap(x.as_ref())) diff --git a/tests/ui/nll/issue-54556-niconii.rs b/tests/ui/nll/issue-54556-niconii.rs index 9d37adede6adb..dc641524b155b 100644 --- a/tests/ui/nll/issue-54556-niconii.rs +++ b/tests/ui/nll/issue-54556-niconii.rs @@ -18,7 +18,7 @@ impl Drop for Mutex { fn drop(&mut self) { println!("Mutex::drop"); } } impl<'a> Drop for MutexGuard<'a> { fn drop(&mut self) { println!("MutexGuard::drop"); } } impl Mutex { - fn lock(&self) -> Result { Ok(MutexGuard(self)) } + fn lock(&self) -> Result, ()> { Ok(MutexGuard(self)) } } fn main() { diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.rs b/tests/ui/object-lifetime/object-lifetime-default-elision.rs index ede6af51174b2..f7c0261cfbb9c 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-elision.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-elision.rs @@ -46,8 +46,6 @@ fn load1(ss: &dyn SomeTrait) -> &dyn SomeTrait { } fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait { - //~^ WARNING elided lifetime has a name - // Same as `load1` but with an explicit name thrown in for fun. ss diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr index b44a184c6848f..b59956879275a 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr @@ -1,15 +1,5 @@ -warning: elided lifetime has a name - --> $DIR/object-lifetime-default-elision.rs:48:40 - | -LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait { - | -- ^ this elided lifetime gets resolved as `'a` - | | - | lifetime `'a` declared here - | - = note: `#[warn(elided_named_lifetimes)]` on by default - error: lifetime may not live long enough - --> $DIR/object-lifetime-default-elision.rs:73:5 + --> $DIR/object-lifetime-default-elision.rs:71:5 | LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait { | -- -- lifetime `'b` defined here @@ -21,5 +11,5 @@ LL | ss | = help: consider adding the following bound: `'a: 'b` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/regions/init-res-into-things.rs b/tests/ui/regions/init-res-into-things.rs index 64909b329199e..7b100d3253355 100644 --- a/tests/ui/regions/init-res-into-things.rs +++ b/tests/ui/regions/init-res-into-things.rs @@ -20,7 +20,7 @@ impl<'a> Drop for r<'a> { } } -fn r(i: &Cell) -> r { +fn r(i: &Cell) -> r<'_> { r { i: i } diff --git a/tests/ui/regions/regions-nullary-variant.rs b/tests/ui/regions/regions-nullary-variant.rs index 8624f9961f667..24c5c6765a86c 100644 --- a/tests/ui/regions/regions-nullary-variant.rs +++ b/tests/ui/regions/regions-nullary-variant.rs @@ -7,7 +7,7 @@ enum roption<'a> { a, b(&'a usize) } -fn mk(cond: bool, ptr: &usize) -> roption { +fn mk(cond: bool, ptr: &usize) -> roption<'_> { if cond {roption::a} else {roption::b(ptr)} } diff --git a/tests/ui/resource-assign-is-not-copy.rs b/tests/ui/resource-assign-is-not-copy.rs index 078824cea1bae..ab42601690131 100644 --- a/tests/ui/resource-assign-is-not-copy.rs +++ b/tests/ui/resource-assign-is-not-copy.rs @@ -14,7 +14,7 @@ impl<'a> Drop for r<'a> { } } -fn r(i: &Cell) -> r { +fn r(i: &Cell) -> r<'_> { r { i: i } diff --git a/tests/ui/resource-destruct.rs b/tests/ui/resource-destruct.rs index cbb17bb6ba61c..480cbe091a7a2 100644 --- a/tests/ui/resource-destruct.rs +++ b/tests/ui/resource-destruct.rs @@ -17,7 +17,7 @@ impl<'a> shrinky_pointer<'a> { pub fn look_at(&self) -> isize { return self.i.get(); } } -fn shrinky_pointer(i: &Cell) -> shrinky_pointer { +fn shrinky_pointer(i: &Cell) -> shrinky_pointer<'_> { shrinky_pointer { i: i } diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs index 5dd928dbce5b0..a61be38a23af9 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs @@ -33,7 +33,7 @@ impl DropOrderCollector { println!("{n}"); self.0.borrow_mut().push(n) } - fn some_loud(&self, n: u32) -> Option { + fn some_loud(&self, n: u32) -> Option> { Some(LoudDrop(self, n)) } diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs index 7d8dfe37135c7..3e4fae2e84e76 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs @@ -8,7 +8,7 @@ struct Pd; impl Pd { - fn it(&self) -> It { + fn it(&self) -> It<'_> { todo!() } } diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.rs b/tests/ui/self/elision/ignore-non-reference-lifetimes.rs index cedc6f0f9bc62..ecd669059ed3a 100644 --- a/tests/ui/self/elision/ignore-non-reference-lifetimes.rs +++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.rs @@ -4,11 +4,11 @@ struct Foo<'a>(&'a str); impl<'b> Foo<'b> { fn a<'a>(self: Self, a: &'a str) -> &str { - //~^ WARNING elided lifetime has a name + //~^ WARNING lifetime flowing from input to output with different syntax a } fn b<'a>(self: Foo<'b>, a: &'a str) -> &str { - //~^ WARNING elided lifetime has a name + //~^ WARNING lifetime flowing from input to output with different syntax a } } diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr index 4465dbae52989..e395c035526ed 100644 --- a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr +++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr @@ -1,16 +1,29 @@ -warning: elided lifetime has a name - --> $DIR/ignore-non-reference-lifetimes.rs:6:41 +warning: lifetime flowing from input to output with different syntax + --> $DIR/ignore-non-reference-lifetimes.rs:6:30 | LL | fn a<'a>(self: Self, a: &'a str) -> &str { - | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` + | ^^ ---- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output | - = note: `#[warn(elided_named_lifetimes)]` on by default + = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default +help: one option is to consistently use `'a` + | +LL | fn a<'a>(self: Self, a: &'a str) -> &'a str { + | ++ -warning: elided lifetime has a name - --> $DIR/ignore-non-reference-lifetimes.rs:10:44 +warning: lifetime flowing from input to output with different syntax + --> $DIR/ignore-non-reference-lifetimes.rs:10:33 | LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &str { - | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` + | ^^ ---- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &'a str { + | ++ warning: 2 warnings emitted diff --git a/tests/ui/self/elision/lt-ref-self-async.fixed b/tests/ui/self/elision/lt-ref-self-async.fixed index aae94f7a6ccce..191610336de3f 100644 --- a/tests/ui/self/elision/lt-ref-self-async.fixed +++ b/tests/ui/self/elision/lt-ref-self-async.fixed @@ -1,6 +1,6 @@ //@ edition:2018 //@ run-rustfix -#![allow(non_snake_case, dead_code, elided_named_lifetimes)] +#![allow(non_snake_case, dead_code, mismatched_lifetime_syntaxes)] use std::pin::Pin; diff --git a/tests/ui/self/elision/lt-ref-self-async.rs b/tests/ui/self/elision/lt-ref-self-async.rs index 0c11b271c35a7..c910a5d6d7e87 100644 --- a/tests/ui/self/elision/lt-ref-self-async.rs +++ b/tests/ui/self/elision/lt-ref-self-async.rs @@ -1,6 +1,6 @@ //@ edition:2018 //@ run-rustfix -#![allow(non_snake_case, dead_code, elided_named_lifetimes)] +#![allow(non_snake_case, dead_code, mismatched_lifetime_syntaxes)] use std::pin::Pin; diff --git a/tests/ui/self/self_lifetime-async.rs b/tests/ui/self/self_lifetime-async.rs index fd6902071188c..f839ab03a6072 100644 --- a/tests/ui/self/self_lifetime-async.rs +++ b/tests/ui/self/self_lifetime-async.rs @@ -4,13 +4,13 @@ struct Foo<'a>(&'a ()); impl<'a> Foo<'a> { async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } - //~^ WARNING elided lifetime has a name + //~^ WARNING lifetime flowing from input to output with different syntax } type Alias = Foo<'static>; impl Alias { async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } - //~^ WARNING elided lifetime has a name + //~^ WARNING lifetime flowing from input to output with different syntax } fn main() {} diff --git a/tests/ui/self/self_lifetime-async.stderr b/tests/ui/self/self_lifetime-async.stderr index 32de3fd18c97f..e33d7a831405a 100644 --- a/tests/ui/self/self_lifetime-async.stderr +++ b/tests/ui/self/self_lifetime-async.stderr @@ -1,18 +1,29 @@ -warning: elided lifetime has a name - --> $DIR/self_lifetime-async.rs:6:44 +warning: lifetime flowing from input to output with different syntax + --> $DIR/self_lifetime-async.rs:6:29 | LL | async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } - | -- ^ this elided lifetime gets resolved as `'b` - | | - | lifetime `'b` declared here + | ^^ --- the elided lifetime gets resolved as `'b` + | | + | this lifetime flows to the output | - = note: `#[warn(elided_named_lifetimes)]` on by default + = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default +help: one option is to consistently use `'b` + | +LL | async fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } + | ++ -warning: elided lifetime has a name - --> $DIR/self_lifetime-async.rs:12:52 +warning: lifetime flowing from input to output with different syntax + --> $DIR/self_lifetime-async.rs:12:42 | LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } - | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` + | ^^ --- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } + | ++ warning: 2 warnings emitted diff --git a/tests/ui/self/self_lifetime.rs b/tests/ui/self/self_lifetime.rs index 0607c3b9317f1..aaa31f85ad5b0 100644 --- a/tests/ui/self/self_lifetime.rs +++ b/tests/ui/self/self_lifetime.rs @@ -5,13 +5,13 @@ struct Foo<'a>(&'a ()); impl<'a> Foo<'a> { fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } - //~^ WARNING elided lifetime has a name + //~^ WARNING lifetime flowing from input to output with different syntax } type Alias = Foo<'static>; impl Alias { fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } - //~^ WARNING elided lifetime has a name + //~^ WARNING lifetime flowing from input to output with different syntax } fn main() {} diff --git a/tests/ui/self/self_lifetime.stderr b/tests/ui/self/self_lifetime.stderr index cd8f4d8adf8b1..895978e9c0c2f 100644 --- a/tests/ui/self/self_lifetime.stderr +++ b/tests/ui/self/self_lifetime.stderr @@ -1,18 +1,29 @@ -warning: elided lifetime has a name - --> $DIR/self_lifetime.rs:7:38 +warning: lifetime flowing from input to output with different syntax + --> $DIR/self_lifetime.rs:7:23 | LL | fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } - | -- ^ this elided lifetime gets resolved as `'b` - | | - | lifetime `'b` declared here + | ^^ --- the elided lifetime gets resolved as `'b` + | | + | this lifetime flows to the output | - = note: `#[warn(elided_named_lifetimes)]` on by default + = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default +help: one option is to consistently use `'b` + | +LL | fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } + | ++ -warning: elided lifetime has a name - --> $DIR/self_lifetime.rs:13:46 +warning: lifetime flowing from input to output with different syntax + --> $DIR/self_lifetime.rs:13:36 | LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } - | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` + | ^^ --- the elided lifetime gets resolved as `'a` + | | + | this lifetime flows to the output + | +help: one option is to consistently use `'a` + | +LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } + | ++ warning: 2 warnings emitted diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs index f5c3da847c72f..f176d52c087ef 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs +++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs @@ -73,7 +73,6 @@ mod in_path { // This must not err, as the `&` actually resolves to `'a`. fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) { - //~^ WARNING elided lifetime has a name f("f"); } diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr index 92996ca846782..f29107b297a5b 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr +++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr @@ -149,14 +149,6 @@ LL - fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() } LL + fn g(mut x: impl Foo<()>) -> Option<()> { x.next() } | -warning: elided lifetime has a name - --> $DIR/impl-trait-missing-lifetime-gated.rs:75:57 - | -LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) { - | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` - | - = note: `#[warn(elided_named_lifetimes)]` on by default - error[E0658]: anonymous lifetimes in `impl Trait` are unstable --> $DIR/impl-trait-missing-lifetime-gated.rs:6:35 | @@ -289,7 +281,7 @@ help: consider introducing a named lifetime parameter LL | fn g<'a>(mut x: impl Foo<'a, ()>) -> Option<&()> { x.next() } | ++++ +++ -error: aborting due to 17 previous errors; 1 warning emitted +error: aborting due to 17 previous errors Some errors have detailed explanations: E0106, E0658. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs index b61bea16e3bc8..b641f5941dcef 100644 --- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs +++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs @@ -100,7 +100,6 @@ where // This also works. The `'_` isn't necessary but it's where we arrive to following the suggestions: fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a -//~^ WARNING elided lifetime has a name where G: Get, { diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index b92719e8033a0..41cb2ee46bb5a 100644 --- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -6,14 +6,6 @@ LL | fn baz(g: G, dest: &mut T) -> impl FnOnce() + '_ | | | help: consider introducing lifetime `'a` here: `'a,` -warning: elided lifetime has a name - --> $DIR/missing-lifetimes-in-signature.rs:102:64 - | -LL | fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a - | -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a` - | - = note: `#[warn(elided_named_lifetimes)]` on by default - error[E0700]: hidden type for `impl FnOnce()` captures lifetime that does not appear in bounds --> $DIR/missing-lifetimes-in-signature.rs:19:5 | @@ -136,7 +128,7 @@ help: consider adding an explicit lifetime bound LL | G: Get + 'a, | ++++ -error: aborting due to 8 previous errors; 1 warning emitted +error: aborting due to 8 previous errors Some errors have detailed explanations: E0261, E0309, E0311, E0621, E0700. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs index d77efa39aeb61..60d9521621fac 100644 --- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs +++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs @@ -3,7 +3,7 @@ type Opaque2 = impl Sized; type Opaque<'a, T> = Opaque2; #[define_opaque(Opaque)] -fn defining<'a, T>(x: &'a i32) -> Opaque { x } //~ WARNING elided lifetime has a name +fn defining<'a, T>(x: &'a i32) -> Opaque { x } //~^ ERROR: hidden type for `Opaque2` captures lifetime that does not appear in bounds fn main() {} diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr index 61eb76ffc5ae2..b73e6b8c1015b 100644 --- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr +++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr @@ -1,13 +1,3 @@ -warning: elided lifetime has a name - --> $DIR/missing_lifetime_bound.rs:6:41 - | -LL | fn defining<'a, T>(x: &'a i32) -> Opaque { x } - | -- ^ this elided lifetime gets resolved as `'a` - | | - | lifetime `'a` declared here - | - = note: `#[warn(elided_named_lifetimes)]` on by default - error[E0700]: hidden type for `Opaque2` captures lifetime that does not appear in bounds --> $DIR/missing_lifetime_bound.rs:6:47 | @@ -19,6 +9,6 @@ LL | fn defining<'a, T>(x: &'a i32) -> Opaque { x } | | | hidden type `&'a i32` captures the lifetime `'a` as defined here -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/type-id-higher-rank-2.rs b/tests/ui/type-id-higher-rank-2.rs index 4a76b737e8c43..7b0c7b5394084 100644 --- a/tests/ui/type-id-higher-rank-2.rs +++ b/tests/ui/type-id-higher-rank-2.rs @@ -5,7 +5,7 @@ use std::any::Any; struct Foo<'a>(&'a str); -fn good(s: &String) -> Foo { Foo(s) } +fn good(s: &String) -> Foo<'_> { Foo(s) } fn bad1(s: String) -> Option<&'static str> { let a: Box = Box::new(good as fn(&String) -> Foo); diff --git a/tests/ui/underscore-lifetimes.rs b/tests/ui/underscore-lifetimes.rs index 6174f8ce036fa..a372851f9cfff 100644 --- a/tests/ui/underscore-lifetimes.rs +++ b/tests/ui/underscore-lifetimes.rs @@ -1,6 +1,6 @@ //@ run-pass -#![allow(dead_code)] +#![allow(dead_code, mismatched_lifetime_syntaxes)] struct Foo<'a>(&'a u8); fn foo(x: &u8) -> Foo<'_> {