about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs21
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs106
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs45
-rw-r--r--compiler/rustc_ast_lowering/src/lifetime_collector.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs24
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs24
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs45
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs22
-rw-r--r--compiler/rustc_span/src/def_id.rs1
-rw-r--r--library/alloc/src/boxed/thin.rs1
m---------src/tools/cargo0
-rw-r--r--tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr4
-rw-r--r--tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.fixed20
-rw-r--r--tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.rs20
-rw-r--r--tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.stderr29
-rw-r--r--tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.fixed77
-rw-r--r--tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.rs77
-rw-r--r--tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.stderr80
-rw-r--r--tests/ui/resolve/resolve-dont-hint-macro.rs4
-rw-r--r--tests/ui/resolve/resolve-dont-hint-macro.stderr9
25 files changed, 489 insertions, 132 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 180459efef9..068f2199105 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -530,7 +530,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     this.mark_span_with_reason(
                         DesugaringKind::TryBlock,
                         expr.span,
-                        this.allow_try_trait.clone(),
+                        Some(this.allow_try_trait.clone()),
                     ),
                     expr,
                 )
@@ -538,7 +538,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let try_span = this.mark_span_with_reason(
                     DesugaringKind::TryBlock,
                     this.tcx.sess.source_map().end_point(body.span),
-                    this.allow_try_trait.clone(),
+                    Some(this.allow_try_trait.clone()),
                 );
 
                 (try_span, this.expr_unit(try_span))
@@ -618,8 +618,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
 
         // Resume argument type: `ResumeTy`
-        let unstable_span =
-            self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
+        let unstable_span = self.mark_span_with_reason(
+            DesugaringKind::Async,
+            span,
+            Some(self.allow_gen_future.clone()),
+        );
         let resume_ty = hir::QPath::LangItem(hir::LangItem::ResumeTy, unstable_span);
         let input_ty = hir::Ty {
             hir_id: self.next_id(),
@@ -741,7 +744,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             let unstable_span = self.mark_span_with_reason(
                 DesugaringKind::Async,
                 span,
-                self.allow_gen_future.clone(),
+                Some(self.allow_gen_future.clone()),
             );
             self.lower_attrs(
                 inner_hir_id,
@@ -788,7 +791,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let gen_future_span = self.mark_span_with_reason(
             DesugaringKind::Await,
             full_span,
-            self.allow_gen_future.clone(),
+            Some(self.allow_gen_future.clone()),
         );
         let expr = self.lower_expr_mut(expr);
         let expr_hir_id = expr.hir_id;
@@ -1646,13 +1649,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let unstable_span = self.mark_span_with_reason(
             DesugaringKind::QuestionMark,
             span,
-            self.allow_try_trait.clone(),
+            Some(self.allow_try_trait.clone()),
         );
         let try_span = self.tcx.sess.source_map().end_point(span);
         let try_span = self.mark_span_with_reason(
             DesugaringKind::QuestionMark,
             try_span,
-            self.allow_try_trait.clone(),
+            Some(self.allow_try_trait.clone()),
         );
 
         // `Try::branch(<expr>)`
@@ -1745,7 +1748,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let unstable_span = self.mark_span_with_reason(
             DesugaringKind::YeetExpr,
             span,
-            self.allow_try_trait.clone(),
+            Some(self.allow_try_trait.clone()),
         );
 
         let from_yeet_expr = self.wrap_in_try_constructor(
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index e91b78720a8..1741611fb11 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -10,7 +10,7 @@ use rustc_middle::ty::TyCtxt;
 use rustc_span::{Span, DUMMY_SP};
 
 /// A visitor that walks over the HIR and collects `Node`s into a HIR map.
-pub(super) struct NodeCollector<'a, 'hir> {
+struct NodeCollector<'a, 'hir> {
     tcx: TyCtxt<'hir>,
 
     bodies: &'a SortedMap<ItemLocalId, &'hir Body<'hir>>,
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index fb75471ede3..e9779a9bf94 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -7,7 +7,6 @@ use hir::definitions::DefPathData;
 use rustc_ast::ptr::P;
 use rustc_ast::visit::AssocCtxt;
 use rustc_ast::*;
-use rustc_data_structures::sorted_map::SortedMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -55,42 +54,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
         owner: NodeId,
         f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>,
     ) {
-        let allow_gen_future = Some(if self.tcx.features().async_fn_track_caller {
-            [sym::gen_future, sym::closure_track_caller][..].into()
-        } else {
-            [sym::gen_future][..].into()
-        });
-        let mut lctx = LoweringContext {
-            // Pseudo-globals.
-            tcx: self.tcx,
-            resolver: self.resolver,
-            arena: self.tcx.hir_arena,
-
-            // HirId handling.
-            bodies: Vec::new(),
-            attrs: SortedMap::default(),
-            children: Vec::default(),
-            current_hir_id_owner: hir::CRATE_OWNER_ID,
-            item_local_id_counter: hir::ItemLocalId::new(0),
-            node_id_to_local_id: Default::default(),
-            trait_map: Default::default(),
-
-            // Lowering state.
-            catch_scope: None,
-            loop_scope: None,
-            is_in_loop_condition: false,
-            is_in_trait_impl: false,
-            is_in_dyn_type: false,
-            coroutine_kind: None,
-            task_context: None,
-            current_item: None,
-            impl_trait_defs: Vec::new(),
-            impl_trait_bounds: Vec::new(),
-            allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
-            allow_gen_future,
-            generics_def_id_map: Default::default(),
-            host_param_id: None,
-        };
+        let mut lctx = LoweringContext::new(self.tcx, self.resolver);
         lctx.with_hir_id_owner(owner, |lctx| f(lctx));
 
         for (def_id, info) in lctx.children {
@@ -136,39 +100,9 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
 
     fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
         let def_id = self.resolver.node_id_to_def_id[&item.id];
-
         let parent_id = self.tcx.local_parent(def_id);
         let parent_hir = self.lower_node(parent_id).unwrap();
-        self.with_lctx(item.id, |lctx| {
-            // Evaluate with the lifetimes in `params` in-scope.
-            // This is used to track which lifetimes have already been defined,
-            // and which need to be replicated when lowering an async fn.
-
-            match parent_hir.node().expect_item().kind {
-                hir::ItemKind::Impl(impl_) => {
-                    lctx.is_in_trait_impl = impl_.of_trait.is_some();
-                }
-                hir::ItemKind::Trait(_, _, generics, _, _) if lctx.tcx.features().effects => {
-                    lctx.host_param_id = generics
-                        .params
-                        .iter()
-                        .find(|param| {
-                            parent_hir
-                                .attrs
-                                .get(param.hir_id.local_id)
-                                .iter()
-                                .any(|attr| attr.has_name(sym::rustc_host))
-                        })
-                        .map(|param| param.def_id);
-                }
-                _ => {}
-            }
-
-            match ctxt {
-                AssocCtxt::Trait => hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)),
-                AssocCtxt::Impl => hir::OwnerNode::ImplItem(lctx.lower_impl_item(item)),
-            }
-        })
+        self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt, parent_hir))
     }
 
     fn lower_foreign_item(&mut self, item: &ForeignItem) {
@@ -611,6 +545,42 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
+    fn lower_assoc_item(
+        &mut self,
+        item: &AssocItem,
+        ctxt: AssocCtxt,
+        parent_hir: &'hir hir::OwnerInfo<'hir>,
+    ) -> hir::OwnerNode<'hir> {
+        // Evaluate with the lifetimes in `params` in-scope.
+        // This is used to track which lifetimes have already been defined,
+        // and which need to be replicated when lowering an async fn.
+
+        match parent_hir.node().expect_item().kind {
+            hir::ItemKind::Impl(impl_) => {
+                self.is_in_trait_impl = impl_.of_trait.is_some();
+            }
+            hir::ItemKind::Trait(_, _, generics, _, _) if self.tcx.features().effects => {
+                self.host_param_id = generics
+                    .params
+                    .iter()
+                    .find(|param| {
+                        parent_hir
+                            .attrs
+                            .get(param.hir_id.local_id)
+                            .iter()
+                            .any(|attr| attr.has_name(sym::rustc_host))
+                    })
+                    .map(|param| param.def_id);
+            }
+            _ => {}
+        }
+
+        match ctxt {
+            AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
+            AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)),
+        }
+    }
+
     fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
         let hir_id = self.lower_node_id(i.id);
         let owner_id = hir_id.expect_owner();
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 4c7b9b4155f..1a92657ed48 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -35,7 +35,6 @@
 #![doc(rust_logo)]
 #![feature(box_patterns)]
 #![feature(let_chains)]
-#![feature(never_type)]
 #![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
@@ -132,8 +131,8 @@ struct LoweringContext<'a, 'hir> {
     /// NodeIds that are lowered inside the current HIR owner.
     node_id_to_local_id: FxHashMap<NodeId, hir::ItemLocalId>,
 
-    allow_try_trait: Option<Lrc<[Symbol]>>,
-    allow_gen_future: Option<Lrc<[Symbol]>>,
+    allow_try_trait: Lrc<[Symbol]>,
+    allow_gen_future: Lrc<[Symbol]>,
 
     /// Mapping from generics `def_id`s to TAIT generics `def_id`s.
     /// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic
@@ -144,6 +143,46 @@ struct LoweringContext<'a, 'hir> {
     host_param_id: Option<LocalDefId>,
 }
 
+impl<'a, 'hir> LoweringContext<'a, 'hir> {
+    fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
+        Self {
+            // Pseudo-globals.
+            tcx,
+            resolver: resolver,
+            arena: tcx.hir_arena,
+
+            // HirId handling.
+            bodies: Vec::new(),
+            attrs: SortedMap::default(),
+            children: Vec::default(),
+            current_hir_id_owner: hir::CRATE_OWNER_ID,
+            item_local_id_counter: hir::ItemLocalId::new(0),
+            node_id_to_local_id: Default::default(),
+            trait_map: Default::default(),
+
+            // Lowering state.
+            catch_scope: None,
+            loop_scope: None,
+            is_in_loop_condition: false,
+            is_in_trait_impl: false,
+            is_in_dyn_type: false,
+            coroutine_kind: None,
+            task_context: None,
+            current_item: None,
+            impl_trait_defs: Vec::new(),
+            impl_trait_bounds: Vec::new(),
+            allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
+            allow_gen_future: if tcx.features().async_fn_track_caller {
+                [sym::gen_future, sym::closure_track_caller].into()
+            } else {
+                [sym::gen_future].into()
+            },
+            generics_def_id_map: Default::default(),
+            host_param_id: None,
+        }
+    }
+}
+
 trait ResolverAstLoweringExt {
     fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>>;
     fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
index d66bba517e0..4b1c057cdbf 100644
--- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs
+++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
@@ -108,7 +108,7 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
     }
 }
 
-pub fn lifetimes_in_bounds(
+pub(crate) fn lifetimes_in_bounds(
     resolver: &ResolverAstLowering,
     bounds: &GenericBounds,
 ) -> Vec<Lifetime> {
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index a30f264bc7d..4950f6e54b5 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -18,7 +18,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.arena.alloc(self.lower_pat_mut(pattern))
     }
 
-    pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
+    fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
         ensure_sufficient_stack(|| {
             // loop here to avoid recursion
             let node = loop {
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 9225f19876d..ef4bf543454 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2352,7 +2352,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                                     Applicability::MaybeIncorrect,
                                 );
                             } else {
-                                err.note("the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used");
+                                err.note("the result of `format_args!` can only be assigned directly if no placeholders in its arguments are used");
                                 err.note("to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>");
                             }
                             suggested = true;
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 12d12d5bff0..c5fd535b036 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -672,30 +672,22 @@ fn report_missing_placeholders(
                     if explained.contains(&sub) {
                         continue;
                     }
-                    explained.insert(sub.clone());
+                    explained.insert(sub);
 
                     if !found_foreign {
                         found_foreign = true;
                         show_doc_note = true;
                     }
 
-                    if let Some(inner_sp) = pos {
-                        let sp = fmt_span.from_inner(inner_sp);
+                    let sp = fmt_span.from_inner(pos);
 
-                        if success {
-                            suggestions.push((sp, trn));
-                        } else {
-                            diag.span_note(
-                                sp,
-                                format!("format specifiers use curly braces, and {}", trn),
-                            );
-                        }
+                    if success {
+                        suggestions.push((sp, trn));
                     } else {
-                        if success {
-                            diag.help(format!("`{}` should be written as `{}`", sub, trn));
-                        } else {
-                            diag.note(format!("`{}` should use curly braces, and {}", sub, trn));
-                        }
+                        diag.span_note(
+                            sp,
+                            format!("format specifiers use curly braces, and {}", trn),
+                        );
                     }
                 }
 
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index 2fc8a076366..307e582d65e 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -19,10 +19,10 @@ pub(crate) mod printf {
             }
         }
 
-        pub fn position(&self) -> Option<InnerSpan> {
+        pub fn position(&self) -> InnerSpan {
             match self {
-                Substitution::Format(fmt) => Some(fmt.position),
-                &Substitution::Escape((start, end)) => Some(InnerSpan::new(start, end)),
+                Substitution::Format(fmt) => fmt.position,
+                &Substitution::Escape((start, end)) => InnerSpan::new(start, end),
             }
         }
 
@@ -302,10 +302,9 @@ pub(crate) mod printf {
         fn next(&mut self) -> Option<Self::Item> {
             let (mut sub, tail) = parse_next_substitution(self.s)?;
             self.s = tail;
-            if let Some(InnerSpan { start, end }) = sub.position() {
-                sub.set_position(start + self.pos, end + self.pos);
-                self.pos += end;
-            }
+            let InnerSpan { start, end } = sub.position();
+            sub.set_position(start + self.pos, end + self.pos);
+            self.pos += end;
             Some(sub)
         }
 
@@ -629,9 +628,9 @@ pub mod shell {
             }
         }
 
-        pub fn position(&self) -> Option<InnerSpan> {
+        pub fn position(&self) -> InnerSpan {
             let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
-            Some(InnerSpan::new(pos.0, pos.1))
+            InnerSpan::new(pos.0, pos.1)
         }
 
         pub fn set_position(&mut self, start: usize, end: usize) {
@@ -664,10 +663,9 @@ pub mod shell {
         fn next(&mut self) -> Option<Self::Item> {
             let (mut sub, tail) = parse_next_substitution(self.s)?;
             self.s = tail;
-            if let Some(InnerSpan { start, end }) = sub.position() {
-                sub.set_position(start + self.pos, end + self.pos);
-                self.pos += end;
-            }
+            let InnerSpan { start, end } = sub.position();
+            sub.set_position(start + self.pos, end + self.pos);
+            self.pos += end;
             Some(sub)
         }
 
diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs
index cf9312ea8fb..b54d75f7ed7 100644
--- a/compiler/rustc_data_structures/src/graph/scc/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs
@@ -492,7 +492,7 @@ where
             let returned_walk =
                 return_value.take().into_iter().map(|walk| (*successor_node, Some(walk)));
 
-            let successor_walk = successors.by_ref().map(|successor_node| {
+            let successor_walk = successors.map(|successor_node| {
                 debug!(?node, ?successor_node);
                 (successor_node, self.inspect_node(successor_node))
             });
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index aff1baa1960..74aec897f95 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -626,7 +626,7 @@ pub struct SuggestConvertViaMethod<'tcx> {
     pub span: Span,
     #[suggestion_part(code = "")]
     pub borrow_removal_span: Option<Span>,
-    pub sugg: &'static str,
+    pub sugg: String,
     pub expected: Ty<'tcx>,
     pub found: Ty<'tcx>,
 }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index c74ef8f2713..a904b419a94 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -442,12 +442,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     expected,
                 )
             });
+
+            let prefix_wrap = |sugg: &str| {
+                if let Some(name) = self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+                    format!(": {}{}", name, sugg)
+                } else {
+                    sugg.to_string()
+                }
+            };
+
             // FIXME: This could/should be extended to suggest `as_mut` and `as_deref_mut`,
             // but those checks need to be a bit more delicate and the benefit is diminishing.
             if self.can_eq(self.param_env, found_ty_inner, peeled) && error_tys_equate_as_ref {
+                let sugg = prefix_wrap(".as_ref()");
                 err.subdiagnostic(errors::SuggestConvertViaMethod {
                     span: expr.span.shrink_to_hi(),
-                    sugg: ".as_ref()",
+                    sugg,
                     expected,
                     found,
                     borrow_removal_span,
@@ -458,9 +468,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 && self.can_eq(self.param_env, deref_ty, peeled)
                 && error_tys_equate_as_ref
             {
+                let sugg = prefix_wrap(".as_deref()");
                 err.subdiagnostic(errors::SuggestConvertViaMethod {
                     span: expr.span.shrink_to_hi(),
-                    sugg: ".as_deref()",
+                    sugg,
                     expected,
                     found,
                     borrow_removal_span,
@@ -474,10 +485,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.can_eq(self.param_env, found, expected)
                 })
             {
+                let sugg = prefix_wrap(".map(|x| x.as_str())");
                 err.span_suggestion_verbose(
                     expr.span.shrink_to_hi(),
                     fluent::hir_typeck_convert_to_str,
-                    ".map(|x| x.as_str())",
+                    sugg,
                     Applicability::MachineApplicable,
                 );
                 return true;
@@ -628,12 +640,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             err.help("use `Box::pin`");
                         }
                         _ => {
+                            let prefix = if let Some(name) =
+                                self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr)
+                            {
+                                format!("{}: ", name)
+                            } else {
+                                String::new()
+                            };
+                            let suggestion = vec![
+                                (expr.span.shrink_to_lo(), format!("{prefix}Box::pin(")),
+                                (expr.span.shrink_to_hi(), ")".to_string()),
+                            ];
                             err.multipart_suggestion(
                                 "you need to pin and box this expression",
-                                vec![
-                                    (expr.span.shrink_to_lo(), "Box::pin(".to_string()),
-                                    (expr.span.shrink_to_hi(), ")".to_string()),
-                                ],
+                                suggestion,
                                 Applicability::MaybeIncorrect,
                             );
                         }
@@ -1214,7 +1234,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 span = parent_callsite;
             }
 
-            let sugg = if expr.precedence().order() >= PREC_POSTFIX {
+            let mut sugg = if expr.precedence().order() >= PREC_POSTFIX {
                 vec![(span.shrink_to_hi(), ".into()".to_owned())]
             } else {
                 vec![
@@ -1222,6 +1242,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     (span.shrink_to_hi(), ").into()".to_owned()),
                 ]
             };
+            if let Some(name) = self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+                sugg.insert(0, (expr.span.shrink_to_lo(), format!("{}: ", name)));
+            }
             diag.multipart_suggestion(
                 format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"),
                 sugg,
@@ -1811,6 +1834,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ".expect(\"REASON\")",
             )
         };
+
+        let sugg = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
+            Some(ident) => format!(": {ident}{sugg}"),
+            None => sugg.to_string(),
+        };
+
         err.span_suggestion_verbose(
             expr.span.shrink_to_hi(),
             msg,
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 8316102b507..df30c185c60 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -744,6 +744,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 err,
                 span,
                 source,
+                path,
                 res,
                 &path_str,
                 &base_error.fallback_label,
@@ -1328,6 +1329,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         err: &mut Diagnostic,
         span: Span,
         source: PathSource<'_>,
+        path: &[Segment],
         res: Res,
         path_str: &str,
         fallback_label: &str,
@@ -1523,12 +1525,20 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 | PathSource::Struct,
             ) => {
                 err.span_label(span, fallback_label.to_string());
-                err.span_suggestion_verbose(
-                    span.shrink_to_hi(),
-                    "use `!` to invoke the macro",
-                    "!",
-                    Applicability::MaybeIncorrect,
-                );
+
+                // Don't suggest `!` for a macro invocation if there are generic args
+                if path
+                    .last()
+                    .is_some_and(|segment| !segment.has_generic_args && !segment.has_lifetime_args)
+                {
+                    err.span_suggestion_verbose(
+                        span.shrink_to_hi(),
+                        "use `!` to invoke the macro",
+                        "!",
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+
                 if path_str == "try" && span.is_rust_2015() {
                     err.note("if you want the `try` keyword, you need Rust 2018 or later");
                 }
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 4b5bd75d5b1..b2d51ac6c0d 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -222,7 +222,6 @@ rustc_index::newtype_index! {
     }
 }
 
-// njn: I don't understand these
 impl<E: Encoder> Encodable<E> for DefIndex {
     default fn encode(&self, _: &mut E) {
         panic!("cannot encode `DefIndex` with `{}`", std::any::type_name::<E>());
diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs
index f83c8f83cc9..a8005b7067d 100644
--- a/library/alloc/src/boxed/thin.rs
+++ b/library/alloc/src/boxed/thin.rs
@@ -171,6 +171,7 @@ struct WithHeader<H>(NonNull<u8>, PhantomData<H>);
 /// An opaque representation of `WithHeader<H>` to avoid the
 /// projection invariance of `<T as Pointee>::Metadata`.
 #[repr(transparent)]
+#[allow(unused_tuple_struct_fields)] // Field only used through `WithHeader` type above.
 struct WithOpaqueHeader(NonNull<u8>);
 
 impl WithOpaqueHeader {
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 9b13310ca596020a737aaa47daa4ed9ff8898a2
+Subproject 26333c732095d207aa05932ce863d850fb30938
diff --git a/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr b/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr
index 8221505b100..3ee89d9734a 100644
--- a/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr
+++ b/tests/ui/borrowck/issue-114374-invalid-help-fmt-args.stderr
@@ -9,7 +9,7 @@ LL |     let x = format_args!("a {} {} {}.", 1, format_args!("b{}!", 2), 3);
 LL |     bar(x);
    |         - borrow later used here
    |
-   = note: the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used
+   = note: the result of `format_args!` can only be assigned directly if no placeholders in its arguments are used
    = note: to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>
    = note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -24,7 +24,7 @@ LL |
 LL |     bar(foo);
    |         --- borrow later used here
    |
-   = note: the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used
+   = note: the result of `format_args!` can only be assigned directly if no placeholders in its arguments are used
    = note: to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>
    = note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.fixed b/tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.fixed
new file mode 100644
index 00000000000..15d4e393874
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.fixed
@@ -0,0 +1,20 @@
+// run-rustfix
+#![allow(unused, dead_code)]
+
+#[derive(Clone, Copy)]
+struct Stuff {
+    count: i32,
+}
+struct Error;
+
+fn demo() -> Result<Stuff, Error> {
+    let count = Ok(1);
+    Ok(Stuff { count: count? }) //~ ERROR mismatched types
+}
+
+fn demo_unwrap() -> Stuff {
+    let count = Some(1);
+    Stuff { count: count.expect("REASON") } //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.rs b/tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.rs
new file mode 100644
index 00000000000..8e811caa3bd
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.rs
@@ -0,0 +1,20 @@
+// run-rustfix
+#![allow(unused, dead_code)]
+
+#[derive(Clone, Copy)]
+struct Stuff {
+    count: i32,
+}
+struct Error;
+
+fn demo() -> Result<Stuff, Error> {
+    let count = Ok(1);
+    Ok(Stuff { count }) //~ ERROR mismatched types
+}
+
+fn demo_unwrap() -> Stuff {
+    let count = Some(1);
+    Stuff { count } //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.stderr b/tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.stderr
new file mode 100644
index 00000000000..0bcbd6f27c4
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-118145-unwrap-for-shorthand.stderr
@@ -0,0 +1,29 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-118145-unwrap-for-shorthand.rs:12:16
+   |
+LL |     Ok(Stuff { count })
+   |                ^^^^^ expected `i32`, found `Result<{integer}, _>`
+   |
+   = note: expected type `i32`
+              found enum `Result<{integer}, _>`
+help: use the `?` operator to extract the `Result<{integer}, _>` value, propagating a `Result::Err` value to the caller
+   |
+LL |     Ok(Stuff { count: count? })
+   |                     ++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/issue-118145-unwrap-for-shorthand.rs:17:13
+   |
+LL |     Stuff { count }
+   |             ^^^^^ expected `i32`, found `Option<{integer}>`
+   |
+   = note: expected type `i32`
+              found enum `Option<{integer}>`
+help: consider using `Option::expect` to unwrap the `Option<{integer}>` value, panicking if the value is an `Option::None`
+   |
+LL |     Stuff { count: count.expect("REASON") }
+   |                  ++++++++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.fixed b/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.fixed
new file mode 100644
index 00000000000..e1f929e6170
--- /dev/null
+++ b/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.fixed
@@ -0,0 +1,77 @@
+// run-rustfix
+// edition:2021
+#![allow(dead_code)]
+#![allow(unused_variables)]
+use std::future::Future;
+use std::pin::Pin;
+
+fn test1() {
+    let string = String::from("Hello, world");
+
+    struct Demo<'a> {
+        option: Option<&'a str>,
+    }
+
+    let option: Option<String> = Some(string.clone());
+    let s = Demo { option: option.as_deref() }; //~ ERROR mismatched types
+}
+
+fn test2() {
+    let string = String::from("Hello, world");
+
+    struct Demo<'a> {
+        option_ref: Option<&'a str>,
+    }
+
+    let option_ref = Some(&string);
+    let s = Demo { option_ref: option_ref.map(|x| x.as_str()) }; //~ ERROR mismatched types
+}
+
+fn test3() {
+    let string = String::from("Hello, world");
+
+    struct Demo<'a> {
+        option_ref_ref: Option<&'a str>,
+    }
+
+    let option_ref = Some(&string);
+    let option_ref_ref = option_ref.as_ref();
+
+    let s = Demo { option_ref_ref: option_ref_ref.map(|x| x.as_str()) }; //~ ERROR mismatched types
+}
+
+fn test4() {
+    let a = 1;
+    struct Demo {
+        a: String,
+    }
+    let s = Demo { a: a.to_string() }; //~ ERROR mismatched types
+}
+
+type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
+fn test5() {
+    let a = async { 42 };
+    struct Demo {
+        a: BoxFuture<'static, i32>,
+    }
+    let s = Demo { a: Box::pin(a) }; //~ ERROR mismatched types
+}
+
+fn test6() {
+    struct A;
+    struct B;
+
+    impl From<B> for A {
+        fn from(_: B) -> Self {
+            A
+        }
+    }
+
+    struct Demo {
+        a: A,
+    }
+    let a = B;
+    let s = Demo { a: a.into() }; //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.rs b/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.rs
new file mode 100644
index 00000000000..956936c925b
--- /dev/null
+++ b/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.rs
@@ -0,0 +1,77 @@
+// run-rustfix
+// edition:2021
+#![allow(dead_code)]
+#![allow(unused_variables)]
+use std::future::Future;
+use std::pin::Pin;
+
+fn test1() {
+    let string = String::from("Hello, world");
+
+    struct Demo<'a> {
+        option: Option<&'a str>,
+    }
+
+    let option: Option<String> = Some(string.clone());
+    let s = Demo { option }; //~ ERROR mismatched types
+}
+
+fn test2() {
+    let string = String::from("Hello, world");
+
+    struct Demo<'a> {
+        option_ref: Option<&'a str>,
+    }
+
+    let option_ref = Some(&string);
+    let s = Demo { option_ref }; //~ ERROR mismatched types
+}
+
+fn test3() {
+    let string = String::from("Hello, world");
+
+    struct Demo<'a> {
+        option_ref_ref: Option<&'a str>,
+    }
+
+    let option_ref = Some(&string);
+    let option_ref_ref = option_ref.as_ref();
+
+    let s = Demo { option_ref_ref }; //~ ERROR mismatched types
+}
+
+fn test4() {
+    let a = 1;
+    struct Demo {
+        a: String,
+    }
+    let s = Demo { a }; //~ ERROR mismatched types
+}
+
+type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
+fn test5() {
+    let a = async { 42 };
+    struct Demo {
+        a: BoxFuture<'static, i32>,
+    }
+    let s = Demo { a }; //~ ERROR mismatched types
+}
+
+fn test6() {
+    struct A;
+    struct B;
+
+    impl From<B> for A {
+        fn from(_: B) -> Self {
+            A
+        }
+    }
+
+    struct Demo {
+        a: A,
+    }
+    let a = B;
+    let s = Demo { a }; //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.stderr b/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.stderr
new file mode 100644
index 00000000000..1baf95d2bf7
--- /dev/null
+++ b/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.stderr
@@ -0,0 +1,80 @@
+error[E0308]: mismatched types
+  --> $DIR/mismatch-sugg-for-shorthand-field.rs:16:20
+   |
+LL |     let s = Demo { option };
+   |                    ^^^^^^ expected `Option<&str>`, found `Option<String>`
+   |
+   = note: expected enum `Option<&str>`
+              found enum `Option<String>`
+help: try using `: option.as_deref()` to convert `Option<String>` to `Option<&str>`
+   |
+LL |     let s = Demo { option: option.as_deref() };
+   |                          +++++++++++++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/mismatch-sugg-for-shorthand-field.rs:27:20
+   |
+LL |     let s = Demo { option_ref };
+   |                    ^^^^^^^^^^ expected `Option<&str>`, found `Option<&String>`
+   |
+   = note: expected enum `Option<&str>`
+              found enum `Option<&String>`
+help: try converting the passed type into a `&str`
+   |
+LL |     let s = Demo { option_ref: option_ref.map(|x| x.as_str()) };
+   |                              ++++++++++++++++++++++++++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/mismatch-sugg-for-shorthand-field.rs:40:20
+   |
+LL |     let s = Demo { option_ref_ref };
+   |                    ^^^^^^^^^^^^^^ expected `Option<&str>`, found `Option<&&String>`
+   |
+   = note: expected enum `Option<&str>`
+              found enum `Option<&&String>`
+help: try converting the passed type into a `&str`
+   |
+LL |     let s = Demo { option_ref_ref: option_ref_ref.map(|x| x.as_str()) };
+   |                                  ++++++++++++++++++++++++++++++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/mismatch-sugg-for-shorthand-field.rs:48:20
+   |
+LL |     let s = Demo { a };
+   |                    ^ expected `String`, found integer
+   |
+help: try using a conversion method
+   |
+LL |     let s = Demo { a: a.to_string() };
+   |                    ++  ++++++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/mismatch-sugg-for-shorthand-field.rs:57:20
+   |
+LL |     let a = async { 42 };
+   |             ------------ the found `async` block
+...
+LL |     let s = Demo { a };
+   |                    ^ expected `Pin<Box<...>>`, found `async` block
+   |
+   = note:     expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
+           found `async` block `{async block@$DIR/mismatch-sugg-for-shorthand-field.rs:53:13: 53:25}`
+help: you need to pin and box this expression
+   |
+LL |     let s = Demo { a: Box::pin(a) };
+   |                    ++++++++++++ +
+
+error[E0308]: mismatched types
+  --> $DIR/mismatch-sugg-for-shorthand-field.rs:74:20
+   |
+LL |     let s = Demo { a };
+   |                    ^ expected `A`, found `B`
+   |
+help: call `Into::into` on this expression to convert `B` into `A`
+   |
+LL |     let s = Demo { a: a.into() };
+   |                    ++  +++++++
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/resolve/resolve-dont-hint-macro.rs b/tests/ui/resolve/resolve-dont-hint-macro.rs
new file mode 100644
index 00000000000..da1752b337e
--- /dev/null
+++ b/tests/ui/resolve/resolve-dont-hint-macro.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let zero = assert_eq::<()>();
+    //~^ ERROR expected function, found macro `assert_eq`
+}
diff --git a/tests/ui/resolve/resolve-dont-hint-macro.stderr b/tests/ui/resolve/resolve-dont-hint-macro.stderr
new file mode 100644
index 00000000000..597e014d255
--- /dev/null
+++ b/tests/ui/resolve/resolve-dont-hint-macro.stderr
@@ -0,0 +1,9 @@
+error[E0423]: expected function, found macro `assert_eq`
+  --> $DIR/resolve-dont-hint-macro.rs:2:16
+   |
+LL |     let zero = assert_eq::<()>();
+   |                ^^^^^^^^^^^^^^^ not a function
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0423`.