about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs35
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/significant_drop_order.rs2
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs8
-rw-r--r--compiler/rustc_middle/src/ty/util.rs64
-rw-r--r--library/std/src/net/socket_addr.rs2
-rw-r--r--src/bootstrap/src/utils/helpers.rs4
-rw-r--r--src/doc/unstable-book/src/language-features/type-alias-impl-trait.md159
-rw-r--r--src/librustdoc/doctest/runner.rs8
-rw-r--r--tests/rustdoc-ui/doctest/edition-2024-error-output.rs14
-rw-r--r--tests/rustdoc-ui/doctest/edition-2024-error-output.stdout20
-rw-r--r--tests/ui/consts/const-block-const-bound.stderr2
-rw-r--r--tests/ui/nll/ty-outlives/impl-trait-captures.stderr8
-rw-r--r--tests/ui/traits/const-traits/assoc-type.current.stderr2
-rw-r--r--tests/ui/traits/const-traits/assoc-type.next.stderr2
-rw-r--r--tests/ui/traits/const-traits/call-generic-method-nonconst.stderr2
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr4
-rw-r--r--tests/ui/traits/const-traits/const-opaque.no.stderr2
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr2
-rw-r--r--tests/ui/traits/const-traits/item-bound-entailment-fails.stderr6
-rw-r--r--tests/ui/traits/const-traits/minicore-fn-fail.stderr2
-rw-r--r--tests/ui/traits/const-traits/predicate-entailment-fails.stderr12
-rw-r--r--tests/ui/traits/const-traits/trait-where-clause-const.stderr4
-rw-r--r--tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr2
-rw-r--r--triagebot.toml4
32 files changed, 274 insertions, 128 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index fddddf404db..56cc4327585 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -969,7 +969,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             }
         };
 
-        // If we can detect the expression to be an function or method call where the closure was
+        // If we can detect the expression to be a function or method call where the closure was
         // an argument, we point at the function or method definition argument...
         if let Some((callee_def_id, call_span, call_args)) = get_call_details() {
             let arg_pos = call_args
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index aec9518494c..5e68bb31001 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -12,7 +12,6 @@ use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisi
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::util;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::util::ExplicitSelf;
 use rustc_middle::ty::{
     self, BottomUpFolder, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder,
     TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast,
@@ -995,6 +994,26 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
     }
 }
 
+/// Gets the string for an explicit self declaration, e.g. "self", "&self",
+/// etc.
+fn get_self_string<'tcx, P>(self_arg_ty: Ty<'tcx>, is_self_ty: P) -> String
+where
+    P: Fn(Ty<'tcx>) -> bool,
+{
+    if is_self_ty(self_arg_ty) {
+        "self".to_owned()
+    } else if let ty::Ref(_, ty, mutbl) = self_arg_ty.kind()
+        && is_self_ty(*ty)
+    {
+        match mutbl {
+            hir::Mutability::Not => "&self".to_owned(),
+            hir::Mutability::Mut => "&mut self".to_owned(),
+        }
+    } else {
+        format!("self: {self_arg_ty}")
+    }
+}
+
 fn report_trait_method_mismatch<'tcx>(
     infcx: &InferCtxt<'tcx>,
     mut cause: ObligationCause<'tcx>,
@@ -1020,12 +1039,7 @@ fn report_trait_method_mismatch<'tcx>(
             if trait_m.fn_has_self_parameter =>
         {
             let ty = trait_sig.inputs()[0];
-            let sugg = match ExplicitSelf::determine(ty, |ty| ty == impl_trait_ref.self_ty()) {
-                ExplicitSelf::ByValue => "self".to_owned(),
-                ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
-                ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
-                _ => format!("self: {ty}"),
-            };
+            let sugg = get_self_string(ty, |ty| ty == impl_trait_ref.self_ty());
 
             // When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
             // span points only at the type `Box<Self`>, but we want to cover the whole
@@ -1238,12 +1252,7 @@ fn compare_self_type<'tcx>(
             .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, method.def_id));
         let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty);
         let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty);
-        match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
-            ExplicitSelf::ByValue => "self".to_owned(),
-            ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
-            ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
-            _ => format!("self: {self_arg_ty}"),
-        }
+        get_self_string(self_arg_ty, can_eq_self)
     };
 
     match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 83925b5ec52..b4a71edc118 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -838,7 +838,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 | PredicateFilter::SelfOnly
                 | PredicateFilter::SelfAndAssociatedTypeBounds => {
                     match constness {
-                        hir::BoundConstness::Always(span) => {
+                        hir::BoundConstness::Always(_) => {
                             if polarity == ty::PredicatePolarity::Positive {
                                 bounds.push((
                                     poly_trait_ref
@@ -864,7 +864,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 // in `lower_assoc_item_constraint`.
                 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
                     match constness {
-                        hir::BoundConstness::Maybe(span) => {
+                        hir::BoundConstness::Maybe(_) => {
                             if polarity == ty::PredicatePolarity::Positive {
                                 bounds.push((
                                     poly_trait_ref
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 8db0c7c9b3a..80f1bd7c6f4 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1147,10 +1147,8 @@ pub struct Destructor {
 // FIXME: consider combining this definition with regular `Destructor`
 #[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
 pub struct AsyncDestructor {
-    /// The `DefId` of the async destructor future constructor
-    pub ctor: DefId,
-    /// The `DefId` of the async destructor future type
-    pub future: DefId,
+    /// The `DefId` of the `impl AsyncDrop`
+    pub impl_did: LocalDefId,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs
index 2d9e0331451..4881d611c12 100644
--- a/compiler/rustc_middle/src/ty/significant_drop_order.rs
+++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs
@@ -154,7 +154,7 @@ pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Span> {
             let dtor = if let Some(dtor) = tcx.adt_destructor(did) {
                 dtor.did
             } else if let Some(dtor) = tcx.adt_async_destructor(did) {
-                dtor.future
+                return Some(tcx.source_span(dtor.impl_did));
             } else {
                 return Some(try_local_did_span(did));
             };
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 60fd531b4d0..798ef352c40 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -86,15 +86,15 @@ impl fmt::Debug for ty::LateParamRegion {
 impl fmt::Debug for ty::LateParamRegionKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
-            ty::LateParamRegionKind::Anon(idx) => write!(f, "BrAnon({idx})"),
+            ty::LateParamRegionKind::Anon(idx) => write!(f, "LateAnon({idx})"),
             ty::LateParamRegionKind::Named(did, name) => {
                 if did.is_crate_root() {
-                    write!(f, "BrNamed({name})")
+                    write!(f, "LateNamed({name})")
                 } else {
-                    write!(f, "BrNamed({did:?}, {name})")
+                    write!(f, "LateNamed({did:?}, {name})")
                 }
             }
-            ty::LateParamRegionKind::ClosureEnv => write!(f, "BrEnv"),
+            ty::LateParamRegionKind::ClosureEnv => write!(f, "LateEnv"),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index bebbe17d518..e4863896fc8 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -455,26 +455,17 @@ impl<'tcx> TyCtxt<'tcx> {
                 continue;
             }
 
-            let [future, ctor] = self.associated_item_def_ids(impl_did) else {
-                self.dcx().span_delayed_bug(
-                    self.def_span(impl_did),
-                    "AsyncDrop impl without async_drop function or Dropper type",
-                );
-                continue;
-            };
-
-            if let Some((_, _, old_impl_did)) = dtor_candidate {
+            if let Some(old_impl_did) = dtor_candidate {
                 self.dcx()
                     .struct_span_err(self.def_span(impl_did), "multiple async drop impls found")
                     .with_span_note(self.def_span(old_impl_did), "other impl here")
                     .delay_as_bug();
             }
 
-            dtor_candidate = Some((*future, *ctor, impl_did));
+            dtor_candidate = Some(impl_did);
         }
 
-        let (future, ctor, _) = dtor_candidate?;
-        Some(ty::AsyncDestructor { future, ctor })
+        Some(ty::AsyncDestructor { impl_did: dtor_candidate? })
     }
 
     /// Returns async drop glue morphology for a definition. To get async drop
@@ -1561,55 +1552,6 @@ impl<'tcx> Ty<'tcx> {
     }
 }
 
-pub enum ExplicitSelf<'tcx> {
-    ByValue,
-    ByReference(ty::Region<'tcx>, hir::Mutability),
-    ByRawPointer(hir::Mutability),
-    ByBox,
-    Other,
-}
-
-impl<'tcx> ExplicitSelf<'tcx> {
-    /// Categorizes an explicit self declaration like `self: SomeType`
-    /// into either `self`, `&self`, `&mut self`, `Box<Self>`, or
-    /// `Other`.
-    /// This is mainly used to require the arbitrary_self_types feature
-    /// in the case of `Other`, to improve error messages in the common cases,
-    /// and to make `Other` dyn-incompatible.
-    ///
-    /// Examples:
-    ///
-    /// ```ignore (illustrative)
-    /// impl<'a> Foo for &'a T {
-    ///     // Legal declarations:
-    ///     fn method1(self: &&'a T); // ExplicitSelf::ByReference
-    ///     fn method2(self: &'a T); // ExplicitSelf::ByValue
-    ///     fn method3(self: Box<&'a T>); // ExplicitSelf::ByBox
-    ///     fn method4(self: Rc<&'a T>); // ExplicitSelf::Other
-    ///
-    ///     // Invalid cases will be caught by `check_method_receiver`:
-    ///     fn method_err1(self: &'a mut T); // ExplicitSelf::Other
-    ///     fn method_err2(self: &'static T) // ExplicitSelf::ByValue
-    ///     fn method_err3(self: &&T) // ExplicitSelf::ByReference
-    /// }
-    /// ```
-    ///
-    pub fn determine<P>(self_arg_ty: Ty<'tcx>, is_self_ty: P) -> ExplicitSelf<'tcx>
-    where
-        P: Fn(Ty<'tcx>) -> bool,
-    {
-        use self::ExplicitSelf::*;
-
-        match *self_arg_ty.kind() {
-            _ if is_self_ty(self_arg_ty) => ByValue,
-            ty::Ref(region, ty, mutbl) if is_self_ty(ty) => ByReference(region, mutbl),
-            ty::RawPtr(ty, mutbl) if is_self_ty(ty) => ByRawPointer(mutbl),
-            _ if self_arg_ty.boxed_ty().is_some_and(is_self_ty) => ByBox,
-            _ => Other,
-        }
-    }
-}
-
 /// Returns a list of types such that the given type needs drop if and only if
 /// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if
 /// this type always needs drop.
diff --git a/library/std/src/net/socket_addr.rs b/library/std/src/net/socket_addr.rs
index 4c8905c0d46..41e623e79ce 100644
--- a/library/std/src/net/socket_addr.rs
+++ b/library/std/src/net/socket_addr.rs
@@ -101,7 +101,7 @@ use crate::{io, iter, option, slice, vec};
 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
 /// ```
 ///
-/// [`TcpStream::connect`] is an example of an function that utilizes
+/// [`TcpStream::connect`] is an example of a function that utilizes
 /// `ToSocketAddrs` as a trait bound on its parameter in order to accept
 /// different types:
 ///
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index f8e4d4e0471..78dcdcbd187 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -474,13 +474,13 @@ pub fn linker_flags(
                 if stage == 0 && target.is_windows() {
                     args.push("-Clink-arg=-fuse-ld=lld".to_string());
                 } else {
-                    args.push("-Clinker-flavor=gnu-lld-cc".to_string());
+                    args.push("-Zlinker-features=+lld".to_string());
                 }
                 // FIXME(kobzol): remove this flag once MCP510 gets stabilized
                 args.push("-Zunstable-options".to_string());
             }
             LldMode::SelfContained => {
-                args.push("-Clinker-flavor=gnu-lld-cc".to_string());
+                args.push("-Zlinker-features=+lld".to_string());
                 args.push("-Clink-self-contained=+linker".to_string());
                 // FIXME(kobzol): remove this flag once MCP510 gets stabilized
                 args.push("-Zunstable-options".to_string());
diff --git a/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md b/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md
new file mode 100644
index 00000000000..a6fb25a55be
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md
@@ -0,0 +1,159 @@
+# `type_alias_impl_trait`
+
+The tracking issue for this feature is: [#63063]
+
+------------------------
+
+> This feature is not to be confused with [`trait_alias`] or [`impl_trait_in_assoc_type`].
+
+### What is `impl Trait`?
+
+`impl Trait` in return position is useful for declaring types that are constrained by traits, but whose concrete type should be hidden:
+
+```rust
+use std::fmt::Debug;
+
+fn new() -> impl Debug {
+    42
+}
+
+fn main() {
+    let thing = new();
+    // What actually is a `thing`?
+    // No idea but we know it implements `Debug`, so we can debug print it
+    println!("{thing:?}");
+}
+```
+
+See the [reference] for more information about `impl Trait` in return position.
+
+### `type_alias_impl_trait`
+
+However, we might want to use an `impl Trait` in multiple locations but actually use the same concrete type everywhere while keeping it hidden.
+This can be useful in libraries where you want to hide implementation details.
+
+The `#[define_opaque]` attribute must be used to explicitly list opaque items constrained by the item it's on.
+
+```rust
+#![feature(type_alias_impl_trait)]
+# #![allow(unused_variables, dead_code)]
+trait Trait {}
+
+struct MyType;
+
+impl Trait for MyType {}
+
+type Alias = impl Trait;
+
+#[define_opaque(Alias)] // To constrain the type alias to `MyType`
+fn new() -> Alias {
+    MyType
+}
+
+#[define_opaque(Alias)] // So we can name the concrete type inside this item
+fn main() {
+    let thing: MyType = new();
+}
+
+// It can be a part of a struct too
+struct HaveAlias {
+    stuff: String,
+    thing: Alias,
+}
+```
+
+In this example, the concrete type referred to by `Alias` is guaranteed to be the same wherever `Alias` occurs.
+
+> Orginally this feature included type aliases as an associated type of a trait. In [#110237] this was split off to [`impl_trait_in_assoc_type`].
+
+### `type_alias_impl_trait` in argument position.
+
+Note that using `Alias` as an argument type is *not* the same as argument-position `impl Trait`, as `Alias` refers to a unique type, whereas the concrete type for argument-position `impl Trait` is chosen by the caller.
+
+```rust
+# #![feature(type_alias_impl_trait)]
+# #![allow(unused_variables)]
+# pub mod x {
+# pub trait Trait {}
+#
+# struct MyType;
+#
+# impl Trait for MyType {}
+#
+# pub type Alias = impl Trait;
+#
+# #[define_opaque(Alias)]
+# pub fn new() -> Alias {
+#     MyType
+# }
+# }
+# use x::*;
+// this...
+pub fn take_alias(x: Alias) {
+    // ...
+}
+
+// ...is *not* the same as
+pub fn take_impl(x: impl Trait) {
+    // ...
+}
+# fn main(){}
+```
+
+```rust,compile_fail,E0308
+# #![feature(type_alias_impl_trait)]
+# #![allow(unused_variables)]
+# pub mod x {
+# pub trait Trait {}
+#
+# struct MyType;
+#
+# impl Trait for MyType {}
+#
+# pub type Alias = impl Trait;
+#
+# #[define_opaque(Alias)]
+# pub fn new() -> Alias {
+#     MyType
+# }
+# }
+# use x::*;
+# pub fn take_alias(x: Alias) {
+#     // ...
+# }
+#
+# pub fn take_impl(x: impl Trait) {
+#    // ...
+# }
+#
+// a user's crate using the trait and type alias
+struct UserType;
+impl Trait for UserType {}
+
+# fn main(){
+let x = UserType;
+take_alias(x);
+// ERROR expected opaque type, found `UserType`
+// this function *actually* takes a `MyType` as is constrained in `new`
+
+let x = UserType;
+take_impl(x);
+// OK
+
+let x = new();
+take_alias(x);
+// OK
+
+let x = new();
+take_impl(x);
+// OK
+# }
+```
+
+Note that the user cannot use `#[define_opaque(Alias)]` to reify the opaque type because only the crate where the type alias is declared may do so. But if this happened in the same crate and the opaque type was reified, they'd get a familiar error: "expected `MyType`, got `UserType`".
+
+[#63063]: https://github.com/rust-lang/rust/issues/63063
+[#110237]: https://github.com/rust-lang/rust/pull/110237
+[reference]: https://doc.rust-lang.org/stable/reference/types/impl-trait.html#abstract-return-types
+[`trait_alias`]: ./trait-alias.md
+[`impl_trait_in_assoc_type`]: ./impl-trait-in-assoc-type.md
diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs
index e34b8a53b07..784d628805d 100644
--- a/src/librustdoc/doctest/runner.rs
+++ b/src/librustdoc/doctest/runner.rs
@@ -113,6 +113,7 @@ impl DocTestRunner {
 mod __doctest_mod {{
     use std::sync::OnceLock;
     use std::path::PathBuf;
+    use std::process::ExitCode;
 
     pub static BINARY_PATH: OnceLock<PathBuf> = OnceLock::new();
     pub const RUN_OPTION: &str = \"RUSTDOC_DOCTEST_RUN_NB_TEST\";
@@ -123,16 +124,17 @@ mod __doctest_mod {{
     }}
 
     #[allow(unused)]
-    pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> Result<(), String> {{
+    pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> ExitCode {{
         let out = std::process::Command::new(bin)
             .env(self::RUN_OPTION, test_nb.to_string())
             .args(std::env::args().skip(1).collect::<Vec<_>>())
             .output()
             .expect(\"failed to run command\");
         if !out.status.success() {{
-            Err(String::from_utf8_lossy(&out.stderr).to_string())
+            eprint!(\"{{}}\", String::from_utf8_lossy(&out.stderr));
+            ExitCode::FAILURE
         }} else {{
-            Ok(())
+            ExitCode::SUCCESS
         }}
     }}
 }}
diff --git a/tests/rustdoc-ui/doctest/edition-2024-error-output.rs b/tests/rustdoc-ui/doctest/edition-2024-error-output.rs
new file mode 100644
index 00000000000..82a85debcd1
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/edition-2024-error-output.rs
@@ -0,0 +1,14 @@
+// This is a regression test for <https://github.com/rust-lang/rust/issues/137970>.
+// The output must look nice and not like a `Debug` display of a `String`.
+
+//@ edition: 2024
+//@ compile-flags: --test
+//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout: "panicked at .+rs:" -> "panicked at $$TMP:"
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ rustc-env:RUST_BACKTRACE=0
+//@ failure-status: 101
+
+//! ```rust
+//! assert_eq!(2 + 2, 5);
+//! ```
diff --git a/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout b/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout
new file mode 100644
index 00000000000..8f056a5f703
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout
@@ -0,0 +1,20 @@
+
+running 1 test
+test $DIR/edition-2024-error-output.rs - (line 12) ... FAILED
+
+failures:
+
+---- $DIR/edition-2024-error-output.rs - (line 12) stdout ----
+
+thread 'main' panicked at $TMP:6:1:
+assertion `left == right` failed
+  left: 4
+ right: 5
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+
+
+failures:
+    $DIR/edition-2024-error-output.rs - (line 12)
+
+test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr
index 14c62fb4d25..624772f5aed 100644
--- a/tests/ui/consts/const-block-const-bound.stderr
+++ b/tests/ui/consts/const-block-const-bound.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `f`
   --> $DIR/const-block-const-bound.rs:6:15
    |
 LL | const fn f<T: ~const Destruct>(x: T) {}
-   |               ^^^^^^ required by this bound in `f`
+   |               ^^^^^^^^^^^^^^^ required by this bound in `f`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr
index 87bbd50a15c..6fd41a761e9 100644
--- a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr
+++ b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr
@@ -4,14 +4,14 @@ error[E0700]: hidden type for `Opaque(DefId(0:11 ~ impl_trait_captures[aeb9]::fo
 LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
    |                  --     ------------ opaque type defined here
    |                  |
-   |                  hidden type `&ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)) T` captures the anonymous lifetime defined here
+   |                  hidden type `&ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), LateNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)) T` captures the anonymous lifetime defined here
 LL |     x
    |     ^
    |
-help: add a `use<...>` bound to explicitly capture `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_))`
+help: add a `use<...>` bound to explicitly capture `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), LateNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_))`
    |
-LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + use<'a, ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)), T> {
-   |                                      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + use<'a, ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), LateNamed(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::'_), '_)), T> {
+   |                                      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/assoc-type.current.stderr b/tests/ui/traits/const-traits/assoc-type.current.stderr
index 4bf9acfbd65..7526369194b 100644
--- a/tests/ui/traits/const-traits/assoc-type.current.stderr
+++ b/tests/ui/traits/const-traits/assoc-type.current.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Foo::Bar`
   --> $DIR/assoc-type.rs:33:15
    |
 LL |     type Bar: ~const Add;
-   |               ^^^^^^ required by this bound in `Foo::Bar`
+   |               ^^^^^^^^^^ required by this bound in `Foo::Bar`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/assoc-type.next.stderr b/tests/ui/traits/const-traits/assoc-type.next.stderr
index 4bf9acfbd65..7526369194b 100644
--- a/tests/ui/traits/const-traits/assoc-type.next.stderr
+++ b/tests/ui/traits/const-traits/assoc-type.next.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Foo::Bar`
   --> $DIR/assoc-type.rs:33:15
    |
 LL |     type Bar: ~const Add;
-   |               ^^^^^^ required by this bound in `Foo::Bar`
+   |               ^^^^^^^^^^ required by this bound in `Foo::Bar`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
index 74a22186a16..11bbe8bbb40 100644
--- a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
+++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `equals_self`
   --> $DIR/call-generic-method-nonconst.rs:17:25
    |
 LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
-   |                         ^^^^^^ required by this bound in `equals_self`
+   |                         ^^^^^^^^^^ required by this bound in `equals_self`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
index 2b5e66b1a08..76207ea0939 100644
--- a/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr
@@ -8,14 +8,14 @@ note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `const
   --> $DIR/const-drop-fail-2.rs:25:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
-   |         ------          ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         --------        ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |         |
    |         unsatisfied trait bound introduced here
 note: required by a bound in `check`
   --> $DIR/const-drop-fail-2.rs:21:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
index 2b5e66b1a08..76207ea0939 100644
--- a/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr
@@ -8,14 +8,14 @@ note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `const
   --> $DIR/const-drop-fail-2.rs:25:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
-   |         ------          ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         --------        ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |         |
    |         unsatisfied trait bound introduced here
 note: required by a bound in `check`
   --> $DIR/const-drop-fail-2.rs:21:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr
index 682f48fe07a..f38e642bb63 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:35:5
@@ -26,7 +26,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr
index 682f48fe07a..f38e642bb63 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:35:5
@@ -26,7 +26,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr
index 682f48fe07a..f38e642bb63 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:35:5
@@ -26,7 +26,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr
index 682f48fe07a..f38e642bb63 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:35:5
@@ -26,7 +26,7 @@ note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:24:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^ required by this bound in `check`
+   |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/const-opaque.no.stderr b/tests/ui/traits/const-traits/const-opaque.no.stderr
index 1278e125746..47e692936e0 100644
--- a/tests/ui/traits/const-traits/const-opaque.no.stderr
+++ b/tests/ui/traits/const-traits/const-opaque.no.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `bar`
   --> $DIR/const-opaque.rs:26:17
    |
 LL | const fn bar<T: ~const Foo>(t: T) -> impl ~const Foo {
-   |                 ^^^^^^ required by this bound in `bar`
+   |                 ^^^^^^^^^^ required by this bound in `bar`
 
 error[E0277]: the trait bound `(): const Foo` is not satisfied
   --> $DIR/const-opaque.rs:33:12
diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr
index 8c284bde67e..b3017523b27 100644
--- a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `foo`
   --> $DIR/default-method-body-is-const-body-checking.rs:7:28
    |
 LL | const fn foo<T>() where T: ~const Tr {}
-   |                            ^^^^^^ required by this bound in `foo`
+   |                            ^^^^^^^^^ required by this bound in `foo`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr
index 0d53bc5897e..7e72dc9abaa 100644
--- a/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr
+++ b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Foo::Assoc`
   --> $DIR/item-bound-entailment-fails.rs:5:20
    |
 LL |     type Assoc<T>: ~const Bar
-   |                    ^^^^^^ required by this bound in `Foo::Assoc`
+   |                    ^^^^^^^^^^ required by this bound in `Foo::Assoc`
 
 error[E0277]: the trait bound `T: ~const Bar` is not satisfied
   --> $DIR/item-bound-entailment-fails.rs:24:21
@@ -20,12 +20,12 @@ note: required for `C<T>` to implement `~const Bar`
   --> $DIR/item-bound-entailment-fails.rs:14:15
    |
 LL | impl<T> const Bar for C<T> where T: ~const Bar {}
-   |               ^^^     ^^^^          ------ unsatisfied trait bound introduced here
+   |               ^^^     ^^^^          ---------- unsatisfied trait bound introduced here
 note: required by a bound in `Foo::Assoc`
   --> $DIR/item-bound-entailment-fails.rs:5:20
    |
 LL |     type Assoc<T>: ~const Bar
-   |                    ^^^^^^ required by this bound in `Foo::Assoc`
+   |                    ^^^^^^^^^^ required by this bound in `Foo::Assoc`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/minicore-fn-fail.stderr b/tests/ui/traits/const-traits/minicore-fn-fail.stderr
index fa8be631a26..03c7ade87c0 100644
--- a/tests/ui/traits/const-traits/minicore-fn-fail.stderr
+++ b/tests/ui/traits/const-traits/minicore-fn-fail.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `call_indirect`
   --> $DIR/minicore-fn-fail.rs:11:27
    |
 LL | const fn call_indirect<T: ~const Fn()>(t: &T) { t() }
-   |                           ^^^^^^ required by this bound in `call_indirect`
+   |                           ^^^^^^^^^^^ required by this bound in `call_indirect`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/const-traits/predicate-entailment-fails.stderr b/tests/ui/traits/const-traits/predicate-entailment-fails.stderr
index 369e95688a9..dfdc4d23250 100644
--- a/tests/ui/traits/const-traits/predicate-entailment-fails.stderr
+++ b/tests/ui/traits/const-traits/predicate-entailment-fails.stderr
@@ -5,7 +5,7 @@ LL |     type Bar<T> where T: ~const Bar;
    |     ----------- definition of `Bar` from trait
 ...
 LL |     type Bar<T> = () where T: const Bar;
-   |                               ^^^^^ impl has extra requirement `T: const Bar`
+   |                               ^^^^^^^^^ impl has extra requirement `T: const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:17:26
@@ -14,7 +14,7 @@ LL |     fn foo<T>() where T: ~const Bar;
    |     -------------------------------- definition of `foo` from trait
 ...
 LL |     fn foo<T>() where T: const Bar {}
-   |                          ^^^^^ impl has extra requirement `T: const Bar`
+   |                          ^^^^^^^^^ impl has extra requirement `T: const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:28:31
@@ -23,7 +23,7 @@ LL |     type Bar<T> where T: Bar;
    |     ----------- definition of `Bar` from trait
 ...
 LL |     type Bar<T> = () where T: const Bar;
-   |                               ^^^^^ impl has extra requirement `T: const Bar`
+   |                               ^^^^^^^^^ impl has extra requirement `T: const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:31:26
@@ -32,7 +32,7 @@ LL |     fn foo<T>() where T: Bar;
    |     ------------------------- definition of `foo` from trait
 ...
 LL |     fn foo<T>() where T: const Bar {}
-   |                          ^^^^^ impl has extra requirement `T: const Bar`
+   |                          ^^^^^^^^^ impl has extra requirement `T: const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:35:31
@@ -41,7 +41,7 @@ LL |     type Bar<T> where T: Bar;
    |     ----------- definition of `Bar` from trait
 ...
 LL |     type Bar<T> = () where T: ~const Bar;
-   |                               ^^^^^^ impl has extra requirement `T: ~const Bar`
+   |                               ^^^^^^^^^^ impl has extra requirement `T: ~const Bar`
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/predicate-entailment-fails.rs:38:26
@@ -50,7 +50,7 @@ LL |     fn foo<T>() where T: Bar;
    |     ------------------------- definition of `foo` from trait
 ...
 LL |     fn foo<T>() where T: ~const Bar {}
-   |                          ^^^^^^ impl has extra requirement `T: ~const Bar`
+   |                          ^^^^^^^^^^ impl has extra requirement `T: ~const Bar`
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.stderr b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
index 4100ae1c6bf..4ebd7b9757f 100644
--- a/tests/ui/traits/const-traits/trait-where-clause-const.stderr
+++ b/tests/ui/traits/const-traits/trait-where-clause-const.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Foo::b`
   --> $DIR/trait-where-clause-const.rs:15:24
    |
 LL |     fn b() where Self: ~const Bar;
-   |                        ^^^^^^ required by this bound in `Foo::b`
+   |                        ^^^^^^^^^^ required by this bound in `Foo::b`
 
 error[E0277]: the trait bound `T: ~const Bar` is not satisfied
   --> $DIR/trait-where-clause-const.rs:23:12
@@ -20,7 +20,7 @@ note: required by a bound in `Foo::c`
   --> $DIR/trait-where-clause-const.rs:16:13
    |
 LL |     fn c<T: ~const Bar>();
-   |             ^^^^^^ required by this bound in `Foo::c`
+   |             ^^^^^^^^^^ required by this bound in `Foo::c`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
index bda6a029cc2..be761e49ba0 100644
--- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
+++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr
@@ -28,7 +28,7 @@ note: required by a bound in `require`
   --> $DIR/unsatisfied-const-trait-bound.rs:8:15
    |
 LL | fn require<T: const Trait>() {}
-   |               ^^^^^ required by this bound in `require`
+   |               ^^^^^^^^^^^ required by this bound in `require`
 
 error: aborting due to 4 previous errors
 
diff --git a/triagebot.toml b/triagebot.toml
index 4abd164080b..c2a0ea3068f 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1278,11 +1278,13 @@ project-stable-mir = [
     "@oli-obk",
     "@scottmcm",
 ]
-
 project-exploit-mitigations = [
     "@cuviper",
     "@rcvalle",
 ]
+compiletest = [
+    "@jieyouxu",
+]
 
 [assign.owners]
 "/.github/workflows" =                                   ["infra-ci"]