summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs509
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl4
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/offset_of.rs99
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs50
-rw-r--r--compiler/rustc_data_structures/src/owned_slice.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl3
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs34
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs198
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs8
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs2
-rw-r--r--compiler/rustc_parse/messages.ftl5
-rw-r--r--compiler/rustc_parse/src/errors.rs27
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs31
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs61
-rw-r--r--compiler/rustc_parse/src/parser/item.rs8
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs23
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs69
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs4
-rw-r--r--library/core/src/mem/mod.rs6
m---------src/doc/edition-guide0
m---------src/doc/embedded-book0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff16
-rw-r--r--tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff8
-rw-r--r--tests/run-make/branch-protection-check-IBT/Makefile15
-rw-r--r--tests/run-make/branch-protection-check-IBT/main.rs3
-rw-r--r--tests/ui/argument-suggestions/issue-97484.stderr2
-rw-r--r--tests/ui/array-slice-vec/slice-mut-2.stderr2
-rw-r--r--tests/ui/async-await/issues/issue-102206.stderr10
-rw-r--r--tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr4
-rw-r--r--tests/ui/borrowck/borrowck-access-permissions.stderr6
-rw-r--r--tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr8
-rw-r--r--tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr4
-rw-r--r--tests/ui/borrowck/borrowck-issue-14498.stderr2
-rw-r--r--tests/ui/borrowck/borrowck-reborrow-from-mut.stderr2
-rw-r--r--tests/ui/borrowck/issue-85765.stderr2
-rw-r--r--tests/ui/borrowck/mutability-errors.stderr24
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr2
-rw-r--r--tests/ui/coercion/coercion-slice.stderr11
-rw-r--r--tests/ui/did_you_mean/issue-38147-4.stderr4
-rw-r--r--tests/ui/did_you_mean/issue-39544.stderr12
-rw-r--r--tests/ui/did_you_mean/issue-40823.stderr2
-rw-r--r--tests/ui/error-codes/E0389.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-builtin_syntax.rs7
-rw-r--r--tests/ui/feature-gates/feature-gate-builtin_syntax.stderr12
-rw-r--r--tests/ui/inference/deref-suggestion.stderr20
-rw-r--r--tests/ui/issues/issue-11374.stderr10
-rw-r--r--tests/ui/issues/issue-17033.stderr11
-rw-r--r--tests/ui/issues/issue-18819.stderr2
-rw-r--r--tests/ui/issues/issue-46302.stderr10
-rw-r--r--tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr20
-rw-r--r--tests/ui/issues/issue-51515.rs1
-rw-r--r--tests/ui/issues/issue-51515.stderr6
-rw-r--r--tests/ui/issues/issue-61106.stderr10
-rw-r--r--tests/ui/issues/issue-61623.stderr2
-rw-r--r--tests/ui/methods/method-self-arg-1.stderr10
-rw-r--r--tests/ui/mismatched_types/dont-point-return-on-E0308.stderr10
-rw-r--r--tests/ui/mut/mut-cross-borrowing.stderr10
-rw-r--r--tests/ui/nll/issue-47388.stderr2
-rw-r--r--tests/ui/nll/issue-51244.stderr2
-rw-r--r--tests/ui/nll/issue-57989.stderr2
-rw-r--r--tests/ui/offset-of/offset-of-arg-count.rs14
-rw-r--r--tests/ui/offset-of/offset-of-arg-count.stderr59
-rw-r--r--tests/ui/offset-of/offset-of-builtin.rs44
-rw-r--r--tests/ui/offset-of/offset-of-builtin.stderr65
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.stderr3
-rw-r--r--tests/ui/offset-of/offset-of-unstable.stderr5
-rw-r--r--tests/ui/parser/builtin-syntax.rs9
-rw-r--r--tests/ui/parser/builtin-syntax.stderr14
-rw-r--r--tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr4
-rw-r--r--tests/ui/range/issue-54505-no-literals.fixed24
-rw-r--r--tests/ui/range/issue-54505-no-literals.rs24
-rw-r--r--tests/ui/range/issue-54505-no-literals.stderr120
-rw-r--r--tests/ui/range/issue-54505-no-std.rs12
-rw-r--r--tests/ui/range/issue-54505-no-std.stderr60
-rw-r--r--tests/ui/range/issue-54505.fixed12
-rw-r--r--tests/ui/range/issue-54505.rs12
-rw-r--r--tests/ui/range/issue-54505.stderr60
-rw-r--r--tests/ui/range/issue-73553-misinterp-range-literal.stderr20
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs24
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr4
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs24
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs24
-rw-r--r--tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr8
-rw-r--r--tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr4
-rw-r--r--tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr6
-rw-r--r--tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr2
-rw-r--r--tests/ui/span/borrowck-fn-in-const-b.stderr2
-rw-r--r--tests/ui/span/borrowck-object-mutability.stderr2
-rw-r--r--tests/ui/span/coerce-suggestions.stderr11
-rw-r--r--tests/ui/span/issue-39018.stderr10
-rw-r--r--tests/ui/span/mut-arg-hint.stderr6
-rw-r--r--tests/ui/specialization/min_specialization/specialize-associated-type.rs37
-rw-r--r--tests/ui/specialization/min_specialization/specialize_nothing.rs14
-rw-r--r--tests/ui/specialization/min_specialization/specialize_nothing.stderr14
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_type_error.rs33
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_type_error.stderr12
-rw-r--r--tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs50
-rw-r--r--tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr27
-rw-r--r--tests/ui/str/str-array-assignment.stderr21
-rw-r--r--tests/ui/suggestions/as-ref.stderr88
-rw-r--r--tests/ui/suggestions/issue-68049-2.stderr8
-rw-r--r--tests/ui/suggestions/suggest-ref-macro.rs4
-rw-r--r--tests/ui/suggestions/suggest-ref-macro.stderr19
-rw-r--r--tests/ui/suggestions/suggest-ref-mut.rs3
-rw-r--r--tests/ui/suggestions/suggest-ref-mut.stderr12
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-let.fixed11
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-let.rs4
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-let.stderr7
-rw-r--r--tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr4
-rw-r--r--tests/ui/type/missing-let-in-binding-2.fixed5
-rw-r--r--tests/ui/type/missing-let-in-binding-2.rs5
-rw-r--r--tests/ui/type/missing-let-in-binding-2.stderr13
-rw-r--r--tests/ui/type/missing-let-in-binding-3.rs5
-rw-r--r--tests/ui/type/missing-let-in-binding-3.stderr10
-rw-r--r--tests/ui/type/missing-let-in-binding-4.rs5
-rw-r--r--tests/ui/type/missing-let-in-binding-4.stderr10
-rw-r--r--tests/ui/type/type-mismatch.stderr20
-rw-r--r--tests/ui/typeck/bad-index-due-to-nested.stderr18
-rw-r--r--tests/ui/typeck/bad-type-in-vec-contains.stderr10
-rw-r--r--tests/ui/typeck/issue-13853.stderr10
-rw-r--r--tests/ui/unsized-locals/suggest-borrow.stderr11
134 files changed, 1734 insertions, 914 deletions
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index b960671bf6e..3d5056d82c5 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -603,6 +603,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
     gate_all!(yeet_expr, "`do yeet` expression is experimental");
     gate_all!(dyn_star, "`dyn*` trait objects are experimental");
     gate_all!(const_closures, "const closures are experimental");
+    gate_all!(builtin_syntax, "`builtin #` syntax is unstable");
 
     if !visitor.features.negative_bounds {
         for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index b74c59bca30..87c32ffce12 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -556,8 +556,7 @@ impl<'a> State<'a> {
                 self.pclose();
             }
             ast::ExprKind::OffsetOf(container, fields) => {
-                // FIXME: This should have its own syntax, distinct from a macro invocation.
-                self.word("offset_of!");
+                self.word("builtin # offset_of");
                 self.popen();
                 self.rbox(0, Inconsistent);
                 self.print_type(container);
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 7558247948f..6286033e067 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -1,4 +1,4 @@
-use rustc_errors::{Applicability, Diagnostic};
+use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::Node;
@@ -478,179 +478,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
                 match self.local_names[local] {
                     Some(name) if !local_decl.from_compiler_desugaring() => {
-                        let label = match *local_decl.local_info() {
-                            LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
-                                let (span, suggestion) =
-                                    suggest_ampmut_self(self.infcx.tcx, local_decl);
-                                Some((true, span, suggestion))
-                            }
-
-                            LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
-                                binding_mode: ty::BindingMode::BindByValue(_),
-                                opt_ty_info,
-                                ..
-                            })) => {
-                                // check if the RHS is from desugaring
-                                let opt_assignment_rhs_span =
-                                    self.body.find_assignments(local).first().map(|&location| {
-                                        if let Some(mir::Statement {
-                                            source_info: _,
-                                            kind:
-                                                mir::StatementKind::Assign(box (
-                                                    _,
-                                                    mir::Rvalue::Use(mir::Operand::Copy(place)),
-                                                )),
-                                        }) = self.body[location.block]
-                                            .statements
-                                            .get(location.statement_index)
-                                        {
-                                            self.body.local_decls[place.local].source_info.span
-                                        } else {
-                                            self.body.source_info(location).span
-                                        }
-                                    });
-                                match opt_assignment_rhs_span.and_then(|s| s.desugaring_kind()) {
-                                    // on for loops, RHS points to the iterator part
-                                    Some(DesugaringKind::ForLoop) => {
-                                        self.suggest_similar_mut_method_for_for_loop(&mut err);
-                                        err.span_label(opt_assignment_rhs_span.unwrap(), format!(
-                                            "this iterator yields `{pointer_sigil}` {pointer_desc}s",
-                                        ));
-                                        None
-                                    }
-                                    // don't create labels for compiler-generated spans
-                                    Some(_) => None,
-                                    None => {
-                                        let label = if name != kw::SelfLower {
-                                            suggest_ampmut(
-                                                self.infcx.tcx,
-                                                local_decl,
-                                                opt_assignment_rhs_span,
-                                                opt_ty_info,
-                                            )
-                                        } else {
-                                            match local_decl.local_info() {
-                                                LocalInfo::User(mir::BindingForm::Var(
-                                                    mir::VarBindingForm {
-                                                        opt_ty_info: None, ..
-                                                    },
-                                                )) => {
-                                                    let (span, sugg) = suggest_ampmut_self(
-                                                        self.infcx.tcx,
-                                                        local_decl,
-                                                    );
-                                                    (true, span, sugg)
-                                                }
-                                                // explicit self (eg `self: &'a Self`)
-                                                _ => suggest_ampmut(
-                                                    self.infcx.tcx,
-                                                    local_decl,
-                                                    opt_assignment_rhs_span,
-                                                    opt_ty_info,
-                                                ),
-                                            }
-                                        };
-                                        Some(label)
-                                    }
-                                }
-                            }
-
-                            LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
-                                binding_mode: ty::BindingMode::BindByReference(_),
-                                ..
-                            })) => {
-                                let pattern_span = local_decl.source_info.span;
-                                suggest_ref_mut(self.infcx.tcx, pattern_span)
-                                    .map(|replacement| (true, pattern_span, replacement))
-                            }
-
-                            _ => unreachable!(),
-                        };
-
-                        match label {
-                            Some((true, err_help_span, suggested_code)) => {
-                                let (is_trait_sig, local_trait) = self.is_error_in_trait(local);
-                                if !is_trait_sig {
-                                    err.span_suggestion_verbose(
-                                        err_help_span,
-                                        format!(
-                                            "consider changing this to be a mutable {pointer_desc}"
-                                        ),
-                                        suggested_code,
-                                        Applicability::MachineApplicable,
-                                    );
-                                } else if let Some(x) = local_trait {
-                                    err.span_suggestion_verbose(
-                                        x,
-                                        format!(
-                                            "consider changing that to be a mutable {pointer_desc}"
-                                        ),
-                                        suggested_code,
-                                        Applicability::MachineApplicable,
-                                    );
-                                }
-                            }
-                            Some((false, err_label_span, message)) => {
-                                struct BindingFinder {
-                                    span: Span,
-                                    hir_id: Option<hir::HirId>,
-                                }
-
-                                impl<'tcx> Visitor<'tcx> for BindingFinder {
-                                    fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
-                                        if let hir::StmtKind::Local(local) = s.kind {
-                                            if local.pat.span == self.span {
-                                                self.hir_id = Some(local.hir_id);
-                                            }
-                                        }
-                                        hir::intravisit::walk_stmt(self, s);
-                                    }
-                                }
-                                let hir_map = self.infcx.tcx.hir();
-                                let def_id = self.body.source.def_id();
-                                let hir_id = hir_map.local_def_id_to_hir_id(def_id.expect_local());
-                                let node = hir_map.find(hir_id);
-                                let hir_id = if let Some(hir::Node::Item(item)) = node
-                                    && let hir::ItemKind::Fn(.., body_id) = item.kind
-                                {
-                                    let body = hir_map.body(body_id);
-                                    let mut v = BindingFinder {
-                                        span: err_label_span,
-                                        hir_id: None,
-                                    };
-                                    v.visit_body(body);
-                                    v.hir_id
-                                } else {
-                                    None
-                                };
-                                if let Some(hir_id) = hir_id
-                                    && let Some(hir::Node::Local(local)) = hir_map.find(hir_id)
-                                {
-                                    let (changing, span, sugg) = match local.ty {
-                                        Some(ty) => ("changing", ty.span, message),
-                                        None => (
-                                            "specifying",
-                                            local.pat.span.shrink_to_hi(),
-                                            format!(": {message}"),
-                                        ),
-                                    };
-                                    err.span_suggestion_verbose(
-                                        span,
-                                        format!("consider {changing} this binding's type"),
-                                        sugg,
-                                        Applicability::HasPlaceholders,
-                                    );
-                                } else {
-                                    err.span_label(
-                                        err_label_span,
-                                        format!(
-                                            "consider changing this binding's type to be: `{message}`"
-                                        ),
-                                    );
-                                }
-                            }
-                            None => {}
-                        }
                         err.span_label(
                             span,
                             format!(
@@ -658,6 +485,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                  so the data it refers to cannot be {acted_on}",
                             ),
                         );
+
+                        self.suggest_make_local_mut(&mut err, local, name);
                     }
                     _ => {
                         err.span_label(
@@ -1131,6 +960,184 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             }
         }
     }
+
+    fn suggest_make_local_mut(
+        &self,
+        err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+        local: Local,
+        name: Symbol,
+    ) {
+        let local_decl = &self.body.local_decls[local];
+
+        let (pointer_sigil, pointer_desc) =
+            if local_decl.ty.is_ref() { ("&", "reference") } else { ("*const", "pointer") };
+
+        let (is_trait_sig, local_trait) = self.is_error_in_trait(local);
+        if is_trait_sig && local_trait.is_none() {
+            return;
+        }
+
+        let decl_span = match local_trait {
+            Some(span) => span,
+            None => local_decl.source_info.span,
+        };
+
+        let label = match *local_decl.local_info() {
+            LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
+                let suggestion = suggest_ampmut_self(self.infcx.tcx, decl_span);
+                Some((true, decl_span, suggestion))
+            }
+
+            LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
+                binding_mode: ty::BindingMode::BindByValue(_),
+                opt_ty_info,
+                ..
+            })) => {
+                // check if the RHS is from desugaring
+                let opt_assignment_rhs_span =
+                    self.body.find_assignments(local).first().map(|&location| {
+                        if let Some(mir::Statement {
+                            source_info: _,
+                            kind:
+                                mir::StatementKind::Assign(box (
+                                    _,
+                                    mir::Rvalue::Use(mir::Operand::Copy(place)),
+                                )),
+                        }) = self.body[location.block].statements.get(location.statement_index)
+                        {
+                            self.body.local_decls[place.local].source_info.span
+                        } else {
+                            self.body.source_info(location).span
+                        }
+                    });
+                match opt_assignment_rhs_span.and_then(|s| s.desugaring_kind()) {
+                    // on for loops, RHS points to the iterator part
+                    Some(DesugaringKind::ForLoop) => {
+                        self.suggest_similar_mut_method_for_for_loop(err);
+                        err.span_label(
+                            opt_assignment_rhs_span.unwrap(),
+                            format!("this iterator yields `{pointer_sigil}` {pointer_desc}s",),
+                        );
+                        None
+                    }
+                    // don't create labels for compiler-generated spans
+                    Some(_) => None,
+                    None => {
+                        let label = if name != kw::SelfLower {
+                            suggest_ampmut(
+                                self.infcx.tcx,
+                                local_decl.ty,
+                                decl_span,
+                                opt_assignment_rhs_span,
+                                opt_ty_info,
+                            )
+                        } else {
+                            match local_decl.local_info() {
+                                LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
+                                    opt_ty_info: None,
+                                    ..
+                                })) => {
+                                    let sugg = suggest_ampmut_self(self.infcx.tcx, decl_span);
+                                    (true, decl_span, sugg)
+                                }
+                                // explicit self (eg `self: &'a Self`)
+                                _ => suggest_ampmut(
+                                    self.infcx.tcx,
+                                    local_decl.ty,
+                                    decl_span,
+                                    opt_assignment_rhs_span,
+                                    opt_ty_info,
+                                ),
+                            }
+                        };
+                        Some(label)
+                    }
+                }
+            }
+
+            LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
+                binding_mode: ty::BindingMode::BindByReference(_),
+                ..
+            })) => {
+                let pattern_span: Span = local_decl.source_info.span;
+                suggest_ref_mut(self.infcx.tcx, pattern_span)
+                    .map(|span| (true, span, "mut ".to_owned()))
+            }
+
+            _ => unreachable!(),
+        };
+
+        match label {
+            Some((true, err_help_span, suggested_code)) => {
+                err.span_suggestion_verbose(
+                    err_help_span,
+                    format!("consider changing this to be a mutable {pointer_desc}"),
+                    suggested_code,
+                    Applicability::MachineApplicable,
+                );
+            }
+            Some((false, err_label_span, message)) => {
+                struct BindingFinder {
+                    span: Span,
+                    hir_id: Option<hir::HirId>,
+                }
+
+                impl<'tcx> Visitor<'tcx> for BindingFinder {
+                    fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
+                        if let hir::StmtKind::Local(local) = s.kind {
+                            if local.pat.span == self.span {
+                                self.hir_id = Some(local.hir_id);
+                            }
+                        }
+                        hir::intravisit::walk_stmt(self, s);
+                    }
+                }
+                let hir_map = self.infcx.tcx.hir();
+                let def_id = self.body.source.def_id();
+                let hir_id = hir_map.local_def_id_to_hir_id(def_id.expect_local());
+                let node = hir_map.find(hir_id);
+                let hir_id = if let Some(hir::Node::Item(item)) = node
+                && let hir::ItemKind::Fn(.., body_id) = item.kind
+            {
+                let body = hir_map.body(body_id);
+                let mut v = BindingFinder {
+                    span: err_label_span,
+                    hir_id: None,
+                };
+                v.visit_body(body);
+                v.hir_id
+            } else {
+                None
+            };
+                if let Some(hir_id) = hir_id
+                && let Some(hir::Node::Local(local)) = hir_map.find(hir_id)
+            {
+                let (changing, span, sugg) = match local.ty {
+                    Some(ty) => ("changing", ty.span, message),
+                    None => (
+                        "specifying",
+                        local.pat.span.shrink_to_hi(),
+                        format!(": {message}"),
+                    ),
+                };
+                err.span_suggestion_verbose(
+                    span,
+                    format!("consider {changing} this binding's type"),
+                    sugg,
+                    Applicability::HasPlaceholders,
+                );
+            } else {
+                err.span_label(
+                    err_label_span,
+                    format!(
+                        "consider changing this binding's type to be: `{message}`"
+                    ),
+                );
+            }
+            }
+            None => {}
+        }
+    }
 }
 
 pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
@@ -1160,25 +1167,18 @@ pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<
     }
 }
 
-fn suggest_ampmut_self<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    local_decl: &mir::LocalDecl<'tcx>,
-) -> (Span, String) {
-    let sp = local_decl.source_info.span;
-    (
-        sp,
-        match tcx.sess.source_map().span_to_snippet(sp) {
-            Ok(snippet) => {
-                let lt_pos = snippet.find('\'');
-                if let Some(lt_pos) = lt_pos {
-                    format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4])
-                } else {
-                    "&mut self".to_string()
-                }
+fn suggest_ampmut_self<'tcx>(tcx: TyCtxt<'tcx>, span: Span) -> String {
+    match tcx.sess.source_map().span_to_snippet(span) {
+        Ok(snippet) => {
+            let lt_pos = snippet.find('\'');
+            if let Some(lt_pos) = lt_pos {
+                format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4])
+            } else {
+                "&mut self".to_string()
             }
-            _ => "&mut self".to_string(),
-        },
-    )
+        }
+        _ => "&mut self".to_string(),
+    }
 }
 
 // When we want to suggest a user change a local variable to be a `&mut`, there
@@ -1198,72 +1198,89 @@ fn suggest_ampmut_self<'tcx>(
 // by trying (3.), then (2.) and finally falling back on (1.).
 fn suggest_ampmut<'tcx>(
     tcx: TyCtxt<'tcx>,
-    local_decl: &mir::LocalDecl<'tcx>,
+    decl_ty: Ty<'tcx>,
+    decl_span: Span,
     opt_assignment_rhs_span: Option<Span>,
     opt_ty_info: Option<Span>,
 ) -> (bool, Span, String) {
+    // if there is a RHS and it starts with a `&` from it, then check if it is
+    // mutable, and if not, put suggest putting `mut ` to make it mutable.
+    // we don't have to worry about lifetime annotations here because they are
+    // not valid when taking a reference. For example, the following is not valid Rust:
+    //
+    // let x: &i32 = &'a 5;
+    //                ^^ lifetime annotation not allowed
+    //
     if let Some(assignment_rhs_span) = opt_assignment_rhs_span
         && let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span)
+        && let Some(stripped) = src.strip_prefix('&')
     {
-        let is_mutbl = |ty: &str| -> bool {
-            if let Some(rest) = ty.strip_prefix("mut") {
-                match rest.chars().next() {
-                    // e.g. `&mut x`
-                    Some(c) if c.is_whitespace() => true,
-                    // e.g. `&mut(x)`
-                    Some('(') => true,
-                    // e.g. `&mut{x}`
-                    Some('{') => true,
-                    // e.g. `&mutablevar`
-                    _ => false,
-                }
-            } else {
-                false
+        let is_mut = if let Some(rest) = stripped.trim_start().strip_prefix("mut") {
+            match rest.chars().next() {
+                // e.g. `&mut x`
+                Some(c) if c.is_whitespace() => true,
+                // e.g. `&mut(x)`
+                Some('(') => true,
+                // e.g. `&mut{x}`
+                Some('{') => true,
+                // e.g. `&mutablevar`
+                _ => false,
             }
+        } else {
+            false
         };
-        if let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace)) {
-            let lt_name = &src[1..ws_pos];
-            let ty = src[ws_pos..].trim_start();
-            if !is_mutbl(ty) {
-                return (true, assignment_rhs_span, format!("&{lt_name} mut {ty}"));
-            }
-        } else if let Some(stripped) = src.strip_prefix('&') {
-            let stripped = stripped.trim_start();
-            if !is_mutbl(stripped) {
-                return (true, assignment_rhs_span, format!("&mut {stripped}"));
-            }
+        // if the reference is already mutable then there is nothing we can do
+        // here.
+        if !is_mut {
+            let span = assignment_rhs_span;
+            // shrink the span to just after the `&` in `&variable`
+            let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
+
+            // FIXME(Ezrashaw): returning is bad because we still might want to
+            // update the annotated type, see #106857.
+            return (true, span, "mut ".to_owned());
         }
     }
 
-    let (suggestibility, highlight_span) = match opt_ty_info {
+    let (binding_exists, span) = match opt_ty_info {
         // if this is a variable binding with an explicit type,
-        // try to highlight that for the suggestion.
+        // then we will suggest changing it to be mutable.
+        // this is `Applicability::MachineApplicable`.
         Some(ty_span) => (true, ty_span),
 
-        // otherwise, just highlight the span associated with
-        // the (MIR) LocalDecl.
-        None => (false, local_decl.source_info.span),
+        // otherwise, we'll suggest *adding* an annotated type, we'll suggest
+        // the RHS's type for that.
+        // this is `Applicability::HasPlaceholders`.
+        None => (false, decl_span),
     };
 
-    if let Ok(src) = tcx.sess.source_map().span_to_snippet(highlight_span)
-        && let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace))
+    // if the binding already exists and is a reference with a explicit
+    // lifetime, then we can suggest adding ` mut`. this is special-cased from
+    // the path without a explicit lifetime.
+    if let Ok(src) = tcx.sess.source_map().span_to_snippet(span)
+        && src.starts_with("&'")
+        // note that `&     'a T` is invalid so this is correct.
+        && let Some(ws_pos) = src.find(char::is_whitespace)
     {
-        let lt_name = &src[1..ws_pos];
-        let ty = &src[ws_pos..];
-        return (true, highlight_span, format!("&{lt_name} mut{ty}"));
-    }
+        let span = span.with_lo(span.lo() + BytePos(ws_pos as u32)).shrink_to_lo();
+        (true, span, " mut".to_owned())
+    // if there is already a binding, we modify it to be `mut`
+    } else if binding_exists {
+        // shrink the span to just after the `&` in `&variable`
+        let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
+        (true, span, "mut ".to_owned())
+    } else {
+        // otherwise, suggest that the user annotates the binding; we provide the
+        // type of the local.
+        let ty_mut = decl_ty.builtin_deref(true).unwrap();
+        assert_eq!(ty_mut.mutbl, hir::Mutability::Not);
 
-    let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
-    assert_eq!(ty_mut.mutbl, hir::Mutability::Not);
-    (
-        suggestibility,
-        highlight_span,
-        if local_decl.ty.is_ref() {
-            format!("&mut {}", ty_mut.ty)
-        } else {
-            format!("*mut {}", ty_mut.ty)
-        },
-    )
+        (
+            false,
+            span,
+            format!("{}mut {}", if decl_ty.is_ref() {"&"} else {"*"}, ty_mut.ty)
+        )
+    }
 }
 
 fn is_closure_or_generator(ty: Ty<'_>) -> bool {
@@ -1300,11 +1317,13 @@ fn get_mut_span_in_struct_field<'tcx>(
 }
 
 /// If possible, suggest replacing `ref` with `ref mut`.
-fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<String> {
-    let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).ok()?;
-    if hi_src.starts_with("ref") && hi_src["ref".len()..].starts_with(rustc_lexer::is_whitespace) {
-        let replacement = format!("ref mut{}", &hi_src["ref".len()..]);
-        Some(replacement)
+fn suggest_ref_mut(tcx: TyCtxt<'_>, span: Span) -> Option<Span> {
+    let pattern_str = tcx.sess.source_map().span_to_snippet(span).ok()?;
+    if pattern_str.starts_with("ref")
+        && pattern_str["ref".len()..].starts_with(rustc_lexer::is_whitespace)
+    {
+        let span = span.with_lo(span.lo() + BytePos(4)).shrink_to_lo();
+        Some(span)
     } else {
         None
     }
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 0d7cf7cdb26..3b458b1d30b 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -150,10 +150,6 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n ->
     *[more] arguments
     } in format string, but {$desc}
 
-builtin_macros_offset_of_expected_field = expected field
-
-builtin_macros_offset_of_expected_two_args = expected 2 arguments
-
 builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items
 
 builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index c7da61d72b3..4e5edb4d6b1 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -44,7 +44,6 @@ mod format;
 mod format_foreign;
 mod global_allocator;
 mod log_syntax;
-mod offset_of;
 mod source_util;
 mod test;
 mod trace_macros;
@@ -92,7 +91,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         line: source_util::expand_line,
         log_syntax: log_syntax::expand_log_syntax,
         module_path: source_util::expand_mod,
-        offset_of: offset_of::expand_offset_of,
         option_env: env::expand_option_env,
         core_panic: edition_panic::expand_panic,
         std_panic: edition_panic::expand_panic,
diff --git a/compiler/rustc_builtin_macros/src/offset_of.rs b/compiler/rustc_builtin_macros/src/offset_of.rs
deleted file mode 100644
index 0ef3e000e41..00000000000
--- a/compiler/rustc_builtin_macros/src/offset_of.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use rustc_ast as ast;
-use rustc_ast::ptr::P;
-use rustc_ast::token;
-use rustc_ast::tokenstream::TokenStream;
-use rustc_errors::PResult;
-use rustc_expand::base::{self, *};
-use rustc_macros::Diagnostic;
-use rustc_parse::parser::Parser;
-use rustc_span::{symbol::Ident, Span};
-
-#[derive(Diagnostic)]
-#[diag(builtin_macros_offset_of_expected_field)]
-struct ExpectedField {
-    #[primary_span]
-    span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(builtin_macros_offset_of_expected_two_args)]
-struct ExpectedTwoArgs {
-    #[primary_span]
-    span: Span,
-}
-
-fn parse_field<'a>(cx: &ExtCtxt<'a>, p: &mut Parser<'a>) -> PResult<'a, Ident> {
-    let token = p.token.uninterpolate();
-    let field = match token.kind {
-        token::Ident(name, _) => Ident::new(name, token.span),
-        token::Literal(token::Lit { kind: token::Integer, symbol, suffix: None }) => {
-            Ident::new(symbol, token.span)
-        }
-        _ => return Err(cx.create_err(ExpectedField { span: p.token.span })),
-    };
-
-    p.bump();
-
-    Ok(field)
-}
-
-fn parse_args<'a>(
-    cx: &mut ExtCtxt<'a>,
-    sp: Span,
-    tts: TokenStream,
-) -> PResult<'a, (P<ast::Ty>, P<[Ident]>)> {
-    let mut p = cx.new_parser_from_tts(tts);
-
-    let container = p.parse_ty()?;
-
-    p.expect(&token::Comma)?;
-
-    if p.eat(&token::Eof) {
-        return Err(cx.create_err(ExpectedTwoArgs { span: sp }));
-    }
-
-    let mut fields = Vec::new();
-
-    loop {
-        let field = parse_field(cx, &mut p)?;
-        fields.push(field);
-
-        if p.eat(&token::Dot) {
-            continue;
-        }
-
-        p.eat(&token::Comma);
-
-        if !p.eat(&token::Eof) {
-            return Err(cx.create_err(ExpectedTwoArgs { span: sp }));
-        }
-
-        break;
-    }
-
-    Ok((container, fields.into()))
-}
-
-pub fn expand_offset_of<'cx>(
-    cx: &'cx mut ExtCtxt<'_>,
-    sp: Span,
-    tts: TokenStream,
-) -> Box<dyn base::MacResult + 'cx> {
-    match parse_args(cx, sp, tts) {
-        Ok((container, fields)) => {
-            let expr = P(ast::Expr {
-                id: ast::DUMMY_NODE_ID,
-                kind: ast::ExprKind::OffsetOf(container, fields),
-                span: sp,
-                attrs: ast::AttrVec::new(),
-                tokens: None,
-            });
-
-            MacEager::expr(expr)
-        }
-        Err(mut err) => {
-            err.emit();
-            DummyResult::any(sp)
-        }
-    }
-}
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index d5d843702c0..8968133bac5 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -12,6 +12,7 @@ use object::{
 
 use snap::write::FrameEncoder;
 
+use object::elf::NT_GNU_PROPERTY_TYPE_0;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::owned_slice::try_slice_owned;
 use rustc_data_structures::sync::MetadataRef;
@@ -93,6 +94,54 @@ pub(super) fn search_for_section<'a>(
         .map_err(|e| format!("failed to read {} section in '{}': {}", section, path.display(), e))
 }
 
+fn add_gnu_property_note(
+    file: &mut write::Object<'static>,
+    architecture: Architecture,
+    binary_format: BinaryFormat,
+    endianness: Endianness,
+) {
+    // check bti protection
+    if binary_format != BinaryFormat::Elf
+        || !matches!(architecture, Architecture::X86_64 | Architecture::Aarch64)
+    {
+        return;
+    }
+
+    let section = file.add_section(
+        file.segment_name(StandardSegment::Data).to_vec(),
+        b".note.gnu.property".to_vec(),
+        SectionKind::Note,
+    );
+    let mut data: Vec<u8> = Vec::new();
+    let n_namsz: u32 = 4; // Size of the n_name field
+    let n_descsz: u32 = 16; // Size of the n_desc field
+    let n_type: u32 = NT_GNU_PROPERTY_TYPE_0; // Type of note descriptor
+    let header_values = [n_namsz, n_descsz, n_type];
+    header_values.iter().for_each(|v| {
+        data.extend_from_slice(&match endianness {
+            Endianness::Little => v.to_le_bytes(),
+            Endianness::Big => v.to_be_bytes(),
+        })
+    });
+    data.extend_from_slice(b"GNU\0"); // Owner of the program property note
+    let pr_type: u32 = match architecture {
+        Architecture::X86_64 => 0xc0000002,
+        Architecture::Aarch64 => 0xc0000000,
+        _ => unreachable!(),
+    };
+    let pr_datasz: u32 = 4; //size of the pr_data field
+    let pr_data: u32 = 3; //program property descriptor
+    let pr_padding: u32 = 0;
+    let property_values = [pr_type, pr_datasz, pr_data, pr_padding];
+    property_values.iter().for_each(|v| {
+        data.extend_from_slice(&match endianness {
+            Endianness::Little => v.to_le_bytes(),
+            Endianness::Big => v.to_be_bytes(),
+        })
+    });
+    file.append_section_data(section, &data, 8);
+}
+
 pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static>> {
     let endianness = match sess.target.options.endian {
         Endian::Little => Endianness::Little,
@@ -205,6 +254,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
         _ => elf::ELFOSABI_NONE,
     };
     let abi_version = 0;
+    add_gnu_property_note(&mut file, architecture, binary_format, endianness);
     file.flags = FileFlags::Elf { os_abi, abi_version, e_flags };
     Some(file)
 }
diff --git a/compiler/rustc_data_structures/src/owned_slice.rs b/compiler/rustc_data_structures/src/owned_slice.rs
index 048401f66c2..311a42aa42a 100644
--- a/compiler/rustc_data_structures/src/owned_slice.rs
+++ b/compiler/rustc_data_structures/src/owned_slice.rs
@@ -109,9 +109,11 @@ impl Borrow<[u8]> for OwnedSlice {
 }
 
 // Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box<dyn Send + Sync>)`, which is `Send`
+#[cfg(parallel_compiler)]
 unsafe impl Send for OwnedSlice {}
 
 // Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box<dyn Send + Sync>)`, which is `Sync`
+#[cfg(parallel_compiler)]
 unsafe impl Sync for OwnedSlice {}
 
 #[cfg(test)]
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 27d30c315af..f4615445f8e 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -313,6 +313,8 @@ declare_features! (
     (active, async_closure, "1.37.0", Some(62290), None),
     /// Allows async functions to be declared, implemented, and used in traits.
     (active, async_fn_in_trait, "1.66.0", Some(91611), None),
+    /// Allows builtin # foo() syntax
+    (active, builtin_syntax, "CURRENT_RUSTC_VERSION", Some(110680), None),
     /// Allows `c"foo"` literals.
     (active, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None),
     /// Treat `extern "C"` function as nounwind.
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 3b42b0fe246..5e5c984a7ea 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -279,6 +279,9 @@ hir_analysis_specialization_trait = implementing `rustc_specialization_trait` tr
 hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are forbidden when `for<...>` is present
     .label = `for<...>` is here
 
+hir_analysis_empty_specialization = specialization impl does not specialize any associated items
+    .note = impl is a specialization of this impl
+
 hir_analysis_const_specialize = cannot specialize on const impl with non-const impl
 
 hir_analysis_static_specialize = cannot specialize on `'static` lifetime
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 379a88538a9..6e7eb4f6cdc 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -815,6 +815,15 @@ pub(crate) struct ClosureImplicitHrtb {
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_analysis_empty_specialization)]
+pub(crate) struct EmptySpecialization {
+    #[primary_span]
+    pub span: Span,
+    #[note]
+    pub base_impl_span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(hir_analysis_const_specialize)]
 pub(crate) struct ConstSpecialize {
     #[primary_span]
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 5cca2dacb5c..e84da2519ae 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -80,7 +80,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
-use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt};
+use rustc_trait_selection::traits::{self, translate_substs_with_cause, wf, ObligationCtxt};
 
 pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
     if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
@@ -100,12 +100,19 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Opti
         // Implementing a normal trait isn't a specialization.
         return None;
     }
+    if trait_def.is_marker {
+        // Overlapping marker implementations are not really specializations.
+        return None;
+    }
     Some(impl2_node)
 }
 
 /// Check that `impl1` is a sound specialization
 #[instrument(level = "debug", skip(tcx))]
 fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node) {
+    let span = tcx.def_span(impl1_def_id);
+    check_has_items(tcx, impl1_def_id, impl2_node, span);
+
     if let Some((impl1_substs, impl2_substs)) = get_impl_substs(tcx, impl1_def_id, impl2_node) {
         let impl2_def_id = impl2_node.def_id();
         debug!(?impl2_def_id, ?impl2_substs);
@@ -116,7 +123,6 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
             unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs)
         };
 
-        let span = tcx.def_span(impl1_def_id);
         check_constness(tcx, impl1_def_id, impl2_node, span);
         check_static_lifetimes(tcx, &parent_substs, span);
         check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
@@ -124,6 +130,13 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
     }
 }
 
+fn check_has_items(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) {
+    if let Node::Impl(impl2_id) = impl2_node && tcx.associated_item_def_ids(impl1_def_id).is_empty() {
+        let base_impl_span = tcx.def_span(impl2_id);
+        tcx.sess.emit_err(errors::EmptySpecialization { span, base_impl_span });
+    }
+}
+
 /// Check that the specializing impl `impl1` is at least as const as the base
 /// impl `impl2`
 fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) {
@@ -167,8 +180,21 @@ fn get_impl_substs(
         ocx.assumed_wf_types(param_env, tcx.def_span(impl1_def_id), impl1_def_id);
 
     let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);
-    let impl2_substs =
-        translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
+    let impl1_span = tcx.def_span(impl1_def_id);
+    let impl2_substs = translate_substs_with_cause(
+        infcx,
+        param_env,
+        impl1_def_id.to_def_id(),
+        impl1_substs,
+        impl2_node,
+        |_, span| {
+            traits::ObligationCause::new(
+                impl1_span,
+                impl1_def_id,
+                traits::ObligationCauseCode::BindingObligation(impl2_node.def_id(), span),
+            )
+        },
+    );
 
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 9d59cdcbc60..2defca54aff 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -86,9 +86,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error);
         self.note_type_is_not_clone(err, expected, expr_ty, expr);
         self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty);
-        self.check_for_range_as_method_call(err, expr, expr_ty, expected);
-        self.check_for_binding_assigned_block_without_tail_expression(err, expr, expr_ty, expected);
-        self.check_wrong_return_type_due_to_generic_arg(err, expr, expr_ty);
+        self.suggest_method_call_on_range_literal(err, expr, expr_ty, expected);
+        self.suggest_return_binding_for_missing_tail_expr(err, expr, expr_ty, expected);
+        self.note_wrong_return_ty_due_to_generic_arg(err, expr, expr_ty);
     }
 
     /// Requires that the two types unify, and prints an error message if
@@ -1087,7 +1087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// ```ignore (illustrative)
     /// opt.map(|param| { takes_ref(param) });
     /// ```
-    fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, String)> {
+    fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Vec<(Span, String)>, &'static str)> {
         let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.kind else {
             return None;
         };
@@ -1133,12 +1133,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             _ => false,
         };
-        match (is_as_ref_able, self.sess().source_map().span_to_snippet(method_path.ident.span)) {
-            (true, Ok(src)) => {
-                let suggestion = format!("as_ref().{}", src);
-                Some((method_path.ident.span, "consider using `as_ref` instead", suggestion))
-            }
-            _ => None,
+        if is_as_ref_able {
+            Some((
+                vec![(method_path.ident.span.shrink_to_lo(), "as_ref().".to_string())],
+                "consider using `as_ref` instead",
+            ))
+        } else {
+            None
         }
     }
 
@@ -1217,14 +1218,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// In addition of this check, it also checks between references mutability state. If the
     /// expected is mutable but the provided isn't, maybe we could just say "Hey, try with
     /// `&mut`!".
-    pub fn check_ref(
+    pub fn suggest_deref_or_ref(
         &self,
         expr: &hir::Expr<'tcx>,
         checked_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
     ) -> Option<(
-        Span,
-        String,
+        Vec<(Span, String)>,
         String,
         Applicability,
         bool, /* verbose */
@@ -1254,30 +1254,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         && let Ok(src) = sm.span_to_snippet(sp)
                         && replace_prefix(&src, "b\"", "\"").is_some()
                     {
-                                let pos = sp.lo() + BytePos(1);
-                                return Some((
-                                    sp.with_hi(pos),
-                                    "consider removing the leading `b`".to_string(),
-                                    String::new(),
-                                    Applicability::MachineApplicable,
-                                    true,
-                                    false,
-                                ));
-                            }
-                        }
+                        let pos = sp.lo() + BytePos(1);
+                        return Some((
+                            vec![(sp.with_hi(pos), String::new())],
+                            "consider removing the leading `b`".to_string(),
+                            Applicability::MachineApplicable,
+                            true,
+                            false,
+                        ));
+                    }
+                }
                 (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => {
                     if let hir::ExprKind::Lit(_) = expr.kind
                         && let Ok(src) = sm.span_to_snippet(sp)
                         && replace_prefix(&src, "\"", "b\"").is_some()
                     {
-                                return Some((
-                                    sp.shrink_to_lo(),
-                                    "consider adding a leading `b`".to_string(),
-                                    "b".to_string(),
-                                    Applicability::MachineApplicable,
-                                    true,
-                                    false,
-                                ));
+                        return Some((
+                            vec![(sp.shrink_to_lo(), "b".to_string())],
+                            "consider adding a leading `b`".to_string(),
+                            Applicability::MachineApplicable,
+                            true,
+                            false,
+                        ));
                     }
                 }
                 _ => {}
@@ -1320,66 +1318,73 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
 
                     if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner) = expr.kind
-                        && let Some(1) = self.deref_steps(expected, checked_ty) {
+                        && let Some(1) = self.deref_steps(expected, checked_ty)
+                    {
                         // We have `*&T`, check if what was expected was `&T`.
                         // If so, we may want to suggest removing a `*`.
                         sugg_sp = sugg_sp.with_hi(inner.span.lo());
                         return Some((
-                            sugg_sp,
+                            vec![(sugg_sp, String::new())],
                             "consider removing deref here".to_string(),
-                            "".to_string(),
                             Applicability::MachineApplicable,
                             true,
                             false,
                         ));
                     }
 
-                    if let Ok(src) = sm.span_to_snippet(sugg_sp) {
-                        let needs_parens = match expr.kind {
-                            // parenthesize if needed (Issue #46756)
-                            hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
-                            // parenthesize borrows of range literals (Issue #54505)
-                            _ if is_range_literal(expr) => true,
-                            _ => false,
-                        };
-
-                        if let Some(sugg) = self.can_use_as_ref(expr) {
-                            return Some((
-                                sugg.0,
-                                sugg.1.to_string(),
-                                sugg.2,
-                                Applicability::MachineApplicable,
-                                false,
-                                false,
-                            ));
-                        }
-
-                        let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
-                            Some(ident) => format!("{ident}: "),
-                            None => String::new(),
-                        };
-
-                        if let Some(hir::Node::Expr(hir::Expr {
-                            kind: hir::ExprKind::Assign(..),
-                            ..
-                        })) = self.tcx.hir().find_parent(expr.hir_id)
-                        {
-                            if mutability.is_mut() {
-                                // Suppressing this diagnostic, we'll properly print it in `check_expr_assign`
-                                return None;
-                            }
-                        }
+                    let needs_parens = match expr.kind {
+                        // parenthesize if needed (Issue #46756)
+                        hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
+                        // parenthesize borrows of range literals (Issue #54505)
+                        _ if is_range_literal(expr) => true,
+                        _ => false,
+                    };
 
-                        let sugg_expr = if needs_parens { format!("({src})") } else { src };
+                    if let Some((sugg, msg)) = self.can_use_as_ref(expr) {
                         return Some((
-                            sp,
-                            format!("consider {}borrowing here", mutability.mutably_str()),
-                            format!("{prefix}{}{sugg_expr}", mutability.ref_prefix_str()),
+                            sugg,
+                            msg.to_string(),
                             Applicability::MachineApplicable,
-                            false,
+                            true,
                             false,
                         ));
                     }
+
+                    let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
+                        Some(ident) => format!("{ident}: "),
+                        None => String::new(),
+                    };
+
+                    if let Some(hir::Node::Expr(hir::Expr {
+                        kind: hir::ExprKind::Assign(..),
+                        ..
+                    })) = self.tcx.hir().find_parent(expr.hir_id)
+                    {
+                        if mutability.is_mut() {
+                            // Suppressing this diagnostic, we'll properly print it in `check_expr_assign`
+                            return None;
+                        }
+                    }
+
+                    let sugg = mutability.ref_prefix_str();
+                    let (sugg, verbose) = if needs_parens {
+                        (
+                            vec![
+                                (sp.shrink_to_lo(), format!("{prefix}{sugg}(")),
+                                (sp.shrink_to_hi(), ")".to_string()),
+                            ],
+                            false,
+                        )
+                    } else {
+                        (vec![(sp.shrink_to_lo(), format!("{prefix}{sugg}"))], true)
+                    };
+                    return Some((
+                        sugg,
+                        format!("consider {}borrowing here", mutability.mutably_str()),
+                        Applicability::MachineApplicable,
+                        verbose,
+                        false,
+                    ));
                 }
             }
             (
@@ -1401,23 +1406,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         && sm.is_span_accessible(call_span)
                     {
                         return Some((
-                            sp.with_hi(call_span.lo()),
+                            vec![(sp.with_hi(call_span.lo()), String::new())],
                             "consider removing the borrow".to_string(),
-                            String::new(),
                             Applicability::MachineApplicable,
                             true,
-                            true
+                            true,
                         ));
                     }
                     return None;
                 }
-                if sp.contains(expr.span)
-                    && sm.is_span_accessible(expr.span)
-                {
+                if sp.contains(expr.span) && sm.is_span_accessible(expr.span) {
                     return Some((
-                        sp.with_hi(expr.span.lo()),
+                        vec![(sp.with_hi(expr.span.lo()), String::new())],
                         "consider removing the borrow".to_string(),
-                        String::new(),
                         Applicability::MachineApplicable,
                         true,
                         true,
@@ -1441,23 +1442,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                     let suggestion = replace_prefix(&src, old_prefix, &new_prefix).map(|_| {
                         // skip `&` or `&mut ` if both mutabilities are mutable
-                        let lo = sp.lo() + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _);
+                        let lo = sp.lo()
+                            + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _);
                         // skip `&` or `&mut `
                         let hi = sp.lo() + BytePos(old_prefix.len() as _);
                         let sp = sp.with_lo(lo).with_hi(hi);
 
                         (
                             sp,
-                            format!("{}{derefs}", if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }),
-                            if mutbl_b <= mutbl_a { Applicability::MachineApplicable } else { Applicability::MaybeIncorrect }
+                            format!(
+                                "{}{derefs}",
+                                if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }
+                            ),
+                            if mutbl_b <= mutbl_a {
+                                Applicability::MachineApplicable
+                            } else {
+                                Applicability::MaybeIncorrect
+                            },
                         )
                     });
 
                     if let Some((span, src, applicability)) = suggestion {
                         return Some((
-                            span,
+                            vec![(span, src)],
                             "consider dereferencing".to_string(),
-                            src,
                             applicability,
                             true,
                             false,
@@ -1486,9 +1494,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // If we've reached our target type with just removing `&`, then just print now.
                     if steps == 0 && !remove.trim().is_empty() {
                         return Some((
-                            prefix_span,
+                            vec![(prefix_span, String::new())],
                             format!("consider removing the `{}`", remove.trim()),
-                            String::new(),
                             // Do not remove `&&` to get to bool, because it might be something like
                             // { a } && b, which we have a separate fixup suggestion that is more
                             // likely correct...
@@ -1554,9 +1561,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
 
                         return Some((
-                            span,
+                            vec![(span, suggestion)],
                             message,
-                            suggestion,
                             Applicability::MachineApplicable,
                             true,
                             false,
@@ -1569,7 +1575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         None
     }
 
-    pub fn check_for_cast(
+    pub fn suggest_cast(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
@@ -1936,7 +1942,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Identify when the user has written `foo..bar()` instead of `foo.bar()`.
-    pub fn check_for_range_as_method_call(
+    pub fn suggest_method_call_on_range_literal(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'tcx>,
@@ -2005,7 +2011,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Identify when the type error is because `()` is found in a binding that was assigned a
     /// block without a tail expression.
-    fn check_for_binding_assigned_block_without_tail_expression(
+    fn suggest_return_binding_for_missing_tail_expr(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
@@ -2047,7 +2053,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_wrong_return_type_due_to_generic_arg(
+    fn note_wrong_return_ty_due_to_generic_arg(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 2867fcc8ecd..c4add4dbdfb 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -275,13 +275,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
     ) -> bool {
         let expr = expr.peel_blocks();
-        if let Some((sp, msg, suggestion, applicability, verbose, annotation)) =
-            self.check_ref(expr, found, expected)
+        if let Some((suggestion, msg, applicability, verbose, annotation)) =
+            self.suggest_deref_or_ref(expr, found, expected)
         {
             if verbose {
-                err.span_suggestion_verbose(sp, msg, suggestion, applicability);
+                err.multipart_suggestion_verbose(msg, suggestion, applicability);
             } else {
-                err.span_suggestion(sp, msg, suggestion, applicability);
+                err.multipart_suggestion(msg, suggestion, applicability);
             }
             if annotation {
                 let suggest_annotation = match expr.peel_drop_temps().kind {
@@ -343,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 err.span_label(sp, format!("{descr} `{name}` defined here"));
             }
             return true;
-        } else if self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
+        } else if self.suggest_cast(err, expr, found, expected, expected_ty_expr) {
             return true;
         } else {
             let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 3741672e568..486c217707e 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1045,7 +1045,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
 
-        self.check_for_inner_self(&mut err, source, rcvr_ty, item_name);
+        self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name);
 
         bound_spans.sort();
         bound_spans.dedup();
@@ -1132,7 +1132,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        self.check_for_deref_method(&mut err, source, rcvr_ty, item_name, expected);
+        self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
         return Some(err);
     }
 
@@ -1805,7 +1805,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_for_inner_self(
+    fn suggest_unwrapping_inner_self(
         &self,
         err: &mut Diagnostic,
         source: SelfSource<'tcx>,
@@ -2175,7 +2175,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_for_deref_method(
+    fn note_derefed_ty_has_method(
         &self,
         err: &mut Diagnostic,
         self_source: SelfSource<'tcx>,
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index bd84681cbb4..a536eb3b04e 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -140,7 +140,7 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
 /// ```fluent
 /// parser_expected_identifier = expected identifier
 ///
-/// parser_expected_identifier-found = expected identifier, found {$found}
+/// parser_expected_identifier_found = expected identifier, found {$found}
 ///
 /// parser_raw_identifier = escape `{$ident}` to use it as an identifier
 /// ```
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 858a3d266ea..f2841182a1a 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2728,8 +2728,6 @@ pub struct UserTypeProjection {
     pub projs: Vec<ProjectionKind>,
 }
 
-impl Copy for ProjectionKind {}
-
 impl UserTypeProjection {
     pub(crate) fn index(mut self) -> Self {
         self.projs.push(ProjectionElem::Index(()));
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index cd296dca133..1bbf833e3cd 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -257,6 +257,10 @@ parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are inva
     .tuple_exception_line_2 = on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access
     .tuple_exception_line_3 = see issue #60210 <https://github.com/rust-lang/rust/issues/60210> for more information
 
+parse_expected_builtin_ident = expected identifier after `builtin #`
+
+parse_unknown_builtin_construct = unknown `builtin #` construct `{$name}`
+
 parse_non_string_abi_literal = non-string ABI literal
     .suggestion = specify the ABI with a string literal
 
@@ -339,6 +343,7 @@ parse_expected_identifier = expected identifier
 parse_sugg_escape_identifier = escape `{$ident_name}` to use it as an identifier
 
 parse_sugg_remove_comma = remove this comma
+parse_sugg_add_let_for_stmt = you might have meant to introduce a new binding
 
 parse_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token}`
 parse_expected_semi_found_keyword_str = expected `;`, found keyword `{$token}`
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 010a13aefa4..b6aeaf3d59f 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -907,6 +907,18 @@ pub(crate) struct SuggRemoveComma {
 }
 
 #[derive(Subdiagnostic)]
+#[suggestion(
+    parse_sugg_add_let_for_stmt,
+    style = "verbose",
+    applicability = "maybe-incorrect",
+    code = "let "
+)]
+pub(crate) struct SuggAddMissingLetStmt {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Subdiagnostic)]
 pub(crate) enum ExpectedIdentifierFound {
     #[label(parse_expected_identifier_found_reserved_identifier)]
     ReservedIdentifier(#[primary_span] Span),
@@ -2644,3 +2656,18 @@ pub(crate) struct MalformedCfgAttr {
     pub span: Span,
     pub sugg: &'static str,
 }
+
+#[derive(Diagnostic)]
+#[diag(parse_unknown_builtin_construct)]
+pub(crate) struct UnknownBuiltinConstruct {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_expected_builtin_ident)]
+pub(crate) struct ExpectedBuiltinIdent {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 36883bd2172..3002f23da75 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -13,7 +13,7 @@ use crate::errors::{
     IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg,
     PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst,
     StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens,
-    StructLiteralNeedingParensSugg, SuggEscapeIdentifier, SuggRemoveComma,
+    StructLiteralNeedingParensSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma,
     UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
     UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead,
 };
@@ -32,8 +32,8 @@ use rustc_ast::{
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{
-    pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed,
-    FatalError, Handler, IntoDiagnostic, MultiSpan, PResult,
+    pluralize, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage,
+    ErrorGuaranteed, FatalError, Handler, IntoDiagnostic, MultiSpan, PResult,
 };
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
@@ -1006,6 +1006,31 @@ impl<'a> Parser<'a> {
         Err(e)
     }
 
+    /// Suggest add the missing `let` before the identifier in stmt
+    /// `a: Ty = 1` -> `let a: Ty = 1`
+    pub(super) fn suggest_add_missing_let_for_stmt(
+        &mut self,
+        err: &mut DiagnosticBuilder<'a, ErrorGuaranteed>,
+    ) {
+        if self.token == token::Colon {
+            let prev_span = self.prev_token.span.shrink_to_lo();
+            let snapshot = self.create_snapshot_for_diagnostic();
+            self.bump();
+            match self.parse_ty() {
+                Ok(_) => {
+                    if self.token == token::Eq {
+                        let sugg = SuggAddMissingLetStmt { span: prev_span };
+                        sugg.add_to_diagnostic(err);
+                    }
+                }
+                Err(e) => {
+                    e.cancel();
+                }
+            }
+            self.restore_snapshot(snapshot);
+        }
+    }
+
     /// Check to see if a pair of chained operators looks like an attempt at chained comparison,
     /// e.g. `1 < x <= 3`. If so, suggest either splitting the comparison into two, or
     /// parenthesising the leftmost comparison.
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 018eddea4b0..887e155426f 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1300,6 +1300,8 @@ impl<'a> Parser<'a> {
             })
         } else if self.check(&token::OpenDelim(Delimiter::Bracket)) {
             self.parse_expr_array_or_repeat(Delimiter::Bracket)
+        } else if self.is_builtin() {
+            self.parse_expr_builtin()
         } else if self.check_path() {
             self.parse_expr_path_start()
         } else if self.check_keyword(kw::Move)
@@ -1766,6 +1768,61 @@ impl<'a> Parser<'a> {
         self.maybe_recover_from_bad_qpath(expr)
     }
 
+    /// Parse `builtin # ident(args,*)`.
+    fn parse_expr_builtin(&mut self) -> PResult<'a, P<Expr>> {
+        self.parse_builtin(|this, lo, ident| {
+            if ident.name == sym::offset_of {
+                return Ok(Some(this.parse_expr_offset_of(lo)?));
+            }
+
+            Ok(None)
+        })
+    }
+
+    pub(crate) fn parse_builtin<T>(
+        &mut self,
+        parse: impl FnOnce(&mut Parser<'a>, Span, Ident) -> PResult<'a, Option<T>>,
+    ) -> PResult<'a, T> {
+        let lo = self.token.span;
+
+        self.bump(); // `builtin`
+        self.bump(); // `#`
+
+        let Some((ident, false)) = self.token.ident() else {
+            let err = errors::ExpectedBuiltinIdent { span: self.token.span }
+                .into_diagnostic(&self.sess.span_diagnostic);
+            return Err(err);
+        };
+        self.sess.gated_spans.gate(sym::builtin_syntax, ident.span);
+        self.bump();
+
+        self.expect(&TokenKind::OpenDelim(Delimiter::Parenthesis))?;
+        let ret = if let Some(res) = parse(self, lo, ident)? {
+            Ok(res)
+        } else {
+            let err = errors::UnknownBuiltinConstruct { span: lo.to(ident.span), name: ident.name }
+                .into_diagnostic(&self.sess.span_diagnostic);
+            return Err(err);
+        };
+        self.expect(&TokenKind::CloseDelim(Delimiter::Parenthesis))?;
+
+        ret
+    }
+
+    pub(crate) fn parse_expr_offset_of(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
+        let container = self.parse_ty()?;
+        self.expect(&TokenKind::Comma)?;
+
+        let seq_sep = SeqSep { sep: Some(token::Dot), trailing_sep_allowed: false };
+        let (fields, _trailing, _recovered) = self.parse_seq_to_before_end(
+            &TokenKind::CloseDelim(Delimiter::Parenthesis),
+            seq_sep,
+            Parser::parse_field_name,
+        )?;
+        let span = lo.to(self.token.span);
+        Ok(self.mk_expr(span, ExprKind::OffsetOf(container, fields.to_vec().into())))
+    }
+
     /// Returns a string literal if the next token is a string literal.
     /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
     /// and returns `None` if the next token is not literal at all.
@@ -2835,6 +2892,10 @@ impl<'a> Parser<'a> {
         })
     }
 
+    pub(crate) fn is_builtin(&self) -> bool {
+        self.token.is_keyword(kw::Builtin) && self.look_ahead(1, |t| *t == token::Pound)
+    }
+
     /// Parses a `try {...}` expression (`try` token already eaten).
     fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> {
         let (attrs, body) = self.parse_inner_attrs_and_block()?;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 49e05efd39d..840cfe90899 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -265,6 +265,9 @@ impl<'a> Parser<'a> {
             // UNION ITEM
             self.bump(); // `union`
             self.parse_item_union()?
+        } else if self.is_builtin() {
+            // BUILTIN# ITEM
+            return self.parse_item_builtin();
         } else if self.eat_keyword(kw::Macro) {
             // MACROS 2.0 ITEM
             self.parse_item_decl_macro(lo)?
@@ -434,6 +437,11 @@ impl<'a> Parser<'a> {
         }
     }
 
+    fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> {
+        // To be expanded
+        return Ok(None);
+    }
+
     /// Parses an item macro, e.g., `item!();`.
     fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
         let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 1c17de337e8..03279124177 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -90,7 +90,11 @@ impl<'a> Parser<'a> {
                 attrs,
                 errors::InvalidVariableDeclarationSub::UseLetNotVar,
             )?
-        } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
+        } else if self.check_path()
+            && !self.token.is_qpath_start()
+            && !self.is_path_start_item()
+            && !self.is_builtin()
+        {
             // We have avoided contextual keywords like `union`, items with `crate` visibility,
             // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
             // that starts like a path (1 token), but it fact not a path.
@@ -99,7 +103,13 @@ impl<'a> Parser<'a> {
                 ForceCollect::Yes => {
                     self.collect_tokens_no_attrs(|this| this.parse_stmt_path_start(lo, attrs))?
                 }
-                ForceCollect::No => self.parse_stmt_path_start(lo, attrs)?,
+                ForceCollect::No => match self.parse_stmt_path_start(lo, attrs) {
+                    Ok(stmt) => stmt,
+                    Err(mut err) => {
+                        self.suggest_add_missing_let_for_stmt(&mut err);
+                        return Err(err);
+                    }
+                },
             }
         } else if let Some(item) = self.parse_item_common(
             attrs.clone(),
@@ -555,7 +565,6 @@ impl<'a> Parser<'a> {
                     if self.token == token::Colon {
                         // if next token is following a colon, it's likely a path
                         // and we can suggest a path separator
-                        let ident_span = self.prev_token.span;
                         self.bump();
                         if self.token.span.lo() == self.prev_token.span.hi() {
                             err.span_suggestion_verbose(
@@ -565,14 +574,6 @@ impl<'a> Parser<'a> {
                                 Applicability::MaybeIncorrect,
                             );
                         }
-                        if self.look_ahead(1, |token| token == &token::Eq) {
-                            err.span_suggestion_verbose(
-                                ident_span.shrink_to_lo(),
-                                "you might have meant to introduce a new binding",
-                                "let ",
-                                Applicability::MaybeIncorrect,
-                            );
-                        }
                         if self.sess.unstable_features.is_nightly_build() {
                             // FIXME(Nilstrieb): Remove this again after a few months.
                             err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index b97ec6c684b..117e2774bd8 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -95,6 +95,7 @@ symbols! {
 
         // Weak keywords, have special meaning only in specific contexts.
         Auto:               "auto",
+        Builtin:            "builtin",
         Catch:              "catch",
         Default:            "default",
         MacroRules:         "macro_rules",
@@ -440,6 +441,7 @@ symbols! {
         breakpoint,
         bridge,
         bswap,
+        builtin_syntax,
         c_str,
         c_str_literals,
         c_unwind,
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 402b09419c8..969e5fa64b0 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -322,7 +322,9 @@ fn negative_impl(tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId) -> b
     let selcx = &mut SelectionContext::new(&infcx);
     let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id);
     let (subject2, obligations) =
-        impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs);
+        impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs, |_, _| {
+            ObligationCause::dummy()
+        });
 
     !equate(&infcx, impl_env, subject1, subject2, obligations, impl1_def_id)
 }
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index b162e5b8995..38daca5377a 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -55,7 +55,9 @@ pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
 pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
 pub use self::specialize::specialization_graph::FutureCompatOverlapError;
 pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
-pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
+pub use self::specialize::{
+    specialization_graph, translate_substs, translate_substs_with_cause, OverlapError,
+};
 pub use self::structural_match::{
     search_for_adt_const_param_violation, search_for_structural_match_violation,
 };
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 233d35aed38..9a4b72013b8 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -83,6 +83,30 @@ pub fn translate_substs<'tcx>(
     source_substs: SubstsRef<'tcx>,
     target_node: specialization_graph::Node,
 ) -> SubstsRef<'tcx> {
+    translate_substs_with_cause(
+        infcx,
+        param_env,
+        source_impl,
+        source_substs,
+        target_node,
+        |_, _| ObligationCause::dummy(),
+    )
+}
+
+/// Like [translate_substs], but obligations from the parent implementation
+/// are registered with the provided `ObligationCause`.
+///
+/// This is for reporting *region* errors from those bounds. Type errors should
+/// not happen because the specialization graph already checks for those, and
+/// will result in an ICE.
+pub fn translate_substs_with_cause<'tcx>(
+    infcx: &InferCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    source_impl: DefId,
+    source_substs: SubstsRef<'tcx>,
+    target_node: specialization_graph::Node,
+    cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
+) -> SubstsRef<'tcx> {
     debug!(
         "translate_substs({:?}, {:?}, {:?}, {:?})",
         param_env, source_impl, source_substs, target_node
@@ -99,14 +123,13 @@ pub fn translate_substs<'tcx>(
                 return source_substs;
             }
 
-            fulfill_implication(infcx, param_env, source_trait_ref, target_impl).unwrap_or_else(
-                |()| {
+            fulfill_implication(infcx, param_env, source_trait_ref, source_impl, target_impl, cause)
+                .unwrap_or_else(|()| {
                     bug!(
                         "When translating substitutions from {source_impl:?} to {target_impl:?}, \
                         the expected specialization failed to hold"
                     )
-                },
-            )
+                })
         }
         specialization_graph::Node::Trait(..) => source_trait_ref.substs,
     };
@@ -153,20 +176,12 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
 
     // Create an infcx, taking the predicates of impl1 as assumptions:
     let infcx = tcx.infer_ctxt().build();
-    let impl1_trait_ref =
-        match traits::fully_normalize(&infcx, ObligationCause::dummy(), penv, impl1_trait_ref) {
-            Ok(impl1_trait_ref) => impl1_trait_ref,
-            Err(_errors) => {
-                tcx.sess.delay_span_bug(
-                    tcx.def_span(impl1_def_id),
-                    format!("failed to fully normalize {impl1_trait_ref}"),
-                );
-                impl1_trait_ref
-            }
-        };
 
     // Attempt to prove that impl2 applies, given all of the above.
-    fulfill_implication(&infcx, penv, impl1_trait_ref, impl2_def_id).is_ok()
+    fulfill_implication(&infcx, penv, impl1_trait_ref, impl1_def_id, impl2_def_id, |_, _| {
+        ObligationCause::dummy()
+    })
+    .is_ok()
 }
 
 /// Attempt to fulfill all obligations of `target_impl` after unification with
@@ -178,23 +193,41 @@ fn fulfill_implication<'tcx>(
     infcx: &InferCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     source_trait_ref: ty::TraitRef<'tcx>,
+    source_impl: DefId,
     target_impl: DefId,
+    error_cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
 ) -> Result<SubstsRef<'tcx>, ()> {
     debug!(
         "fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)",
         param_env, source_trait_ref, target_impl
     );
 
+    let source_trait_ref = match traits::fully_normalize(
+        &infcx,
+        ObligationCause::dummy(),
+        param_env,
+        source_trait_ref,
+    ) {
+        Ok(source_trait_ref) => source_trait_ref,
+        Err(_errors) => {
+            infcx.tcx.sess.delay_span_bug(
+                infcx.tcx.def_span(source_impl),
+                format!("failed to fully normalize {source_trait_ref}"),
+            );
+            source_trait_ref
+        }
+    };
+
     let source_trait = ImplSubject::Trait(source_trait_ref);
 
     let selcx = &mut SelectionContext::new(&infcx);
     let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
     let (target_trait, obligations) =
-        util::impl_subject_and_oblig(selcx, param_env, target_impl, target_substs);
+        util::impl_subject_and_oblig(selcx, param_env, target_impl, target_substs, error_cause);
 
     // do the impls unify? If not, no specialization.
     let Ok(InferOk { obligations: more_obligations, .. }) =
-        infcx.at(&ObligationCause::dummy(), param_env, ).eq(DefineOpaqueTypes::No,source_trait, target_trait)
+        infcx.at(&ObligationCause::dummy(), param_env).eq(DefineOpaqueTypes::No, source_trait, target_trait)
     else {
         debug!(
             "fulfill_implication: {:?} does not unify with {:?}",
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 7b7e297c64b..82f3df40198 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -197,6 +197,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
     param_env: ty::ParamEnv<'tcx>,
     impl_def_id: DefId,
     impl_substs: SubstsRef<'tcx>,
+    cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
 ) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
     let subject = selcx.tcx().impl_subject(impl_def_id);
     let subject = subject.subst(selcx.tcx(), impl_substs);
@@ -208,8 +209,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
     let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
     let InferOk { value: predicates, obligations: normalization_obligations2 } =
         selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates);
-    let impl_obligations =
-        super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates);
+    let impl_obligations = super::predicates_for_generics(cause, param_env, predicates);
 
     let impl_obligations = impl_obligations
         .chain(normalization_obligations1.into_iter())
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 7d2f2971523..4913a6de918 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -1315,9 +1315,9 @@ impl<T> SizedTypeProperties for T {}
 ///
 /// assert_eq!(mem::offset_of!(NestedA, b.0), 0);
 /// ```
-#[unstable(feature = "offset_of", issue = "106655")]
-#[rustc_builtin_macro]
 #[cfg(not(bootstrap))]
+#[unstable(feature = "offset_of", issue = "106655")]
+#[allow_internal_unstable(builtin_syntax)]
 pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) {
-    /* compiler built-in */
+    builtin # offset_of($Container, $($fields).+)
 }
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 6038be9d37d7251c966b486154af621d1794d7a
+Subproject f63e578b92ff43e8cc38fcaa257b660f45c8a8c
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 897fcf566f16bf87bf37199bdddec1801fd0053
+Subproject d9eb4c3f75435b008881062ffa77bf0d1527b37
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 1f8dc727e94ae4ef92adf70df979521a1ea1143
+Subproject 28dc0f3576b55f5e57c5d6e65cd68ba3161e9fd
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 31961fe22521a779070a44a8f30a2b00a20b621
+Subproject 8ee9528b72b927cff8fd32346db8bbd1198816f
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 2a5eb92197e9cf8fe91164dcbf4f9b88c0d7e73
+Subproject 28dbeaf5c44bc7f5111ad412e99f2d7c5cec6c9
diff --git a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
index e768a47a96d..e3757941c8c 100644
--- a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
+++ b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
@@ -22,17 +22,17 @@
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/offset_of.rs:+1:9: +1:10
--         _1 = OffsetOf(Alpha, [0]);       // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
-+         _1 = const 4_usize;              // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
+-         _1 = OffsetOf(Alpha, [0]);       // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
++         _1 = const 4_usize;              // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
           StorageLive(_2);                 // scope 1 at $DIR/offset_of.rs:+2:9: +2:10
--         _2 = OffsetOf(Alpha, [1]);       // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
-+         _2 = const 0_usize;              // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
+-         _2 = OffsetOf(Alpha, [1]);       // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
++         _2 = const 0_usize;              // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
           StorageLive(_3);                 // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
--         _3 = OffsetOf(Alpha, [2, 0]);    // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
-+         _3 = const 2_usize;              // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
+-         _3 = OffsetOf(Alpha, [2, 0]);    // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
++         _3 = const 2_usize;              // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
           StorageLive(_4);                 // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
--         _4 = OffsetOf(Alpha, [2, 1]);    // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
-+         _4 = const 3_usize;              // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
+-         _4 = OffsetOf(Alpha, [2, 1]);    // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
++         _4 = const 3_usize;              // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
           _0 = const ();                   // scope 0 at $DIR/offset_of.rs:+0:15: +5:2
           StorageDead(_4);                 // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
           StorageDead(_3);                 // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
diff --git a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
index e40fdbd79d8..4a655604cd1 100644
--- a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
+++ b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
@@ -22,13 +22,13 @@
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/offset_of.rs:+1:9: +1:11
-          _1 = OffsetOf(Gamma<T>, [0]);    // scope 0 at $DIR/offset_of.rs:+1:14: +1:37
+          _1 = OffsetOf(Gamma<T>, [0]);    // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
           StorageLive(_2);                 // scope 1 at $DIR/offset_of.rs:+2:9: +2:11
-          _2 = OffsetOf(Gamma<T>, [1]);    // scope 1 at $DIR/offset_of.rs:+2:14: +2:37
+          _2 = OffsetOf(Gamma<T>, [1]);    // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
           StorageLive(_3);                 // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
-          _3 = OffsetOf(Delta<T>, [1]);    // scope 2 at $DIR/offset_of.rs:+3:14: +3:37
+          _3 = OffsetOf(Delta<T>, [1]);    // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
           StorageLive(_4);                 // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
-          _4 = OffsetOf(Delta<T>, [2]);    // scope 3 at $DIR/offset_of.rs:+4:14: +4:37
+          _4 = OffsetOf(Delta<T>, [2]);    // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
           _0 = const ();                   // scope 0 at $DIR/offset_of.rs:+0:17: +5:2
           StorageDead(_4);                 // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
           StorageDead(_3);                 // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
diff --git a/tests/run-make/branch-protection-check-IBT/Makefile b/tests/run-make/branch-protection-check-IBT/Makefile
new file mode 100644
index 00000000000..cabe951e1c5
--- /dev/null
+++ b/tests/run-make/branch-protection-check-IBT/Makefile
@@ -0,0 +1,15 @@
+# Check for GNU Property Note
+
+include ../tools.mk
+
+# How to run this
+# python3 x.py test --target x86_64-unknown-linux-gnu  tests/run-make/branch-protection-check-IBT/
+
+# only-x86_64
+
+all:
+ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86_64)
+	$(RUSTC) --target x86_64-unknown-linux-gnu -Z cf-protection=branch -L$(TMPDIR) -C link-args='-nostartfiles'  -C save-temps  ./main.rs -o $(TMPDIR)/rsmain
+	 readelf -nW $(TMPDIR)/rsmain | $(CGREP) -e ".note.gnu.property"
+endif
+
diff --git a/tests/run-make/branch-protection-check-IBT/main.rs b/tests/run-make/branch-protection-check-IBT/main.rs
new file mode 100644
index 00000000000..ad379d6ea43
--- /dev/null
+++ b/tests/run-make/branch-protection-check-IBT/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+    println!("hello world");
+}
diff --git a/tests/ui/argument-suggestions/issue-97484.stderr b/tests/ui/argument-suggestions/issue-97484.stderr
index a86cbbf1802..082564fbc7f 100644
--- a/tests/ui/argument-suggestions/issue-97484.stderr
+++ b/tests/ui/argument-suggestions/issue-97484.stderr
@@ -16,7 +16,7 @@ LL | fn foo(a: &A, d: D, e: &E, g: G) {}
 help: consider borrowing here
    |
 LL |     foo(&&A, B, C, D, &E, F, G);
-   |                       ~~
+   |                       +
 help: remove the extra arguments
    |
 LL -     foo(&&A, B, C, D, E, F, G);
diff --git a/tests/ui/array-slice-vec/slice-mut-2.stderr b/tests/ui/array-slice-vec/slice-mut-2.stderr
index 5b040d3e4d3..c33919c41cd 100644
--- a/tests/ui/array-slice-vec/slice-mut-2.stderr
+++ b/tests/ui/array-slice-vec/slice-mut-2.stderr
@@ -7,7 +7,7 @@ LL |     let _ = &mut x[2..4];
 help: consider changing this to be a mutable reference
    |
 LL |     let x: &[isize] = &mut [1, 2, 3, 4, 5];
-   |                       ~~~~~~~~~~~~~~~~~~~~
+   |                        +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/async-await/issues/issue-102206.stderr b/tests/ui/async-await/issues/issue-102206.stderr
index 750b7a886ef..cd845056805 100644
--- a/tests/ui/async-await/issues/issue-102206.stderr
+++ b/tests/ui/async-await/issues/issue-102206.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-102206.rs:6:27
    |
 LL |     std::mem::size_of_val(foo());
-   |     --------------------- ^^^^^
-   |     |                     |
-   |     |                     expected `&_`, found future
-   |     |                     help: consider borrowing here: `&foo()`
+   |     --------------------- ^^^^^ expected `&_`, found future
+   |     |
    |     arguments to this function are incorrect
    |
 note: function defined here
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+help: consider borrowing here
+   |
+LL |     std::mem::size_of_val(&foo());
+   |                           +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr b/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr
index 4cc1d821d0a..cfc86ff0dc1 100644
--- a/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr
+++ b/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr
@@ -7,7 +7,7 @@ LL |     let q = &raw mut *x;
 help: consider changing this to be a mutable reference
    |
 LL |     let x = &mut 0;
-   |             ~~~~~~
+   |              +++
 
 error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
   --> $DIR/borrow-raw-address-of-deref-mutability.rs:14:13
@@ -18,7 +18,7 @@ LL |     let q = &raw mut *x;
 help: consider changing this to be a mutable pointer
    |
 LL |     let x = &mut 0 as *const i32;
-   |             ~~~~~~
+   |              +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/borrowck/borrowck-access-permissions.stderr b/tests/ui/borrowck/borrowck-access-permissions.stderr
index 26f3e2bbdb7..c161e2d95b4 100644
--- a/tests/ui/borrowck/borrowck-access-permissions.stderr
+++ b/tests/ui/borrowck/borrowck-access-permissions.stderr
@@ -35,7 +35,7 @@ LL |         let _y1 = &mut *ref_x;
 help: consider changing this to be a mutable reference
    |
 LL |         let ref_x = &mut x;
-   |                     ~~~~~~
+   |                      +++
 
 error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
   --> $DIR/borrowck-access-permissions.rs:39:23
@@ -46,7 +46,7 @@ LL |             let _y1 = &mut *ptr_x;
 help: consider changing this to be a mutable pointer
    |
 LL |         let ptr_x : *const _ = &mut x;
-   |                                ~~~~~~
+   |                                 +++
 
 error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-access-permissions.rs:48:18
@@ -57,7 +57,7 @@ LL |         let _y = &mut *foo_ref.f;
 help: consider changing this to be a mutable reference
    |
 LL |         let foo_ref = &mut foo;
-   |                       ~~~~~~~~
+   |                        +++
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr b/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr
index cbacc87a0e8..cf0c4127d82 100644
--- a/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr
+++ b/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr
@@ -6,8 +6,8 @@ LL |     *s.pointer += 1;
    |
 help: consider changing this to be a mutable reference
    |
-LL | fn a(s: &mut S<'_>) {
-   |         ~~~~~~~~~~
+LL | fn a(s: &mut S) {
+   |          +++
 
 error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
   --> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:17:5
@@ -17,8 +17,8 @@ LL |     *s.pointer += 1;
    |
 help: consider changing this to be a mutable reference
    |
-LL | fn c(s: &mut &mut S<'_>) {
-   |         ~~~~~~~~~~~~~~~
+LL | fn c(s: &mut  &mut S) {
+   |          +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr b/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
index dd0817ff233..59ef61b19d5 100644
--- a/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
+++ b/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
@@ -27,8 +27,8 @@ LL |     let x:  &mut isize = &mut **t0;
    |
 help: consider changing this to be a mutable reference
    |
-LL | fn foo4(t0: &mut &mut isize) {
-   |             ~~~~~~~~~~~~~~~
+LL | fn foo4(t0: &mut  &mut isize) {
+   |              +++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/borrowck/borrowck-issue-14498.stderr b/tests/ui/borrowck/borrowck-issue-14498.stderr
index 374c5ee3ed2..12d67d536d9 100644
--- a/tests/ui/borrowck/borrowck-issue-14498.stderr
+++ b/tests/ui/borrowck/borrowck-issue-14498.stderr
@@ -7,7 +7,7 @@ LL |     ***p = 2;
 help: consider changing this to be a mutable reference
    |
 LL |     let p = &mut y;
-   |             ~~~~~~
+   |              +++
 
 error[E0506]: cannot assign to `**y` because it is borrowed
   --> $DIR/borrowck-issue-14498.rs:25:5
diff --git a/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr b/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr
index d9590e446c7..fb3db4e1446 100644
--- a/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr
+++ b/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr
@@ -111,7 +111,7 @@ LL |     let _bar1 = &mut foo.bar1;
 help: consider changing this to be a mutable reference
    |
 LL | fn borrow_mut_from_imm(foo: &mut Foo) {
-   |                             ~~~~~~~~
+   |                              +++
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/borrowck/issue-85765.stderr b/tests/ui/borrowck/issue-85765.stderr
index b4bb128cbb4..2985a658fdd 100644
--- a/tests/ui/borrowck/issue-85765.stderr
+++ b/tests/ui/borrowck/issue-85765.stderr
@@ -18,7 +18,7 @@ LL |     *r = 0;
 help: consider changing this to be a mutable reference
    |
 LL |     let r = &mut mutvar;
-   |             ~~~~~~~~~~~
+   |              +++
 
 error[E0594]: cannot assign to `*x`, which is behind a `&` reference
   --> $DIR/issue-85765.rs:19:5
diff --git a/tests/ui/borrowck/mutability-errors.stderr b/tests/ui/borrowck/mutability-errors.stderr
index d7c602718f1..b39e57d70ec 100644
--- a/tests/ui/borrowck/mutability-errors.stderr
+++ b/tests/ui/borrowck/mutability-errors.stderr
@@ -7,7 +7,7 @@ LL |     *x = (1,);
 help: consider changing this to be a mutable reference
    |
 LL | fn named_ref(x: &mut (i32,)) {
-   |                 ~~~~~~~~~~~
+   |                  +++
 
 error[E0594]: cannot assign to `x.0`, which is behind a `&` reference
   --> $DIR/mutability-errors.rs:10:5
@@ -18,7 +18,7 @@ LL |     x.0 = 1;
 help: consider changing this to be a mutable reference
    |
 LL | fn named_ref(x: &mut (i32,)) {
-   |                 ~~~~~~~~~~~
+   |                  +++
 
 error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/mutability-errors.rs:11:5
@@ -29,7 +29,7 @@ LL |     &mut *x;
 help: consider changing this to be a mutable reference
    |
 LL | fn named_ref(x: &mut (i32,)) {
-   |                 ~~~~~~~~~~~
+   |                  +++
 
 error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `&` reference
   --> $DIR/mutability-errors.rs:12:5
@@ -40,7 +40,7 @@ LL |     &mut x.0;
 help: consider changing this to be a mutable reference
    |
 LL | fn named_ref(x: &mut (i32,)) {
-   |                 ~~~~~~~~~~~
+   |                  +++
 
 error[E0594]: cannot assign to data in a `&` reference
   --> $DIR/mutability-errors.rs:16:5
@@ -74,8 +74,8 @@ LL |     *x = (1,);
    |
 help: consider changing this to be a mutable pointer
    |
-LL | unsafe fn named_ptr(x: *mut (i32,)) {
-   |                        ~~~~~~~~~~~
+LL | unsafe fn named_ptr(x: *mut const (i32,)) {
+   |                         +++
 
 error[E0594]: cannot assign to `x.0`, which is behind a `*const` pointer
   --> $DIR/mutability-errors.rs:24:5
@@ -85,8 +85,8 @@ LL |     (*x).0 = 1;
    |
 help: consider changing this to be a mutable pointer
    |
-LL | unsafe fn named_ptr(x: *mut (i32,)) {
-   |                        ~~~~~~~~~~~
+LL | unsafe fn named_ptr(x: *mut const (i32,)) {
+   |                         +++
 
 error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
   --> $DIR/mutability-errors.rs:25:5
@@ -96,8 +96,8 @@ LL |     &mut *x;
    |
 help: consider changing this to be a mutable pointer
    |
-LL | unsafe fn named_ptr(x: *mut (i32,)) {
-   |                        ~~~~~~~~~~~
+LL | unsafe fn named_ptr(x: *mut const (i32,)) {
+   |                         +++
 
 error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `*const` pointer
   --> $DIR/mutability-errors.rs:26:5
@@ -107,8 +107,8 @@ LL |     &mut (*x).0;
    |
 help: consider changing this to be a mutable pointer
    |
-LL | unsafe fn named_ptr(x: *mut (i32,)) {
-   |                        ~~~~~~~~~~~
+LL | unsafe fn named_ptr(x: *mut const (i32,)) {
+   |                         +++
 
 error[E0594]: cannot assign to data in a `*const` pointer
   --> $DIR/mutability-errors.rs:30:5
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
index 95f36fc042c..1904faa9598 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
@@ -10,7 +10,7 @@ LL |         **ref_mref_x = y;
 help: consider changing this to be a mutable reference
    |
 LL |     let ref_mref_x = &mut mref_x;
-   |                      ~~~~~~~~~~~
+   |                       +++
 
 error[E0596]: cannot borrow `**mref_ref_x` as mutable, as it is behind a `&` reference
   --> $DIR/mut_ref.rs:26:13
diff --git a/tests/ui/coercion/coercion-slice.stderr b/tests/ui/coercion/coercion-slice.stderr
index c7b856a57eb..17bbca7a0bd 100644
--- a/tests/ui/coercion/coercion-slice.stderr
+++ b/tests/ui/coercion/coercion-slice.stderr
@@ -2,11 +2,14 @@ error[E0308]: mismatched types
   --> $DIR/coercion-slice.rs:4:21
    |
 LL |     let _: &[i32] = [0];
-   |            ------   ^^^
-   |            |        |
-   |            |        expected `&[i32]`, found `[{integer}; 1]`
-   |            |        help: consider borrowing here: `&[0]`
+   |            ------   ^^^ expected `&[i32]`, found `[{integer}; 1]`
+   |            |
    |            expected due to this
+   |
+help: consider borrowing here
+   |
+LL |     let _: &[i32] = &[0];
+   |                     +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/did_you_mean/issue-38147-4.stderr b/tests/ui/did_you_mean/issue-38147-4.stderr
index d3339989361..43647fa562b 100644
--- a/tests/ui/did_you_mean/issue-38147-4.stderr
+++ b/tests/ui/did_you_mean/issue-38147-4.stderr
@@ -6,8 +6,8 @@ LL |     f.s.push('x');
    |
 help: consider changing this to be a mutable reference
    |
-LL | fn f(x: usize, f: &mut Foo<'_>) {
-   |                   ~~~~~~~~~~~~
+LL | fn f(x: usize, f: &mut Foo) {
+   |                    +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/did_you_mean/issue-39544.stderr b/tests/ui/did_you_mean/issue-39544.stderr
index 8dc0512a945..8ccb4cbb0c1 100644
--- a/tests/ui/did_you_mean/issue-39544.stderr
+++ b/tests/ui/did_you_mean/issue-39544.stderr
@@ -40,7 +40,7 @@ LL |         let _ = &mut other.x;
 help: consider changing this to be a mutable reference
    |
 LL |     fn foo1(&self, other: &mut Z) {
-   |                           ~~~~~~
+   |                            +++
 
 error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
   --> $DIR/issue-39544.rs:25:17
@@ -62,7 +62,7 @@ LL |         let _ = &mut other.x;
 help: consider changing this to be a mutable reference
    |
 LL |     fn foo2<'a>(&'a self, other: &mut Z) {
-   |                                  ~~~~~~
+   |                                   +++
 
 error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
   --> $DIR/issue-39544.rs:30:17
@@ -73,7 +73,7 @@ LL |         let _ = &mut self.x;
 help: consider changing this to be a mutable reference
    |
 LL |     fn foo3<'a>(self: &'a mut Self, other: &Z) {
-   |                       ~~~~~~~~~~~~
+   |                           +++
 
 error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
   --> $DIR/issue-39544.rs:31:17
@@ -84,7 +84,7 @@ LL |         let _ = &mut other.x;
 help: consider changing this to be a mutable reference
    |
 LL |     fn foo3<'a>(self: &'a Self, other: &mut Z) {
-   |                                        ~~~~~~
+   |                                         +++
 
 error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
   --> $DIR/issue-39544.rs:35:17
@@ -95,7 +95,7 @@ LL |         let _ = &mut other.x;
 help: consider changing this to be a mutable reference
    |
 LL |     fn foo4(other: &mut Z) {
-   |                    ~~~~~~
+   |                     +++
 
 error[E0596]: cannot borrow `z.x` as mutable, as `z` is not declared as mutable
   --> $DIR/issue-39544.rs:41:13
@@ -117,7 +117,7 @@ LL |     let _ = &mut w.x;
 help: consider changing this to be a mutable reference
    |
 LL | pub fn with_arg(z: Z, w: &mut Z) {
-   |                          ~~~~~~
+   |                           +++
 
 error[E0594]: cannot assign to `*x.0`, which is behind a `&` reference
   --> $DIR/issue-39544.rs:48:5
diff --git a/tests/ui/did_you_mean/issue-40823.stderr b/tests/ui/did_you_mean/issue-40823.stderr
index aadd698891e..ba94a570256 100644
--- a/tests/ui/did_you_mean/issue-40823.stderr
+++ b/tests/ui/did_you_mean/issue-40823.stderr
@@ -7,7 +7,7 @@ LL |     buf.iter_mut();
 help: consider changing this to be a mutable reference
    |
 LL |     let mut buf = &mut [1, 2, 3, 4];
-   |                   ~~~~~~~~~~~~~~~~~
+   |                    +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/error-codes/E0389.stderr b/tests/ui/error-codes/E0389.stderr
index 51c4c92addf..e4001856c38 100644
--- a/tests/ui/error-codes/E0389.stderr
+++ b/tests/ui/error-codes/E0389.stderr
@@ -7,7 +7,7 @@ LL |     fancy_ref.num = 6;
 help: consider changing this to be a mutable reference
    |
 LL |     let fancy_ref = &mut (&mut fancy);
-   |                     ~~~~~~~~~~~~~~~~~
+   |                      +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/feature-gates/feature-gate-builtin_syntax.rs b/tests/ui/feature-gates/feature-gate-builtin_syntax.rs
new file mode 100644
index 00000000000..832bb5a96bc
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-builtin_syntax.rs
@@ -0,0 +1,7 @@
+struct Foo {
+    v: u8,
+    w: u8,
+}
+fn main() {
+    builtin # offset_of(Foo, v); //~ ERROR `builtin #` syntax is unstable
+}
diff --git a/tests/ui/feature-gates/feature-gate-builtin_syntax.stderr b/tests/ui/feature-gates/feature-gate-builtin_syntax.stderr
new file mode 100644
index 00000000000..3bc7848f66d
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-builtin_syntax.stderr
@@ -0,0 +1,12 @@
+error[E0658]: `builtin #` syntax is unstable
+  --> $DIR/feature-gate-builtin_syntax.rs:6:15
+   |
+LL |     builtin # offset_of(Foo, v);
+   |               ^^^^^^^^^
+   |
+   = note: see issue #110680 <https://github.com/rust-lang/rust/issues/110680> for more information
+   = help: add `#![feature(builtin_syntax)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr
index 6f5aacacfc1..c58aab42269 100644
--- a/tests/ui/inference/deref-suggestion.stderr
+++ b/tests/ui/inference/deref-suggestion.stderr
@@ -98,19 +98,23 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:40:17
    |
 LL |     let s = S { u };
-   |                 ^
-   |                 |
-   |                 expected `&u32`, found integer
-   |                 help: consider borrowing here: `u: &u`
+   |                 ^ expected `&u32`, found integer
+   |
+help: consider borrowing here
+   |
+LL |     let s = S { u: &u };
+   |                 ++++
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:42:20
    |
 LL |     let s = S { u: u };
-   |                    ^
-   |                    |
-   |                    expected `&u32`, found integer
-   |                    help: consider borrowing here: `&u`
+   |                    ^ expected `&u32`, found integer
+   |
+help: consider borrowing here
+   |
+LL |     let s = S { u: &u };
+   |                    +
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:45:17
diff --git a/tests/ui/issues/issue-11374.stderr b/tests/ui/issues/issue-11374.stderr
index 6e1fb1540bb..879dc5b76c5 100644
--- a/tests/ui/issues/issue-11374.stderr
+++ b/tests/ui/issues/issue-11374.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-11374.rs:26:15
    |
 LL |     c.read_to(v);
-   |       ------- ^
-   |       |       |
-   |       |       expected `&mut [u8]`, found `Vec<_>`
-   |       |       help: consider mutably borrowing here: `&mut v`
+   |       ------- ^ expected `&mut [u8]`, found `Vec<_>`
+   |       |
    |       arguments to this method are incorrect
    |
    = note: expected mutable reference `&mut [u8]`
@@ -15,6 +13,10 @@ note: method defined here
    |
 LL |     pub fn read_to(&mut self, vec: &mut [u8]) {
    |            ^^^^^^^            --------------
+help: consider mutably borrowing here
+   |
+LL |     c.read_to(&mut v);
+   |               ++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-17033.stderr b/tests/ui/issues/issue-17033.stderr
index f26bee5ff45..3419c079859 100644
--- a/tests/ui/issues/issue-17033.stderr
+++ b/tests/ui/issues/issue-17033.stderr
@@ -2,11 +2,14 @@ error[E0308]: mismatched types
   --> $DIR/issue-17033.rs:2:10
    |
 LL |     (*p)(())
-   |     ---- ^^
-   |     |    |
-   |     |    expected `&mut ()`, found `()`
-   |     |    help: consider mutably borrowing here: `&mut ()`
+   |     ---- ^^ expected `&mut ()`, found `()`
+   |     |
    |     arguments to this function are incorrect
+   |
+help: consider mutably borrowing here
+   |
+LL |     (*p)(&mut ())
+   |          ++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-18819.stderr b/tests/ui/issues/issue-18819.stderr
index 1fc974b609c..40098f9622f 100644
--- a/tests/ui/issues/issue-18819.stderr
+++ b/tests/ui/issues/issue-18819.stderr
@@ -19,7 +19,7 @@ LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) {
 help: consider borrowing here
    |
 LL |     print_x(&X);
-   |             ~~
+   |             +
 help: provide the argument
    |
 LL |     print_x(/* &dyn Foo<Item = bool> */, /* &str */);
diff --git a/tests/ui/issues/issue-46302.stderr b/tests/ui/issues/issue-46302.stderr
index a6f97c3c9af..6e126038cc9 100644
--- a/tests/ui/issues/issue-46302.stderr
+++ b/tests/ui/issues/issue-46302.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-46302.rs:3:27
    |
 LL |   let u: &str = if true { s[..2] } else { s };
-   |                           ^^^^^^
-   |                           |
-   |                           expected `&str`, found `str`
-   |                           help: consider borrowing here: `&s[..2]`
+   |                           ^^^^^^ expected `&str`, found `str`
+   |
+help: consider borrowing here
+   |
+LL |   let u: &str = if true { &s[..2] } else { s };
+   |                           +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
index e874ded8ec5..211dd512895 100644
--- a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
+++ b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:12:42
    |
 LL |     light_flows_our_war_of_mocking_words(behold as usize);
-   |     ------------------------------------ ^^^^^^^^^^^^^^^
-   |     |                                    |
-   |     |                                    expected `&usize`, found `usize`
-   |     |                                    help: consider borrowing here: `&(behold as usize)`
+   |     ------------------------------------ ^^^^^^^^^^^^^^^ expected `&usize`, found `usize`
+   |     |
    |     arguments to this function are incorrect
    |
 note: function defined here
@@ -13,15 +11,17 @@ note: function defined here
    |
 LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
    |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------
+help: consider borrowing here
+   |
+LL |     light_flows_our_war_of_mocking_words(&(behold as usize));
+   |                                          ++               +
 
 error[E0308]: mismatched types
   --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:14:42
    |
 LL |     light_flows_our_war_of_mocking_words(with_tears + 4);
-   |     ------------------------------------ ^^^^^^^^^^^^^^
-   |     |                                    |
-   |     |                                    expected `&usize`, found `usize`
-   |     |                                    help: consider borrowing here: `&(with_tears + 4)`
+   |     ------------------------------------ ^^^^^^^^^^^^^^ expected `&usize`, found `usize`
+   |     |
    |     arguments to this function are incorrect
    |
 note: function defined here
@@ -29,6 +29,10 @@ note: function defined here
    |
 LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
    |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------
+help: consider borrowing here
+   |
+LL |     light_flows_our_war_of_mocking_words(&(with_tears + 4));
+   |                                          ++              +
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/issues/issue-51515.rs b/tests/ui/issues/issue-51515.rs
index 84e09afac0a..33a9bf85e23 100644
--- a/tests/ui/issues/issue-51515.rs
+++ b/tests/ui/issues/issue-51515.rs
@@ -1,7 +1,6 @@
 fn main() {
     let foo = &16;
     //~^ HELP consider changing this to be a mutable reference
-    //~| SUGGESTION &mut 16
     *foo = 32;
     //~^ ERROR cannot assign to `*foo`, which is behind a `&` reference
     let bar = foo;
diff --git a/tests/ui/issues/issue-51515.stderr b/tests/ui/issues/issue-51515.stderr
index 94e5c9f1b83..88b8d210908 100644
--- a/tests/ui/issues/issue-51515.stderr
+++ b/tests/ui/issues/issue-51515.stderr
@@ -1,5 +1,5 @@
 error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
-  --> $DIR/issue-51515.rs:5:5
+  --> $DIR/issue-51515.rs:4:5
    |
 LL |     *foo = 32;
    |     ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
@@ -7,10 +7,10 @@ LL |     *foo = 32;
 help: consider changing this to be a mutable reference
    |
 LL |     let foo = &mut 16;
-   |               ~~~~~~~
+   |                +++
 
 error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
-  --> $DIR/issue-51515.rs:9:5
+  --> $DIR/issue-51515.rs:8:5
    |
 LL |     *bar = 64;
    |     ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
diff --git a/tests/ui/issues/issue-61106.stderr b/tests/ui/issues/issue-61106.stderr
index eff3e6e7849..aa922e2682d 100644
--- a/tests/ui/issues/issue-61106.stderr
+++ b/tests/ui/issues/issue-61106.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-61106.rs:3:9
    |
 LL |     foo(x.clone());
-   |     --- ^^^^^^^^^
-   |     |   |
-   |     |   expected `&str`, found `String`
-   |     |   help: consider borrowing here: `&x`
+   |     --- ^^^^^^^^^ expected `&str`, found `String`
+   |     |
    |     arguments to this function are incorrect
    |
 note: function defined here
@@ -13,6 +11,10 @@ note: function defined here
    |
 LL | fn foo(_: &str) {}
    |    ^^^ -------
+help: consider borrowing here
+   |
+LL |     foo(&x.clone());
+   |         +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-61623.stderr b/tests/ui/issues/issue-61623.stderr
index 5fcc338557c..bedea3890a3 100644
--- a/tests/ui/issues/issue-61623.stderr
+++ b/tests/ui/issues/issue-61623.stderr
@@ -7,7 +7,7 @@ LL |     f2(|| x.0, f1(x.1))
 help: consider changing this to be a mutable reference
    |
 LL | fn f3<'a>(x: &'a mut ((), &'a mut ())) {
-   |              ~~~~~~~~~~~~~~~~~~~~~~~~
+   |                  +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/methods/method-self-arg-1.stderr b/tests/ui/methods/method-self-arg-1.stderr
index 9241a8be58f..dcc21acc5c0 100644
--- a/tests/ui/methods/method-self-arg-1.stderr
+++ b/tests/ui/methods/method-self-arg-1.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/method-self-arg-1.rs:11:14
    |
 LL |     Foo::bar(x);
-   |     -------- ^
-   |     |        |
-   |     |        expected `&Foo`, found `Foo`
-   |     |        help: consider borrowing here: `&x`
+   |     -------- ^ expected `&Foo`, found `Foo`
+   |     |
    |     arguments to this function are incorrect
    |
 note: method defined here
@@ -13,6 +11,10 @@ note: method defined here
    |
 LL |     fn bar(&self) {}
    |        ^^^ -----
+help: consider borrowing here
+   |
+LL |     Foo::bar(&x);
+   |              +
 
 error[E0308]: mismatched types
   --> $DIR/method-self-arg-1.rs:13:14
diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
index 13942682d28..7be94ef4ad6 100644
--- a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
+++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/dont-point-return-on-E0308.rs:11:11
    |
 LL |         f(());
-   |         - ^^
-   |         | |
-   |         | expected `&()`, found `()`
-   |         | help: consider borrowing here: `&()`
+   |         - ^^ expected `&()`, found `()`
+   |         |
    |         arguments to this function are incorrect
    |
 note: function defined here
@@ -13,6 +11,10 @@ note: function defined here
    |
 LL | async fn f(_: &()) {}
    |          ^ ------
+help: consider borrowing here
+   |
+LL |         f(&());
+   |           +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/mut/mut-cross-borrowing.stderr b/tests/ui/mut/mut-cross-borrowing.stderr
index 8401827e51f..8a3076db9b2 100644
--- a/tests/ui/mut/mut-cross-borrowing.stderr
+++ b/tests/ui/mut/mut-cross-borrowing.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/mut-cross-borrowing.rs:7:7
    |
 LL |     f(x)
-   |     - ^
-   |     | |
-   |     | expected `&mut isize`, found `Box<{integer}>`
-   |     | help: consider mutably borrowing here: `&mut x`
+   |     - ^ expected `&mut isize`, found `Box<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut isize`
@@ -15,6 +13,10 @@ note: function defined here
    |
 LL | fn f(_: &mut isize) {}
    |    ^ -------------
+help: consider mutably borrowing here
+   |
+LL |     f(&mut x)
+   |       ++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/nll/issue-47388.stderr b/tests/ui/nll/issue-47388.stderr
index c780451dfa9..09b9d638afb 100644
--- a/tests/ui/nll/issue-47388.stderr
+++ b/tests/ui/nll/issue-47388.stderr
@@ -7,7 +7,7 @@ LL |     fancy_ref.num = 6;
 help: consider changing this to be a mutable reference
    |
 LL |     let fancy_ref = &mut (&mut fancy);
-   |                     ~~~~~~~~~~~~~~~~~
+   |                      +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/nll/issue-51244.stderr b/tests/ui/nll/issue-51244.stderr
index 03d8acc8188..8ccb5809e39 100644
--- a/tests/ui/nll/issue-51244.stderr
+++ b/tests/ui/nll/issue-51244.stderr
@@ -7,7 +7,7 @@ LL |     *my_ref = 0;
 help: consider changing this to be a mutable reference
    |
 LL |     let ref mut my_ref @ _ = 0;
-   |         ~~~~~~~~~~~~~~
+   |             +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/nll/issue-57989.stderr b/tests/ui/nll/issue-57989.stderr
index d5effd6f346..6062b31d688 100644
--- a/tests/ui/nll/issue-57989.stderr
+++ b/tests/ui/nll/issue-57989.stderr
@@ -7,7 +7,7 @@ LL |     *x = 0;
 help: consider changing this to be a mutable reference
    |
 LL | fn f(x: &mut i32) {
-   |         ~~~~~~~~
+   |          +++
 
 error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-57989.rs:5:5
diff --git a/tests/ui/offset-of/offset-of-arg-count.rs b/tests/ui/offset-of/offset-of-arg-count.rs
index 163b07454ec..5e66e33f8a2 100644
--- a/tests/ui/offset-of/offset-of-arg-count.rs
+++ b/tests/ui/offset-of/offset-of-arg-count.rs
@@ -3,7 +3,15 @@
 use std::mem::offset_of;
 
 fn main() {
-    offset_of!(NotEnoughArguments); //~ ERROR expected one of
-    offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR expected 2 arguments
-    offset_of!(Container, field, too many arguments); //~ ERROR expected 2 arguments
+    offset_of!(NotEnoughArguments); //~ ERROR unexpected end of macro invocation
+    offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR unexpected end of macro invocation
+    offset_of!(Container, field, too many arguments); //~ ERROR no rules expected the token `too`
+    offset_of!(S, f); // compiles fine
+    offset_of!(S, f,); // also compiles fine
+    offset_of!(S, f.); //~ ERROR unexpected end of macro invocation
+    offset_of!(S, f.,); //~ ERROR expected identifier
+    offset_of!(S, f..); //~ ERROR no rules expected the token
+    offset_of!(S, f..,); //~ ERROR no rules expected the token
 }
+
+struct S { f: u8, }
diff --git a/tests/ui/offset-of/offset-of-arg-count.stderr b/tests/ui/offset-of/offset-of-arg-count.stderr
index ebecc982c51..4275a89545f 100644
--- a/tests/ui/offset-of/offset-of-arg-count.stderr
+++ b/tests/ui/offset-of/offset-of-arg-count.stderr
@@ -1,20 +1,59 @@
-error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `<eof>`
-  --> $DIR/offset-of-arg-count.rs:6:16
+error: unexpected end of macro invocation
+  --> $DIR/offset-of-arg-count.rs:6:34
    |
 LL |     offset_of!(NotEnoughArguments);
-   |                ^^^^^^^^^^^^^^^^^^ expected one of `!`, `(`, `+`, `,`, `::`, or `<`
+   |                                  ^ missing tokens in macro arguments
+   |
+note: while trying to match `,`
+  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
 
-error: expected 2 arguments
-  --> $DIR/offset-of-arg-count.rs:7:5
+error: unexpected end of macro invocation
+  --> $DIR/offset-of-arg-count.rs:7:45
    |
 LL |     offset_of!(NotEnoughArgumentsWithAComma, );
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                             ^ missing tokens in macro arguments
+   |
+note: while trying to match meta-variable `$fields:tt`
+  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
 
-error: expected 2 arguments
-  --> $DIR/offset-of-arg-count.rs:8:5
+error: no rules expected the token `too`
+  --> $DIR/offset-of-arg-count.rs:8:34
    |
 LL |     offset_of!(Container, field, too many arguments);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                  ^^^ no rules expected this token in macro call
+   |
+   = note: while trying to match sequence end
+
+error: unexpected end of macro invocation
+  --> $DIR/offset-of-arg-count.rs:11:21
+   |
+LL |     offset_of!(S, f.);
+   |                     ^ missing tokens in macro arguments
+   |
+note: while trying to match meta-variable `$fields:tt`
+  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+
+error: expected identifier, found `,`
+  --> $DIR/offset-of-arg-count.rs:12:21
+   |
+LL |     offset_of!(S, f.,);
+   |                     ^ expected identifier
+
+error: no rules expected the token `..`
+  --> $DIR/offset-of-arg-count.rs:13:20
+   |
+LL |     offset_of!(S, f..);
+   |                    ^^ no rules expected this token in macro call
+   |
+   = note: while trying to match sequence start
+
+error: no rules expected the token `..`
+  --> $DIR/offset-of-arg-count.rs:14:20
+   |
+LL |     offset_of!(S, f..,);
+   |                    ^^ no rules expected this token in macro call
+   |
+   = note: while trying to match sequence start
 
-error: aborting due to 3 previous errors
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/offset-of/offset-of-builtin.rs b/tests/ui/offset-of/offset-of-builtin.rs
new file mode 100644
index 00000000000..1be9899887b
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-builtin.rs
@@ -0,0 +1,44 @@
+#![feature(builtin_syntax)]
+
+// For the exposed macro we already test these errors in the other files,
+// but this test helps to make sure the builtin construct also errors.
+// This has the same examples as offset-of-arg-count.rs
+
+fn main() {
+    builtin # offset_of(NotEnoughArguments); //~ ERROR expected one of
+}
+fn t1() {
+    // Already errored upon at the macro level. Yielding an error would require
+    // extra effort.
+    builtin # offset_of(NotEnoughArgumentsWithAComma, );
+}
+fn t2() {
+    builtin # offset_of(Container, field, too many arguments); //~ ERROR expected identifier, found
+    //~| ERROR found `,`
+    //~| ERROR found `many`
+    //~| ERROR found `arguments`
+}
+fn t3() {
+    builtin # offset_of(S, f); // compiles fine
+}
+fn t4() {
+    // Already errored upon at the macro level. Yielding an error would require
+    // extra effort.
+    builtin # offset_of(S, f);
+}
+fn t5() {
+    builtin # offset_of(S, f.); //~ ERROR expected identifier
+}
+fn t6() {
+    builtin # offset_of(S, f.,); //~ ERROR expected identifier
+}
+fn t7() {
+    builtin # offset_of(S, f..); //~ ERROR expected one of
+}
+fn t8() {
+    // Already errored upon at the macro level. Yielding an error would require
+    // extra effort.
+    builtin # offset_of(S, f..,);
+}
+
+struct S { f: u8, }
diff --git a/tests/ui/offset-of/offset-of-builtin.stderr b/tests/ui/offset-of/offset-of-builtin.stderr
new file mode 100644
index 00000000000..1a1f33cc613
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-builtin.stderr
@@ -0,0 +1,65 @@
+error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `)`
+  --> $DIR/offset-of-builtin.rs:8:43
+   |
+LL |     builtin # offset_of(NotEnoughArguments);
+   |                                           ^ expected one of `!`, `(`, `+`, `,`, `::`, or `<`
+
+error: expected identifier, found `,`
+  --> $DIR/offset-of-builtin.rs:16:41
+   |
+LL |     builtin # offset_of(Container, field, too many arguments);
+   |                                         ^
+   |                                         |
+   |                                         expected identifier
+   |                                         help: remove this comma
+
+error: expected one of `)` or `.`, found `,`
+  --> $DIR/offset-of-builtin.rs:16:41
+   |
+LL |     builtin # offset_of(Container, field, too many arguments);
+   |                                         ^
+   |                                         |
+   |                                         expected one of `)` or `.`
+   |                                         help: missing `.`
+
+error: expected one of `)` or `.`, found `many`
+  --> $DIR/offset-of-builtin.rs:16:47
+   |
+LL |     builtin # offset_of(Container, field, too many arguments);
+   |                                              -^^^^ expected one of `)` or `.`
+   |                                              |
+   |                                              help: missing `.`
+
+error: expected one of `)` or `.`, found `arguments`
+  --> $DIR/offset-of-builtin.rs:16:52
+   |
+LL |     builtin # offset_of(Container, field, too many arguments);
+   |                                                   -^^^^^^^^^ expected one of `)` or `.`
+   |                                                   |
+   |                                                   help: missing `.`
+
+error: expected identifier, found `)`
+  --> $DIR/offset-of-builtin.rs:30:30
+   |
+LL |     builtin # offset_of(S, f.);
+   |                              ^ expected identifier
+
+error: expected identifier, found `,`
+  --> $DIR/offset-of-builtin.rs:33:30
+   |
+LL |     builtin # offset_of(S, f.,);
+   |                              ^ expected identifier
+
+error: expected one of `)` or `.`, found `..`
+  --> $DIR/offset-of-builtin.rs:36:29
+   |
+LL |     builtin # offset_of(S, f..);
+   |                             ^^ expected one of `)` or `.`
+   |
+help: if you meant to bind the contents of the rest of the array pattern into `f`, use `@`
+   |
+LL |     builtin # offset_of(S, f @ ..);
+   |                              +
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr
index 8e88015b07a..e6e0f499236 100644
--- a/tests/ui/offset-of/offset-of-dst-field.stderr
+++ b/tests/ui/offset-of/offset-of-dst-field.stderr
@@ -5,6 +5,7 @@ LL |     offset_of!(Alpha, z);
    |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u8]`
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
   --> $DIR/offset-of-dst-field.rs:31:5
@@ -13,6 +14,7 @@ LL |     offset_of!(Beta, z);
    |     ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)`
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the size for values of type `Extern` cannot be known at compilation time
   --> $DIR/offset-of-dst-field.rs:32:5
@@ -21,6 +23,7 @@ LL |     offset_of!(Gamma, z);
    |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `Extern`
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/offset-of/offset-of-unstable.stderr b/tests/ui/offset-of/offset-of-unstable.stderr
index 25811a061d7..c39882519a5 100644
--- a/tests/ui/offset-of/offset-of-unstable.stderr
+++ b/tests/ui/offset-of/offset-of-unstable.stderr
@@ -33,6 +33,7 @@ LL | |     );
    | |_____^
    |
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
   --> $DIR/offset-of-unstable.rs:18:5
@@ -41,6 +42,7 @@ LL |     offset_of!(StableWithUnstableField, unstable);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
   --> $DIR/offset-of-unstable.rs:20:5
@@ -49,6 +51,7 @@ LL |     offset_of!(StableWithUnstableFieldType, stable.unstable);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
   --> $DIR/offset-of-unstable.rs:21:5
@@ -61,6 +64,7 @@ LL | |     );
    | |_____^
    |
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
   --> $DIR/offset-of-unstable.rs:26:5
@@ -73,6 +77,7 @@ LL | |     );
    | |_____^
    |
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/parser/builtin-syntax.rs b/tests/ui/parser/builtin-syntax.rs
new file mode 100644
index 00000000000..897dab8ec50
--- /dev/null
+++ b/tests/ui/parser/builtin-syntax.rs
@@ -0,0 +1,9 @@
+#![feature(builtin_syntax)]
+
+fn main() {
+    builtin # foobar(); //~ ERROR unknown `builtin #` construct
+}
+
+fn not_identifier() {
+    builtin # {}(); //~ ERROR expected identifier after
+}
diff --git a/tests/ui/parser/builtin-syntax.stderr b/tests/ui/parser/builtin-syntax.stderr
new file mode 100644
index 00000000000..ee3764a6221
--- /dev/null
+++ b/tests/ui/parser/builtin-syntax.stderr
@@ -0,0 +1,14 @@
+error: unknown `builtin #` construct `foobar`
+  --> $DIR/builtin-syntax.rs:4:5
+   |
+LL |     builtin # foobar();
+   |     ^^^^^^^^^^^^^^^^
+
+error: expected identifier after `builtin #`
+  --> $DIR/builtin-syntax.rs:8:15
+   |
+LL |     builtin # {}();
+   |               ^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
index c7c7c074f7c..a033cc0655e 100644
--- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
+++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
@@ -112,7 +112,7 @@ LL |     *_x0 = U;
 help: consider changing this to be a mutable reference
    |
 LL |     let (ref mut _x0, _x1, ref _x2, ..) = tup;
-   |          ~~~~~~~~~~~
+   |              +++
 
 error[E0594]: cannot assign to `*_x2`, which is behind a `&` reference
   --> $DIR/borrowck-move-ref-pattern.rs:27:5
@@ -123,7 +123,7 @@ LL |     *_x2 = U;
 help: consider changing this to be a mutable reference
    |
 LL |     let (ref _x0, _x1, ref mut _x2, ..) = tup;
-   |                        ~~~~~~~~~~~
+   |                            +++
 
 error[E0382]: use of moved value: `tup.1`
   --> $DIR/borrowck-move-ref-pattern.rs:28:10
diff --git a/tests/ui/range/issue-54505-no-literals.fixed b/tests/ui/range/issue-54505-no-literals.fixed
index 4d8f67182b9..71c36c741cc 100644
--- a/tests/ui/range/issue-54505-no-literals.fixed
+++ b/tests/ui/range/issue-54505-no-literals.fixed
@@ -16,60 +16,60 @@ fn main() {
     take_range(&std::ops::Range { start: 0, end: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::Range { start: 0, end: 1 }
+    //~| SUGGESTION &
 
     take_range(&::std::ops::Range { start: 0, end: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 }
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeFrom { start: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeFrom { start: 1 }
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeFrom { start: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeFrom { start: 1 }
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeFull {});
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeFull {}
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeFull {});
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeFull {}
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeInclusive::new(0, 1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1)
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeInclusive::new(0, 1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1)
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeTo { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeTo { end: 5 }
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeTo { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeTo { end: 5 }
+    //~| SUGGESTION &
 
     take_range(&std::ops::RangeToInclusive { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 }
+    //~| SUGGESTION &
 
     take_range(&::std::ops::RangeToInclusive { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 }
+    //~| SUGGESTION &
 }
diff --git a/tests/ui/range/issue-54505-no-literals.rs b/tests/ui/range/issue-54505-no-literals.rs
index dc21dcbc2db..db125d1a22b 100644
--- a/tests/ui/range/issue-54505-no-literals.rs
+++ b/tests/ui/range/issue-54505-no-literals.rs
@@ -16,60 +16,60 @@ fn main() {
     take_range(std::ops::Range { start: 0, end: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::Range { start: 0, end: 1 }
+    //~| SUGGESTION &
 
     take_range(::std::ops::Range { start: 0, end: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 }
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeFrom { start: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeFrom { start: 1 }
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeFrom { start: 1 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeFrom { start: 1 }
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeFull {});
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeFull {}
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeFull {});
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeFull {}
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeInclusive::new(0, 1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1)
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeInclusive::new(0, 1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1)
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeTo { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeTo { end: 5 }
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeTo { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeTo { end: 5 }
+    //~| SUGGESTION &
 
     take_range(std::ops::RangeToInclusive { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 }
+    //~| SUGGESTION &
 
     take_range(::std::ops::RangeToInclusive { end: 5 });
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 }
+    //~| SUGGESTION &
 }
diff --git a/tests/ui/range/issue-54505-no-literals.stderr b/tests/ui/range/issue-54505-no-literals.stderr
index d112983848d..5894bb6ba55 100644
--- a/tests/ui/range/issue-54505-no-literals.stderr
+++ b/tests/ui/range/issue-54505-no-literals.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:16:16
    |
 LL |     take_range(std::ops::Range { start: 0, end: 1 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `Range<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -15,15 +13,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::Range { start: 0, end: 1 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:21:16
    |
 LL |     take_range(::std::ops::Range { start: 0, end: 1 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `Range<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -33,15 +33,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::Range { start: 0, end: 1 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:26:16
    |
 LL |     take_range(std::ops::RangeFrom { start: 1 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFrom<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -51,15 +53,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeFrom { start: 1 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:31:16
    |
 LL |     take_range(::std::ops::RangeFrom { start: 1 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFrom<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -69,15 +73,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeFrom { start: 1 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:36:16
    |
 LL |     take_range(std::ops::RangeFull {});
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFull`
-   |     |          help: consider borrowing here: `&std::ops::RangeFull {}`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -87,15 +93,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeFull {});
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:41:16
    |
 LL |     take_range(::std::ops::RangeFull {});
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFull`
-   |     |          help: consider borrowing here: `&::std::ops::RangeFull {}`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -105,15 +113,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeFull {});
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:46:16
    |
 LL |     take_range(std::ops::RangeInclusive::new(0, 1));
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -123,15 +133,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeInclusive::new(0, 1));
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:51:16
    |
 LL |     take_range(::std::ops::RangeInclusive::new(0, 1));
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -141,15 +153,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeInclusive::new(0, 1));
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:56:16
    |
 LL |     take_range(std::ops::RangeTo { end: 5 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeTo<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::RangeTo { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -159,15 +173,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeTo { end: 5 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:61:16
    |
 LL |     take_range(::std::ops::RangeTo { end: 5 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeTo<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -177,15 +193,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeTo { end: 5 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:66:16
    |
 LL |     take_range(std::ops::RangeToInclusive { end: 5 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeToInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -195,15 +213,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&std::ops::RangeToInclusive { end: 5 });
+   |                +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:71:16
    |
 LL |     take_range(::std::ops::RangeToInclusive { end: 5 });
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeToInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -213,6 +233,10 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&::std::ops::RangeToInclusive { end: 5 });
+   |                +
 
 error: aborting due to 12 previous errors
 
diff --git a/tests/ui/range/issue-54505-no-std.rs b/tests/ui/range/issue-54505-no-std.rs
index 9f378b4836e..db455fada3b 100644
--- a/tests/ui/range/issue-54505-no-std.rs
+++ b/tests/ui/range/issue-54505-no-std.rs
@@ -29,30 +29,30 @@ fn main() {
     take_range(0..1);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..1)
+    //~| SUGGESTION &(
 
     take_range(1..);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(1..)
+    //~| SUGGESTION &(
 
     take_range(..);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..)
+    //~| SUGGESTION &(
 
     take_range(0..=1);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..=1)
+    //~| SUGGESTION &(
 
     take_range(..5);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..5)
+    //~| SUGGESTION &(
 
     take_range(..=42);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..=42)
+    //~| SUGGESTION &(
 }
diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr
index a6a9f89da74..13563d1940c 100644
--- a/tests/ui/range/issue-54505-no-std.stderr
+++ b/tests/ui/range/issue-54505-no-std.stderr
@@ -14,10 +14,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:29:16
    |
 LL |     take_range(0..1);
-   |     ---------- ^^^^
-   |     |          |
-   |     |          expected `&_`, found `Range<{integer}>`
-   |     |          help: consider borrowing here: `&(0..1)`
+   |     ---------- ^^^^ expected `&_`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -27,15 +25,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(0..1));
+   |                ++    +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:34:16
    |
 LL |     take_range(1..);
-   |     ---------- ^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFrom<{integer}>`
-   |     |          help: consider borrowing here: `&(1..)`
+   |     ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -45,15 +45,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(1..));
+   |                ++   +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:39:16
    |
 LL |     take_range(..);
-   |     ---------- ^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFull`
-   |     |          help: consider borrowing here: `&(..)`
+   |     ---------- ^^ expected `&_`, found `RangeFull`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -63,15 +65,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..));
+   |                ++  +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:44:16
    |
 LL |     take_range(0..=1);
-   |     ---------- ^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&(0..=1)`
+   |     ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -81,15 +85,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(0..=1));
+   |                ++     +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:49:16
    |
 LL |     take_range(..5);
-   |     ---------- ^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeTo<{integer}>`
-   |     |          help: consider borrowing here: `&(..5)`
+   |     ---------- ^^^ expected `&_`, found `RangeTo<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -99,15 +105,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..5));
+   |                ++   +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:54:16
    |
 LL |     take_range(..=42);
-   |     ---------- ^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeToInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&(..=42)`
+   |     ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -117,6 +125,10 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..=42));
+   |                ++     +
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/range/issue-54505.fixed b/tests/ui/range/issue-54505.fixed
index f8298c0b5ce..9d113ba1d35 100644
--- a/tests/ui/range/issue-54505.fixed
+++ b/tests/ui/range/issue-54505.fixed
@@ -14,30 +14,30 @@ fn main() {
     take_range(&(0..1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..1)
+    //~| SUGGESTION &(
 
     take_range(&(1..));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(1..)
+    //~| SUGGESTION &(
 
     take_range(&(..));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..)
+    //~| SUGGESTION &(
 
     take_range(&(0..=1));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..=1)
+    //~| SUGGESTION &(
 
     take_range(&(..5));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..5)
+    //~| SUGGESTION &(
 
     take_range(&(..=42));
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..=42)
+    //~| SUGGESTION &(
 }
diff --git a/tests/ui/range/issue-54505.rs b/tests/ui/range/issue-54505.rs
index 03673252dd3..c9929988fe5 100644
--- a/tests/ui/range/issue-54505.rs
+++ b/tests/ui/range/issue-54505.rs
@@ -14,30 +14,30 @@ fn main() {
     take_range(0..1);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..1)
+    //~| SUGGESTION &(
 
     take_range(1..);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(1..)
+    //~| SUGGESTION &(
 
     take_range(..);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..)
+    //~| SUGGESTION &(
 
     take_range(0..=1);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(0..=1)
+    //~| SUGGESTION &(
 
     take_range(..5);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..5)
+    //~| SUGGESTION &(
 
     take_range(..=42);
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider borrowing here
-    //~| SUGGESTION &(..=42)
+    //~| SUGGESTION &(
 }
diff --git a/tests/ui/range/issue-54505.stderr b/tests/ui/range/issue-54505.stderr
index eda047b507a..0e959fc05e2 100644
--- a/tests/ui/range/issue-54505.stderr
+++ b/tests/ui/range/issue-54505.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:14:16
    |
 LL |     take_range(0..1);
-   |     ---------- ^^^^
-   |     |          |
-   |     |          expected `&_`, found `Range<{integer}>`
-   |     |          help: consider borrowing here: `&(0..1)`
+   |     ---------- ^^^^ expected `&_`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -15,15 +13,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(0..1));
+   |                ++    +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:19:16
    |
 LL |     take_range(1..);
-   |     ---------- ^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFrom<{integer}>`
-   |     |          help: consider borrowing here: `&(1..)`
+   |     ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -33,15 +33,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(1..));
+   |                ++   +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:24:16
    |
 LL |     take_range(..);
-   |     ---------- ^^
-   |     |          |
-   |     |          expected `&_`, found `RangeFull`
-   |     |          help: consider borrowing here: `&(..)`
+   |     ---------- ^^ expected `&_`, found `RangeFull`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -51,15 +53,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..));
+   |                ++  +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:29:16
    |
 LL |     take_range(0..=1);
-   |     ---------- ^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&(0..=1)`
+   |     ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -69,15 +73,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(0..=1));
+   |                ++     +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:34:16
    |
 LL |     take_range(..5);
-   |     ---------- ^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeTo<{integer}>`
-   |     |          help: consider borrowing here: `&(..5)`
+   |     ---------- ^^^ expected `&_`, found `RangeTo<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -87,15 +93,17 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..5));
+   |                ++   +
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:39:16
    |
 LL |     take_range(..=42);
-   |     ---------- ^^^^^
-   |     |          |
-   |     |          expected `&_`, found `RangeToInclusive<{integer}>`
-   |     |          help: consider borrowing here: `&(..=42)`
+   |     ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -105,6 +113,10 @@ note: function defined here
    |
 LL | fn take_range(_r: &impl RangeBounds<i8>) {}
    |    ^^^^^^^^^^ -------------------------
+help: consider borrowing here
+   |
+LL |     take_range(&(..=42));
+   |                ++     +
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/range/issue-73553-misinterp-range-literal.stderr b/tests/ui/range/issue-73553-misinterp-range-literal.stderr
index 77595b3678e..52efa241d0b 100644
--- a/tests/ui/range/issue-73553-misinterp-range-literal.stderr
+++ b/tests/ui/range/issue-73553-misinterp-range-literal.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-73553-misinterp-range-literal.rs:12:10
    |
 LL |     demo(tell(1)..tell(10));
-   |     ---- ^^^^^^^^^^^^^^^^^
-   |     |    |
-   |     |    expected `&Range<usize>`, found `Range<usize>`
-   |     |    help: consider borrowing here: `&(tell(1)..tell(10))`
+   |     ---- ^^^^^^^^^^^^^^^^^ expected `&Range<usize>`, found `Range<usize>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&std::ops::Range<usize>`
@@ -15,15 +13,17 @@ note: function defined here
    |
 LL | fn demo(r: &Range) {
    |    ^^^^ ---------
+help: consider borrowing here
+   |
+LL |     demo(&(tell(1)..tell(10)));
+   |          ++                 +
 
 error[E0308]: mismatched types
   --> $DIR/issue-73553-misinterp-range-literal.rs:14:10
    |
 LL |     demo(1..10);
-   |     ---- ^^^^^
-   |     |    |
-   |     |    expected `&Range<usize>`, found `Range<{integer}>`
-   |     |    help: consider borrowing here: `&(1..10)`
+   |     ---- ^^^^^ expected `&Range<usize>`, found `Range<{integer}>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&std::ops::Range<usize>`
@@ -33,6 +33,10 @@ note: function defined here
    |
 LL | fn demo(r: &Range) {
    |    ^^^^ ---------
+help: consider borrowing here
+   |
+LL |     demo(&(1..10));
+   |          ++     +
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
index 3ac90992486..f31123f16f1 100644
--- a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
+++ b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
@@ -12,7 +12,9 @@ trait Specialize {}
 trait Foo {}
 
 #[const_trait]
-trait Bar {}
+trait Bar {
+    fn bar();
+}
 
 // bgr360: I was only able to exercise the code path that raises the
 // "missing ~const qualifier" error by making this base impl non-const, even
@@ -21,26 +23,36 @@ trait Bar {}
 impl<T> Bar for T
 where
     T: ~const Foo,
-{}
+{
+    default fn bar() {}
+}
 
 impl<T> Bar for T
 where
     T: Foo, //~ ERROR missing `~const` qualifier
     T: Specialize,
-{}
+{
+    fn bar() {}
+}
 
 #[const_trait]
-trait Baz {}
+trait Baz {
+    fn baz();
+}
 
 impl<T> const Baz for T
 where
     T: ~const Foo,
-{}
+{
+    default fn baz() {}
+}
 
 impl<T> const Baz for T //~ ERROR conflicting implementations of trait `Baz`
 where
     T: Foo,
     T: Specialize,
-{}
+{
+    fn baz() {}
+}
 
 fn main() {}
diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
index 4aea1979421..057cf4aea8a 100644
--- a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
+++ b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
@@ -1,11 +1,11 @@
 error: missing `~const` qualifier for specialization
-  --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:8
+  --> $DIR/const-default-bound-non-const-specialized-bound.rs:32:8
    |
 LL |     T: Foo,
    |        ^^^
 
 error[E0119]: conflicting implementations of trait `Baz`
-  --> $DIR/const-default-bound-non-const-specialized-bound.rs:40:1
+  --> $DIR/const-default-bound-non-const-specialized-bound.rs:50:1
    |
 LL | impl<T> const Baz for T
    | ----------------------- first implementation here
diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
index 9c2c2cf1610..92d8be6bb16 100644
--- a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
+++ b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
@@ -11,27 +11,39 @@
 trait Specialize {}
 
 #[const_trait]
-trait Foo {}
+trait Foo {
+    fn foo();
+}
 
-impl<T> const Foo for T {}
+impl<T> const Foo for T {
+    default fn foo() {}
+}
 
 impl<T> const Foo for T
 where
     T: ~const Specialize,
-{}
+{
+    fn foo() {}
+}
 
 #[const_trait]
-trait Bar {}
+trait Bar {
+    fn bar() {}
+}
 
 impl<T> const Bar for T
 where
     T: ~const Foo,
-{}
+{
+    default fn bar() {}
+}
 
 impl<T> const Bar for T
 where
     T: ~const Foo,
     T: ~const Specialize,
-{}
+{
+    fn bar() {}
+}
 
 fn main() {}
diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
index 1e6b1c6513b..51bfaf73b57 100644
--- a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
+++ b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -15,31 +15,43 @@ trait Specialize {}
 trait Foo {}
 
 #[const_trait]
-trait Bar {}
+trait Bar {
+    fn bar();
+}
 
 impl<T> Bar for T
 where
     T: Foo,
-{}
+{
+    default fn bar() {}
+}
 
 impl<T> const Bar for T
 where
     T: ~const Foo,
     T: Specialize,
-{}
+{
+    fn bar() {}
+}
 
 #[const_trait]
-trait Baz {}
+trait Baz {
+    fn baz();
+}
 
 impl<T> const Baz for T
 where
     T: Foo,
-{}
+{
+    default fn baz() {}
+}
 
 impl<T> const Baz for T
 where
     T: ~const Foo,
     T: Specialize,
-{}
+{
+    fn baz() {}
+}
 
 fn main() {}
diff --git a/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
index 570328fc211..80c5f9da40c 100644
--- a/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
+++ b/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
@@ -18,7 +18,7 @@ LL |     &mut x.y
 help: consider changing this to be a mutable reference
    |
 LL | fn deref_extend_mut_field1(x: &mut Own<Point>) -> &mut isize {
-   |                               ~~~~~~~~~~~~~~~
+   |                                +++
 
 error[E0499]: cannot borrow `*x` as mutable more than once at a time
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:78:19
@@ -50,7 +50,7 @@ LL |     x.y = 3;
 help: consider changing this to be a mutable reference
    |
 LL | fn assign_field2<'a>(x: &'a mut Own<Point>) {
-   |                         ~~~~~~~~~~~~~~~~~~
+   |                             +++
 
 error[E0499]: cannot borrow `*x` as mutable more than once at a time
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:101:5
@@ -82,7 +82,7 @@ LL |     x.y_mut()
 help: consider changing this to be a mutable reference
    |
 LL | fn deref_extend_mut_method1(x: &mut Own<Point>) -> &mut isize {
-   |                                ~~~~~~~~~~~~~~~
+   |                                 +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:129:6
@@ -104,7 +104,7 @@ LL |     *x.y_mut() = 3;
 help: consider changing this to be a mutable reference
    |
 LL | fn assign_method2<'a>(x: &'a mut Own<Point>) {
-   |                          ~~~~~~~~~~~~~~~~~~
+   |                              +++
 
 error: aborting due to 10 previous errors
 
diff --git a/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
index 3fed7b3f4dc..dbd52dc2d38 100644
--- a/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
+++ b/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
@@ -18,7 +18,7 @@ LL |     &mut **x
 help: consider changing this to be a mutable reference
    |
 LL | fn deref_extend_mut1<'a>(x: &'a mut Own<isize>) -> &'a mut isize {
-   |                             ~~~~~~~~~~~~~~~~~~
+   |                                 +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:49:6
@@ -40,7 +40,7 @@ LL |     **x = 3;
 help: consider changing this to be a mutable reference
    |
 LL | fn assign2<'a>(x: &'a mut Own<isize>) {
-   |                   ~~~~~~~~~~~~~~~~~~
+   |                       +++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
index 9711dad8078..99c8fa1f932 100644
--- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
+++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -19,7 +19,7 @@ LL |     (*f)();
 help: consider changing this to be a mutable reference
    |
 LL | fn test2<F>(f: &mut F) where F: FnMut() {
-   |                ~~~~~~
+   |                 +++
 
 error[E0596]: cannot borrow `f.f` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:34:5
@@ -29,8 +29,8 @@ LL |     f.f.call_mut(())
    |
 help: consider changing this to be a mutable reference
    |
-LL | fn test4(f: &mut Test<'_>) {
-   |             ~~~~~~~~~~~~~
+LL | fn test4(f: &mut Test) {
+   |              +++
 
 error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
diff --git a/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr b/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr
index 2a842f5a2a9..328197ae9f4 100644
--- a/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr
+++ b/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr
@@ -7,7 +7,7 @@ LL |     x.h();
 help: consider changing this to be a mutable reference
    |
 LL | fn b(x: &mut Foo) {
-   |         ~~~~~~~~
+   |          +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/span/borrowck-fn-in-const-b.stderr b/tests/ui/span/borrowck-fn-in-const-b.stderr
index 1df19deb12f..17fdcc622f7 100644
--- a/tests/ui/span/borrowck-fn-in-const-b.stderr
+++ b/tests/ui/span/borrowck-fn-in-const-b.stderr
@@ -7,7 +7,7 @@ LL |         x.push(format!("this is broken"));
 help: consider changing this to be a mutable reference
    |
 LL |     fn broken(x: &mut Vec<String>) {
-   |                  ~~~~~~~~~~~~~~~~
+   |                   +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/span/borrowck-object-mutability.stderr b/tests/ui/span/borrowck-object-mutability.stderr
index b6517e0b309..805a8034c18 100644
--- a/tests/ui/span/borrowck-object-mutability.stderr
+++ b/tests/ui/span/borrowck-object-mutability.stderr
@@ -7,7 +7,7 @@ LL |     x.borrowed_mut();
 help: consider changing this to be a mutable reference
    |
 LL | fn borrowed_receiver(x: &mut dyn Foo) {
-   |                         ~~~~~~~~~~~~
+   |                          +++
 
 error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable
   --> $DIR/borrowck-object-mutability.rs:18:5
diff --git a/tests/ui/span/coerce-suggestions.stderr b/tests/ui/span/coerce-suggestions.stderr
index bb30f000ea7..ff840b781f0 100644
--- a/tests/ui/span/coerce-suggestions.stderr
+++ b/tests/ui/span/coerce-suggestions.stderr
@@ -10,11 +10,14 @@ error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:9:19
    |
 LL |     let x: &str = String::new();
-   |            ----   ^^^^^^^^^^^^^
-   |            |      |
-   |            |      expected `&str`, found `String`
-   |            |      help: consider borrowing here: `&String::new()`
+   |            ----   ^^^^^^^^^^^^^ expected `&str`, found `String`
+   |            |
    |            expected due to this
+   |
+help: consider borrowing here
+   |
+LL |     let x: &str = &String::new();
+   |                   +
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:12:10
diff --git a/tests/ui/span/issue-39018.stderr b/tests/ui/span/issue-39018.stderr
index bae93639271..c8c4a513988 100644
--- a/tests/ui/span/issue-39018.stderr
+++ b/tests/ui/span/issue-39018.stderr
@@ -78,10 +78,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-39018.rs:29:17
    |
 LL |     let _ = a + b;
-   |                 ^
-   |                 |
-   |                 expected `&str`, found `String`
-   |                 help: consider borrowing here: `&b`
+   |                 ^ expected `&str`, found `String`
+   |
+help: consider borrowing here
+   |
+LL |     let _ = a + &b;
+   |                 +
 
 error[E0369]: cannot add `String` to `&String`
   --> $DIR/issue-39018.rs:30:15
diff --git a/tests/ui/span/mut-arg-hint.stderr b/tests/ui/span/mut-arg-hint.stderr
index 96ce4d5bc6c..06011eac674 100644
--- a/tests/ui/span/mut-arg-hint.stderr
+++ b/tests/ui/span/mut-arg-hint.stderr
@@ -7,7 +7,7 @@ LL |         a.push_str("bar");
 help: consider changing this to be a mutable reference
    |
 LL |     fn foo(mut a: &mut String) {
-   |                   ~~~~~~~~~~~
+   |                    +++
 
 error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
   --> $DIR/mut-arg-hint.rs:8:5
@@ -18,7 +18,7 @@ LL |     a.push_str("foo");
 help: consider changing this to be a mutable reference
    |
 LL | pub fn foo<'a>(mut a: &'a mut String) {
-   |                       ~~~~~~~~~~~~~~
+   |                           +++
 
 error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
   --> $DIR/mut-arg-hint.rs:15:9
@@ -29,7 +29,7 @@ LL |         a.push_str("foo");
 help: consider changing this to be a mutable reference
    |
 LL |     pub fn foo(mut a: &mut String) {
-   |                       ~~~~~~~~~~~
+   |                        +++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/specialization/min_specialization/specialize-associated-type.rs b/tests/ui/specialization/min_specialization/specialize-associated-type.rs
new file mode 100644
index 00000000000..c4960b0c28e
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize-associated-type.rs
@@ -0,0 +1,37 @@
+// Another regression test for #109815.
+
+// check-pass
+
+#![feature(min_specialization)]
+#![feature(rustc_attrs)]
+
+#[rustc_specialization_trait]
+trait X {}
+trait Z {
+    type Assoc: X;
+}
+struct A<T>(T);
+
+impl X for () {}
+
+impl<T: X> Z for A<T> {
+    type Assoc = ();
+}
+
+trait MyFrom<T> {
+    fn from(other: T) -> Self;
+}
+
+impl<T> MyFrom<()> for T {
+    default fn from(other: ()) -> T {
+        panic!();
+    }
+}
+
+impl<T: X> MyFrom<<A<T> as Z>::Assoc> for T {
+    fn from(other: ()) -> T {
+        panic!();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/min_specialization/specialize_nothing.rs b/tests/ui/specialization/min_specialization/specialize_nothing.rs
new file mode 100644
index 00000000000..ef92254d465
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_nothing.rs
@@ -0,0 +1,14 @@
+#![feature(min_specialization)]
+
+trait Special {
+    fn be_special();
+}
+
+impl<T> Special for T {
+    fn be_special() {}
+}
+
+impl Special for usize {}
+//~^ ERROR specialization impl does not specialize any associated items
+
+fn main() {}
diff --git a/tests/ui/specialization/min_specialization/specialize_nothing.stderr b/tests/ui/specialization/min_specialization/specialize_nothing.stderr
new file mode 100644
index 00000000000..65f73781cae
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_nothing.stderr
@@ -0,0 +1,14 @@
+error: specialization impl does not specialize any associated items
+  --> $DIR/specialize_nothing.rs:11:1
+   |
+LL | impl Special for usize {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: impl is a specialization of this impl
+  --> $DIR/specialize_nothing.rs:7:1
+   |
+LL | impl<T> Special for T {
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/specialization/min_specialization/specialize_on_type_error.rs b/tests/ui/specialization/min_specialization/specialize_on_type_error.rs
new file mode 100644
index 00000000000..24e92a0abc3
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_on_type_error.rs
@@ -0,0 +1,33 @@
+// A regression test for #109815.
+
+#![feature(min_specialization)]
+#![feature(rustc_attrs)]
+
+#[rustc_specialization_trait]
+trait X {}
+trait Y: X {}
+trait Z {
+    type Assoc: Y;
+}
+struct A<T>(T);
+
+impl<T: X> Z for A<T> {}
+//~^ ERROR not all trait items implemented
+
+trait MyFrom<T> {
+    fn from(other: T) -> Self;
+}
+
+impl<T> MyFrom<T> for T {
+    default fn from(other: T) -> T {
+        other
+    }
+}
+
+impl<T: X> MyFrom<<A<T> as Z>::Assoc> for T {
+    fn from(other: <A<T> as Z>::Assoc) -> T {
+        other
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/min_specialization/specialize_on_type_error.stderr b/tests/ui/specialization/min_specialization/specialize_on_type_error.stderr
new file mode 100644
index 00000000000..cc12302bd8c
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_on_type_error.stderr
@@ -0,0 +1,12 @@
+error[E0046]: not all trait items implemented, missing: `Assoc`
+  --> $DIR/specialize_on_type_error.rs:14:1
+   |
+LL |     type Assoc: Y;
+   |     ------------- `Assoc` from trait
+...
+LL | impl<T: X> Z for A<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs
new file mode 100644
index 00000000000..d90b81f717a
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs
@@ -0,0 +1,50 @@
+// Regression test for #79457.
+
+#![feature(min_specialization)]
+
+use std::any::Any;
+
+pub trait Tr {
+    fn method(self) -> Box<dyn Any + 'static>;
+    fn other(self);
+}
+
+impl<T: Any + 'static> Tr for T {
+    default fn method(self) -> Box<dyn Any + 'static> {
+        Box::new(self)
+    }
+
+    default fn other(self) {}
+}
+
+impl<'a> Tr for &'a i32 {
+    //~^ ERROR does not fulfill the required lifetime
+    fn other(self) {}
+}
+
+fn promote_to_static<'a>(i: &'a i32) -> &'static i32 {
+    *i.method().downcast().unwrap()
+}
+
+struct Wrapper<'a>(&'a i32);
+
+impl<'a> Tr for Wrapper<'a> {
+    //~^ ERROR does not fulfill the required lifetime
+    fn other(self) {}
+}
+
+fn promote_to_static_2<'a>(w: Wrapper<'a>) -> Wrapper<'static> {
+    *w.method().downcast().unwrap()
+}
+
+fn main() {
+    let i = Box::new(100_i32);
+    let static_i: &'static i32 = promote_to_static(&*i);
+    drop(i);
+    println!("{}", *static_i);
+
+    let j = Box::new(200_i32);
+    let static_w: Wrapper<'static> = promote_to_static_2(Wrapper(&*j));
+    drop(j);
+    println!("{}", *static_w.0);
+}
diff --git a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr
new file mode 100644
index 00000000000..2af75876d5b
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr
@@ -0,0 +1,27 @@
+error[E0477]: the type `&'a i32` does not fulfill the required lifetime
+  --> $DIR/specialize_with_generalize_lifetimes.rs:20:1
+   |
+LL | impl<'a> Tr for &'a i32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/specialize_with_generalize_lifetimes.rs:12:15
+   |
+LL | impl<T: Any + 'static> Tr for T {
+   |               ^^^^^^^
+
+error[E0477]: the type `Wrapper<'a>` does not fulfill the required lifetime
+  --> $DIR/specialize_with_generalize_lifetimes.rs:31:1
+   |
+LL | impl<'a> Tr for Wrapper<'a> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/specialize_with_generalize_lifetimes.rs:12:15
+   |
+LL | impl<T: Any + 'static> Tr for T {
+   |               ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/tests/ui/str/str-array-assignment.stderr b/tests/ui/str/str-array-assignment.stderr
index c23400a1d14..515cb9e12f8 100644
--- a/tests/ui/str/str-array-assignment.stderr
+++ b/tests/ui/str/str-array-assignment.stderr
@@ -10,10 +10,12 @@ error[E0308]: mismatched types
   --> $DIR/str-array-assignment.rs:5:27
    |
 LL |   let u: &str = if true { s[..2] } else { s };
-   |                           ^^^^^^
-   |                           |
-   |                           expected `&str`, found `str`
-   |                           help: consider borrowing here: `&s[..2]`
+   |                           ^^^^^^ expected `&str`, found `str`
+   |
+help: consider borrowing here
+   |
+LL |   let u: &str = if true { &s[..2] } else { s };
+   |                           +
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/str-array-assignment.rs:7:7
@@ -33,11 +35,14 @@ error[E0308]: mismatched types
   --> $DIR/str-array-assignment.rs:9:17
    |
 LL |   let w: &str = s[..2];
-   |          ----   ^^^^^^
-   |          |      |
-   |          |      expected `&str`, found `str`
-   |          |      help: consider borrowing here: `&s[..2]`
+   |          ----   ^^^^^^ expected `&str`, found `str`
+   |          |
    |          expected due to this
+   |
+help: consider borrowing here
+   |
+LL |   let w: &str = &s[..2];
+   |                 +
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/suggestions/as-ref.stderr b/tests/ui/suggestions/as-ref.stderr
index 0ee343ebf9f..2147d2d92e3 100644
--- a/tests/ui/suggestions/as-ref.stderr
+++ b/tests/ui/suggestions/as-ref.stderr
@@ -2,61 +2,73 @@ error[E0308]: mismatched types
   --> $DIR/as-ref.rs:7:29
    |
 LL |     opt.map(|arg| takes_ref(arg));
-   |         ---       --------- ^^^ expected `&Foo`, found `Foo`
-   |         |         |
-   |         |         arguments to this function are incorrect
-   |         help: consider using `as_ref` instead: `as_ref().map`
+   |                   --------- ^^^ expected `&Foo`, found `Foo`
+   |                   |
+   |                   arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     opt.as_ref().map(|arg| takes_ref(arg));
+   |         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:8:39
    |
 LL |     opt.and_then(|arg| Some(takes_ref(arg)));
-   |         --------            --------- ^^^ expected `&Foo`, found `Foo`
-   |         |                   |
-   |         |                   arguments to this function are incorrect
-   |         help: consider using `as_ref` instead: `as_ref().and_then`
+   |                             --------- ^^^ expected `&Foo`, found `Foo`
+   |                             |
+   |                             arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     opt.as_ref().and_then(|arg| Some(takes_ref(arg)));
+   |         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:10:29
    |
 LL |     opt.map(|arg| takes_ref(arg));
-   |         ---       --------- ^^^ expected `&Foo`, found `Foo`
-   |         |         |
-   |         |         arguments to this function are incorrect
-   |         help: consider using `as_ref` instead: `as_ref().map`
+   |                   --------- ^^^ expected `&Foo`, found `Foo`
+   |                   |
+   |                   arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     opt.as_ref().map(|arg| takes_ref(arg));
+   |         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:11:37
    |
 LL |     opt.and_then(|arg| Ok(takes_ref(arg)));
-   |         --------          --------- ^^^ expected `&Foo`, found `Foo`
-   |         |                 |
-   |         |                 arguments to this function are incorrect
-   |         help: consider using `as_ref` instead: `as_ref().and_then`
+   |                           --------- ^^^ expected `&Foo`, found `Foo`
+   |                           |
+   |                           arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     opt.as_ref().and_then(|arg| Ok(takes_ref(arg)));
+   |         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:13:29
@@ -101,61 +113,73 @@ error[E0308]: mismatched types
   --> $DIR/as-ref.rs:22:42
    |
 LL |     multiple_ref_opt.map(|arg| takes_ref(arg));
-   |                      ---       --------- ^^^ expected `&Foo`, found `Foo`
-   |                      |         |
-   |                      |         arguments to this function are incorrect
-   |                      help: consider using `as_ref` instead: `as_ref().map`
+   |                                --------- ^^^ expected `&Foo`, found `Foo`
+   |                                |
+   |                                arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     multiple_ref_opt.as_ref().map(|arg| takes_ref(arg));
+   |                      +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:23:52
    |
 LL |     multiple_ref_opt.and_then(|arg| Some(takes_ref(arg)));
-   |                      --------            --------- ^^^ expected `&Foo`, found `Foo`
-   |                      |                   |
-   |                      |                   arguments to this function are incorrect
-   |                      help: consider using `as_ref` instead: `as_ref().and_then`
+   |                                          --------- ^^^ expected `&Foo`, found `Foo`
+   |                                          |
+   |                                          arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     multiple_ref_opt.as_ref().and_then(|arg| Some(takes_ref(arg)));
+   |                      +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:25:45
    |
 LL |     multiple_ref_result.map(|arg| takes_ref(arg));
-   |                         ---       --------- ^^^ expected `&Foo`, found `Foo`
-   |                         |         |
-   |                         |         arguments to this function are incorrect
-   |                         help: consider using `as_ref` instead: `as_ref().map`
+   |                                   --------- ^^^ expected `&Foo`, found `Foo`
+   |                                   |
+   |                                   arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     multiple_ref_result.as_ref().map(|arg| takes_ref(arg));
+   |                         +++++++++
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:26:53
    |
 LL |     multiple_ref_result.and_then(|arg| Ok(takes_ref(arg)));
-   |                         --------          --------- ^^^ expected `&Foo`, found `Foo`
-   |                         |                 |
-   |                         |                 arguments to this function are incorrect
-   |                         help: consider using `as_ref` instead: `as_ref().and_then`
+   |                                           --------- ^^^ expected `&Foo`, found `Foo`
+   |                                           |
+   |                                           arguments to this function are incorrect
    |
 note: function defined here
   --> $DIR/as-ref.rs:3:4
    |
 LL | fn takes_ref(_: &Foo) {}
    |    ^^^^^^^^^ -------
+help: consider using `as_ref` instead
+   |
+LL |     multiple_ref_result.as_ref().and_then(|arg| Ok(takes_ref(arg)));
+   |                         +++++++++
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/suggestions/issue-68049-2.stderr b/tests/ui/suggestions/issue-68049-2.stderr
index de35aa5b186..6f3c78443f8 100644
--- a/tests/ui/suggestions/issue-68049-2.stderr
+++ b/tests/ui/suggestions/issue-68049-2.stderr
@@ -4,10 +4,10 @@ error[E0594]: cannot assign to `*input`, which is behind a `&` reference
 LL |       *input = self.0;
    |       ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written
    |
-help: consider changing that to be a mutable reference
+help: consider changing this to be a mutable reference
    |
-LL |   fn example(&self, input: &mut i32); // should suggest here
-   |                            ~~~~~~~~
+LL |   fn example(&self, input: &mut i32) { // should not suggest here
+   |                             +++
 
 error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
   --> $DIR/issue-68049-2.rs:17:5
@@ -15,7 +15,7 @@ error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
 LL |     self.0 += *input;
    |     ^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
    |
-help: consider changing that to be a mutable reference
+help: consider changing this to be a mutable reference
    |
 LL |   fn example(&mut self, input: &i32); // should suggest here
    |              ~~~~~~~~~
diff --git a/tests/ui/suggestions/suggest-ref-macro.rs b/tests/ui/suggestions/suggest-ref-macro.rs
index 6f780f32a14..730f5fa1b5e 100644
--- a/tests/ui/suggestions/suggest-ref-macro.rs
+++ b/tests/ui/suggestions/suggest-ref-macro.rs
@@ -14,7 +14,7 @@ macro_rules! bla {
     () => {
         x(123);
         //~^ ERROR mismatched types
-        //~| SUGGESTION &mut 123
+        //~| SUGGESTION &mut
     };
     ($v:expr) => {
         x($v)
@@ -25,5 +25,5 @@ fn main() {
     bla!();
     bla!(456);
     //~^ ERROR mismatched types
-    //~| SUGGESTION &mut 456
+    //~| SUGGESTION &mut
 }
diff --git a/tests/ui/suggestions/suggest-ref-macro.stderr b/tests/ui/suggestions/suggest-ref-macro.stderr
index 17de49fbd84..08bc9e86a50 100644
--- a/tests/ui/suggestions/suggest-ref-macro.stderr
+++ b/tests/ui/suggestions/suggest-ref-macro.stderr
@@ -18,10 +18,8 @@ error[E0308]: mismatched types
   --> $DIR/suggest-ref-macro.rs:15:11
    |
 LL |         x(123);
-   |         - ^^^
-   |         | |
-   |         | expected `&mut i32`, found integer
-   |         | help: consider mutably borrowing here: `&mut 123`
+   |         - ^^^ expected `&mut i32`, found integer
+   |         |
    |         arguments to this function are incorrect
 ...
 LL |     bla!();
@@ -33,6 +31,10 @@ note: function defined here
 LL | fn x(_: &mut i32) {}
    |    ^ -----------
    = note: this error originates in the macro `bla` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider mutably borrowing here
+   |
+LL |         x(&mut 123);
+   |           ++++
 
 error[E0308]: mismatched types
   --> $DIR/suggest-ref-macro.rs:26:10
@@ -41,16 +43,17 @@ LL |         x($v)
    |         - arguments to this function are incorrect
 ...
 LL |     bla!(456);
-   |          ^^^
-   |          |
-   |          expected `&mut i32`, found integer
-   |          help: consider mutably borrowing here: `&mut 456`
+   |          ^^^ expected `&mut i32`, found integer
    |
 note: function defined here
   --> $DIR/suggest-ref-macro.rs:11:4
    |
 LL | fn x(_: &mut i32) {}
    |    ^ -----------
+help: consider mutably borrowing here
+   |
+LL |     bla!(&mut 456);
+   |          ++++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/suggestions/suggest-ref-mut.rs b/tests/ui/suggestions/suggest-ref-mut.rs
index d04113ffccc..b40439b8e37 100644
--- a/tests/ui/suggestions/suggest-ref-mut.rs
+++ b/tests/ui/suggestions/suggest-ref-mut.rs
@@ -12,12 +12,10 @@ impl X {
 fn main() {
     let ref foo = 16;
     //~^ HELP
-    //~| SUGGESTION ref mut foo
     *foo = 32;
     //~^ ERROR
     if let Some(ref bar) = Some(16) {
         //~^ HELP
-        //~| SUGGESTION ref mut bar
         *bar = 32;
         //~^ ERROR
     }
@@ -25,6 +23,5 @@ fn main() {
         ref quo => { *quo = 32; },
         //~^ ERROR
         //~| HELP
-        //~| SUGGESTION ref mut quo
     }
 }
diff --git a/tests/ui/suggestions/suggest-ref-mut.stderr b/tests/ui/suggestions/suggest-ref-mut.stderr
index 7973759bf5e..cc00022ab8e 100644
--- a/tests/ui/suggestions/suggest-ref-mut.stderr
+++ b/tests/ui/suggestions/suggest-ref-mut.stderr
@@ -10,7 +10,7 @@ LL |     fn zap(&mut self) {
    |            ~~~~~~~~~
 
 error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
-  --> $DIR/suggest-ref-mut.rs:16:5
+  --> $DIR/suggest-ref-mut.rs:15:5
    |
 LL |     *foo = 32;
    |     ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
@@ -18,10 +18,10 @@ LL |     *foo = 32;
 help: consider changing this to be a mutable reference
    |
 LL |     let ref mut foo = 16;
-   |         ~~~~~~~~~~~
+   |             +++
 
 error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
-  --> $DIR/suggest-ref-mut.rs:21:9
+  --> $DIR/suggest-ref-mut.rs:19:9
    |
 LL |         *bar = 32;
    |         ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
@@ -29,10 +29,10 @@ LL |         *bar = 32;
 help: consider changing this to be a mutable reference
    |
 LL |     if let Some(ref mut bar) = Some(16) {
-   |                 ~~~~~~~~~~~
+   |                     +++
 
 error[E0594]: cannot assign to `*quo`, which is behind a `&` reference
-  --> $DIR/suggest-ref-mut.rs:25:22
+  --> $DIR/suggest-ref-mut.rs:23:22
    |
 LL |         ref quo => { *quo = 32; },
    |                      ^^^^^^^^^ `quo` is a `&` reference, so the data it refers to cannot be written
@@ -40,7 +40,7 @@ LL |         ref quo => { *quo = 32; },
 help: consider changing this to be a mutable reference
    |
 LL |         ref mut quo => { *quo = 32; },
-   |         ~~~~~~~~~~~
+   |             +++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.fixed b/tests/ui/suggestions/type-ascription-instead-of-let.fixed
new file mode 100644
index 00000000000..e3d03b6f22a
--- /dev/null
+++ b/tests/ui/suggestions/type-ascription-instead-of-let.fixed
@@ -0,0 +1,11 @@
+// run-rustfix
+
+fn fun(x: i32) -> i32 { x }
+
+fn main() {
+    let _closure_annotated = |value: i32| -> i32 {
+        let temp: i32 = fun(5i32);
+        //~^ ERROR expected identifier, found `:`
+        temp + value + 1
+    };
+}
diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.rs b/tests/ui/suggestions/type-ascription-instead-of-let.rs
index 5ad60243298..6e1c86f9671 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-let.rs
+++ b/tests/ui/suggestions/type-ascription-instead-of-let.rs
@@ -1,7 +1,9 @@
+// run-rustfix
+
 fn fun(x: i32) -> i32 { x }
 
 fn main() {
-    let closure_annotated = |value: i32| -> i32 {
+    let _closure_annotated = |value: i32| -> i32 {
         temp: i32 = fun(5i32);
         //~^ ERROR expected identifier, found `:`
         temp + value + 1
diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.stderr b/tests/ui/suggestions/type-ascription-instead-of-let.stderr
index fb697b0ccfd..065b1f4d353 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-let.stderr
+++ b/tests/ui/suggestions/type-ascription-instead-of-let.stderr
@@ -1,8 +1,13 @@
 error: expected identifier, found `:`
-  --> $DIR/type-ascription-instead-of-let.rs:5:13
+  --> $DIR/type-ascription-instead-of-let.rs:7:13
    |
 LL |         temp: i32 = fun(5i32);
    |             ^ expected identifier
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |         let temp: i32 = fun(5i32);
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr
index 39b60c31197..c054ddb893d 100644
--- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr
+++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr
@@ -7,7 +7,7 @@ LL |     *t
 help: consider changing this to be a mutable reference
    |
 LL | fn reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
-   |                        ~~~~~~~~~~~~~~~~~~~
+   |                            +++
 
 error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
   --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:10:6
@@ -18,7 +18,7 @@ LL |     {*t}
 help: consider changing this to be a mutable reference
    |
 LL | fn copy_reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
-   |                             ~~~~~~~~~~~~~~~~~~~
+   |                                 +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type/missing-let-in-binding-2.fixed b/tests/ui/type/missing-let-in-binding-2.fixed
new file mode 100644
index 00000000000..d64013c8c83
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-2.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+
+fn main() {
+    let _v: Vec<i32> = vec![1, 2, 3]; //~ ERROR expected identifier, found `:`
+}
diff --git a/tests/ui/type/missing-let-in-binding-2.rs b/tests/ui/type/missing-let-in-binding-2.rs
new file mode 100644
index 00000000000..f95f7bef215
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-2.rs
@@ -0,0 +1,5 @@
+// run-rustfix
+
+fn main() {
+    _v: Vec<i32> = vec![1, 2, 3]; //~ ERROR expected identifier, found `:`
+}
diff --git a/tests/ui/type/missing-let-in-binding-2.stderr b/tests/ui/type/missing-let-in-binding-2.stderr
new file mode 100644
index 00000000000..2e10125943e
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-2.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found `:`
+  --> $DIR/missing-let-in-binding-2.rs:4:7
+   |
+LL |     _v: Vec<i32> = vec![1, 2, 3];
+   |       ^ expected identifier
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |     let _v: Vec<i32> = vec![1, 2, 3];
+   |     +++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type/missing-let-in-binding-3.rs b/tests/ui/type/missing-let-in-binding-3.rs
new file mode 100644
index 00000000000..d56b1393336
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-3.rs
@@ -0,0 +1,5 @@
+struct A {
+    : :u8, //~ ERROR expected identifier, found `:`
+}
+
+fn main() {}
diff --git a/tests/ui/type/missing-let-in-binding-3.stderr b/tests/ui/type/missing-let-in-binding-3.stderr
new file mode 100644
index 00000000000..ca828ce37eb
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-3.stderr
@@ -0,0 +1,10 @@
+error: expected identifier, found `:`
+  --> $DIR/missing-let-in-binding-3.rs:2:5
+   |
+LL | struct A {
+   |        - while parsing this struct
+LL |     : :u8,
+   |     ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type/missing-let-in-binding-4.rs b/tests/ui/type/missing-let-in-binding-4.rs
new file mode 100644
index 00000000000..879a6fedcd6
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-4.rs
@@ -0,0 +1,5 @@
+struct A {
+    : u8 =, //~ ERROR expected identifier, found `:`
+}
+
+fn main() {}
diff --git a/tests/ui/type/missing-let-in-binding-4.stderr b/tests/ui/type/missing-let-in-binding-4.stderr
new file mode 100644
index 00000000000..e6f173a6658
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-4.stderr
@@ -0,0 +1,10 @@
+error: expected identifier, found `:`
+  --> $DIR/missing-let-in-binding-4.rs:2:5
+   |
+LL | struct A {
+   |        - while parsing this struct
+LL |     : u8 =,
+   |     ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type/type-mismatch.stderr b/tests/ui/type/type-mismatch.stderr
index 67a1f893050..ce6f29d354f 100644
--- a/tests/ui/type/type-mismatch.stderr
+++ b/tests/ui/type/type-mismatch.stderr
@@ -378,10 +378,8 @@ error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:47:23
    |
 LL |     want::<&Foo<foo>>(f);
-   |     ----------------- ^
-   |     |                 |
-   |     |                 expected `&Foo<foo>`, found `Foo<foo>`
-   |     |                 help: consider borrowing here: `&f`
+   |     ----------------- ^ expected `&Foo<foo>`, found `Foo<foo>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo>`
@@ -391,6 +389,10 @@ note: function defined here
    |
 LL | fn want<T>(t: T) {}
    |    ^^^^    ----
+help: consider borrowing here
+   |
+LL |     want::<&Foo<foo>>(&f);
+   |                       +
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:48:26
@@ -556,10 +558,8 @@ error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:61:26
    |
 LL |     want::<&Foo<foo, B>>(f);
-   |     -------------------- ^
-   |     |                    |
-   |     |                    expected `&Foo<foo, B>`, found `Foo<foo, B>`
-   |     |                    help: consider borrowing here: `&f`
+   |     -------------------- ^ expected `&Foo<foo, B>`, found `Foo<foo, B>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo, B>`
@@ -569,6 +569,10 @@ note: function defined here
    |
 LL | fn want<T>(t: T) {}
    |    ^^^^    ----
+help: consider borrowing here
+   |
+LL |     want::<&Foo<foo, B>>(&f);
+   |                          +
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:65:19
diff --git a/tests/ui/typeck/bad-index-due-to-nested.stderr b/tests/ui/typeck/bad-index-due-to-nested.stderr
index cdb23372c4b..f9cdb280e27 100644
--- a/tests/ui/typeck/bad-index-due-to-nested.stderr
+++ b/tests/ui/typeck/bad-index-due-to-nested.stderr
@@ -42,13 +42,14 @@ error[E0308]: mismatched types
 LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V {
    |              - this type parameter
 LL |     map[k]
-   |         ^
-   |         |
-   |         expected `&K`, found type parameter `K`
-   |         help: consider borrowing here: `&k`
+   |         ^ expected `&K`, found type parameter `K`
    |
    = note:   expected reference `&K`
            found type parameter `K`
+help: consider borrowing here
+   |
+LL |     map[&k]
+   |         +
 
 error[E0308]: mismatched types
   --> $DIR/bad-index-due-to-nested.rs:20:5
@@ -56,13 +57,14 @@ error[E0308]: mismatched types
 LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V {
    |                 - this type parameter               ----- expected `&'a V` because of return type
 LL |     map[k]
-   |     ^^^^^^
-   |     |
-   |     expected `&V`, found type parameter `V`
-   |     help: consider borrowing here: `&map[k]`
+   |     ^^^^^^ expected `&V`, found type parameter `V`
    |
    = note:   expected reference `&'a V`
            found type parameter `V`
+help: consider borrowing here
+   |
+LL |     &map[k]
+   |     +
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/typeck/bad-type-in-vec-contains.stderr b/tests/ui/typeck/bad-type-in-vec-contains.stderr
index 72533ab1fa3..b9b3a5fe5ec 100644
--- a/tests/ui/typeck/bad-type-in-vec-contains.stderr
+++ b/tests/ui/typeck/bad-type-in-vec-contains.stderr
@@ -2,16 +2,18 @@ error[E0308]: mismatched types
   --> $DIR/bad-type-in-vec-contains.rs:5:21
    |
 LL |     primes.contains(3);
-   |            -------- ^
-   |            |        |
-   |            |        expected `&_`, found integer
-   |            |        help: consider borrowing here: `&3`
+   |            -------- ^ expected `&_`, found integer
+   |            |
    |            arguments to this method are incorrect
    |
    = note: expected reference `&_`
                    found type `{integer}`
 note: method defined here
   --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
+help: consider borrowing here
+   |
+LL |     primes.contains(&3);
+   |                     +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/typeck/issue-13853.stderr b/tests/ui/typeck/issue-13853.stderr
index 11d34f5b93b..8ecb8b68016 100644
--- a/tests/ui/typeck/issue-13853.stderr
+++ b/tests/ui/typeck/issue-13853.stderr
@@ -20,10 +20,8 @@ error[E0308]: mismatched types
   --> $DIR/issue-13853.rs:37:13
    |
 LL |     iterate(graph);
-   |     ------- ^^^^^
-   |     |       |
-   |     |       expected `&_`, found `Vec<Stuff>`
-   |     |       help: consider borrowing here: `&graph`
+   |     ------- ^^^^^ expected `&_`, found `Vec<Stuff>`
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
@@ -33,6 +31,10 @@ note: function defined here
    |
 LL | fn iterate<N: Node, G: Graph<N>>(graph: &G) {
    |    ^^^^^^^                       ---------
+help: consider borrowing here
+   |
+LL |     iterate(&graph);
+   |             +
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/unsized-locals/suggest-borrow.stderr b/tests/ui/unsized-locals/suggest-borrow.stderr
index d456c16de0d..8741b35cdcf 100644
--- a/tests/ui/unsized-locals/suggest-borrow.stderr
+++ b/tests/ui/unsized-locals/suggest-borrow.stderr
@@ -16,11 +16,14 @@ error[E0308]: mismatched types
   --> $DIR/suggest-borrow.rs:3:20
    |
 LL |     let x: &[u8] = vec!(1, 2, 3)[..];
-   |            -----   ^^^^^^^^^^^^^^^^^
-   |            |       |
-   |            |       expected `&[u8]`, found `[{integer}]`
-   |            |       help: consider borrowing here: `&vec!(1, 2, 3)[..]`
+   |            -----   ^^^^^^^^^^^^^^^^^ expected `&[u8]`, found `[{integer}]`
+   |            |
    |            expected due to this
+   |
+help: consider borrowing here
+   |
+LL |     let x: &[u8] = &vec!(1, 2, 3)[..];
+   |                    +
 
 error[E0308]: mismatched types
   --> $DIR/suggest-borrow.rs:4:19