about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-07-08 03:30:58 +0000
committerbors <bors@rust-lang.org>2025-07-08 03:30:58 +0000
commit2783fc43fd13a669f314742890acd64200ad0bbf (patch)
tree61f7b83de01b9a9625f848943694ab53af77e37f
parent688ea65df6a47866d0f72a00f1e18b47a7edf83b (diff)
parentfd05071727ede428ff9a3bf7844f22d2274b7363 (diff)
downloadrust-2783fc43fd13a669f314742890acd64200ad0bbf.tar.gz
rust-2783fc43fd13a669f314742890acd64200ad0bbf.zip
Auto merge of #143621 - matthiaskrgr:rollup-p1ce8l7, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - rust-lang/rust#142098 (Implement `int_format_into` feature)
 - rust-lang/rust#143567 (Point to correct argument in Func Call when Self type fails trait bound)
 - rust-lang/rust#143570 (consider nested cases for duplicate RPITIT)
 - rust-lang/rust#143571 (remove `has_nested` from builtin candidates)
 - rust-lang/rust#143586 (Fix wrong cache event query key)
 - rust-lang/rust#143589 (const-block-as-pattern: do not refer to no-longer-existing nightly feature)
 - rust-lang/rust#143608 (Fix in std::String docs)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs11
-rw-r--r--compiler/rustc_middle/src/traits/select.rs9
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs26
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs79
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs6
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs34
-rw-r--r--library/alloc/src/string.rs8
-rw-r--r--library/alloctests/tests/lib.rs1
-rw-r--r--library/alloctests/tests/num.rs46
-rw-r--r--library/core/src/fmt/mod.rs4
-rw-r--r--library/core/src/fmt/num.rs290
-rw-r--r--library/core/src/fmt/num_buffer.rs60
-rw-r--r--tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.current.stderr4
-rw-r--r--tests/ui/const-generics/infer/issue-77092.stderr2
-rw-r--r--tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr4
-rw-r--r--tests/ui/impl-trait/auto-trait-selection.old.stderr4
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs46
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr49
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.rs11
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.stderr33
-rw-r--r--tests/ui/inline-const/in-pat-recovery.rs2
-rw-r--r--tests/ui/inline-const/in-pat-recovery.stderr4
-rw-r--r--tests/ui/trait-bounds/false-span-in-trait-bound-label.rs10
-rw-r--r--tests/ui/trait-bounds/false-span-in-trait-bound-label.stderr17
-rw-r--r--tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr4
-rw-r--r--tests/ui/traits/multidispatch-convert-ambig-dest.stderr2
28 files changed, 598 insertions, 176 deletions
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index 1b4db7adc27..881aa679156 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -142,7 +142,7 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
     ("generic-activity", EventFilter::GENERIC_ACTIVITIES),
     ("query-provider", EventFilter::QUERY_PROVIDERS),
     ("query-cache-hit", EventFilter::QUERY_CACHE_HITS),
-    ("query-cache-hit-count", EventFilter::QUERY_CACHE_HITS),
+    ("query-cache-hit-count", EventFilter::QUERY_CACHE_HIT_COUNTS),
     ("query-blocked", EventFilter::QUERY_BLOCKED),
     ("incr-cache-load", EventFilter::INCR_CACHE_LOADS),
     ("query-keys", EventFilter::QUERY_KEYS),
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 2bc007b3ad4..4e4bf8a5562 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
@@ -184,9 +184,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     return true;
                 }
 
-                for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
-                    .into_iter()
-                    .flatten()
+                for param in [
+                    predicate_self_type_to_point_at,
+                    param_to_point_at,
+                    fallback_param_to_point_at,
+                    self_param_to_point_at,
+                ]
+                .into_iter()
+                .flatten()
                 {
                     if self.blame_specific_arg_if_possible(
                         error,
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index aa2ee756bc5..c498e6b3c83 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -97,9 +97,7 @@ pub type EvaluationCache<'tcx, ENV> = Cache<(ENV, ty::PolyTraitPredicate<'tcx>),
 pub enum SelectionCandidate<'tcx> {
     /// A built-in implementation for the `Sized` trait. This is preferred
     /// over all other candidates.
-    SizedCandidate {
-        has_nested: bool,
-    },
+    SizedCandidate,
 
     /// A builtin implementation for some specific traits, used in cases
     /// where we cannot rely an ordinary library implementations.
@@ -107,10 +105,7 @@ pub enum SelectionCandidate<'tcx> {
     /// The most notable examples are `Copy` and `Clone`. This is also
     /// used for the `DiscriminantKind` and `Pointee` trait, both of which have
     /// an associated type.
-    BuiltinCandidate {
-        /// `false` if there are no *further* obligations.
-        has_nested: bool,
-    },
+    BuiltinCandidate,
 
     /// Implementation of transmutability trait.
     TransmutabilityCandidate,
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index cfc0399b0ca..2787be46f33 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1293,8 +1293,10 @@ impl<'a> Parser<'a> {
         let kind = if pat {
             let guar = self
                 .dcx()
-                .struct_span_err(blk_span, "`inline_const_pat` has been removed")
-                .with_help("use a named `const`-item or an `if`-guard instead")
+                .struct_span_err(blk_span, "const blocks cannot be used as patterns")
+                .with_help(
+                    "use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead",
+                )
                 .emit();
             ExprKind::Err(guar)
         } else {
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 81ce58a93fa..9af85f5e3f0 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -80,11 +80,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
                 Some(LangItem::DiscriminantKind) => {
                     // `DiscriminantKind` is automatically implemented for every type.
-                    candidates.vec.push(BuiltinCandidate { has_nested: false });
+                    candidates.vec.push(BuiltinCandidate);
                 }
                 Some(LangItem::PointeeTrait) => {
                     // `Pointee` is automatically implemented for every type.
-                    candidates.vec.push(BuiltinCandidate { has_nested: false });
+                    candidates.vec.push(BuiltinCandidate);
                 }
                 Some(LangItem::Sized) => {
                     self.assemble_builtin_sized_candidate(
@@ -365,7 +365,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         {
             debug!(?self_ty, ?obligation, "assemble_fused_iterator_candidates",);
 
-            candidates.vec.push(BuiltinCandidate { has_nested: false });
+            candidates.vec.push(BuiltinCandidate);
         }
     }
 
@@ -810,7 +810,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         hir::Movability::Movable => {
                             // Movable coroutines are always `Unpin`, so add an
                             // unconditional builtin candidate.
-                            candidates.vec.push(BuiltinCandidate { has_nested: false });
+                            candidates.vec.push(BuiltinCandidate);
                         }
                     }
                 }
@@ -1122,10 +1122,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         sizedness: SizedTraitKind,
     ) {
         match self.sizedness_conditions(obligation, sizedness) {
-            BuiltinImplConditions::Where(nested) => {
-                candidates
-                    .vec
-                    .push(SizedCandidate { has_nested: !nested.skip_binder().is_empty() });
+            BuiltinImplConditions::Where(_nested) => {
+                candidates.vec.push(SizedCandidate);
             }
             BuiltinImplConditions::None => {}
             BuiltinImplConditions::Ambiguous => {
@@ -1143,10 +1141,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         candidates: &mut SelectionCandidateSet<'tcx>,
     ) {
         match conditions {
-            BuiltinImplConditions::Where(nested) => {
-                candidates
-                    .vec
-                    .push(BuiltinCandidate { has_nested: !nested.skip_binder().is_empty() });
+            BuiltinImplConditions::Where(_) => {
+                candidates.vec.push(BuiltinCandidate);
             }
             BuiltinImplConditions::None => {}
             BuiltinImplConditions::Ambiguous => {
@@ -1160,7 +1156,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         _obligation: &PolyTraitObligation<'tcx>,
         candidates: &mut SelectionCandidateSet<'tcx>,
     ) {
-        candidates.vec.push(BuiltinCandidate { has_nested: false });
+        candidates.vec.push(BuiltinCandidate);
     }
 
     fn assemble_candidate_for_tuple(
@@ -1171,7 +1167,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
         match self_ty.kind() {
             ty::Tuple(_) => {
-                candidates.vec.push(BuiltinCandidate { has_nested: false });
+                candidates.vec.push(BuiltinCandidate);
             }
             ty::Infer(ty::TyVar(_)) => {
                 candidates.ambiguous = true;
@@ -1215,7 +1211,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty());
 
         match self_ty.skip_binder().kind() {
-            ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate { has_nested: false }),
+            ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate),
             ty::Bool
             | ty::Char
             | ty::Int(_)
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index a6b77583fdc..545531f927a 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -37,13 +37,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         candidate: SelectionCandidate<'tcx>,
     ) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
         Ok(match candidate {
-            SizedCandidate { has_nested } => {
-                let data = self.confirm_builtin_candidate(obligation, has_nested);
+            SizedCandidate => {
+                let data = self.confirm_builtin_candidate(obligation);
                 ImplSource::Builtin(BuiltinImplSource::Misc, data)
             }
 
-            BuiltinCandidate { has_nested } => {
-                let data = self.confirm_builtin_candidate(obligation, has_nested);
+            BuiltinCandidate => {
+                let data = self.confirm_builtin_candidate(obligation);
                 ImplSource::Builtin(BuiltinImplSource::Misc, data)
             }
 
@@ -249,50 +249,47 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self), ret)]
     fn confirm_builtin_candidate(
         &mut self,
         obligation: &PolyTraitObligation<'tcx>,
-        has_nested: bool,
     ) -> PredicateObligations<'tcx> {
-        debug!(?obligation, ?has_nested, "confirm_builtin_candidate");
-
+        debug!(?obligation, "confirm_builtin_candidate");
         let tcx = self.tcx();
-        let obligations = if has_nested {
-            let trait_def = obligation.predicate.def_id();
-            let conditions = match tcx.as_lang_item(trait_def) {
-                Some(LangItem::Sized) => {
-                    self.sizedness_conditions(obligation, SizedTraitKind::Sized)
-                }
-                Some(LangItem::MetaSized) => {
-                    self.sizedness_conditions(obligation, SizedTraitKind::MetaSized)
-                }
-                Some(LangItem::PointeeSized) => {
-                    bug!("`PointeeSized` is removing during lowering");
-                }
-                Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation),
-                Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation),
-                other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"),
-            };
-            let BuiltinImplConditions::Where(types) = conditions else {
-                bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
-            };
-            let types = self.infcx.enter_forall_and_leak_universe(types);
-
-            let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
-            self.collect_predicates_for_types(
-                obligation.param_env,
-                cause,
-                obligation.recursion_depth + 1,
-                trait_def,
-                types,
-            )
-        } else {
-            PredicateObligations::new()
+        let trait_def = obligation.predicate.def_id();
+        let conditions = match tcx.as_lang_item(trait_def) {
+            Some(LangItem::Sized) => self.sizedness_conditions(obligation, SizedTraitKind::Sized),
+            Some(LangItem::MetaSized) => {
+                self.sizedness_conditions(obligation, SizedTraitKind::MetaSized)
+            }
+            Some(LangItem::PointeeSized) => {
+                bug!("`PointeeSized` is removing during lowering");
+            }
+            Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation),
+            Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation),
+            Some(
+                LangItem::Destruct
+                | LangItem::DiscriminantKind
+                | LangItem::FnPtrTrait
+                | LangItem::PointeeTrait
+                | LangItem::Tuple
+                | LangItem::Unpin,
+            ) => BuiltinImplConditions::Where(ty::Binder::dummy(vec![])),
+            other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"),
         };
+        let BuiltinImplConditions::Where(types) = conditions else {
+            bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
+        };
+        let types = self.infcx.enter_forall_and_leak_universe(types);
 
-        debug!(?obligations);
-
-        obligations
+        let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
+        self.collect_predicates_for_types(
+            obligation.param_env,
+            cause,
+            obligation.recursion_depth + 1,
+            trait_def,
+            types,
+        )
     }
 
     #[instrument(level = "debug", skip(self))]
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index af3641c22ed..c9930c69b32 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1834,7 +1834,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
 
         // We prefer `Sized` candidates over everything.
         let mut sized_candidates =
-            candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate { has_nested: _ }));
+            candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate));
         if let Some(sized_candidate) = sized_candidates.next() {
             // There should only ever be a single sized candidate
             // as they would otherwise overlap.
@@ -1986,8 +1986,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             // Don't use impl candidates which overlap with other candidates.
             // This should pretty much only ever happen with malformed impls.
             if candidates.iter().all(|c| match c.candidate {
-                SizedCandidate { has_nested: _ }
-                | BuiltinCandidate { has_nested: _ }
+                SizedCandidate
+                | BuiltinCandidate
                 | TransmutabilityCandidate
                 | AutoImplCandidate
                 | ClosureCandidate { .. }
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 2fb3c5ff945..6a9461f2b43 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -177,6 +177,17 @@ impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
     }
 }
 
+struct DisambiguatorIdxVisitor {
+    depth: u32,
+}
+
+impl<'tcx> Visitor<'tcx> for DisambiguatorIdxVisitor {
+    fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result {
+        self.depth += 1;
+        intravisit::walk_opaque_ty(self, opaque)
+    }
+}
+
 /// Given an `fn_def_id` of a trait or a trait implementation:
 ///
 /// if `fn_def_id` is a function defined inside a trait, then it synthesizes
@@ -211,16 +222,19 @@ fn associated_types_for_impl_traits_in_associated_fn(
                 let disambiguator_idx = trait_item_refs
                     .iter()
                     .take_while(|item| item.id.owner_id.def_id != fn_def_id)
-                    .fold(0, |acc, item| {
-                        if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
-                            acc
-                        } else if def_path_id(item.id.owner_id.def_id) == def_path_data {
-                            tcx.def_key(item.id.owner_id.def_id).disambiguated_data.disambiguator
-                                + 1
-                        } else {
-                            acc
-                        }
-                    });
+                    .filter(|item| {
+                        matches!(item.kind, hir::AssocItemKind::Fn { .. })
+                            && def_path_id(item.id.owner_id.def_id) == def_path_data
+                    })
+                    .last()
+                    .map(|item| {
+                        let output = tcx.hir_get_fn_output(item.id.owner_id.def_id).unwrap();
+                        let mut visitor = DisambiguatorIdxVisitor { depth: 0 };
+                        visitor.visit_fn_ret_ty(output);
+                        tcx.def_key(item.id.owner_id.def_id).disambiguated_data.disambiguator
+                            + visitor.depth
+                    })
+                    .unwrap_or_default();
 
                 let data = DefPathData::AnonAssocTy(def_path_data);
                 let mut visitor = RPITVisitor {
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 5f69f699867..187d1ca71d9 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -156,7 +156,7 @@ use crate::vec::{self, Vec};
 /// ```
 ///
 /// Next, what should `s[i]` return? Because indexing returns a reference
-/// to underlying data it could be `&u8`, `&[u8]`, or something else similar.
+/// to underlying data it could be `&u8`, `&[u8]`, or something similar.
 /// Since we're only providing one index, `&u8` makes the most sense but that
 /// might not be what the user expects and can be explicitly achieved with
 /// [`as_bytes()`]:
@@ -2875,7 +2875,8 @@ macro_rules! impl_to_string {
                     out = String::with_capacity(SIZE);
                 }
 
-                out.push_str(self.unsigned_abs()._fmt(&mut buf));
+                // SAFETY: `buf` is always big enough to contain all the digits.
+                unsafe { out.push_str(self.unsigned_abs()._fmt(&mut buf)); }
                 out
             }
         }
@@ -2887,7 +2888,8 @@ macro_rules! impl_to_string {
                 const SIZE: usize = $unsigned::MAX.ilog10() as usize + 1;
                 let mut buf = [core::mem::MaybeUninit::<u8>::uninit(); SIZE];
 
-                self._fmt(&mut buf).to_string()
+                // SAFETY: `buf` is always big enough to contain all the digits.
+                unsafe { self._fmt(&mut buf).to_string() }
             }
         }
         )*
diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs
index a41162ecd51..fcfc7f8dd29 100644
--- a/library/alloctests/tests/lib.rs
+++ b/library/alloctests/tests/lib.rs
@@ -9,6 +9,7 @@
 #![feature(downcast_unchecked)]
 #![feature(exact_size_is_empty)]
 #![feature(hashmap_internals)]
+#![feature(int_format_into)]
 #![feature(linked_list_cursors)]
 #![feature(map_try_insert)]
 #![feature(pattern)]
diff --git a/library/alloctests/tests/num.rs b/library/alloctests/tests/num.rs
index a169bbec8e0..589b8090096 100644
--- a/library/alloctests/tests/num.rs
+++ b/library/alloctests/tests/num.rs
@@ -1,15 +1,21 @@
-use std::fmt::{Debug, Display};
+use core::fmt::NumBuffer;
 use std::str::FromStr;
 
-fn assert_nb<Int: ToString + FromStr + Debug + Display + Eq>(value: Int) {
-    let s = value.to_string();
-    let s2 = format!("s: {}.", value);
+macro_rules! assert_nb {
+    ($int:ident, $value:expr) => {
+        let value: $int = $value;
+        let s = value.to_string();
+        let s2 = format!("s: {}.", value);
 
-    assert_eq!(format!("s: {s}."), s2);
-    let Ok(ret) = Int::from_str(&s) else {
-        panic!("failed to convert into to string");
+        assert_eq!(format!("s: {s}."), s2);
+        let Ok(ret) = $int::from_str(&s) else {
+            panic!("failed to convert into to string");
+        };
+        assert_eq!(ret, value);
+
+        let mut buffer = NumBuffer::<$int>::new();
+        assert_eq!(value.format_into(&mut buffer), s.as_str());
     };
-    assert_eq!(ret, value);
 }
 
 macro_rules! uint_to_s {
@@ -17,11 +23,11 @@ macro_rules! uint_to_s {
         $(
             #[test]
             fn $fn_name() {
-                assert_nb::<$int>($int::MIN);
-                assert_nb::<$int>($int::MAX);
-                assert_nb::<$int>(1);
-                assert_nb::<$int>($int::MIN / 2);
-                assert_nb::<$int>($int::MAX / 2);
+                assert_nb!($int, $int::MIN);
+                assert_nb!($int, $int::MAX);
+                assert_nb!($int, 1);
+                assert_nb!($int, $int::MIN / 2);
+                assert_nb!($int, $int::MAX / 2);
             }
         )+
     }
@@ -31,13 +37,13 @@ macro_rules! int_to_s {
         $(
             #[test]
             fn $fn_name() {
-                assert_nb::<$int>($int::MIN);
-                assert_nb::<$int>($int::MAX);
-                assert_nb::<$int>(1);
-                assert_nb::<$int>(0);
-                assert_nb::<$int>(-1);
-                assert_nb::<$int>($int::MIN / 2);
-                assert_nb::<$int>($int::MAX / 2);
+                assert_nb!($int, $int::MIN);
+                assert_nb!($int, $int::MAX);
+                assert_nb!($int, 1);
+                assert_nb!($int, 0);
+                assert_nb!($int, -1);
+                assert_nb!($int, $int::MIN / 2);
+                assert_nb!($int, $int::MAX / 2);
             }
         )+
     }
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index c593737af8a..5e50eacec6e 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -15,6 +15,7 @@ mod float;
 #[cfg(no_fp_fmt_parse)]
 mod nofloat;
 mod num;
+mod num_buffer;
 mod rt;
 
 #[stable(feature = "fmt_flags_align", since = "1.28.0")]
@@ -33,6 +34,9 @@ pub enum Alignment {
     Center,
 }
 
+#[unstable(feature = "int_format_into", issue = "138215")]
+pub use num_buffer::{NumBuffer, NumBufferTrait};
+
 #[stable(feature = "debug_builders", since = "1.2.0")]
 pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
 #[unstable(feature = "debug_closure_helpers", issue = "117729")]
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index 80f462263a5..e1381ace441 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -1,5 +1,6 @@
 //! Integer and floating-point number formatting
 
+use crate::fmt::NumBuffer;
 use crate::mem::MaybeUninit;
 use crate::num::fmt as numfmt;
 use crate::ops::{Div, Rem, Sub};
@@ -60,7 +61,7 @@ unsafe trait GenericRadix: Sized {
         let zero = T::zero();
         let is_nonnegative = x >= zero;
         let mut buf = [MaybeUninit::<u8>::uninit(); 128];
-        let mut curr = buf.len();
+        let mut offset = buf.len();
         let base = T::from_u8(Self::BASE);
         if is_nonnegative {
             // Accumulate each digit of the number from the least significant
@@ -68,8 +69,8 @@ unsafe trait GenericRadix: Sized {
             loop {
                 let n = x % base; // Get the current place value.
                 x = x / base; // Deaccumulate the number.
-                curr -= 1;
-                buf[curr].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
+                offset -= 1;
+                buf[offset].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
                 if x == zero {
                     // No more digits left to accumulate.
                     break;
@@ -80,27 +81,17 @@ unsafe trait GenericRadix: Sized {
             loop {
                 let n = zero - (x % base); // Get the current place value.
                 x = x / base; // Deaccumulate the number.
-                curr -= 1;
-                buf[curr].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
+                offset -= 1;
+                buf[offset].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
                 if x == zero {
                     // No more digits left to accumulate.
                     break;
                 };
             }
         }
-        // SAFETY: `curr` is initialized to `buf.len()` and is only decremented, so it can't overflow. It is
-        // decremented exactly once for each digit. Since u128 is the widest fixed width integer format supported,
-        // the maximum number of digits (bits) is 128 for base-2, so `curr` won't underflow as well.
-        let buf = unsafe { buf.get_unchecked(curr..) };
-        // SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be
-        // valid UTF-8
-        let buf = unsafe {
-            str::from_utf8_unchecked(slice::from_raw_parts(
-                MaybeUninit::slice_as_ptr(buf),
-                buf.len(),
-            ))
-        };
-        f.pad_integral(is_nonnegative, Self::PREFIX, buf)
+        // SAFETY: Starting from `offset`, all elements of the slice have been set.
+        let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) };
+        f.pad_integral(is_nonnegative, Self::PREFIX, buf_slice)
     }
 }
 
@@ -199,6 +190,20 @@ static DEC_DIGITS_LUT: &[u8; 200] = b"\
       6061626364656667686970717273747576777879\
       8081828384858687888990919293949596979899";
 
+/// This function converts a slice of ascii characters into a `&str` starting from `offset`.
+///
+/// # Safety
+///
+/// `buf` content starting from `offset` index MUST BE initialized and MUST BE ascii
+/// characters.
+unsafe fn slice_buffer_to_str(buf: &[MaybeUninit<u8>], offset: usize) -> &str {
+    // SAFETY: `offset` is always included between 0 and `buf`'s length.
+    let written = unsafe { buf.get_unchecked(offset..) };
+    // SAFETY: (`assume_init_ref`) All buf content since offset is set.
+    // SAFETY: (`from_utf8_unchecked`) Writes use ASCII from the lookup table exclusively.
+    unsafe { str::from_utf8_unchecked(written.assume_init_ref()) }
+}
+
 macro_rules! impl_Display {
     ($($signed:ident, $unsigned:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => {
 
@@ -212,7 +217,8 @@ macro_rules! impl_Display {
                     // Buffer decimals for $unsigned with right alignment.
                     let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
 
-                    f.pad_integral(true, "", self._fmt(&mut buf))
+                    // SAFETY: `buf` is always big enough to contain all the digits.
+                    unsafe { f.pad_integral(true, "", self._fmt(&mut buf)) }
                 }
                 #[cfg(feature = "optimize_for_size")]
                 {
@@ -230,7 +236,8 @@ macro_rules! impl_Display {
                     // Buffer decimals for $unsigned with right alignment.
                     let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
 
-                    f.pad_integral(*self >= 0, "", self.unsigned_abs()._fmt(&mut buf))
+                    // SAFETY: `buf` is always big enough to contain all the digits.
+                    unsafe { f.pad_integral(*self >= 0, "", self.unsigned_abs()._fmt(&mut buf)) }
                 }
                 #[cfg(feature = "optimize_for_size")]
                 {
@@ -247,7 +254,14 @@ macro_rules! impl_Display {
                 reason = "specialized method meant to only be used by `SpecToString` implementation",
                 issue = "none"
             )]
-            pub fn _fmt<'a>(self, buf: &'a mut [MaybeUninit::<u8>]) -> &'a str {
+            pub unsafe fn _fmt<'a>(self, buf: &'a mut [MaybeUninit::<u8>]) -> &'a str {
+                // SAFETY: `buf` will always be big enough to contain all digits.
+                let offset = unsafe { self._fmt_inner(buf) };
+                // SAFETY: Starting from `offset`, all elements of the slice have been set.
+                unsafe { slice_buffer_to_str(buf, offset) }
+            }
+
+            unsafe fn _fmt_inner(self, buf: &mut [MaybeUninit::<u8>]) -> usize {
                 // Count the number of bytes in buf that are not initialized.
                 let mut offset = buf.len();
                 // Consume the least-significant decimals from a working copy.
@@ -309,47 +323,123 @@ macro_rules! impl_Display {
                     // not used: remain = 0;
                 }
 
-                // SAFETY: All buf content since offset is set.
-                let written = unsafe { buf.get_unchecked(offset..) };
-                // SAFETY: Writes use ASCII from the lookup table exclusively.
+                offset
+            }
+        }
+
+        impl $signed {
+            /// Allows users to write an integer (in signed decimal format) into a variable `buf` of
+            /// type [`NumBuffer`] that is passed by the caller by mutable reference.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// #![feature(int_format_into)]
+            /// use core::fmt::NumBuffer;
+            ///
+            #[doc = concat!("let n = 0", stringify!($signed), ";")]
+            /// let mut buf = NumBuffer::new();
+            /// assert_eq!(n.format_into(&mut buf), "0");
+            ///
+            #[doc = concat!("let n1 = 32", stringify!($signed), ";")]
+            /// assert_eq!(n1.format_into(&mut buf), "32");
+            ///
+            #[doc = concat!("let n2 = ", stringify!($signed::MAX), ";")]
+            #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($signed::MAX), ".to_string());")]
+            /// ```
+            #[unstable(feature = "int_format_into", issue = "138215")]
+            pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
+                let mut offset;
+
+                #[cfg(not(feature = "optimize_for_size"))]
+                // SAFETY: `buf` will always be big enough to contain all digits.
                 unsafe {
-                    str::from_utf8_unchecked(slice::from_raw_parts(
-                          MaybeUninit::slice_as_ptr(written),
-                          written.len(),
-                    ))
+                    offset = self.unsigned_abs()._fmt_inner(&mut buf.buf);
                 }
+                #[cfg(feature = "optimize_for_size")]
+                {
+                    offset = _inner_slow_integer_to_str(self.unsigned_abs().$conv_fn(), &mut buf.buf);
+                }
+                // Only difference between signed and unsigned are these 4 lines.
+                if self < 0 {
+                    offset -= 1;
+                    buf.buf[offset].write(b'-');
+                }
+                // SAFETY: Starting from `offset`, all elements of the slice have been set.
+                unsafe { slice_buffer_to_str(&buf.buf, offset) }
             }
-        })*
+        }
+
+        impl $unsigned {
+            /// Allows users to write an integer (in signed decimal format) into a variable `buf` of
+            /// type [`NumBuffer`] that is passed by the caller by mutable reference.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// #![feature(int_format_into)]
+            /// use core::fmt::NumBuffer;
+            ///
+            #[doc = concat!("let n = 0", stringify!($unsigned), ";")]
+            /// let mut buf = NumBuffer::new();
+            /// assert_eq!(n.format_into(&mut buf), "0");
+            ///
+            #[doc = concat!("let n1 = 32", stringify!($unsigned), ";")]
+            /// assert_eq!(n1.format_into(&mut buf), "32");
+            ///
+            #[doc = concat!("let n2 = ", stringify!($unsigned::MAX), ";")]
+            #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($unsigned::MAX), ".to_string());")]
+            /// ```
+            #[unstable(feature = "int_format_into", issue = "138215")]
+            pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
+                let offset;
+
+                #[cfg(not(feature = "optimize_for_size"))]
+                // SAFETY: `buf` will always be big enough to contain all digits.
+                unsafe {
+                    offset = self._fmt_inner(&mut buf.buf);
+                }
+                #[cfg(feature = "optimize_for_size")]
+                {
+                    offset = _inner_slow_integer_to_str(self.$conv_fn(), &mut buf.buf);
+                }
+                // SAFETY: Starting from `offset`, all elements of the slice have been set.
+                unsafe { slice_buffer_to_str(&buf.buf, offset) }
+            }
+        }
+
+
+        )*
 
         #[cfg(feature = "optimize_for_size")]
-        fn $gen_name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            const MAX_DEC_N: usize = $u::MAX.ilog10() as usize + 1;
-            let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
-            let mut curr = MAX_DEC_N;
-            let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
+        fn _inner_slow_integer_to_str(mut n: $u, buf: &mut [MaybeUninit::<u8>]) -> usize {
+            let mut curr = buf.len();
 
             // SAFETY: To show that it's OK to copy into `buf_ptr`, notice that at the beginning
             // `curr == buf.len() == 39 > log(n)` since `n < 2^128 < 10^39`, and at
             // each step this is kept the same as `n` is divided. Since `n` is always
             // non-negative, this means that `curr > 0` so `buf_ptr[curr..curr + 1]`
             // is safe to access.
-            unsafe {
-                loop {
-                    curr -= 1;
-                    buf_ptr.add(curr).write((n % 10) as u8 + b'0');
-                    n /= 10;
+            loop {
+                curr -= 1;
+                buf[curr].write((n % 10) as u8 + b'0');
+                n /= 10;
 
-                    if n == 0 {
-                        break;
-                    }
+                if n == 0 {
+                    break;
                 }
             }
+            curr
+        }
 
-            // SAFETY: `curr` > 0 (since we made `buf` large enough), and all the chars are valid UTF-8
-            let buf_slice = unsafe {
-                str::from_utf8_unchecked(
-                    slice::from_raw_parts(buf_ptr.add(curr), buf.len() - curr))
-            };
+        #[cfg(feature = "optimize_for_size")]
+        fn $gen_name(n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            const MAX_DEC_N: usize = $u::MAX.ilog(10) as usize + 1;
+            let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
+
+            let offset = _inner_slow_integer_to_str(n, &mut buf);
+            // SAFETY: Starting from `offset`, all elements of the slice have been set.
+            let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) };
             f.pad_integral(is_nonnegative, "", buf_slice)
         }
     };
@@ -572,7 +662,8 @@ impl fmt::Display for u128 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut buf = [MaybeUninit::<u8>::uninit(); U128_MAX_DEC_N];
 
-        f.pad_integral(true, "", self._fmt(&mut buf))
+        // SAFETY: `buf` is always big enough to contain all the digits.
+        unsafe { f.pad_integral(true, "", self._fmt(&mut buf)) }
     }
 }
 
@@ -584,7 +675,8 @@ impl fmt::Display for i128 {
         let mut buf = [MaybeUninit::<u8>::uninit(); U128_MAX_DEC_N];
 
         let is_nonnegative = *self >= 0;
-        f.pad_integral(is_nonnegative, "", self.unsigned_abs()._fmt(&mut buf))
+        // SAFETY: `buf` is always big enough to contain all the digits.
+        unsafe { f.pad_integral(is_nonnegative, "", self.unsigned_abs()._fmt(&mut buf)) }
     }
 }
 
@@ -597,13 +689,21 @@ impl u128 {
         reason = "specialized method meant to only be used by `SpecToString` implementation",
         issue = "none"
     )]
-    pub fn _fmt<'a>(self, buf: &'a mut [MaybeUninit<u8>]) -> &'a str {
+    pub unsafe fn _fmt<'a>(self, buf: &'a mut [MaybeUninit<u8>]) -> &'a str {
+        // SAFETY: `buf` will always be big enough to contain all digits.
+        let offset = unsafe { self._fmt_inner(buf) };
+        // SAFETY: Starting from `offset`, all elements of the slice have been set.
+        unsafe { slice_buffer_to_str(buf, offset) }
+    }
+
+    unsafe fn _fmt_inner(self, buf: &mut [MaybeUninit<u8>]) -> usize {
         // Optimize common-case zero, which would also need special treatment due to
         // its "leading" zero.
         if self == 0 {
-            return "0";
+            let offset = buf.len() - 1;
+            buf[offset].write(b'0');
+            return offset;
         }
-
         // Take the 16 least-significant decimals.
         let (quot_1e16, mod_1e16) = div_rem_1e16(self);
         let (mut remain, mut offset) = if quot_1e16 == 0 {
@@ -677,16 +777,86 @@ impl u128 {
             buf[offset].write(DEC_DIGITS_LUT[last * 2 + 1]);
             // not used: remain = 0;
         }
+        offset
+    }
+
+    /// Allows users to write an integer (in signed decimal format) into a variable `buf` of
+    /// type [`NumBuffer`] that is passed by the caller by mutable reference.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(int_format_into)]
+    /// use core::fmt::NumBuffer;
+    ///
+    /// let n = 0u128;
+    /// let mut buf = NumBuffer::new();
+    /// assert_eq!(n.format_into(&mut buf), "0");
+    ///
+    /// let n1 = 32u128;
+    /// let mut buf1 = NumBuffer::new();
+    /// assert_eq!(n1.format_into(&mut buf1), "32");
+    ///
+    /// let n2 = u128::MAX;
+    /// let mut buf2 = NumBuffer::new();
+    /// assert_eq!(n2.format_into(&mut buf2), u128::MAX.to_string());
+    /// ```
+    #[unstable(feature = "int_format_into", issue = "138215")]
+    pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
+        let diff = buf.capacity() - U128_MAX_DEC_N;
+        // FIXME: Once const generics are better, use `NumberBufferTrait::BUF_SIZE` as generic const
+        // for `fmt_u128_inner`.
+        //
+        // In the meantime, we have to use a slice starting at index 1 and add 1 to the returned
+        // offset to ensure the number is correctly generated at the end of the buffer.
+        // SAFETY: `diff` will always be between 0 and its initial value.
+        unsafe { self._fmt(buf.buf.get_unchecked_mut(diff..)) }
+    }
+}
 
-        // SAFETY: All buf content since offset is set.
-        let written = unsafe { buf.get_unchecked(offset..) };
-        // SAFETY: Writes use ASCII from the lookup table exclusively.
-        unsafe {
-            str::from_utf8_unchecked(slice::from_raw_parts(
-                MaybeUninit::slice_as_ptr(written),
-                written.len(),
-            ))
+impl i128 {
+    /// Allows users to write an integer (in signed decimal format) into a variable `buf` of
+    /// type [`NumBuffer`] that is passed by the caller by mutable reference.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(int_format_into)]
+    /// use core::fmt::NumBuffer;
+    ///
+    /// let n = 0i128;
+    /// let mut buf = NumBuffer::new();
+    /// assert_eq!(n.format_into(&mut buf), "0");
+    ///
+    /// let n1 = i128::MIN;
+    /// assert_eq!(n1.format_into(&mut buf), i128::MIN.to_string());
+    ///
+    /// let n2 = i128::MAX;
+    /// assert_eq!(n2.format_into(&mut buf), i128::MAX.to_string());
+    /// ```
+    #[unstable(feature = "int_format_into", issue = "138215")]
+    pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
+        let diff = buf.capacity() - U128_MAX_DEC_N;
+        // FIXME: Once const generics are better, use `NumberBufferTrait::BUF_SIZE` as generic const
+        // for `fmt_u128_inner`.
+        //
+        // In the meantime, we have to use a slice starting at index 1 and add 1 to the returned
+        // offset to ensure the number is correctly generated at the end of the buffer.
+        let mut offset =
+            // SAFETY: `buf` will always be big enough to contain all digits.
+            unsafe { self.unsigned_abs()._fmt_inner(buf.buf.get_unchecked_mut(diff..)) };
+        // We put back the offset at the right position.
+        offset += diff;
+        // Only difference between signed and unsigned are these 4 lines.
+        if self < 0 {
+            offset -= 1;
+            // SAFETY: `buf` will always be big enough to contain all digits plus the minus sign.
+            unsafe {
+                buf.buf.get_unchecked_mut(offset).write(b'-');
+            }
         }
+        // SAFETY: Starting from `offset`, all elements of the slice have been set.
+        unsafe { slice_buffer_to_str(&buf.buf, offset) }
     }
 }
 
diff --git a/library/core/src/fmt/num_buffer.rs b/library/core/src/fmt/num_buffer.rs
new file mode 100644
index 00000000000..474a8d20ef6
--- /dev/null
+++ b/library/core/src/fmt/num_buffer.rs
@@ -0,0 +1,60 @@
+use crate::mem::MaybeUninit;
+
+/// Trait used to describe the maximum number of digits in decimal base of the implemented integer.
+#[unstable(feature = "int_format_into", issue = "138215")]
+pub trait NumBufferTrait {
+    /// Maximum number of digits in decimal base of the implemented integer.
+    const BUF_SIZE: usize;
+}
+
+macro_rules! impl_NumBufferTrait {
+    ($($signed:ident, $unsigned:ident,)*) => {
+        $(
+            #[unstable(feature = "int_format_into", issue = "138215")]
+            impl NumBufferTrait for $signed {
+                // `+ 2` and not `+ 1` to include the `-` character.
+                const BUF_SIZE: usize = $signed::MAX.ilog(10) as usize + 2;
+            }
+            #[unstable(feature = "int_format_into", issue = "138215")]
+            impl NumBufferTrait for $unsigned {
+                const BUF_SIZE: usize = $unsigned::MAX.ilog(10) as usize + 1;
+            }
+        )*
+    }
+}
+
+impl_NumBufferTrait! {
+    i8, u8,
+    i16, u16,
+    i32, u32,
+    i64, u64,
+    isize, usize,
+    i128, u128,
+}
+
+/// A buffer wrapper of which the internal size is based on the maximum
+/// number of digits the associated integer can have.
+#[unstable(feature = "int_format_into", issue = "138215")]
+#[derive(Debug)]
+pub struct NumBuffer<T: NumBufferTrait> {
+    // FIXME: Once const generics feature is working, use `T::BUF_SIZE` instead of 40.
+    pub(crate) buf: [MaybeUninit<u8>; 40],
+    // FIXME: Remove this field once we can actually use `T`.
+    phantom: core::marker::PhantomData<T>,
+}
+
+#[unstable(feature = "int_format_into", issue = "138215")]
+impl<T: NumBufferTrait> NumBuffer<T> {
+    /// Initializes internal buffer.
+    #[unstable(feature = "int_format_into", issue = "138215")]
+    pub const fn new() -> Self {
+        // FIXME: Once const generics feature is working, use `T::BUF_SIZE` instead of 40.
+        NumBuffer { buf: [MaybeUninit::<u8>::uninit(); 40], phantom: core::marker::PhantomData }
+    }
+
+    /// Returns the length of the internal buffer.
+    #[unstable(feature = "int_format_into", issue = "138215")]
+    pub const fn capacity(&self) -> usize {
+        self.buf.len()
+    }
+}
diff --git a/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.current.stderr b/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.current.stderr
index 64304be9d6b..eaa212c6ce8 100644
--- a/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.current.stderr
+++ b/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.current.stderr
@@ -2,7 +2,9 @@ error[E0283]: type annotations needed
   --> $DIR/dedup-normalized-2-higher-ranked.rs:28:5
    |
 LL |     impls(rigid);
-   |     ^^^^^ cannot infer type of the type parameter `U` declared on the function `impls`
+   |     ^^^^^ ----- type must be known at this point
+   |     |
+   |     cannot infer type of the type parameter `U` declared on the function `impls`
    |
    = note: cannot satisfy `for<'b> <P as Trait>::Rigid: Bound<'b, _>`
 note: required by a bound in `impls`
diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr
index 4ab80cec58d..3763cd738a8 100644
--- a/tests/ui/const-generics/infer/issue-77092.stderr
+++ b/tests/ui/const-generics/infer/issue-77092.stderr
@@ -20,7 +20,7 @@ error[E0284]: type annotations needed
 LL |         println!("{:?}", take_array_from_mut(&mut arr, i));
    |                   ----   ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut`
    |                   |
-   |                   type must be known at this point
+   |                   required by this formatting parameter
    |
    = note: required for `[i32; _]` to implement `Debug`
    = note: 1 redundant requirement hidden
diff --git a/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr b/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr
index b4d2229d408..b6c6e74f260 100644
--- a/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr
+++ b/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr
@@ -2,7 +2,9 @@ error[E0283]: type annotations needed
   --> $DIR/auto-trait-selection-freeze.rs:19:16
    |
 LL |     if false { is_trait(foo()) } else { Default::default() }
-   |                ^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `is_trait`
+   |                ^^^^^^^^ ----- type must be known at this point
+   |                |
+   |                cannot infer type of the type parameter `U` declared on the function `is_trait`
    |
 note: multiple `impl`s satisfying `impl Sized: Trait<_>` found
   --> $DIR/auto-trait-selection-freeze.rs:16:1
diff --git a/tests/ui/impl-trait/auto-trait-selection.old.stderr b/tests/ui/impl-trait/auto-trait-selection.old.stderr
index 1b5fd95fdf9..8e441001771 100644
--- a/tests/ui/impl-trait/auto-trait-selection.old.stderr
+++ b/tests/ui/impl-trait/auto-trait-selection.old.stderr
@@ -2,7 +2,9 @@ error[E0283]: type annotations needed
   --> $DIR/auto-trait-selection.rs:15:16
    |
 LL |     if false { is_trait(foo()) } else { Default::default() }
-   |                ^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `is_trait`
+   |                ^^^^^^^^ ----- type must be known at this point
+   |                |
+   |                cannot infer type of the type parameter `U` declared on the function `is_trait`
    |
 note: multiple `impl`s satisfying `impl Sized: Trait<_>` found
   --> $DIR/auto-trait-selection.rs:12:1
diff --git a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs
new file mode 100644
index 00000000000..e3dc22c1992
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs
@@ -0,0 +1,46 @@
+// issue#143560
+
+trait T {
+    type Target;
+}
+
+trait Foo {
+    fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
+    fn foo() -> impl Sized;
+    //~^ ERROR: the name `foo` is defined multiple times
+}
+
+trait Bar {
+    fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
+    fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
+    //~^ ERROR: the name `foo` is defined multiple times
+}
+
+struct S<T> {
+    a: T
+}
+
+trait Baz {
+    fn foo() -> S<impl T<Target = S<S<impl Sized>>>>;
+    fn foo() -> S<impl T<Target = S<S<impl Sized>>>>;
+    //~^ ERROR: the name `foo` is defined multiple times
+}
+
+struct S1<T1, T2> {
+    a: T1,
+    b: T2
+}
+
+trait Qux {
+    fn foo() -> S1<
+        impl T<Target = impl T<Target = impl Sized>>,
+        impl T<Target = impl T<Target = S<impl Sized>>>
+        >;
+    fn foo() -> S1<
+        impl T<Target = impl T<Target = impl Sized>>,
+        impl T<Target = impl T<Target = S<impl Sized>>>
+        >;
+    //~^^^^ ERROR: the name `foo` is defined multiple times
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr
new file mode 100644
index 00000000000..f4e73dc1798
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr
@@ -0,0 +1,49 @@
+error[E0428]: the name `foo` is defined multiple times
+  --> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:9:5
+   |
+LL |     fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
+   |     --------------------------------------------------------- previous definition of the value `foo` here
+LL |     fn foo() -> impl Sized;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
+   |
+   = note: `foo` must be defined only once in the value namespace of this trait
+
+error[E0428]: the name `foo` is defined multiple times
+  --> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:15:5
+   |
+LL |     fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
+   |     --------------------------------------------------------- previous definition of the value `foo` here
+LL |     fn foo() -> impl T<Target = impl T<Target = impl Sized>>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
+   |
+   = note: `foo` must be defined only once in the value namespace of this trait
+
+error[E0428]: the name `foo` is defined multiple times
+  --> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:25:5
+   |
+LL |     fn foo() -> S<impl T<Target = S<S<impl Sized>>>>;
+   |     ------------------------------------------------- previous definition of the value `foo` here
+LL |     fn foo() -> S<impl T<Target = S<S<impl Sized>>>>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
+   |
+   = note: `foo` must be defined only once in the value namespace of this trait
+
+error[E0428]: the name `foo` is defined multiple times
+  --> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:39:5
+   |
+LL | /     fn foo() -> S1<
+LL | |         impl T<Target = impl T<Target = impl Sized>>,
+LL | |         impl T<Target = impl T<Target = S<impl Sized>>>
+LL | |         >;
+   | |__________- previous definition of the value `foo` here
+LL | /     fn foo() -> S1<
+LL | |         impl T<Target = impl T<Target = impl Sized>>,
+LL | |         impl T<Target = impl T<Target = S<impl Sized>>>
+LL | |         >;
+   | |__________^ `foo` redefined here
+   |
+   = note: `foo` must be defined only once in the value namespace of this trait
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0428`.
diff --git a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.rs b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.rs
index 4fddd7c4ac8..6db0c88f6c0 100644
--- a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.rs
+++ b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.rs
@@ -27,4 +27,15 @@ impl T for () {
     }
 }
 
+trait Baz {
+    fn foo();
+    fn foo() -> impl Sized;     //~ ERROR: the name `foo` is defined multiple times
+}
+
+trait Foo {
+    fn foo() -> impl Sized;
+    fn foo();                   //~ ERROR: the name `foo` is defined multiple times
+    fn foo() -> impl Sized;     //~ ERROR: the name `foo` is defined multiple times
+}
+
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.stderr b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.stderr
index b58e8136479..faa65f45d33 100644
--- a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.stderr
+++ b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn.stderr
@@ -8,6 +8,37 @@ LL |     fn method() -> impl Sized;
    |
    = note: `method` must be defined only once in the value namespace of this trait
 
+error[E0428]: the name `foo` is defined multiple times
+  --> $DIR/rpitit-duplicate-associated-fn.rs:32:5
+   |
+LL |     fn foo();
+   |     --------- previous definition of the value `foo` here
+LL |     fn foo() -> impl Sized;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
+   |
+   = note: `foo` must be defined only once in the value namespace of this trait
+
+error[E0428]: the name `foo` is defined multiple times
+  --> $DIR/rpitit-duplicate-associated-fn.rs:37:5
+   |
+LL |     fn foo() -> impl Sized;
+   |     ----------------------- previous definition of the value `foo` here
+LL |     fn foo();
+   |     ^^^^^^^^^ `foo` redefined here
+   |
+   = note: `foo` must be defined only once in the value namespace of this trait
+
+error[E0428]: the name `foo` is defined multiple times
+  --> $DIR/rpitit-duplicate-associated-fn.rs:38:5
+   |
+LL |     fn foo() -> impl Sized;
+   |     ----------------------- previous definition of the value `foo` here
+LL |     fn foo();
+LL |     fn foo() -> impl Sized;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ `foo` redefined here
+   |
+   = note: `foo` must be defined only once in the value namespace of this trait
+
 error[E0201]: duplicate definitions with name `method`:
   --> $DIR/rpitit-duplicate-associated-fn.rs:12:5
    |
@@ -47,7 +78,7 @@ LL |     fn method() -> impl Sized;
 LL | impl Bar for () {
    | ^^^^^^^^^^^^^^^ missing `method` in implementation
 
-error: aborting due to 4 previous errors
+error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0046, E0201, E0428.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/inline-const/in-pat-recovery.rs b/tests/ui/inline-const/in-pat-recovery.rs
index e9e60116ff4..a46e56e3be6 100644
--- a/tests/ui/inline-const/in-pat-recovery.rs
+++ b/tests/ui/inline-const/in-pat-recovery.rs
@@ -4,7 +4,7 @@
 fn main() {
     match 1 {
         const { 1 + 7 } => {}
-        //~^ ERROR `inline_const_pat` has been removed
+        //~^ ERROR const blocks cannot be used as patterns
         2 => {}
         _ => {}
     }
diff --git a/tests/ui/inline-const/in-pat-recovery.stderr b/tests/ui/inline-const/in-pat-recovery.stderr
index e1f2e681e77..0698cff1480 100644
--- a/tests/ui/inline-const/in-pat-recovery.stderr
+++ b/tests/ui/inline-const/in-pat-recovery.stderr
@@ -1,10 +1,10 @@
-error: `inline_const_pat` has been removed
+error: const blocks cannot be used as patterns
   --> $DIR/in-pat-recovery.rs:6:15
    |
 LL |         const { 1 + 7 } => {}
    |               ^^^^^^^^^
    |
-   = help: use a named `const`-item or an `if`-guard instead
+   = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/trait-bounds/false-span-in-trait-bound-label.rs b/tests/ui/trait-bounds/false-span-in-trait-bound-label.rs
new file mode 100644
index 00000000000..0e307309860
--- /dev/null
+++ b/tests/ui/trait-bounds/false-span-in-trait-bound-label.rs
@@ -0,0 +1,10 @@
+// In this test, the span of the trait bound label should point to `1`, not `""`.
+// See issue #143336
+
+trait A<T> {
+    fn f(self, x: T);
+}
+
+fn main() {
+    A::f(1, ""); //~ ERROR the trait bound `{integer}: A<_>` is not satisfied [E0277]
+}
diff --git a/tests/ui/trait-bounds/false-span-in-trait-bound-label.stderr b/tests/ui/trait-bounds/false-span-in-trait-bound-label.stderr
new file mode 100644
index 00000000000..9a480273338
--- /dev/null
+++ b/tests/ui/trait-bounds/false-span-in-trait-bound-label.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `{integer}: A<_>` is not satisfied
+  --> $DIR/false-span-in-trait-bound-label.rs:9:10
+   |
+LL |     A::f(1, "");
+   |     ---- ^ the trait `A<_>` is not implemented for `{integer}`
+   |     |
+   |     required by a bound introduced by this call
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/false-span-in-trait-bound-label.rs:4:1
+   |
+LL | trait A<T> {
+   | ^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr b/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr
index fdf0b1722be..23cced2bc28 100644
--- a/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr
+++ b/tests/ui/traits/inheritance/repeated-supertrait-ambig.stderr
@@ -34,10 +34,10 @@ LL |     <dyn CompareToInts>::same_as(c, 22)
              `i64` implements `CompareTo<u64>`
 
 error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
-  --> $DIR/repeated-supertrait-ambig.rs:38:27
+  --> $DIR/repeated-supertrait-ambig.rs:38:24
    |
 LL |     CompareTo::same_as(c, 22)
-   |     ------------------    ^^ the trait `CompareTo<i32>` is not implemented for `C`
+   |     ------------------ ^ the trait `CompareTo<i32>` is not implemented for `C`
    |     |
    |     required by a bound introduced by this call
    |
diff --git a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr
index 17c3db9ad33..12984c7936c 100644
--- a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr
+++ b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr
@@ -2,7 +2,7 @@ error[E0283]: type annotations needed
   --> $DIR/multidispatch-convert-ambig-dest.rs:26:5
    |
 LL |     test(22, std::default::Default::default());
-   |     ^^^^     -------------------------------- type must be known at this point
+   |     ^^^^ -- type must be known at this point
    |     |
    |     cannot infer type of the type parameter `U` declared on the function `test`
    |