summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-07-25 00:51:03 +0000
committerbors <bors@rust-lang.org>2025-07-25 00:51:03 +0000
commit4229c2e708ce796c71747b7fa177ff4ef9aa794c (patch)
treeda3488c994674fb8f6b64dc2ab210749c38a0698
parent20c571f4ca4689572df8c27fdde8eaa36d77a11d (diff)
parent156e2a61ddc90d23f49ee1e175a5f8f566c96ca3 (diff)
downloadrust-4229c2e708ce796c71747b7fa177ff4ef9aa794c.tar.gz
rust-4229c2e708ce796c71747b7fa177ff4ef9aa794c.zip
Auto merge of #144414 - cuviper:beta-next, r=cuviper
[beta] backports

- Reword mismatched-lifetime-syntaxes text based on feedback rust-lang/rust#143914
- Fix `-Ctarget-feature`s getting ignored after `crt-static` rust-lang/rust#144143
- Mitigate `#[align]` name resolution ambiguity regression with a rename rust-lang/rust#144080

r? cuviper
-rw-r--r--compiler/rustc_attr_data_structures/src/attributes.rs1
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/repr.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs4
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs3
-rw-r--r--compiler/rustc_lint/messages.ftl53
-rw-r--r--compiler/rustc_lint/src/lib.rs2
-rw-r--r--compiler/rustc_lint/src/lifetime_syntax.rs145
-rw-r--r--compiler/rustc_lint/src/lints.rs64
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs1
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs3
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.rs2
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.stderr11
-rw-r--r--src/tools/miri/tests/pass/fn_align.rs10
-rw-r--r--tests/assembly/naked-functions/wasm32.rs4
-rw-r--r--tests/codegen/align-fn.rs26
-rw-r--r--tests/codegen/min-function-alignment.rs6
-rw-r--r--tests/codegen/naked-fn/aligned.rs5
-rw-r--r--tests/codegen/naked-fn/min-function-alignment.rs6
-rw-r--r--tests/ui/asm/naked-with-invalid-repr-attr.rs6
-rw-r--r--tests/ui/asm/naked-with-invalid-repr-attr.stderr12
-rw-r--r--tests/ui/attributes/fn-align-nameres-ambiguity-143834.rs19
-rw-r--r--tests/ui/attributes/malformed-fn-align.rs17
-rw-r--r--tests/ui/attributes/malformed-fn-align.stderr62
-rw-r--r--tests/ui/cfg/crt-static-with-target-features-works.rs24
-rw-r--r--tests/ui/cfg/crt-static-with-target-features-works.stderr8
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.full.stderr11
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-fn_align.rs14
-rw-r--r--tests/ui/feature-gates/feature-gate-fn_align.stderr26
-rw-r--r--tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs2
-rw-r--r--tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr7
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs2
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr9
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs8
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr36
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs4
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr18
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs8
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr36
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs104
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr497
-rw-r--r--tests/ui/self/elision/ignore-non-reference-lifetimes.rs4
-rw-r--r--tests/ui/self/elision/ignore-non-reference-lifetimes.stderr18
-rw-r--r--tests/ui/self/self_lifetime-async.rs4
-rw-r--r--tests/ui/self/self_lifetime-async.stderr18
-rw-r--r--tests/ui/self/self_lifetime.rs4
-rw-r--r--tests/ui/self/self_lifetime.stderr18
50 files changed, 852 insertions, 504 deletions
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index c7487847e6f..e27aa8e3614 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -184,6 +184,7 @@ impl Deprecation {
 pub enum AttributeKind {
     // tidy-alphabetical-start
     /// Represents `#[align(N)]`.
+    // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
     Align { align: Align, span: Span },
 
     /// Represents `#[rustc_allow_const_fn_unstable]`.
diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs
index 4aa27043e98..8ec1dcd9690 100644
--- a/compiler/rustc_attr_parsing/src/attributes/repr.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs
@@ -273,7 +273,7 @@ fn parse_alignment(node: &LitKind) -> Result<Align, &'static str> {
 pub(crate) struct AlignParser(Option<(Align, Span)>);
 
 impl AlignParser {
-    const PATH: &'static [Symbol] = &[sym::align];
+    const PATH: &'static [Symbol] = &[sym::rustc_align];
     const TEMPLATE: AttributeTemplate = template!(List: "<alignment in bytes>");
 
     fn parse<'c, S: Stage>(
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 67ac619091b..9d2aa92b7b8 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -176,14 +176,14 @@ fn parse_rust_feature_flag<'a>(
         if let Some(base_feature) = feature.strip_prefix('+') {
             // Skip features that are not target features, but rustc features.
             if RUSTC_SPECIFIC_FEATURES.contains(&base_feature) {
-                return;
+                continue;
             }
 
             callback(base_feature, sess.target.implied_target_features(base_feature), true)
         } else if let Some(base_feature) = feature.strip_prefix('-') {
             // Skip features that are not target features, but rustc features.
             if RUSTC_SPECIFIC_FEATURES.contains(&base_feature) {
-                return;
+                continue;
             }
 
             // If `f1` implies `f2`, then `!f2` implies `!f1` -- this is standard logical
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 280b33f0723..b309c49ac19 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -495,7 +495,8 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
     ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
     ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No),
-    gated!(align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(align)),
+    // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+    gated!(rustc_align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)),
     ungated!(unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
     ungated!(unsafe(Edition2024) link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
     ungated!(unsafe(Edition2024) no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 8d9f2385b71..5fece464270 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -508,27 +508,50 @@ 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 can be confusing
-    .label_mismatched_lifetime_syntaxes_inputs =
-        {$n_inputs ->
-            [one] this lifetime flows
-            *[other] these lifetimes flow
-        } to the output
-    .label_mismatched_lifetime_syntaxes_outputs =
-        the {$n_outputs ->
-            [one] lifetime gets
-            *[other] lifetimes get
-        } resolved as `{$lifetime_name}`
+lint_mismatched_lifetime_syntaxes_eliding_while_named =
+    eliding a lifetime that's named elsewhere is confusing
+
+lint_mismatched_lifetime_syntaxes_help =
+    the same lifetime is referred to in inconsistent ways, making the signature confusing
+
+lint_mismatched_lifetime_syntaxes_hiding_and_eliding_while_named =
+    hiding or eliding a lifetime that's named elsewhere is confusing
+
+lint_mismatched_lifetime_syntaxes_hiding_while_elided =
+    hiding a lifetime that's elided elsewhere is confusing
+
+lint_mismatched_lifetime_syntaxes_hiding_while_named =
+    hiding a lifetime that's named elsewhere is confusing
+
+lint_mismatched_lifetime_syntaxes_input_elided =
+    the lifetime is elided here
+
+lint_mismatched_lifetime_syntaxes_input_hidden =
+    the lifetime is hidden here
+
+lint_mismatched_lifetime_syntaxes_input_named =
+    the lifetime is named here
+
+lint_mismatched_lifetime_syntaxes_output_elided =
+    the same lifetime is elided here
+
+lint_mismatched_lifetime_syntaxes_output_hidden =
+    the same lifetime is hidden here
+
+lint_mismatched_lifetime_syntaxes_output_named =
+    the same lifetime is named here
 
 lint_mismatched_lifetime_syntaxes_suggestion_explicit =
-    one option is to consistently use `{$lifetime_name}`
+    consistently use `{$lifetime_name}`
 
 lint_mismatched_lifetime_syntaxes_suggestion_implicit =
-    one option is to consistently remove the lifetime
+    remove the lifetime name from references
 
 lint_mismatched_lifetime_syntaxes_suggestion_mixed =
-    one option is to remove the lifetime for references and use the anonymous lifetime for paths
+    remove the lifetime name from references and use `'_` for type paths
+
+lint_mismatched_lifetime_syntaxes_suggestion_mixed_only_paths =
+    use `'_` for type paths
 
 lint_missing_unsafe_on_extern = extern blocks should be unsafe
     .suggestion = needs `unsafe` before the extern keyword
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 20568f35a47..27ce614d8c9 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -55,7 +55,7 @@ mod invalid_from_utf8;
 mod late;
 mod let_underscore;
 mod levels;
-mod lifetime_syntax;
+pub mod lifetime_syntax;
 mod lints;
 mod macro_expr_fragment_specifier_2024_migration;
 mod map_unit_fn;
diff --git a/compiler/rustc_lint/src/lifetime_syntax.rs b/compiler/rustc_lint/src/lifetime_syntax.rs
index 95b7b69bd5a..2a5a34cdc6e 100644
--- a/compiler/rustc_lint/src/lifetime_syntax.rs
+++ b/compiler/rustc_lint/src/lifetime_syntax.rs
@@ -140,43 +140,115 @@ fn report_mismatches<'tcx>(
     }
 }
 
-fn lifetimes_use_matched_syntax(input_info: &[Info<'_>], output_info: &[Info<'_>]) -> bool {
-    // Categorize lifetimes into source/syntax buckets.
-    let mut n_hidden = 0;
-    let mut n_elided = 0;
-    let mut n_named = 0;
+#[derive(Debug, Copy, Clone, PartialEq)]
+enum LifetimeSyntaxCategory {
+    Hidden,
+    Elided,
+    Named,
+}
 
-    for info in input_info.iter().chain(output_info) {
+impl LifetimeSyntaxCategory {
+    fn new(syntax_source: (hir::LifetimeSyntax, LifetimeSource)) -> Option<Self> {
         use LifetimeSource::*;
         use hir::LifetimeSyntax::*;
 
-        let syntax_source = (info.lifetime.syntax, info.lifetime.source);
-
         match syntax_source {
-            // Ignore any other kind of lifetime.
-            (_, Other) => continue,
-
             // E.g. `&T`.
-            (Implicit, Reference | OutlivesBound | PreciseCapturing) |
+            (Implicit, Reference) |
             // E.g. `&'_ T`.
-            (ExplicitAnonymous, Reference | OutlivesBound | PreciseCapturing) |
+            (ExplicitAnonymous, Reference) |
             // E.g. `ContainsLifetime<'_>`.
-            (ExplicitAnonymous, Path { .. }) => n_elided += 1,
+            (ExplicitAnonymous, Path { .. }) |
+            // E.g. `+ '_`, `+ use<'_>`.
+            (ExplicitAnonymous, OutlivesBound | PreciseCapturing) => {
+                Some(Self::Elided)
+            }
 
             // E.g. `ContainsLifetime`.
-            (Implicit, Path { .. }) => n_hidden += 1,
+            (Implicit, Path { .. }) => {
+                Some(Self::Hidden)
+            }
 
             // E.g. `&'a T`.
-            (ExplicitBound, Reference | OutlivesBound | PreciseCapturing) |
+            (ExplicitBound, Reference) |
             // E.g. `ContainsLifetime<'a>`.
-            (ExplicitBound, Path { .. }) => n_named += 1,
-        };
+            (ExplicitBound, Path { .. }) |
+            // E.g. `+ 'a`, `+ use<'a>`.
+            (ExplicitBound, OutlivesBound | PreciseCapturing) => {
+                Some(Self::Named)
+            }
+
+            (Implicit, OutlivesBound | PreciseCapturing) |
+            (_, Other) => {
+                None
+            }
+        }
+    }
+}
+
+#[derive(Debug, Default)]
+pub struct LifetimeSyntaxCategories<T> {
+    pub hidden: T,
+    pub elided: T,
+    pub named: T,
+}
+
+impl<T> LifetimeSyntaxCategories<T> {
+    fn select(&mut self, category: LifetimeSyntaxCategory) -> &mut T {
+        use LifetimeSyntaxCategory::*;
+
+        match category {
+            Elided => &mut self.elided,
+            Hidden => &mut self.hidden,
+            Named => &mut self.named,
+        }
+    }
+}
+
+impl<T> LifetimeSyntaxCategories<Vec<T>> {
+    pub fn len(&self) -> LifetimeSyntaxCategories<usize> {
+        LifetimeSyntaxCategories {
+            hidden: self.hidden.len(),
+            elided: self.elided.len(),
+            named: self.named.len(),
+        }
+    }
+
+    pub fn flatten(&self) -> impl Iterator<Item = &T> {
+        let Self { hidden, elided, named } = self;
+        [hidden.iter(), elided.iter(), named.iter()].into_iter().flatten()
+    }
+}
+
+impl std::ops::Add for LifetimeSyntaxCategories<usize> {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self::Output {
+        Self {
+            hidden: self.hidden + rhs.hidden,
+            elided: self.elided + rhs.elided,
+            named: self.named + rhs.named,
+        }
+    }
+}
+
+fn lifetimes_use_matched_syntax(input_info: &[Info<'_>], output_info: &[Info<'_>]) -> bool {
+    let mut syntax_counts = LifetimeSyntaxCategories::<usize>::default();
+
+    for info in input_info.iter().chain(output_info) {
+        if let Some(category) = info.lifetime_syntax_category() {
+            *syntax_counts.select(category) += 1;
+        }
     }
 
-    let syntax_counts = (n_hidden, n_elided, n_named);
     tracing::debug!(?syntax_counts);
 
-    matches!(syntax_counts, (_, 0, 0) | (0, _, 0) | (0, 0, _))
+    matches!(
+        syntax_counts,
+        LifetimeSyntaxCategories { hidden: _, elided: 0, named: 0 }
+            | LifetimeSyntaxCategories { hidden: 0, elided: _, named: 0 }
+            | LifetimeSyntaxCategories { hidden: 0, elided: 0, named: _ }
+    )
 }
 
 fn emit_mismatch_diagnostic<'tcx>(
@@ -238,7 +310,7 @@ fn emit_mismatch_diagnostic<'tcx>(
         use LifetimeSource::*;
         use hir::LifetimeSyntax::*;
 
-        let syntax_source = (info.lifetime.syntax, info.lifetime.source);
+        let syntax_source = info.syntax_source();
 
         if let (_, Other) = syntax_source {
             // Ignore any other kind of lifetime.
@@ -259,7 +331,6 @@ fn emit_mismatch_diagnostic<'tcx>(
             // 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);
             }
 
@@ -319,12 +390,22 @@ fn emit_mismatch_diagnostic<'tcx>(
         }
     }
 
+    let categorize = |infos: &[Info<'_>]| {
+        let mut categories = LifetimeSyntaxCategories::<Vec<_>>::default();
+        for info in infos {
+            if let Some(category) = info.lifetime_syntax_category() {
+                categories.select(category).push(info.reporting_span());
+            }
+        }
+        categories
+    };
+
+    let inputs = categorize(input_info);
+    let outputs = categorize(output_info);
+
     let make_implicit_suggestions =
         |infos: &[&Info<'_>]| infos.iter().map(|i| i.removing_span()).collect::<Vec<_>>();
 
-    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)
     });
@@ -399,8 +480,6 @@ fn emit_mismatch_diagnostic<'tcx>(
         ?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
@@ -413,8 +492,8 @@ fn emit_mismatch_diagnostic<'tcx>(
 
     cx.emit_span_lint(
         MISMATCHED_LIFETIME_SYNTAXES,
-        Vec::clone(&inputs),
-        lints::MismatchedLifetimeSyntaxes { lifetime_name, inputs, outputs, suggestions },
+        inputs.flatten().copied().collect::<Vec<_>>(),
+        lints::MismatchedLifetimeSyntaxes { inputs, outputs, suggestions },
     );
 }
 
@@ -441,6 +520,14 @@ struct Info<'tcx> {
 }
 
 impl<'tcx> Info<'tcx> {
+    fn syntax_source(&self) -> (hir::LifetimeSyntax, LifetimeSource) {
+        (self.lifetime.syntax, self.lifetime.source)
+    }
+
+    fn lifetime_syntax_category(&self) -> Option<LifetimeSyntaxCategory> {
+        LifetimeSyntaxCategory::new(self.syntax_source())
+    }
+
     fn lifetime_name(&self) -> &str {
         self.lifetime.ident.as_str()
     }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index c4a6695efe9..1728f7d2902 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -22,6 +22,7 @@ use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym};
 
 use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds};
 use crate::errors::{OverruledAttributeSub, RequestedLevel};
+use crate::lifetime_syntax::LifetimeSyntaxCategories;
 use crate::{LateContext, fluent_generated as fluent};
 
 // array_into_iter.rs
@@ -3176,30 +3177,59 @@ pub(crate) struct ReservedMultihash {
 
 #[derive(Debug)]
 pub(crate) struct MismatchedLifetimeSyntaxes {
-    pub lifetime_name: String,
-    pub inputs: Vec<Span>,
-    pub outputs: Vec<Span>,
+    pub inputs: LifetimeSyntaxCategories<Vec<Span>>,
+    pub outputs: LifetimeSyntaxCategories<Vec<Span>>,
 
     pub suggestions: Vec<MismatchedLifetimeSyntaxesSuggestion>,
 }
 
 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);
+        let counts = self.inputs.len() + self.outputs.len();
+        let message = match counts {
+            LifetimeSyntaxCategories { hidden: 0, elided: 0, named: 0 } => {
+                panic!("No lifetime mismatch detected")
+            }
+
+            LifetimeSyntaxCategories { hidden: _, elided: _, named: 0 } => {
+                fluent::lint_mismatched_lifetime_syntaxes_hiding_while_elided
+            }
+
+            LifetimeSyntaxCategories { hidden: _, elided: 0, named: _ } => {
+                fluent::lint_mismatched_lifetime_syntaxes_hiding_while_named
+            }
+
+            LifetimeSyntaxCategories { hidden: 0, elided: _, named: _ } => {
+                fluent::lint_mismatched_lifetime_syntaxes_eliding_while_named
+            }
 
-        diag.arg("lifetime_name", self.lifetime_name);
+            LifetimeSyntaxCategories { hidden: _, elided: _, named: _ } => {
+                fluent::lint_mismatched_lifetime_syntaxes_hiding_and_eliding_while_named
+            }
+        };
+        diag.primary_message(message);
 
-        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);
+        for s in self.inputs.hidden {
+            diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_input_hidden);
+        }
+        for s in self.inputs.elided {
+            diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_input_elided);
+        }
+        for s in self.inputs.named {
+            diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_input_named);
         }
 
-        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);
+        for s in self.outputs.hidden {
+            diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_output_hidden);
+        }
+        for s in self.outputs.elided {
+            diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_output_elided);
         }
+        for s in self.outputs.named {
+            diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_output_named);
+        }
+
+        diag.help(fluent::lint_mismatched_lifetime_syntaxes_help);
 
         let mut suggestions = self.suggestions.into_iter();
         if let Some(s) = suggestions.next() {
@@ -3267,6 +3297,12 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion {
             }
 
             Mixed { implicit_suggestions, explicit_anonymous_suggestions, tool_only } => {
+                let message = if implicit_suggestions.is_empty() {
+                    fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed_only_paths
+                } else {
+                    fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed
+                };
+
                 let implicit_suggestions =
                     implicit_suggestions.into_iter().map(|s| (s, String::new()));
 
@@ -3274,7 +3310,7 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion {
                     implicit_suggestions.chain(explicit_anonymous_suggestions).collect();
 
                 diag.multipart_suggestion_with_style(
-                    fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed,
+                    message,
                     suggestions,
                     Applicability::MaybeIncorrect,
                     style(tool_only),
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 2f16d385efb..8d905862c64 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -48,6 +48,7 @@ pub struct CodegenFnAttrs {
     /// switching between multiple instruction sets.
     pub instruction_set: Option<InstructionSetAttr>,
     /// The `#[align(...)]` attribute. Determines the alignment of the function body.
+    // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
     pub alignment: Option<Align>,
     /// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
     /// the function entry.
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 8e6442353c3..8599022b935 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -289,7 +289,8 @@ fn emit_malformed_attribute(
             | sym::rustc_force_inline
             | sym::rustc_confusables
             | sym::repr
-            | sym::align
+            // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+            | sym::rustc_align
             | sym::deprecated
             | sym::optimize
             | sym::cold
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index c1a2b3b2973..9dbdbd23b7b 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -14,7 +14,7 @@ passes_abi_of =
     fn_abi_of({$fn_name}) = {$fn_abi}
 
 passes_align_should_be_repr_align =
-    `#[align(...)]` is not supported on {$item} items
+    `#[rustc_align(...)]` is not supported on {$item} items
     .suggestion = use `#[repr(align(...))]` instead
 
 passes_allow_incoherent_impl =
@@ -589,7 +589,7 @@ passes_repr_align_greater_than_target_max =
 
 passes_repr_align_should_be_align =
     `#[repr(align(...))]` is not supported on {$item} items
-    .help = use `#[align(...)]` instead
+    .help = use `#[rustc_align(...)]` instead
 
 passes_repr_conflicting =
     conflicting representation hints
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index ad1a2a04273..f6d7af541a6 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -662,7 +662,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             sym::naked,
             sym::instruction_set,
             sym::repr,
-            sym::align,
+            // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+            sym::rustc_align,
             sym::rustc_std_internal_symbol,
             // documentation
             sym::doc,
@@ -1996,6 +1997,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     }
 
     /// Checks if the `#[align]` attributes on `item` are valid.
+    // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
     fn check_align(&self, span: Span, target: Target, align: Align, repr_span: Span) {
         match target {
             Target::Fn | Target::Method(_) => {}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 684b1781b44..8c9f18f50a3 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1806,6 +1806,8 @@ symbols! {
         rust_out,
         rustc,
         rustc_abi,
+        // FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity
+        rustc_align,
         rustc_allocator,
         rustc_allocator_zeroed,
         rustc_allow_const_fn_unstable,
diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs
index 65f3f05d6cb..578641e910d 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: lifetime flowing from input to output with different syntax
+        //~^ ERROR: eliding a lifetime that's named elsewhere is confusing
         todo!()
     }
 }
diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr
index 600343754e1..fd9ceddfe11 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.stderr
+++ b/src/tools/clippy/tests/ui/ptr_arg.stderr
@@ -231,18 +231,19 @@ 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 can be confusing
+error: eliding a lifetime that's named elsewhere is confusing
   --> tests/ui/ptr_arg.rs:314:36
    |
 LL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {
-   |                                    ^^     ^^           ---- the lifetime gets resolved as `'a`
+   |                                    ^^     ^^           ---- the same lifetime is elided here
    |                                    |      |
-   |                                    |      these lifetimes flow to the output
-   |                                    these lifetimes flow to the output
+   |                                    |      the lifetime is named here
+   |                                    the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
    = 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`
+help: consistently use `'a`
    |
 LL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &'a str {
    |                                                         ++
diff --git a/src/tools/miri/tests/pass/fn_align.rs b/src/tools/miri/tests/pass/fn_align.rs
index 28f92995880..9752d033458 100644
--- a/src/tools/miri/tests/pass/fn_align.rs
+++ b/src/tools/miri/tests/pass/fn_align.rs
@@ -1,15 +1,19 @@
 //@compile-flags: -Zmin-function-alignment=8
+
+// FIXME(rust-lang/rust#82232, rust-lang/rust#143834): temporarily renamed to mitigate `#[align]`
+// nameres ambiguity
+#![feature(rustc_attrs)]
 #![feature(fn_align)]
 
 // When a function uses `align(N)`, the function address should be a multiple of `N`.
 
-#[align(256)]
+#[rustc_align(256)]
 fn foo() {}
 
-#[align(16)]
+#[rustc_align(16)]
 fn bar() {}
 
-#[align(4)]
+#[rustc_align(4)]
 fn baz() {}
 
 fn main() {
diff --git a/tests/assembly/naked-functions/wasm32.rs b/tests/assembly/naked-functions/wasm32.rs
index 5f114246ad5..66f746613a6 100644
--- a/tests/assembly/naked-functions/wasm32.rs
+++ b/tests/assembly/naked-functions/wasm32.rs
@@ -9,6 +9,8 @@
 //@ [wasm32-wasip1] needs-llvm-components: webassembly
 
 #![crate_type = "lib"]
+// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+#![feature(rustc_attrs)]
 #![feature(no_core, asm_experimental_arch, f128, linkage, fn_align)]
 #![no_core]
 
@@ -37,7 +39,7 @@ extern "C" fn nop() {
 #[unsafe(naked)]
 #[linkage = "weak"]
 // wasm functions cannot be aligned, so this has no effect
-#[align(32)]
+#[rustc_align(32)]
 extern "C" fn weak_aligned_nop() {
     naked_asm!("nop")
 }
diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs
index 267da060240..f30b63f96d5 100644
--- a/tests/codegen/align-fn.rs
+++ b/tests/codegen/align-fn.rs
@@ -1,11 +1,13 @@
 //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0
 
 #![crate_type = "lib"]
+// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+#![feature(rustc_attrs)]
 #![feature(fn_align)]
 
 // CHECK: align 16
 #[no_mangle]
-#[align(16)]
+#[rustc_align(16)]
 pub fn fn_align() {}
 
 pub struct A;
@@ -13,12 +15,12 @@ pub struct A;
 impl A {
     // CHECK: align 16
     #[no_mangle]
-    #[align(16)]
+    #[rustc_align(16)]
     pub fn method_align(self) {}
 
     // CHECK: align 16
     #[no_mangle]
-    #[align(16)]
+    #[rustc_align(16)]
     pub fn associated_fn() {}
 }
 
@@ -26,19 +28,19 @@ trait T: Sized {
     fn trait_fn() {}
 
     // CHECK: align 32
-    #[align(32)]
+    #[rustc_align(32)]
     fn trait_method(self) {}
 }
 
 impl T for A {
     // CHECK: align 16
     #[no_mangle]
-    #[align(16)]
+    #[rustc_align(16)]
     fn trait_fn() {}
 
     // CHECK: align 16
     #[no_mangle]
-    #[align(16)]
+    #[rustc_align(16)]
     fn trait_method(self) {}
 }
 
@@ -51,20 +53,20 @@ pub fn foo() {
 // CHECK-LABEL: align_specified_twice_1
 // CHECK-SAME: align 64
 #[no_mangle]
-#[align(32)]
-#[align(64)]
+#[rustc_align(32)]
+#[rustc_align(64)]
 pub fn align_specified_twice_1() {}
 
 // CHECK-LABEL: align_specified_twice_2
 // CHECK-SAME: align 128
 #[no_mangle]
-#[align(128)]
-#[align(32)]
+#[rustc_align(128)]
+#[rustc_align(32)]
 pub fn align_specified_twice_2() {}
 
 // CHECK-LABEL: align_specified_twice_3
 // CHECK-SAME: align 256
 #[no_mangle]
-#[align(32)]
-#[align(256)]
+#[rustc_align(32)]
+#[rustc_align(256)]
 pub fn align_specified_twice_3() {}
diff --git a/tests/codegen/min-function-alignment.rs b/tests/codegen/min-function-alignment.rs
index 75f845572a4..8ae2614e23e 100644
--- a/tests/codegen/min-function-alignment.rs
+++ b/tests/codegen/min-function-alignment.rs
@@ -4,6 +4,8 @@
 //@ [align1024] compile-flags: -Zmin-function-alignment=1024
 
 #![crate_type = "lib"]
+// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+#![feature(rustc_attrs)]
 #![feature(fn_align)]
 
 // functions without explicit alignment use the global minimum
@@ -18,7 +20,7 @@ pub fn no_explicit_align() {}
 // align16: align 16
 // align1024: align 1024
 #[no_mangle]
-#[align(8)]
+#[rustc_align(8)]
 pub fn lower_align() {}
 
 // the higher value of min-function-alignment and the align attribute wins out
@@ -27,7 +29,7 @@ pub fn lower_align() {}
 // align16: align 32
 // align1024: align 1024
 #[no_mangle]
-#[align(32)]
+#[rustc_align(32)]
 pub fn higher_align() {}
 
 // cold functions follow the same rules as other functions
diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs
index f9fce8e5a5d..5b542043718 100644
--- a/tests/codegen/naked-fn/aligned.rs
+++ b/tests/codegen/naked-fn/aligned.rs
@@ -3,12 +3,15 @@
 //@ ignore-arm no "ret" mnemonic
 
 #![crate_type = "lib"]
+// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+#![feature(rustc_attrs)]
 #![feature(fn_align)]
+
 use std::arch::naked_asm;
 
 // CHECK: .balign 16
 // CHECK-LABEL: naked_empty:
-#[align(16)]
+#[rustc_align(16)]
 #[no_mangle]
 #[unsafe(naked)]
 pub extern "C" fn naked_empty() {
diff --git a/tests/codegen/naked-fn/min-function-alignment.rs b/tests/codegen/naked-fn/min-function-alignment.rs
index 59554c1cae5..2db5b73cba4 100644
--- a/tests/codegen/naked-fn/min-function-alignment.rs
+++ b/tests/codegen/naked-fn/min-function-alignment.rs
@@ -2,6 +2,8 @@
 //@ needs-asm-support
 //@ ignore-arm no "ret" mnemonic
 
+// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+#![feature(rustc_attrs)]
 #![feature(fn_align)]
 #![crate_type = "lib"]
 
@@ -16,7 +18,7 @@ pub extern "C" fn naked_no_explicit_align() {
 
 // CHECK: .balign 16
 #[no_mangle]
-#[align(8)]
+#[rustc_align(8)]
 #[unsafe(naked)]
 pub extern "C" fn naked_lower_align() {
     core::arch::naked_asm!("ret")
@@ -24,7 +26,7 @@ pub extern "C" fn naked_lower_align() {
 
 // CHECK: .balign 32
 #[no_mangle]
-#[align(32)]
+#[rustc_align(32)]
 #[unsafe(naked)]
 pub extern "C" fn naked_higher_align() {
     core::arch::naked_asm!("ret")
diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.rs b/tests/ui/asm/naked-with-invalid-repr-attr.rs
index bfbbf29a69e..4620d007e4e 100644
--- a/tests/ui/asm/naked-with-invalid-repr-attr.rs
+++ b/tests/ui/asm/naked-with-invalid-repr-attr.rs
@@ -1,5 +1,9 @@
 //@ needs-asm-support
+
+// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+#![feature(rustc_attrs)]
 #![feature(fn_align)]
+
 #![crate_type = "lib"]
 use std::arch::naked_asm;
 
@@ -21,7 +25,7 @@ extern "C" fn example2() {
 
 #[repr(C)]
 //~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
-#[align(16)]
+#[rustc_align(16)]
 #[unsafe(naked)]
 extern "C" fn example3() {
     //~^ NOTE not a struct, enum, or union
diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.stderr b/tests/ui/asm/naked-with-invalid-repr-attr.stderr
index 4eb4a4e5a04..8530495be66 100644
--- a/tests/ui/asm/naked-with-invalid-repr-attr.stderr
+++ b/tests/ui/asm/naked-with-invalid-repr-attr.stderr
@@ -1,5 +1,5 @@
 error[E0517]: attribute should be applied to a struct, enum, or union
-  --> $DIR/naked-with-invalid-repr-attr.rs:6:8
+  --> $DIR/naked-with-invalid-repr-attr.rs:10:8
    |
 LL |   #[repr(C)]
    |          ^
@@ -11,7 +11,7 @@ LL | | }
    | |_- not a struct, enum, or union
 
 error[E0517]: attribute should be applied to a struct, enum, or union
-  --> $DIR/naked-with-invalid-repr-attr.rs:14:8
+  --> $DIR/naked-with-invalid-repr-attr.rs:18:8
    |
 LL |   #[repr(transparent)]
    |          ^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL | | }
    | |_- not a struct, enum, or union
 
 error[E0517]: attribute should be applied to a struct, enum, or union
-  --> $DIR/naked-with-invalid-repr-attr.rs:22:8
+  --> $DIR/naked-with-invalid-repr-attr.rs:26:8
    |
 LL |   #[repr(C)]
    |          ^
@@ -35,7 +35,7 @@ LL | | }
    | |_- not a struct, enum, or union
 
 error[E0517]: attribute should be applied to a struct, enum, or union
-  --> $DIR/naked-with-invalid-repr-attr.rs:32:8
+  --> $DIR/naked-with-invalid-repr-attr.rs:36:8
    |
 LL |   #[repr(C, packed)]
    |          ^
@@ -48,7 +48,7 @@ LL | | }
    | |_- not a struct, enum, or union
 
 error[E0517]: attribute should be applied to a struct or union
-  --> $DIR/naked-with-invalid-repr-attr.rs:32:11
+  --> $DIR/naked-with-invalid-repr-attr.rs:36:11
    |
 LL |   #[repr(C, packed)]
    |             ^^^^^^
@@ -61,7 +61,7 @@ LL | | }
    | |_- not a struct or union
 
 error[E0517]: attribute should be applied to an enum
-  --> $DIR/naked-with-invalid-repr-attr.rs:42:8
+  --> $DIR/naked-with-invalid-repr-attr.rs:46:8
    |
 LL |   #[repr(u8)]
    |          ^^
diff --git a/tests/ui/attributes/fn-align-nameres-ambiguity-143834.rs b/tests/ui/attributes/fn-align-nameres-ambiguity-143834.rs
new file mode 100644
index 00000000000..536d6ff43fb
--- /dev/null
+++ b/tests/ui/attributes/fn-align-nameres-ambiguity-143834.rs
@@ -0,0 +1,19 @@
+// Anti-regression test to demonstrate that at least we mitigated breakage from adding a new
+// `#[align]` built-in attribute.
+//
+// See https://github.com/rust-lang/rust/issues/143834.
+
+//@ check-pass
+
+// Needs edition >= 2018 macro use behavior.
+//@ edition: 2018
+
+macro_rules! align {
+    () => {
+        /* .. */
+    };
+}
+
+pub(crate) use align;
+
+fn main() {}
diff --git a/tests/ui/attributes/malformed-fn-align.rs b/tests/ui/attributes/malformed-fn-align.rs
index f5ab9555e56..da5284fd4bd 100644
--- a/tests/ui/attributes/malformed-fn-align.rs
+++ b/tests/ui/attributes/malformed-fn-align.rs
@@ -1,25 +1,30 @@
+// ignore-tidy-linelength
+
+// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+#![feature(rustc_attrs)]
 #![feature(fn_align)]
+
 #![crate_type = "lib"]
 
 trait MyTrait {
-    #[align] //~ ERROR malformed `align` attribute input
+    #[rustc_align] //~ ERROR malformed `rustc_align` attribute input
     fn myfun1();
 
-    #[align(1, 2)] //~ ERROR malformed `align` attribute input
+    #[rustc_align(1, 2)] //~ ERROR malformed `rustc_align` attribute input
     fn myfun2();
 }
 
-#[align = 16] //~ ERROR malformed `align` attribute input
+#[rustc_align = 16] //~ ERROR malformed `rustc_align` attribute input
 fn f1() {}
 
-#[align("hello")] //~ ERROR invalid alignment value: not an unsuffixed integer
+#[rustc_align("hello")] //~ ERROR invalid alignment value: not an unsuffixed integer
 fn f2() {}
 
-#[align(0)] //~ ERROR invalid alignment value: not a power of two
+#[rustc_align(0)] //~ ERROR invalid alignment value: not a power of two
 fn f3() {}
 
 #[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on function items
 fn f4() {}
 
-#[align(16)] //~ ERROR `#[align(...)]` is not supported on struct items
+#[rustc_align(16)] //~ ERROR `#[rustc_align(...)]` is not supported on struct items
 struct S1;
diff --git a/tests/ui/attributes/malformed-fn-align.stderr b/tests/ui/attributes/malformed-fn-align.stderr
index b769d0b457d..c5986efaa34 100644
--- a/tests/ui/attributes/malformed-fn-align.stderr
+++ b/tests/ui/attributes/malformed-fn-align.stderr
@@ -1,63 +1,63 @@
-error[E0539]: malformed `align` attribute input
-  --> $DIR/malformed-fn-align.rs:5:5
+error[E0539]: malformed `rustc_align` attribute input
+  --> $DIR/malformed-fn-align.rs:10:5
    |
-LL |     #[align]
-   |     ^^^^^^^^
+LL |     #[rustc_align]
+   |     ^^^^^^^^^^^^^^
    |     |
    |     expected this to be a list
-   |     help: must be of the form: `#[align(<alignment in bytes>)]`
+   |     help: must be of the form: `#[rustc_align(<alignment in bytes>)]`
 
-error[E0805]: malformed `align` attribute input
-  --> $DIR/malformed-fn-align.rs:8:5
+error[E0805]: malformed `rustc_align` attribute input
+  --> $DIR/malformed-fn-align.rs:13:5
    |
-LL |     #[align(1, 2)]
-   |     ^^^^^^^------^
-   |     |      |
-   |     |      expected a single argument here
-   |     help: must be of the form: `#[align(<alignment in bytes>)]`
+LL |     #[rustc_align(1, 2)]
+   |     ^^^^^^^^^^^^^------^
+   |     |            |
+   |     |            expected a single argument here
+   |     help: must be of the form: `#[rustc_align(<alignment in bytes>)]`
 
-error[E0539]: malformed `align` attribute input
-  --> $DIR/malformed-fn-align.rs:12:1
+error[E0539]: malformed `rustc_align` attribute input
+  --> $DIR/malformed-fn-align.rs:17:1
    |
-LL | #[align = 16]
-   | ^^^^^^^^^^^^^
+LL | #[rustc_align = 16]
+   | ^^^^^^^^^^^^^^^^^^^
    | |
    | expected this to be a list
-   | help: must be of the form: `#[align(<alignment in bytes>)]`
+   | help: must be of the form: `#[rustc_align(<alignment in bytes>)]`
 
 error[E0589]: invalid alignment value: not an unsuffixed integer
-  --> $DIR/malformed-fn-align.rs:15:9
+  --> $DIR/malformed-fn-align.rs:20:15
    |
-LL | #[align("hello")]
-   |         ^^^^^^^
+LL | #[rustc_align("hello")]
+   |               ^^^^^^^
 
 error[E0589]: invalid alignment value: not a power of two
-  --> $DIR/malformed-fn-align.rs:18:9
+  --> $DIR/malformed-fn-align.rs:23:15
    |
-LL | #[align(0)]
-   |         ^
+LL | #[rustc_align(0)]
+   |               ^
 
 error: `#[repr(align(...))]` is not supported on function items
-  --> $DIR/malformed-fn-align.rs:21:8
+  --> $DIR/malformed-fn-align.rs:26:8
    |
 LL | #[repr(align(16))]
    |        ^^^^^^^^^
    |
-help: use `#[align(...)]` instead
-  --> $DIR/malformed-fn-align.rs:21:8
+help: use `#[rustc_align(...)]` instead
+  --> $DIR/malformed-fn-align.rs:26:8
    |
 LL | #[repr(align(16))]
    |        ^^^^^^^^^
 
-error: `#[align(...)]` is not supported on struct items
-  --> $DIR/malformed-fn-align.rs:24:1
+error: `#[rustc_align(...)]` is not supported on struct items
+  --> $DIR/malformed-fn-align.rs:29:1
    |
-LL | #[align(16)]
-   | ^^^^^^^^^^^^
+LL | #[rustc_align(16)]
+   | ^^^^^^^^^^^^^^^^^^
    |
 help: use `#[repr(align(...))]` instead
    |
-LL - #[align(16)]
+LL - #[rustc_align(16)]
 LL + #[repr(align(16))]
    |
 
diff --git a/tests/ui/cfg/crt-static-with-target-features-works.rs b/tests/ui/cfg/crt-static-with-target-features-works.rs
new file mode 100644
index 00000000000..bce02229624
--- /dev/null
+++ b/tests/ui/cfg/crt-static-with-target-features-works.rs
@@ -0,0 +1,24 @@
+// Test to ensure that specifying a value for crt-static in target features
+// does not result in skipping the features following it.
+// This is a regression test for #144143
+
+//@ add-core-stubs
+//@ needs-llvm-components: x86
+//@ compile-flags: --target=x86_64-unknown-linux-gnu
+//@ compile-flags: -Ctarget-feature=+crt-static,+avx2
+
+#![crate_type = "rlib"]
+#![feature(no_core, rustc_attrs, lang_items)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+#[rustc_builtin_macro]
+macro_rules! compile_error {
+    () => {};
+}
+
+#[cfg(target_feature = "avx2")]
+compile_error!("+avx2");
+//~^ ERROR: +avx2
diff --git a/tests/ui/cfg/crt-static-with-target-features-works.stderr b/tests/ui/cfg/crt-static-with-target-features-works.stderr
new file mode 100644
index 00000000000..6f265c685bb
--- /dev/null
+++ b/tests/ui/cfg/crt-static-with-target-features-works.stderr
@@ -0,0 +1,8 @@
+error: +avx2
+  --> $DIR/crt-static-with-target-features-works.rs:23:1
+   |
+LL | compile_error!("+avx2");
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
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 f68fdb3b651..32fa46b92b3 100644
--- a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
+++ b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
@@ -1,14 +1,15 @@
-warning: lifetime flowing from input to output with different syntax can be confusing
+warning: hiding a lifetime that's named elsewhere is confusing
   --> $DIR/issue-71348.rs:18:40
    |
 LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
-   |                                        ^^           -- ------------------------ the lifetimes get resolved as `'a`
+   |                                        ^^           -- ------------------------ the same lifetime is hidden here
    |                                        |            |
-   |                                        |            the lifetimes get resolved as `'a`
-   |                                        this lifetime flows to the output
+   |                                        |            the same lifetime is named here
+   |                                        the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
    = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
-help: one option is to consistently use `'a`
+help: consistently use `'a`
    |
 LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<'a, N>>::Target
    |                                                                     +++
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.rs b/tests/ui/const-generics/type-dependent/issue-71348.rs
index c6563c80305..9053f362ce4 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 <Self as Get<N>>::Target
     //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter
-    //[full]~^^ WARNING lifetime flowing from input to output with different syntax
+    //[full]~^^ WARNING hiding a lifetime that's named elsewhere is confusing
     where
         Self: Get<'a, N>,
     {
diff --git a/tests/ui/feature-gates/feature-gate-fn_align.rs b/tests/ui/feature-gates/feature-gate-fn_align.rs
index b6c300e5cbe..36e17c4a8dd 100644
--- a/tests/ui/feature-gates/feature-gate-fn_align.rs
+++ b/tests/ui/feature-gates/feature-gate-fn_align.rs
@@ -1,12 +1,16 @@
 #![crate_type = "lib"]
 
-#[align(16)]
-//~^ ERROR the `#[align]` attribute is an experimental feature
+// ignore-tidy-linelength
+
+// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
+
+#[rustc_align(16)]
+//~^ ERROR the `#[rustc_align]` attribute is an experimental feature
 fn requires_alignment() {}
 
 trait MyTrait {
-    #[align]
-    //~^ ERROR the `#[align]` attribute is an experimental feature
-    //~| ERROR malformed `align` attribute input
+    #[rustc_align]
+    //~^ ERROR the `#[rustc_align]` attribute is an experimental feature
+    //~| ERROR malformed `rustc_align` attribute input
     fn myfun();
 }
diff --git a/tests/ui/feature-gates/feature-gate-fn_align.stderr b/tests/ui/feature-gates/feature-gate-fn_align.stderr
index 921cf08435c..6196f4f298f 100644
--- a/tests/ui/feature-gates/feature-gate-fn_align.stderr
+++ b/tests/ui/feature-gates/feature-gate-fn_align.stderr
@@ -1,31 +1,31 @@
-error[E0658]: the `#[align]` attribute is an experimental feature
-  --> $DIR/feature-gate-fn_align.rs:3:1
+error[E0658]: the `#[rustc_align]` attribute is an experimental feature
+  --> $DIR/feature-gate-fn_align.rs:7:1
    |
-LL | #[align(16)]
-   | ^^^^^^^^^^^^
+LL | #[rustc_align(16)]
+   | ^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #82232 <https://github.com/rust-lang/rust/issues/82232> for more information
    = help: add `#![feature(fn_align)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: the `#[align]` attribute is an experimental feature
-  --> $DIR/feature-gate-fn_align.rs:8:5
+error[E0658]: the `#[rustc_align]` attribute is an experimental feature
+  --> $DIR/feature-gate-fn_align.rs:12:5
    |
-LL |     #[align]
-   |     ^^^^^^^^
+LL |     #[rustc_align]
+   |     ^^^^^^^^^^^^^^
    |
    = note: see issue #82232 <https://github.com/rust-lang/rust/issues/82232> for more information
    = help: add `#![feature(fn_align)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0539]: malformed `align` attribute input
-  --> $DIR/feature-gate-fn_align.rs:8:5
+error[E0539]: malformed `rustc_align` attribute input
+  --> $DIR/feature-gate-fn_align.rs:12:5
    |
-LL |     #[align]
-   |     ^^^^^^^^
+LL |     #[rustc_align]
+   |     ^^^^^^^^^^^^^^
    |     |
    |     expected this to be a list
-   |     help: must be of the form: `#[align(<alignment in bytes>)]`
+   |     help: must be of the form: `#[rustc_align(<alignment in bytes>)]`
 
 error: aborting due to 3 previous errors
 
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 1ac3c593dbe..1b8a5d4ca99 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<Item = (u32, &u32)> {
-    //~^ WARNING lifetime flowing from input to output with different syntax
+    //~^ WARNING eliding a lifetime that's named elsewhere is confusing
     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 b9d8674992c..3651226e0c3 100644
--- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
+++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
@@ -1,11 +1,12 @@
-warning: lifetime flowing from input to output with different syntax can be confusing
+warning: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/rpit-assoc-pair-with-lifetime.rs:3:31
    |
 LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &u32)> {
-   |                               ^^ this lifetime flows to the output               ---- the lifetime gets resolved as `'a`
+   |                               ^^ the lifetime is named here                      ---- the same lifetime is elided here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
    = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
-help: one option is to consistently use `'a`
+help: consistently use `'a`
    |
 LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &'a u32)> {
    |                                                                                   ++
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs
index 1804003d367..9162a38f510 100644
--- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs
@@ -4,7 +4,7 @@ struct Foo;
 
 impl Foo {
     pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         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
index 7c7411651d0..5a7a5a6ebf9 100644
--- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr
@@ -1,17 +1,18 @@
-error: lifetime flowing from input to output with different syntax can be confusing
+error: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/example-from-issue48686.rs:6:21
    |
 LL |     pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
-   |                     ^^^^^^^                      ------- the lifetime gets resolved as `'static`
+   |                     ^^^^^^^                      ------- the same lifetime is elided here
    |                     |
-   |                     this lifetime flows to the output
+   |                     the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
 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`
+help: consistently use `'static`
    |
 LL |     pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 {
    |                                                   +++++++
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
index 3d5aab5c829..ecc790be5a0 100644
--- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs
@@ -1,26 +1,26 @@
 #![deny(mismatched_lifetime_syntaxes)]
 
 fn ampersand<'a>(x: &'a u8) -> &u8 {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     x
 }
 
 struct Brackets<'a>(&'a u8);
 
 fn brackets<'a>(x: &'a u8) -> Brackets {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's named elsewhere is confusing
     Brackets(x)
 }
 
 struct Comma<'a, T>(&'a T);
 
 fn comma<'a>(x: &'a u8) -> Comma<u8> {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's named elsewhere is confusing
     Comma(x)
 }
 
 fn underscore<'a>(x: &'a u8) -> &'_ u8 {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     x
 }
 
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
index 681b3c97052..af56a0a0ea5 100644
--- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr
@@ -1,56 +1,60 @@
-error: lifetime flowing from input to output with different syntax can be confusing
+error: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/missing-lifetime-kind.rs:3:22
    |
 LL | fn ampersand<'a>(x: &'a u8) -> &u8 {
-   |                      ^^        --- the lifetime gets resolved as `'a`
+   |                      ^^        --- the same lifetime is elided here
    |                      |
-   |                      this lifetime flows to the output
+   |                      the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
 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`
+help: consistently use `'a`
    |
 LL | fn ampersand<'a>(x: &'a u8) -> &'a u8 {
    |                                 ++
 
-error: lifetime flowing from input to output with different syntax can be confusing
+error: hiding a lifetime that's named elsewhere is confusing
   --> $DIR/missing-lifetime-kind.rs:10:21
    |
 LL | fn brackets<'a>(x: &'a u8) -> Brackets {
-   |                     ^^        -------- the lifetime gets resolved as `'a`
+   |                     ^^        -------- the same lifetime is hidden here
    |                     |
-   |                     this lifetime flows to the output
+   |                     the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL | fn brackets<'a>(x: &'a u8) -> Brackets<'a> {
    |                                       ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
+error: hiding a lifetime that's named elsewhere is confusing
   --> $DIR/missing-lifetime-kind.rs:17:18
    |
 LL | fn comma<'a>(x: &'a u8) -> Comma<u8> {
-   |                  ^^        --------- the lifetime gets resolved as `'a`
+   |                  ^^        --------- the same lifetime is hidden here
    |                  |
-   |                  this lifetime flows to the output
+   |                  the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL | fn comma<'a>(x: &'a u8) -> Comma<'a, u8> {
    |                                  +++
 
-error: lifetime flowing from input to output with different syntax can be confusing
+error: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/missing-lifetime-kind.rs:22:23
    |
 LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 {
-   |                       ^^         -- the lifetime gets resolved as `'a`
+   |                       ^^         -- the same lifetime is elided here
    |                       |
-   |                       this lifetime flows to the output
+   |                       the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL - fn underscore<'a>(x: &'a u8) -> &'_ u8 {
 LL + fn underscore<'a>(x: &'a u8) -> &'a u8 {
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
index cc398ab7888..449b2a3c0a8 100644
--- 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
@@ -6,13 +6,13 @@
 #[warn(mismatched_lifetime_syntaxes)]
 mod foo {
     fn bar(x: &'static u8) -> &u8 {
-        //~^ WARNING lifetime flowing from input to output with different syntax
+        //~^ WARNING eliding a lifetime that's named elsewhere is confusing
         x
     }
 
     #[deny(mismatched_lifetime_syntaxes)]
     fn baz(x: &'static u8) -> &u8 {
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         x
     }
 }
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
index da691225c17..cf0a29678fa 100644
--- 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
@@ -1,35 +1,37 @@
-warning: lifetime flowing from input to output with different syntax can be confusing
+warning: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/not-tied-to-crate.rs:8:16
    |
 LL |     fn bar(x: &'static u8) -> &u8 {
-   |                ^^^^^^^        --- the lifetime gets resolved as `'static`
+   |                ^^^^^^^        --- the same lifetime is elided here
    |                |
-   |                this lifetime flows to the output
+   |                the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
 note: the lint level is defined here
   --> $DIR/not-tied-to-crate.rs:6:8
    |
 LL | #[warn(mismatched_lifetime_syntaxes)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: one option is to consistently use `'static`
+help: consistently use `'static`
    |
 LL |     fn bar(x: &'static u8) -> &'static u8 {
    |                                +++++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
+error: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/not-tied-to-crate.rs:14:16
    |
 LL |     fn baz(x: &'static u8) -> &u8 {
-   |                ^^^^^^^        --- the lifetime gets resolved as `'static`
+   |                ^^^^^^^        --- the same lifetime is elided here
    |                |
-   |                this lifetime flows to the output
+   |                the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
 note: the lint level is defined here
   --> $DIR/not-tied-to-crate.rs:13:12
    |
 LL |     #[deny(mismatched_lifetime_syntaxes)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: one option is to consistently use `'static`
+help: consistently use `'static`
    |
 LL |     fn baz(x: &'static u8) -> &'static u8 {
    |                                +++++++
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs
index 47ae258f138..c41cf44e1c5 100644
--- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs
@@ -14,26 +14,26 @@ impl Trait for () {
 }
 
 fn ampersand(x: &'static u8) -> &u8 {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     x
 }
 
 struct Brackets<'a>(&'a u8);
 
 fn brackets(x: &'static u8) -> Brackets {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's named elsewhere is confusing
     Brackets(x)
 }
 
 struct Comma<'a, T>(&'a T);
 
 fn comma(x: &'static u8) -> Comma<u8> {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's named elsewhere is confusing
     Comma(x)
 }
 
 fn underscore(x: &'static u8) -> &'_ u8 {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     x
 }
 
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr
index 5b9a986bcbe..d60bec6f7e4 100644
--- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr
@@ -1,56 +1,60 @@
-error: lifetime flowing from input to output with different syntax can be confusing
+error: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/static.rs:16:18
    |
 LL | fn ampersand(x: &'static u8) -> &u8 {
-   |                  ^^^^^^^        --- the lifetime gets resolved as `'static`
+   |                  ^^^^^^^        --- the same lifetime is elided here
    |                  |
-   |                  this lifetime flows to the output
+   |                  the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
 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`
+help: consistently use `'static`
    |
 LL | fn ampersand(x: &'static u8) -> &'static u8 {
    |                                  +++++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
+error: hiding a lifetime that's named elsewhere is confusing
   --> $DIR/static.rs:23:17
    |
 LL | fn brackets(x: &'static u8) -> Brackets {
-   |                 ^^^^^^^        -------- the lifetime gets resolved as `'static`
+   |                 ^^^^^^^        -------- the same lifetime is hidden here
    |                 |
-   |                 this lifetime flows to the output
+   |                 the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'static`
    |
 LL | fn brackets(x: &'static u8) -> Brackets<'static> {
    |                                        +++++++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
+error: hiding a lifetime that's named elsewhere is confusing
   --> $DIR/static.rs:30:14
    |
 LL | fn comma(x: &'static u8) -> Comma<u8> {
-   |              ^^^^^^^        --------- the lifetime gets resolved as `'static`
+   |              ^^^^^^^        --------- the same lifetime is hidden here
    |              |
-   |              this lifetime flows to the output
+   |              the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'static`
    |
 LL | fn comma(x: &'static u8) -> Comma<'static, u8> {
    |                                   ++++++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
+error: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/static.rs:35:19
    |
 LL | fn underscore(x: &'static u8) -> &'_ u8 {
-   |                   ^^^^^^^         -- the lifetime gets resolved as `'static`
+   |                   ^^^^^^^         -- the same lifetime is elided here
    |                   |
-   |                   this lifetime flows to the output
+   |                   the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'static`
    |
 LL - fn underscore(x: &'static u8) -> &'_ u8 {
 LL + fn underscore(x: &'static u8) -> &'static u8 {
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs
index b98423afb17..f6260c47202 100644
--- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs
@@ -5,109 +5,111 @@ struct ContainsLifetime<'a>(&'a u8);
 
 struct S(u8);
 
+// ref to ref
+
 fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &u8 {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     v
 }
 
 fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     v
 }
 
-// ---
+// path to path
 
 fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime) -> ContainsLifetime<'_> {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
     v
 }
 
 fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
     v
 }
 
 fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's named elsewhere is confusing
     v
 }
 
 fn explicit_bound_path_to_explicit_anonymous_path<'a>(
     v: ContainsLifetime<'a>,
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
 ) -> ContainsLifetime<'_> {
     v
 }
 
-// ---
+// ref to path
 
 fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
     ContainsLifetime(v)
 }
 
 fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
     ContainsLifetime(v)
 }
 
 fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's named elsewhere is confusing
     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
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     ContainsLifetime(v)
 }
 
-// ---
+// path to ref
 
 fn implicit_path_to_implicit_ref(v: ContainsLifetime) -> &u8 {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
     v.0
 }
 
 fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
     v.0
 }
 
 fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &u8 {
-    //~^ ERROR lifetime flowing from input to output with different syntax
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     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
+    //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     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
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         &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
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         &self.0
     }
 
     // ---
 
     fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime {
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
         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
+        //~^ ERROR hiding a lifetime that's named elsewhere is confusing
         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
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         ContainsLifetime(&self.0)
     }
 }
@@ -122,43 +124,43 @@ mod static_suggestions {
     struct S(u8);
 
     fn static_ref_to_implicit_ref(v: &'static u8) -> &u8 {
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         v
     }
 
     fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 {
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         v
     }
 
     fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime {
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR hiding a lifetime that's named elsewhere is confusing
         ContainsLifetime(v)
     }
 
     fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> {
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         ContainsLifetime(v)
     }
 
     impl S {
         fn static_ref_to_implicit_ref(&'static self) -> &u8 {
-            //~^ ERROR lifetime flowing from input to output with different syntax
+            //~^ ERROR eliding a lifetime that's named elsewhere is confusing
             &self.0
         }
 
         fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 {
-            //~^ ERROR lifetime flowing from input to output with different syntax
+            //~^ ERROR eliding a lifetime that's named elsewhere is confusing
             &self.0
         }
 
         fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime {
-            //~^ ERROR lifetime flowing from input to output with different syntax
+            //~^ ERROR hiding a lifetime that's named elsewhere is confusing
             ContainsLifetime(&self.0)
         }
 
         fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> {
-            //~^ ERROR lifetime flowing from input to output with different syntax
+            //~^ ERROR eliding a lifetime that's named elsewhere is confusing
             ContainsLifetime(&self.0)
         }
     }
@@ -170,23 +172,23 @@ mod impl_trait {
     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
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         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
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         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
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         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
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
     ) -> impl FnOnce() + use<'_> {
         move || _ = v
     }
@@ -200,13 +202,13 @@ mod dyn_trait {
     struct ContainsLifetime<'a>(&'a u8);
 
     fn explicit_bound_ref_to_dyn_trait_bound<'a>(v: &'a u8) -> Box<dyn Iterator<Item = &u8> + '_> {
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         Box::new(iter::once(v))
     }
 
     fn explicit_bound_path_to_dyn_trait_bound<'a>(
         v: ContainsLifetime<'a>,
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR hiding a lifetime that's named elsewhere is confusing
     ) -> Box<dyn Iterator<Item = ContainsLifetime> + '_> {
         Box::new(iter::once(v))
     }
@@ -214,10 +216,28 @@ mod dyn_trait {
 
 /// These tests serve to exercise edge cases of the lint formatting
 mod diagnostic_output {
+    #[derive(Copy, Clone)]
+    struct ContainsLifetime<'a>(&'a u8);
+
+    fn multiple_inputs<'a>(v: (&'a u8, &'a u8)) -> &u8 {
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
+        v.0
+    }
+
     fn multiple_outputs<'a>(v: &'a u8) -> (&u8, &u8) {
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
         (v, v)
     }
+
+    fn all_three_categories<'a>(v: ContainsLifetime<'a>) -> (&u8, ContainsLifetime) {
+        //~^ ERROR hiding or eliding a lifetime that's named elsewhere is confusing
+        (v.0, v)
+    }
+
+    fn explicit_bound_output<'a>(v: &'a u8) -> (&u8, &'a u8, ContainsLifetime<'a>) {
+        //~^ ERROR eliding a lifetime that's named elsewhere is confusing
+        (v, v, ContainsLifetime(v))
+    }
 }
 
 /// Trait functions are represented differently in the HIR. Make sure
@@ -228,20 +248,20 @@ mod trait_functions {
 
     trait TheTrait {
         fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime;
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
 
         fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime;
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
     }
 
     impl TheTrait for &u8 {
         fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime {
-            //~^ ERROR lifetime flowing from input to output with different syntax
+            //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
             ContainsLifetime(v)
         }
 
         fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime {
-            //~^ ERROR lifetime flowing from input to output with different syntax
+            //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
             ContainsLifetime(self)
         }
     }
@@ -255,7 +275,7 @@ mod foreign_functions {
 
     extern "Rust" {
         fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime;
-        //~^ ERROR lifetime flowing from input to output with different syntax
+        //~^ ERROR hiding a lifetime that's elided elsewhere is confusing
     }
 }
 
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr
index 108b3f14169..20b7561c594 100644
--- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr
@@ -1,538 +1,613 @@
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:8:47
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:10:47
    |
 LL | fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &u8 {
-   |                                               ^^        --- the lifetime gets resolved as `'a`
+   |                                               ^^        --- the same lifetime is elided here
    |                                               |
-   |                                               this lifetime flows to the output
+   |                                               the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
 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`
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:13:57
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:15:57
    |
 LL | fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 {
-   |                                                         ^^         -- the lifetime gets resolved as `'a`
+   |                                                         ^^         -- the same lifetime is elided here
    |                                                         |
-   |                                                         this lifetime flows to the output
+   |                                                         the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:20:48
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:22:48
    |
 LL | fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime) -> ContainsLifetime<'_> {
-   |                                                ^^^^^^^^^^^^^^^^                      -- the lifetime gets resolved as `'_`
+   |                                                ^^^^^^^^^^^^^^^^                      -- the same lifetime is elided here
    |                                                |
-   |                                                this lifetime flows to the output
+   |                                                the lifetime is hidden here
    |
-help: one option is to consistently use `'_`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'_`
    |
 LL | fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime<'_>) -> ContainsLifetime<'_> {
    |                                                                ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:25:65
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:27:65
    |
 LL | fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime {
-   |                                                                 ^^      ---------------- the lifetime gets resolved as `'_`
+   |                                                                 ^^      ---------------- the same lifetime is hidden here
    |                                                                 |
-   |                                                                 this lifetime flows to the output
+   |                                                                 the lifetime is elided here
    |
-help: one option is to consistently use `'_`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'_`
    |
 LL | fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime<'_> {
    |                                                                                         ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:30:65
+error: hiding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:32:65
    |
 LL | fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime {
-   |                                                                 ^^      ---------------- the lifetime gets resolved as `'a`
+   |                                                                 ^^      ---------------- the same lifetime is hidden here
    |                                                                 |
-   |                                                                 this lifetime flows to the output
+   |                                                                 the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:36:25
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:38:25
    |
 LL |     v: ContainsLifetime<'a>,
-   |                         ^^ this lifetime flows to the output
+   |                         ^^ the lifetime is named here
 LL |
 LL | ) -> ContainsLifetime<'_> {
-   |                       -- the lifetime gets resolved as `'a`
+   |                       -- the same lifetime is elided here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL - ) -> ContainsLifetime<'_> {
 LL + ) -> ContainsLifetime<'a> {
    |
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:44:37
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:46:37
    |
 LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime {
-   |                                     ^^^     ---------------- the lifetime gets resolved as `'_`
+   |                                     ^^^     ---------------- the same lifetime is hidden here
    |                                     |
-   |                                     this lifetime flows to the output
+   |                                     the lifetime is elided here
    |
-help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
 LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> {
    |                                                             ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:49:48
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:51:48
    |
 LL | fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime {
-   |                                                ^^        ---------------- the lifetime gets resolved as `'_`
+   |                                                ^^        ---------------- the same lifetime is hidden here
    |                                                |
-   |                                                this lifetime flows to the output
+   |                                                the lifetime is elided here
    |
-help: one option is to remove 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<'_> {
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
+LL | fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime<'_> {
+   |                                                                          ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:54:48
+error: hiding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:56:48
    |
 LL | fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime {
-   |                                                ^^        ---------------- the lifetime gets resolved as `'a`
+   |                                                ^^        ---------------- the same lifetime is hidden here
    |                                                |
-   |                                                this lifetime flows to the output
+   |                                                the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:59:58
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:61:58
    |
 LL | fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> {
-   |                                                          ^^                         -- the lifetime gets resolved as `'a`
+   |                                                          ^^                         -- the same lifetime is elided here
    |                                                          |
-   |                                                          this lifetime flows to the output
+   |                                                          the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:66:37
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:68:37
    |
 LL | fn implicit_path_to_implicit_ref(v: ContainsLifetime) -> &u8 {
-   |                                     ^^^^^^^^^^^^^^^^     --- the lifetime gets resolved as `'_`
+   |                                     ^^^^^^^^^^^^^^^^     --- the same lifetime is elided here
    |                                     |
-   |                                     this lifetime flows to the output
+   |                                     the lifetime is hidden here
    |
-help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
 LL | fn implicit_path_to_implicit_ref(v: ContainsLifetime<'_>) -> &u8 {
    |                                                     ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:71:47
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:73:47
    |
 LL | fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 {
-   |                                               ^^^^^^^^^^^^^^^^      -- the lifetime gets resolved as `'_`
+   |                                               ^^^^^^^^^^^^^^^^      -- the same lifetime is elided here
    |                                               |
-   |                                               this lifetime flows to the output
-   |
-help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   |                                               the lifetime is hidden here
    |
-LL - fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 {
-LL + fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime<'_>) -> &u8 {
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
+LL | fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime<'_>) -> &'_ u8 {
+   |                                                               ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:76:64
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:78:64
    |
 LL | fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &u8 {
-   |                                                                ^^      --- the lifetime gets resolved as `'a`
+   |                                                                ^^      --- the same lifetime is elided here
    |                                                                |
-   |                                                                this lifetime flows to the output
+   |                                                                the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:81:74
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:83:74
    |
 LL | fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 {
-   |                                                                          ^^       -- the lifetime gets resolved as `'a`
+   |                                                                          ^^       -- the same lifetime is elided here
    |                                                                          |
-   |                                                                          this lifetime flows to the output
+   |                                                                          the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:87:55
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:89:55
    |
 LL |     fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &u8 {
-   |                                                       ^^          --- the lifetime gets resolved as `'a`
+   |                                                       ^^          --- the same lifetime is elided here
    |                                                       |
-   |                                                       this lifetime flows to the output
+   |                                                       the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:92:65
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:94:65
    |
 LL |     fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 {
-   |                                                                 ^^           -- the lifetime gets resolved as `'a`
+   |                                                                 ^^           -- the same lifetime is elided here
    |                                                                 |
-   |                                                                 this lifetime flows to the output
+   |                                                                 the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:99:56
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:101:56
    |
 LL |     fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime {
-   |                                                        ^^          ---------------- the lifetime gets resolved as `'_`
+   |                                                        ^^          ---------------- the same lifetime is hidden here
    |                                                        |
-   |                                                        this lifetime flows to the output
+   |                                                        the lifetime is elided here
    |
-help: one option is to remove 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<'_> {
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
+LL |     fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime<'_> {
+   |                                                                                    ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:104:56
+error: hiding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:106:56
    |
 LL |     fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime {
-   |                                                        ^^          ---------------- the lifetime gets resolved as `'a`
+   |                                                        ^^          ---------------- the same lifetime is hidden here
    |                                                        |
-   |                                                        this lifetime flows to the output
+   |                                                        the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:109:66
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:111:66
    |
 LL |     fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> {
-   |                                                                  ^^                           -- the lifetime gets resolved as `'a`
+   |                                                                  ^^                           -- the same lifetime is elided here
    |                                                                  |
-   |                                                                  this lifetime flows to the output
+   |                                                                  the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:124:39
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:126:39
    |
 LL |     fn static_ref_to_implicit_ref(v: &'static u8) -> &u8 {
-   |                                       ^^^^^^^        --- the lifetime gets resolved as `'static`
+   |                                       ^^^^^^^        --- the same lifetime is elided here
    |                                       |
-   |                                       this lifetime flows to the output
+   |                                       the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:129:49
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:131:49
    |
 LL |     fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 {
-   |                                                 ^^^^^^^         -- the lifetime gets resolved as `'static`
+   |                                                 ^^^^^^^         -- the same lifetime is elided here
    |                                                 |
-   |                                                 this lifetime flows to the output
+   |                                                 the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:134:40
+error: hiding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:136:40
    |
 LL |     fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime {
-   |                                        ^^^^^^^        ---------------- the lifetime gets resolved as `'static`
+   |                                        ^^^^^^^        ---------------- the same lifetime is hidden here
    |                                        |
-   |                                        this lifetime flows to the output
+   |                                        the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:139:50
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:141:50
    |
 LL |     fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> {
-   |                                                  ^^^^^^^                         -- the lifetime gets resolved as `'static`
+   |                                                  ^^^^^^^                         -- the same lifetime is elided here
    |                                                  |
-   |                                                  this lifetime flows to the output
+   |                                                  the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:145:40
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:147:40
    |
 LL |         fn static_ref_to_implicit_ref(&'static self) -> &u8 {
-   |                                        ^^^^^^^          --- the lifetime gets resolved as `'static`
+   |                                        ^^^^^^^          --- the same lifetime is elided here
    |                                        |
-   |                                        this lifetime flows to the output
+   |                                        the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'static`
    |
 LL |         fn static_ref_to_implicit_ref(&'static self) -> &'static u8 {
    |                                                          +++++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:150:50
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:152:50
    |
 LL |         fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 {
-   |                                                  ^^^^^^^           -- the lifetime gets resolved as `'static`
+   |                                                  ^^^^^^^           -- the same lifetime is elided here
    |                                                  |
-   |                                                  this lifetime flows to the output
+   |                                                  the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:155:41
+error: hiding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:157:41
    |
 LL |         fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime {
-   |                                         ^^^^^^^          ---------------- the lifetime gets resolved as `'static`
+   |                                         ^^^^^^^          ---------------- the same lifetime is hidden here
    |                                         |
-   |                                         this lifetime flows to the output
+   |                                         the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'static`
    |
 LL |         fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime<'static> {
    |                                                                          +++++++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:160:51
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:162:51
    |
 LL |         fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> {
-   |                                                   ^^^^^^^                           -- the lifetime gets resolved as `'static`
+   |                                                   ^^^^^^^                           -- the same lifetime is elided here
    |                                                   |
-   |                                                   this lifetime flows to the output
+   |                                                   the lifetime is named here
    |
-help: one option is to consistently use `'static`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:172:55
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:174:55
    |
 LL |     fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ {
-   |                                                       ^^                        -- the lifetime gets resolved as `'a`
+   |                                                       ^^                        -- the same lifetime is elided here
    |                                                       |
-   |                                                       this lifetime flows to the output
+   |                                                       the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:177:65
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:179:65
    |
 LL |     fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> {
-   |                                                                 ^^                            -- the lifetime gets resolved as `'a`
-   |                                                                 |
-   |                                                                 this lifetime flows to the output
+   |                                                                 ^^ the lifetime is named here -- the same lifetime is elided here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:182:72
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:184:72
    |
 LL |     fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ {
-   |                                                                        ^^                      -- the lifetime gets resolved as `'a`
+   |                                                                        ^^                      -- the same lifetime is elided here
    |                                                                        |
-   |                                                                        this lifetime flows to the output
+   |                                                                        the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: 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 can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:188:29
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:190:29
    |
 LL |         v: ContainsLifetime<'a>,
-   |                             ^^ this lifetime flows to the output
+   |                             ^^ the lifetime is named here
 LL |
 LL |     ) -> impl FnOnce() + use<'_> {
-   |                              -- the lifetime gets resolved as `'a`
+   |                              -- the same lifetime is elided here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL -     ) -> impl FnOnce() + use<'_> {
 LL +     ) -> impl FnOnce() + use<'a> {
    |
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:202:54
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:204:54
    |
 LL |     fn explicit_bound_ref_to_dyn_trait_bound<'a>(v: &'a u8) -> Box<dyn Iterator<Item = &u8> + '_> {
-   |                                                      ^^                                ---    -- the lifetimes get resolved as `'a`
-   |                                                      |                                 |
-   |                                                      |                                 the lifetimes get resolved as `'a`
-   |                                                      this lifetime flows to the output
+   |                                                      ^^ the lifetime is named here     --- the same lifetime is elided here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL |     fn explicit_bound_ref_to_dyn_trait_bound<'a>(v: &'a u8) -> Box<dyn Iterator<Item = &'a u8> + '_> {
    |                                                                                         ++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:208:29
+error: hiding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:210:29
    |
 LL |         v: ContainsLifetime<'a>,
-   |                             ^^ this lifetime flows to the output
+   |                             ^^ the lifetime is named here
 LL |
 LL |     ) -> Box<dyn Iterator<Item = ContainsLifetime> + '_> {
-   |                                  ----------------    -- the lifetimes get resolved as `'a`
-   |                                  |
-   |                                  the lifetimes get resolved as `'a`
+   |                                  ---------------- the same lifetime is hidden here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL |     ) -> Box<dyn Iterator<Item = ContainsLifetime<'a>> + '_> {
    |                                                  ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:217:33
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:222:33
+   |
+LL |     fn multiple_inputs<'a>(v: (&'a u8, &'a u8)) -> &u8 {
+   |                                 ^^      ^^         --- the same lifetime is elided here
+   |                                 |       |
+   |                                 |       the lifetime is named here
+   |                                 the lifetime is named here
+   |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
+   |
+LL |     fn multiple_inputs<'a>(v: (&'a u8, &'a u8)) -> &'a u8 {
+   |                                                     ++
+
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:227:33
    |
 LL |     fn multiple_outputs<'a>(v: &'a u8) -> (&u8, &u8) {
-   |                                 ^^         ---  --- the lifetimes get resolved as `'a`
+   |                                 ^^         ---  --- the same lifetime is elided here
    |                                 |          |
-   |                                 |          the lifetimes get resolved as `'a`
-   |                                 this lifetime flows to the output
+   |                                 |          the same lifetime is elided here
+   |                                 the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL |     fn multiple_outputs<'a>(v: &'a u8) -> (&'a u8, &'a u8) {
    |                                             ++      ++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:230:45
+error: hiding or eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:232:53
+   |
+LL |     fn all_three_categories<'a>(v: ContainsLifetime<'a>) -> (&u8, ContainsLifetime) {
+   |                                                     ^^       ---  ---------------- the same lifetime is hidden here
+   |                                                     |        |
+   |                                                     |        the same lifetime is elided here
+   |                                                     the lifetime is named here
+   |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
+   |
+LL |     fn all_three_categories<'a>(v: ContainsLifetime<'a>) -> (&'a u8, ContainsLifetime<'a>) {
+   |                                                               ++                     ++++
+
+error: eliding a lifetime that's named elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:237:38
+   |
+LL |     fn explicit_bound_output<'a>(v: &'a u8) -> (&u8, &'a u8, ContainsLifetime<'a>) {
+   |                                      ^^         ---   --                      -- the same lifetime is named here
+   |                                      |          |     |
+   |                                      |          |     the same lifetime is named here
+   |                                      |          the same lifetime is elided here
+   |                                      the lifetime is named here
+   |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
+   |
+LL |     fn explicit_bound_output<'a>(v: &'a u8) -> (&'a u8, &'a u8, ContainsLifetime<'a>) {
+   |                                                  ++
+
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:250:45
    |
 LL |         fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime;
-   |                                             ^^^     ---------------- the lifetime gets resolved as `'_`
+   |                                             ^^^     ---------------- the same lifetime is hidden here
    |                                             |
-   |                                             this lifetime flows to the output
+   |                                             the lifetime is elided here
    |
-help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
 LL |         fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_>;
    |                                                                     ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:233:49
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:253:49
    |
 LL |         fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime;
-   |                                                 ^^^^^     ---------------- the lifetime gets resolved as `'_`
+   |                                                 ^^^^^     ---------------- the same lifetime is hidden here
    |                                                 |
-   |                                                 this lifetime flows to the output
+   |                                                 the lifetime is elided here
    |
-help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
 LL |         fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime<'_>;
    |                                                                           ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:238:45
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:258:45
    |
 LL |         fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime {
-   |                                             ^^^     ---------------- the lifetime gets resolved as `'_`
+   |                                             ^^^     ---------------- the same lifetime is hidden here
    |                                             |
-   |                                             this lifetime flows to the output
+   |                                             the lifetime is elided here
    |
-help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
 LL |         fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> {
    |                                                                     ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:243:49
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:263:49
    |
 LL |         fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime {
-   |                                                 ^^^^^     ---------------- the lifetime gets resolved as `'_`
+   |                                                 ^^^^^     ---------------- the same lifetime is hidden here
    |                                                 |
-   |                                                 this lifetime flows to the output
+   |                                                 the lifetime is elided here
    |
-help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
 LL |         fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime<'_> {
    |                                                                           ++++
 
-error: lifetime flowing from input to output with different syntax can be confusing
-  --> $DIR/mismatched-lifetime-syntaxes.rs:257:45
+error: hiding a lifetime that's elided elsewhere is confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:277:45
    |
 LL |         fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime;
-   |                                             ^^^     ---------------- the lifetime gets resolved as `'_`
+   |                                             ^^^     ---------------- the same lifetime is hidden here
    |                                             |
-   |                                             this lifetime flows to the output
+   |                                             the lifetime is elided here
    |
-help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: use `'_` for type paths
    |
 LL |         fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_>;
    |                                                                     ++++
 
-error: aborting due to 39 previous errors
+error: aborting due to 42 previous errors
 
diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.rs b/tests/ui/self/elision/ignore-non-reference-lifetimes.rs
index ecd669059ed..ce2fb8235cc 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 lifetime flowing from input to output with different syntax
+        //~^ WARNING eliding a lifetime that's named elsewhere is confusing
         a
     }
     fn b<'a>(self: Foo<'b>, a: &'a str) -> &str {
-        //~^ WARNING lifetime flowing from input to output with different syntax
+        //~^ WARNING eliding a lifetime that's named elsewhere is confusing
         a
     }
 }
diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
index 5351bf3c94c..7108fa1a290 100644
--- a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
+++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
@@ -1,26 +1,28 @@
-warning: lifetime flowing from input to output with different syntax can be confusing
+warning: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/ignore-non-reference-lifetimes.rs:6:30
    |
 LL |     fn a<'a>(self: Self, a: &'a str) -> &str {
-   |                              ^^         ---- the lifetime gets resolved as `'a`
+   |                              ^^         ---- the same lifetime is elided here
    |                              |
-   |                              this lifetime flows to the output
+   |                              the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
    = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
-help: one option is to consistently use `'a`
+help: consistently use `'a`
    |
 LL |     fn a<'a>(self: Self, a: &'a str) -> &'a str {
    |                                          ++
 
-warning: lifetime flowing from input to output with different syntax can be confusing
+warning: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/ignore-non-reference-lifetimes.rs:10:33
    |
 LL |     fn b<'a>(self: Foo<'b>, a: &'a str) -> &str {
-   |                                 ^^         ---- the lifetime gets resolved as `'a`
+   |                                 ^^         ---- the same lifetime is elided here
    |                                 |
-   |                                 this lifetime flows to the output
+   |                                 the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL |     fn b<'a>(self: Foo<'b>, a: &'a str) -> &'a str {
    |                                             ++
diff --git a/tests/ui/self/self_lifetime-async.rs b/tests/ui/self/self_lifetime-async.rs
index f839ab03a60..0093971fee4 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 lifetime flowing from input to output with different syntax
+    //~^ WARNING eliding a lifetime that's named elsewhere is confusing
 }
 
 type Alias = Foo<'static>;
 impl Alias {
     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
-    //~^ WARNING lifetime flowing from input to output with different syntax
+    //~^ WARNING eliding a lifetime that's named elsewhere is confusing
 }
 
 fn main() {}
diff --git a/tests/ui/self/self_lifetime-async.stderr b/tests/ui/self/self_lifetime-async.stderr
index a9c1be2e808..43dc96abdc2 100644
--- a/tests/ui/self/self_lifetime-async.stderr
+++ b/tests/ui/self/self_lifetime-async.stderr
@@ -1,26 +1,28 @@
-warning: lifetime flowing from input to output with different syntax can be confusing
+warning: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/self_lifetime-async.rs:6:29
    |
 LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
-   |                             ^^             --- the lifetime gets resolved as `'b`
+   |                             ^^             --- the same lifetime is elided here
    |                             |
-   |                             this lifetime flows to the output
+   |                             the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
    = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
-help: one option is to consistently use `'b`
+help: consistently use `'b`
    |
 LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 }
    |                                             ++
 
-warning: lifetime flowing from input to output with different syntax can be confusing
+warning: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/self_lifetime-async.rs:12:42
    |
 LL |     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
-   |                                          ^^        --- the lifetime gets resolved as `'a`
+   |                                          ^^        --- the same lifetime is elided here
    |                                          |
-   |                                          this lifetime flows to the output
+   |                                          the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL |     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg }
    |                                                     ++
diff --git a/tests/ui/self/self_lifetime.rs b/tests/ui/self/self_lifetime.rs
index aaa31f85ad5..190809af22f 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 lifetime flowing from input to output with different syntax
+    //~^ WARNING eliding a lifetime that's named elsewhere is confusing
 }
 
 type Alias = Foo<'static>;
 impl Alias {
     fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
-    //~^ WARNING lifetime flowing from input to output with different syntax
+    //~^ WARNING eliding a lifetime that's named elsewhere is confusing
 }
 
 fn main() {}
diff --git a/tests/ui/self/self_lifetime.stderr b/tests/ui/self/self_lifetime.stderr
index ec676e69cf6..4f9b2fcd2ad 100644
--- a/tests/ui/self/self_lifetime.stderr
+++ b/tests/ui/self/self_lifetime.stderr
@@ -1,26 +1,28 @@
-warning: lifetime flowing from input to output with different syntax can be confusing
+warning: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/self_lifetime.rs:7:23
    |
 LL |     fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
-   |                       ^^             --- the lifetime gets resolved as `'b`
+   |                       ^^             --- the same lifetime is elided here
    |                       |
-   |                       this lifetime flows to the output
+   |                       the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
    = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
-help: one option is to consistently use `'b`
+help: consistently use `'b`
    |
 LL |     fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 }
    |                                       ++
 
-warning: lifetime flowing from input to output with different syntax can be confusing
+warning: eliding a lifetime that's named elsewhere is confusing
   --> $DIR/self_lifetime.rs:13:36
    |
 LL |     fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
-   |                                    ^^        --- the lifetime gets resolved as `'a`
+   |                                    ^^        --- the same lifetime is elided here
    |                                    |
-   |                                    this lifetime flows to the output
+   |                                    the lifetime is named here
    |
-help: one option is to consistently use `'a`
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
+help: consistently use `'a`
    |
 LL |     fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg }
    |                                               ++