about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/mem_categorization.rs1
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs40
-rw-r--r--compiler/rustc_serialize/src/serialize.rs5
-rw-r--r--library/core/src/num/int_macros.rs25
-rw-r--r--library/core/src/num/mod.rs384
-rw-r--r--library/core/src/num/uint_macros.rs25
-rw-r--r--src/librustdoc/passes/strip_hidden.rs18
-rw-r--r--tests/rustdoc/issue-108231.rs23
-rw-r--r--tests/rustdoc/reexport-hidden-macro.rs22
-rw-r--r--tests/ui/errors/traits/blame-trait-error-spans-on-exprs.rs6
-rw-r--r--tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr60
-rw-r--r--tests/ui/traits/suggest-deferences/issue-39029.stderr4
15 files changed, 499 insertions, 133 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 80ec1caf521..3f52f174cdf 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -987,7 +987,6 @@ pub struct Pat<'hir> {
 }
 
 impl<'hir> Pat<'hir> {
-    // FIXME(#19596) this is a workaround, but there should be a better way
     fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
         if !it(self) {
             return false;
@@ -1015,7 +1014,6 @@ impl<'hir> Pat<'hir> {
         self.walk_short_(&mut it)
     }
 
-    // FIXME(#19596) this is a workaround, but there should be a better way
     fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
         if !it(self) {
             return;
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 5b641be062b..b2f3a3abb4c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -32,7 +32,7 @@ use rustc_session::lint;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::symbol::{kw, sym, Ident};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
 use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCauseCode, ObligationCtxt};
 
@@ -737,7 +737,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if let ty::subst::GenericArgKind::Type(ty) = ty.unpack()
                     && let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind()
                     && let Some(def_id) = def_id.as_local()
-                    && self.opaque_type_origin(def_id, DUMMY_SP).is_some() {
+                    && self.opaque_type_origin(def_id).is_some() {
                     return None;
                 }
             }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index 06d6a375697..39e0ea98f96 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -549,6 +549,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return Err(expr);
         };
 
+        if let (
+            hir::ExprKind::AddrOf(_borrow_kind, _borrow_mutability, borrowed_expr),
+            ty::Ref(_ty_region, ty_ref_type, _ty_mutability),
+        ) = (&expr.kind, in_ty.kind())
+        {
+            // We can "drill into" the borrowed expression.
+            return self.blame_specific_part_of_expr_corresponding_to_generic_param(
+                param,
+                borrowed_expr,
+                (*ty_ref_type).into(),
+            );
+        }
+
         if let (hir::ExprKind::Tup(expr_elements), ty::Tuple(in_ty_elements)) =
             (&expr.kind, in_ty.kind())
         {
diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs
index 60e0ce3494d..4b08832eddc 100644
--- a/compiler/rustc_hir_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs
@@ -601,7 +601,6 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         }
     }
 
-    // FIXME(#19596) This is a workaround, but there should be a better way to do this
     fn cat_pattern_<F>(
         &self,
         mut place_with_id: PlaceWithHirId<'tcx>,
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 5635e8adf34..e783443502b 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -57,9 +57,7 @@ impl<'tcx> InferCtxt<'tcx> {
         }
         let mut obligations = vec![];
         let replace_opaque_type = |def_id: DefId| {
-            def_id
-                .as_local()
-                .map_or(false, |def_id| self.opaque_type_origin(def_id, span).is_some())
+            def_id.as_local().map_or(false, |def_id| self.opaque_type_origin(def_id).is_some())
         };
         let value = value.fold_with(&mut BottomUpFolder {
             tcx: self.tcx,
@@ -144,9 +142,9 @@ impl<'tcx> InferCtxt<'tcx> {
                         //     let x = || foo(); // returns the Opaque assoc with `foo`
                         // }
                         // ```
-                        self.opaque_type_origin(def_id, cause.span)?
+                        self.opaque_type_origin(def_id)?
                     }
-                    DefiningAnchor::Bubble => self.opaque_ty_origin_unchecked(def_id, cause.span),
+                    DefiningAnchor::Bubble => self.opaque_type_origin_unchecked(def_id),
                     DefiningAnchor::Error => return None,
                 };
                 if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
@@ -155,9 +153,8 @@ impl<'tcx> InferCtxt<'tcx> {
                     // no one encounters it in practice.
                     // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
                     // where it is of no concern, so we only check for TAITs.
-                    if let Some(OpaqueTyOrigin::TyAlias) = b_def_id
-                        .as_local()
-                        .and_then(|b_def_id| self.opaque_type_origin(b_def_id, cause.span))
+                    if let Some(OpaqueTyOrigin::TyAlias) =
+                        b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id))
                     {
                         self.tcx.sess.emit_err(OpaqueHiddenTypeDiag {
                             span: cause.span,
@@ -371,24 +368,18 @@ impl<'tcx> InferCtxt<'tcx> {
         });
     }
 
+    /// Returns the origin of the opaque type `def_id` if we're currently
+    /// in its defining scope.
     #[instrument(skip(self), level = "trace", ret)]
-    pub fn opaque_type_origin(&self, def_id: LocalDefId, span: Span) -> Option<OpaqueTyOrigin> {
+    pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<OpaqueTyOrigin> {
         let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
         let parent_def_id = match self.defining_use_anchor {
             DefiningAnchor::Bubble | DefiningAnchor::Error => return None,
             DefiningAnchor::Bind(bind) => bind,
         };
-        let item_kind = &self.tcx.hir().expect_item(def_id).kind;
-
-        let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {
-            span_bug!(
-                span,
-                "weird opaque type: {:#?}, {:#?}",
-                def_id,
-                item_kind
-            )
-        };
-        let in_definition_scope = match *origin {
+
+        let origin = self.opaque_type_origin_unchecked(def_id);
+        let in_definition_scope = match origin {
             // Async `impl Trait`
             hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
             // Anonymous `impl Trait`
@@ -398,16 +389,17 @@ impl<'tcx> InferCtxt<'tcx> {
                 may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id)
             }
         };
-        trace!(?origin);
-        in_definition_scope.then_some(*origin)
+        in_definition_scope.then_some(origin)
     }
 
+    /// Returns the origin of the opaque type `def_id` even if we are not in its
+    /// defining scope.
     #[instrument(skip(self), level = "trace", ret)]
-    fn opaque_ty_origin_unchecked(&self, def_id: LocalDefId, span: Span) -> OpaqueTyOrigin {
+    fn opaque_type_origin_unchecked(&self, def_id: LocalDefId) -> OpaqueTyOrigin {
         match self.tcx.hir().expect_item(def_id).kind {
             hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => origin,
             ref itemkind => {
-                span_bug!(span, "weird opaque type: {:?}, {:#?}", def_id, itemkind)
+                bug!("weird opaque type: {:?}, {:#?}", def_id, itemkind)
             }
         }
     }
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index 751b209f11a..377c364961b 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -430,11 +430,6 @@ impl<D: Decoder, T: Decodable<D> + Copy> Decodable<D> for Cell<T> {
     }
 }
 
-// FIXME: #15036
-// Should use `try_borrow`, returning an
-// `encoder.error("attempting to Encode borrowed RefCell")`
-// from `encode` when `try_borrow` returns `None`.
-
 impl<S: Encoder, T: Encodable<S>> Encodable<S> for RefCell<T> {
     fn encode(&self, s: &mut S) {
         self.borrow().encode(s);
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 479f8ffb78d..572191d0f9b 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1,9 +1,24 @@
 macro_rules! int_impl {
-    ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $BITS_MINUS_ONE:expr, $Min:expr, $Max:expr,
-     $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
-     $reversed:expr, $le_bytes:expr, $be_bytes:expr,
-     $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr,
-     $bound_condition:expr) => {
+    (
+        Self = $SelfT:ty,
+        ActualT = $ActualT:ident,
+        UnsignedT = $UnsignedT:ty,
+        BITS = $BITS:expr,
+        BITS_MINUS_ONE = $BITS_MINUS_ONE:expr,
+        Min = $Min:expr,
+        Max = $Max:expr,
+        rot = $rot:expr,
+        rot_op = $rot_op:expr,
+        rot_result = $rot_result:expr,
+        swap_op = $swap_op:expr,
+        swapped = $swapped:expr,
+        reversed = $reversed:expr,
+        le_bytes = $le_bytes:expr,
+        be_bytes = $be_bytes:expr,
+        to_xe_bytes_doc = $to_xe_bytes_doc:expr,
+        from_xe_bytes_doc = $from_xe_bytes_doc:expr,
+        bound_condition = $bound_condition:expr,
+    ) => {
         /// The smallest value that can be represented by this integer type
         #[doc = concat!("(&minus;2<sup>", $BITS_MINUS_ONE, "</sup>", $bound_condition, ").")]
         ///
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 0497416745f..a50c91579fa 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -226,72 +226,217 @@ macro_rules! widening_impl {
 }
 
 impl i8 {
-    int_impl! { i8, i8, u8, 8, 7, -128, 127, 2, "-0x7e", "0xa", "0x12", "0x12", "0x48",
-    "[0x12]", "[0x12]", "", "", "" }
+    int_impl! {
+        Self = i8,
+        ActualT = i8,
+        UnsignedT = u8,
+        BITS = 8,
+        BITS_MINUS_ONE = 7,
+        Min = -128,
+        Max = 127,
+        rot = 2,
+        rot_op = "-0x7e",
+        rot_result = "0xa",
+        swap_op = "0x12",
+        swapped = "0x12",
+        reversed = "0x48",
+        le_bytes = "[0x12]",
+        be_bytes = "[0x12]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
 }
 
 impl i16 {
-    int_impl! { i16, i16, u16, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234", "0x3412",
-    "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "", "" }
+    int_impl! {
+        Self = i16,
+        ActualT = i16,
+        UnsignedT = u16,
+        BITS = 16,
+        BITS_MINUS_ONE = 15,
+        Min = -32768,
+        Max = 32767,
+        rot = 4,
+        rot_op = "-0x5ffd",
+        rot_result = "0x3a",
+        swap_op = "0x1234",
+        swapped = "0x3412",
+        reversed = "0x2c48",
+        le_bytes = "[0x34, 0x12]",
+        be_bytes = "[0x12, 0x34]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
 }
 
 impl i32 {
-    int_impl! { i32, i32, u32, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
-    "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
-    "[0x12, 0x34, 0x56, 0x78]", "", "", "" }
+    int_impl! {
+        Self = i32,
+        ActualT = i32,
+        UnsignedT = u32,
+        BITS = 32,
+        BITS_MINUS_ONE = 31,
+        Min = -2147483648,
+        Max = 2147483647,
+        rot = 8,
+        rot_op = "0x10000b3",
+        rot_result = "0xb301",
+        swap_op = "0x12345678",
+        swapped = "0x78563412",
+        reversed = "0x1e6a2c48",
+        le_bytes = "[0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
 }
 
 impl i64 {
-    int_impl! { i64, i64, u64, 64, 63, -9223372036854775808, 9223372036854775807, 12,
-    "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412",
-    "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-    "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", "", "", "" }
+    int_impl! {
+        Self = i64,
+        ActualT = i64,
+        UnsignedT = u64,
+        BITS = 64,
+        BITS_MINUS_ONE = 63,
+        Min = -9223372036854775808,
+        Max = 9223372036854775807,
+        rot = 12,
+        rot_op = "0xaa00000000006e1",
+        rot_result = "0x6e10aa",
+        swap_op = "0x1234567890123456",
+        swapped = "0x5634129078563412",
+        reversed = "0x6a2c48091e6a2c48",
+        le_bytes = "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
 }
 
 impl i128 {
-    int_impl! { i128, i128, u128, 128, 127, -170141183460469231731687303715884105728,
-    170141183460469231731687303715884105727, 16,
-    "0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
-    "0x12907856341290785634129078563412", "0x48091e6a2c48091e6a2c48091e6a2c48",
-    "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
-      0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-    "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
-      0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", "", "", "" }
+    int_impl! {
+        Self = i128,
+        ActualT = i128,
+        UnsignedT = u128,
+        BITS = 128,
+        BITS_MINUS_ONE = 127,
+        Min = -170141183460469231731687303715884105728,
+        Max = 170141183460469231731687303715884105727,
+        rot = 16,
+        rot_op = "0x13f40000000000000000000000004f76",
+        rot_result = "0x4f7613f4",
+        swap_op = "0x12345678901234567890123456789012",
+        swapped = "0x12907856341290785634129078563412",
+        reversed = "0x48091e6a2c48091e6a2c48091e6a2c48",
+        le_bytes = "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
+            0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
+            0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
 }
 
 #[cfg(target_pointer_width = "16")]
 impl isize {
-    int_impl! { isize, i16, usize, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234",
-    "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]",
-    usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
-    " on 16-bit targets" }
+    int_impl! {
+        Self = isize,
+        ActualT = i16,
+        UnsignedT = usize,
+        BITS = 16,
+        BITS_MINUS_ONE = 15,
+        Min = -32768,
+        Max = 32767,
+        rot = 4,
+        rot_op = "-0x5ffd",
+        rot_result = "0x3a",
+        swap_op = "0x1234",
+        swapped = "0x3412",
+        reversed = "0x2c48",
+        le_bytes = "[0x34, 0x12]",
+        be_bytes = "[0x12, 0x34]",
+        to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
+        from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
+        bound_condition = " on 16-bit targets",
+    }
 }
 
 #[cfg(target_pointer_width = "32")]
 impl isize {
-    int_impl! { isize, i32, usize, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
-    "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
-    "[0x12, 0x34, 0x56, 0x78]",
-    usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
-    " on 32-bit targets" }
+    int_impl! {
+        Self = isize,
+        ActualT = i32,
+        UnsignedT = usize,
+        BITS = 32,
+        BITS_MINUS_ONE = 31,
+        Min = -2147483648,
+        Max = 2147483647,
+        rot = 8,
+        rot_op = "0x10000b3",
+        rot_result = "0xb301",
+        swap_op = "0x12345678",
+        swapped = "0x78563412",
+        reversed = "0x1e6a2c48",
+        le_bytes = "[0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78]",
+        to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
+        from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
+        bound_condition = " on 32-bit targets",
+    }
 }
 
 #[cfg(target_pointer_width = "64")]
 impl isize {
-    int_impl! { isize, i64, usize, 64, 63, -9223372036854775808, 9223372036854775807,
-    12, "0xaa00000000006e1", "0x6e10aa",  "0x1234567890123456", "0x5634129078563412",
-    "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-    "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
-    usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
-    " on 64-bit targets" }
+    int_impl! {
+        Self = isize,
+        ActualT = i64,
+        UnsignedT = usize,
+        BITS = 64,
+        BITS_MINUS_ONE = 63,
+        Min = -9223372036854775808,
+        Max = 9223372036854775807,
+        rot = 12,
+        rot_op = "0xaa00000000006e1",
+        rot_result = "0x6e10aa",
+        swap_op = "0x1234567890123456",
+        swapped = "0x5634129078563412",
+        reversed = "0x6a2c48091e6a2c48",
+        le_bytes = "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
+        to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
+        from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
+        bound_condition = " on 64-bit targets",
+    }
 }
 
 /// If 6th bit set ascii is upper case.
 const ASCII_CASE_MASK: u8 = 0b0010_0000;
 
 impl u8 {
-    uint_impl! { u8, u8, i8, NonZeroU8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
-    "[0x12]", "", "", "" }
+    uint_impl! {
+        Self = u8,
+        ActualT = u8,
+        SignedT = i8,
+        NonZeroT = NonZeroU8,
+        BITS = 8,
+        MAX = 255,
+        rot = 2,
+        rot_op = "0x82",
+        rot_result = "0xa",
+        swap_op = "0x12",
+        swapped = "0x12",
+        reversed = "0x48",
+        le_bytes = "[0x12]",
+        be_bytes = "[0x12]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
     widening_impl! { u8, u16, 8, unsigned }
 
     /// Checks if the value is within the ASCII range.
@@ -875,8 +1020,25 @@ impl u8 {
 }
 
 impl u16 {
-    uint_impl! { u16, u16, i16, NonZeroU16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
-    "[0x34, 0x12]", "[0x12, 0x34]", "", "", "" }
+    uint_impl! {
+        Self = u16,
+        ActualT = u16,
+        SignedT = i16,
+        NonZeroT = NonZeroU16,
+        BITS = 16,
+        MAX = 65535,
+        rot = 4,
+        rot_op = "0xa003",
+        rot_result = "0x3a",
+        swap_op = "0x1234",
+        swapped = "0x3412",
+        reversed = "0x2c48",
+        le_bytes = "[0x34, 0x12]",
+        be_bytes = "[0x12, 0x34]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
     widening_impl! { u16, u32, 16, unsigned }
 
     /// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`].
@@ -906,56 +1068,144 @@ impl u16 {
 }
 
 impl u32 {
-    uint_impl! { u32, u32, i32, NonZeroU32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
-    "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "", "" }
+    uint_impl! {
+        Self = u32,
+        ActualT = u32,
+        SignedT = i32,
+        NonZeroT = NonZeroU32,
+        BITS = 32,
+        MAX = 4294967295,
+        rot = 8,
+        rot_op = "0x10000b3",
+        rot_result = "0xb301",
+        swap_op = "0x12345678",
+        swapped = "0x78563412",
+        reversed = "0x1e6a2c48",
+        le_bytes = "[0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
     widening_impl! { u32, u64, 32, unsigned }
 }
 
 impl u64 {
-    uint_impl! { u64, u64, i64, NonZeroU64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
-    "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
-    "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-    "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
-    "", "", ""}
+    uint_impl! {
+        Self = u64,
+        ActualT = u64,
+        SignedT = i64,
+        NonZeroT = NonZeroU64,
+        BITS = 64,
+        MAX = 18446744073709551615,
+        rot = 12,
+        rot_op = "0xaa00000000006e1",
+        rot_result = "0x6e10aa",
+        swap_op = "0x1234567890123456",
+        swapped = "0x5634129078563412",
+        reversed = "0x6a2c48091e6a2c48",
+        le_bytes = "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
     widening_impl! { u64, u128, 64, unsigned }
 }
 
 impl u128 {
-    uint_impl! { u128, u128, i128, NonZeroU128, 128, 340282366920938463463374607431768211455, 16,
-    "0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
-    "0x12907856341290785634129078563412", "0x48091e6a2c48091e6a2c48091e6a2c48",
-    "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
-      0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-    "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
-      0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]",
-     "", "", ""}
+    uint_impl! {
+        Self = u128,
+        ActualT = u128,
+        SignedT = i128,
+        NonZeroT = NonZeroU128,
+        BITS = 128,
+        MAX = 340282366920938463463374607431768211455,
+        rot = 16,
+        rot_op = "0x13f40000000000000000000000004f76",
+        rot_result = "0x4f7613f4",
+        swap_op = "0x12345678901234567890123456789012",
+        swapped = "0x12907856341290785634129078563412",
+        reversed = "0x48091e6a2c48091e6a2c48091e6a2c48",
+        le_bytes = "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
+            0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
+            0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]",
+        to_xe_bytes_doc = "",
+        from_xe_bytes_doc = "",
+        bound_condition = "",
+    }
 }
 
 #[cfg(target_pointer_width = "16")]
 impl usize {
-    uint_impl! { usize, u16, isize, NonZeroUsize, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
-    "[0x34, 0x12]", "[0x12, 0x34]",
-    usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
-    " on 16-bit targets" }
+    uint_impl! {
+        Self = usize,
+        ActualT = u16,
+        SignedT = isize,
+        NonZeroT = NonZeroUsize,
+        BITS = 16,
+        MAX = 65535,
+        rot = 4,
+        rot_op = "0xa003",
+        rot_result = "0x3a",
+        swap_op = "0x1234",
+        swapped = "0x3412",
+        reversed = "0x2c48",
+        le_bytes = "[0x34, 0x12]",
+        be_bytes = "[0x12, 0x34]",
+        to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
+        from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
+        bound_condition = " on 16-bit targets",
+    }
     widening_impl! { usize, u32, 16, unsigned }
 }
+
 #[cfg(target_pointer_width = "32")]
 impl usize {
-    uint_impl! { usize, u32, isize, NonZeroUsize, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
-    "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]",
-    usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
-    " on 32-bit targets" }
+    uint_impl! {
+        Self = usize,
+        ActualT = u32,
+        SignedT = isize,
+        NonZeroT = NonZeroUsize,
+        BITS = 32,
+        MAX = 4294967295,
+        rot = 8,
+        rot_op = "0x10000b3",
+        rot_result = "0xb301",
+        swap_op = "0x12345678",
+        swapped = "0x78563412",
+        reversed = "0x1e6a2c48",
+        le_bytes = "[0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78]",
+        to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
+        from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
+        bound_condition = " on 32-bit targets",
+    }
     widening_impl! { usize, u64, 32, unsigned }
 }
 
 #[cfg(target_pointer_width = "64")]
 impl usize {
-    uint_impl! { usize, u64, isize, NonZeroUsize, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
-    "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
-    "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
-    "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
-    usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
-    " on 64-bit targets" }
+    uint_impl! {
+        Self = usize,
+        ActualT = u64,
+        SignedT = isize,
+        NonZeroT = NonZeroUsize,
+        BITS = 64,
+        MAX = 18446744073709551615,
+        rot = 12,
+        rot_op = "0xaa00000000006e1",
+        rot_result = "0x6e10aa",
+        swap_op = "0x1234567890123456",
+        swapped = "0x5634129078563412",
+        reversed = "0x6a2c48091e6a2c48",
+        le_bytes = "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
+        be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
+        to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
+        from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
+        bound_condition = " on 64-bit targets",
+    }
     widening_impl! { usize, u128, 64, unsigned }
 }
 
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 495c44bd859..c4fe8e966fd 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1,10 +1,23 @@
 macro_rules! uint_impl {
-    ($SelfT:ty, $ActualT:ident, $SignedT:ident, $NonZeroT:ident,
-        $BITS:expr, $MaxV:expr,
-        $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
-        $reversed:expr, $le_bytes:expr, $be_bytes:expr,
-        $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr,
-        $bound_condition:expr) => {
+    (
+        Self = $SelfT:ty,
+        ActualT = $ActualT:ident,
+        SignedT = $SignedT:ident,
+        NonZeroT = $NonZeroT:ident,
+        BITS = $BITS:expr,
+        MAX = $MaxV:expr,
+        rot = $rot:expr,
+        rot_op = $rot_op:expr,
+        rot_result = $rot_result:expr,
+        swap_op = $swap_op:expr,
+        swapped = $swapped:expr,
+        reversed = $reversed:expr,
+        le_bytes = $le_bytes:expr,
+        be_bytes = $be_bytes:expr,
+        to_xe_bytes_doc = $to_xe_bytes_doc:expr,
+        from_xe_bytes_doc = $from_xe_bytes_doc:expr,
+        bound_condition = $bound_condition:expr,
+    ) => {
         /// The smallest value that can be represented by this integer type.
         ///
         /// # Examples
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index 8c733ddefc0..890b3e8d67f 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -62,7 +62,7 @@ impl<'a, 'tcx> Stripper<'a, 'tcx> {
 
     /// In case `i` is a non-hidden impl block, then we special-case it by changing the value
     /// of `is_in_hidden_item` to `true` because the impl children inherit its visibility.
-    fn recurse_in_impl(&mut self, i: Item) -> Item {
+    fn recurse_in_impl_or_exported_macro(&mut self, i: Item) -> Item {
         let prev = mem::replace(&mut self.is_in_hidden_item, false);
         let ret = self.fold_item_recur(i);
         self.is_in_hidden_item = prev;
@@ -73,9 +73,17 @@ impl<'a, 'tcx> Stripper<'a, 'tcx> {
 impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         let has_doc_hidden = i.attrs.lists(sym::doc).has_word(sym::hidden);
-        let is_impl = matches!(*i.kind, clean::ImplItem(..));
+        let is_impl_or_exported_macro = match *i.kind {
+            clean::ImplItem(..) => true,
+            // If the macro has the `#[macro_export]` attribute, it means it's accessible at the
+            // crate level so it should be handled differently.
+            clean::MacroItem(..) => {
+                i.attrs.other_attrs.iter().any(|attr| attr.has_name(sym::macro_export))
+            }
+            _ => false,
+        };
         let mut is_hidden = has_doc_hidden;
-        if !is_impl {
+        if !is_impl_or_exported_macro {
             is_hidden = self.is_in_hidden_item || has_doc_hidden;
             if !is_hidden && i.inline_stmt_id.is_none() {
                 // We don't need to check if it's coming from a reexport since the reexport itself was
@@ -92,8 +100,8 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
             if self.update_retained {
                 self.retained.insert(i.item_id);
             }
-            return Some(if is_impl {
-                self.recurse_in_impl(i)
+            return Some(if is_impl_or_exported_macro {
+                self.recurse_in_impl_or_exported_macro(i)
             } else {
                 self.set_is_in_hidden_item_and_fold(false, i)
             });
diff --git a/tests/rustdoc/issue-108231.rs b/tests/rustdoc/issue-108231.rs
new file mode 100644
index 00000000000..684f0494fd5
--- /dev/null
+++ b/tests/rustdoc/issue-108231.rs
@@ -0,0 +1,23 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/108231>.
+// Macros with `#[macro_export]` attribute should be visible at the top level
+// even if they are inside a doc hidden item.
+
+#![crate_name = "foo"]
+
+// @has 'foo/index.html'
+// @count - '//*[@id="main-content"]//a[@class="macro"]' 1
+// @has - '//*[@id="main-content"]//a[@class="macro"]' 'foo'
+
+#[doc(hidden)]
+pub mod __internal {
+    /// This one should be visible.
+    #[macro_export]
+    macro_rules! foo {
+        () => {};
+    }
+
+    /// This one should be hidden.
+    macro_rules! bar {
+        () => {};
+    }
+}
diff --git a/tests/rustdoc/reexport-hidden-macro.rs b/tests/rustdoc/reexport-hidden-macro.rs
new file mode 100644
index 00000000000..afcfa979616
--- /dev/null
+++ b/tests/rustdoc/reexport-hidden-macro.rs
@@ -0,0 +1,22 @@
+// Ensure that inlined reexport of hidden macros is working as expected.
+// Part of <https://github.com/rust-lang/rust/issues/59368>.
+
+#![crate_name = "foo"]
+
+// @has 'foo/index.html'
+// @has - '//*[@id="main-content"]//a[@href="macro.Macro2.html"]' 'Macro2'
+
+// @has 'foo/macro.Macro2.html'
+// @has - '//*[@class="docblock"]' 'Displayed'
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! foo {
+    () => {};
+}
+
+/// not displayed
+pub use crate::foo as Macro;
+/// Displayed
+#[doc(inline)]
+pub use crate::foo as Macro2;
diff --git a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.rs b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.rs
index 2b75f432412..6fea409ed47 100644
--- a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.rs
+++ b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.rs
@@ -71,6 +71,8 @@ struct DoubleWrapper<T> {
 
 impl<T: T1> T1 for DoubleWrapper<T> {}
 
+impl<'a, T: T2> T1 for &'a T {}
+
 fn example<Q>(q: Q) {
     // In each of the following examples, we expect the error span to point at the 'q' variable,
     // since the missing constraint is `Q: T3`.
@@ -126,6 +128,10 @@ fn example<Q>(q: Q) {
         Two { a: Two { a: (), b: Two { a: Two { a: (), b: q }, b: () } }, b: () },
         //~^ ERROR the trait bound `Q: T1` is not satisfied [E0277]
     );
+
+    // Verifies for reference:
+    want(&Burrito { spicy: false, filling: q });
+    //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277]
 }
 
 fn main() {}
diff --git a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr
index 5f87c670d8a..6913771f288 100644
--- a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr
+++ b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:79:60
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:81:60
    |
 LL |     want(Wrapper { value: Burrito { spicy: false, filling: q } });
    |     ---- required by a bound introduced by this call       ^ the trait `T3` is not implemented for `Q`
@@ -29,7 +29,7 @@ LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:83:84
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:85:84
    |
 LL |     want(Wrapper { value: BurritoKinds::SmallBurrito { spicy: true, small_filling: q } });
    |     ---- required by a bound introduced by this call                               ^ the trait `T3` is not implemented for `Q`
@@ -59,7 +59,7 @@ LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:87:39
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:89:39
    |
 LL |     want(Wrapper { value: Taco(false, q) });
    |     ----                              ^ the trait `T3` is not implemented for `Q`
@@ -91,7 +91,7 @@ LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:91:27
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:93:27
    |
 LL |     want(Wrapper { value: TacoKinds::OneTaco(false, q) });
    |     ----                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `T3` is not implemented for `Q`
@@ -123,7 +123,7 @@ LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:95:74
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:97:74
    |
 LL |     want(Wrapper { value: GenericBurrito { spiciness: NotSpicy, filling: q } });
    |     ---- required by a bound introduced by this call                     ^ the trait `T3` is not implemented for `Q`
@@ -153,7 +153,7 @@ LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T2` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:99:14
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:101:14
    |
 LL |     want((3, q));
    |     ----     ^ the trait `T2` is not implemented for `Q`
@@ -178,7 +178,7 @@ LL | fn example<Q: T2>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:103:31
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:105:31
    |
 LL |     want(Wrapper { value: (3, q) });
    |     ----                      ^ the trait `T3` is not implemented for `Q`
@@ -210,7 +210,7 @@ LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:107:15
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:109:15
    |
 LL |     want(((3, q), 5));
    |     ----      ^ the trait `T3` is not implemented for `Q`
@@ -242,7 +242,7 @@ LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T1` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:110:49
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:112:49
    |
 LL |     want(DoubleWrapper { item: Wrapper { value: q } });
    |     ----                                        ^ the trait `T1` is not implemented for `Q`
@@ -267,7 +267,7 @@ LL | fn example<Q: T1>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T1` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:113:88
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:115:88
    |
 LL |     want(DoubleWrapper { item: Wrapper { value: DoubleWrapper { item: Wrapper { value: q } } } });
    |     ---- required by a bound introduced by this call                                   ^ the trait `T1` is not implemented for `Q`
@@ -292,7 +292,7 @@ LL | fn example<Q: T1>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:117:27
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:119:27
    |
 LL |     want(Wrapper { value: AliasBurrito { spiciness: q, filling: q } });
    |     ----                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `T3` is not implemented for `Q`
@@ -324,7 +324,7 @@ LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T1` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:120:35
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:122:35
    |
 LL |     want(Two { a: Two { a: (), b: q }, b: () });
    |     ----                          ^ the trait `T1` is not implemented for `Q`
@@ -349,7 +349,7 @@ LL | fn example<Q: T1>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T1` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:126:59
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:128:59
    |
 LL |     want(
    |     ---- required by a bound introduced by this call
@@ -375,6 +375,38 @@ help: consider restricting type parameter `Q`
 LL | fn example<Q: T1>(q: Q) {
    |             ++++
 
-error: aborting due to 13 previous errors
+error[E0277]: the trait bound `Q: T3` is not satisfied
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:133:44
+   |
+LL |     want(&Burrito { spicy: false, filling: q });
+   |     ----                                   ^ the trait `T3` is not implemented for `Q`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required for `Burrito<Q>` to implement `T2`
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:22:13
+   |
+LL | impl<A: T3> T2 for Burrito<A> {}
+   |         --  ^^     ^^^^^^^^^^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required for `&Burrito<Q>` to implement `T1`
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:74:17
+   |
+LL | impl<'a, T: T2> T1 for &'a T {}
+   |             --  ^^     ^^^^^
+   |             |
+   |             unsatisfied trait bound introduced here
+note: required by a bound in `want`
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:53:12
+   |
+LL | fn want<V: T1>(_x: V) {}
+   |            ^^ required by this bound in `want`
+help: consider restricting type parameter `Q`
+   |
+LL | fn example<Q: T3>(q: Q) {
+   |             ++++
+
+error: aborting due to 14 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/suggest-deferences/issue-39029.stderr b/tests/ui/traits/suggest-deferences/issue-39029.stderr
index 49e20c6a76a..49105de3d69 100644
--- a/tests/ui/traits/suggest-deferences/issue-39029.stderr
+++ b/tests/ui/traits/suggest-deferences/issue-39029.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied
-  --> $DIR/issue-39029.rs:16:37
+  --> $DIR/issue-39029.rs:16:38
    |
 LL |     let _errors = TcpListener::bind(&bad);
-   |                   ----------------- ^^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
+   |                   -----------------  ^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
    |                   |
    |                   required by a bound introduced by this call
    |