Removes the attribute from `MetaSized` and `PointeeSized`, with a special case in the trait solvers for `MetaSized`.
`dyn MetaSized` is a perfectly cromulent type, and seems to only have had #[rustc_do_not_implement_via_object] so the builtin object
candidate does not overlap with the builtin MetaSized impl that all `dyn` types get.
Resolves this with a special case by checking `is_sizedness_trait` where the trait solvers previously checked `implement_via_object`.
`dyn PointeeSized` alone is rejected for other reasons (since `dyn PointeeSized` is considered to have no principal trait because `PointeeSized`
is removed at an earlier stage of the compiler), but `(dyn PointeeSized + Send)` is valid and equivalent to `dyn Send`.
Add suggestions from code review
Update compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs and tests
Co-authored-by: lcnr <rust@lcnr.de>
These `TrivialClone` impls previously had `?Sized` bounds, which are
different from the `PointeeSized` bounds on the corresponding
`Clone` and `Copy` impls. So, I've changed the `?Sized` bounds into
`PointeeSized` bounds.
This mistake was made presumably because the `TrivialClone` PR
(https://github.com/rust-lang/rust/pull/135634) was opened in Jan 2025,
but merged in Nov 2025. During that time, the sized hierachy PR
(https://github.com/rust-lang/rust/pull/137944) was opened in Mar 2025,
and merged in Jun 2025. The `TrivialClone` PR was not updated to account
for the sized hierachy changes.
As core uses an extern type (`ptr::VTable`), the default `?Sized` to
`MetaSized` migration isn't sufficient, and some code that previously
accepted `VTable` needs relaxed to continue to accept extern types.
Similarly, the compiler uses many extern types in `rustc_codegen_llvm`
and in the `rustc_middle::ty::List` implementation (`OpaqueListContents`)
some bounds must be relaxed to continue to accept these types.
Unfortunately, due to the current inability to relax `Deref::Target`,
some of the bounds in the standard library are forced to be stricter than
they ideally would be.
core: Make `Debug` impl of raw pointers print metadata if present
Make Rust pointers appear less magic by including metadata information in their `Debug` output.
This does not break Rust stability guarantees because `Debug` impl are explicitly exempted from stability:
https://doc.rust-lang.org/std/fmt/trait.Debug.html#stability
> ## Stability
>
> Derived `Debug` formats are not stable, and so may change with future Rust versions. Additionally, `Debug` implementations of types provided by the standard library (`std`, `core`, `alloc`, etc.) are not stable, and may also change with future Rust versions.
Note that a regression test is added as a separate commit to make it clear what impact the last commit has on the output.
Closes#128684 because the output of that code now becomes:
```
thread 'main' panicked at src/main.rs:5:5:
assertion `left == right` failed
left: Pointer { addr: 0x7ffd45c6fc6b, metadata: 5 }
right: Pointer { addr: 0x7ffd45c6fc6b, metadata: 3 }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
Use `std::mem::{size_of, size_of_val, align_of, align_of_val}` from the
prelude instead of importing or qualifying them.
These functions were added to all preludes in Rust 1.80.
This commit splits the `#[rustc_deny_explicit_impl(implement_via_object = ...)]` attribute
into two attributes `#[rustc_deny_explicit_impl]` and `#[rustc_do_not_implement_via_object]`.
This allows us to have special traits that can have user-defined impls but do not have the
automatic trait impl for trait objects (`impl Trait for dyn Trait`).
Fundamentally, we have *three* disjoint categories of functions:
1. const-stable functions
2. private/unstable functions that are meant to be callable from const-stable functions
3. functions that can make use of unstable const features
This PR implements the following system:
- `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions.
- `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category.
- `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls.
Also, several holes in recursive const stability checking are being closed.
There's still one potential hole that is hard to avoid, which is when MIR
building automatically inserts calls to a particular function in stable
functions -- which happens in the panic machinery. Those need to *not* be
`rustc_const_unstable` (or manually get a `rustc_const_stable_indirect`) to be
sure they follow recursive const stability. But that's a fairly rare and special
case so IMO it's fine.
The net effect of this is that a `#[unstable]` or unmarked function can be
constified simply by marking it as `const fn`, and it will then be
const-callable from stable `const fn` and subject to recursive const stability
requirements. If it is publicly reachable (which implies it cannot be unmarked),
it will be const-unstable under the same feature gate. Only if the function ever
becomes `#[stable]` does it need a `#[rustc_const_unstable]` or
`#[rustc_const_stable]` marker to decide if this should also imply
const-stability.
Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to
use unstable const lang features (including intrinsics), or (b) `#[stable]`
functions that are not yet intended to be const-stable. Adding
`#[rustc_const_stable]` is only needed for functions that are actually meant to
be directly callable from stable const code. `#[rustc_const_stable_indirect]` is
used to mark intrinsics as const-callable and for `#[rustc_const_unstable]`
functions that are actually called from other, exposed-on-stable `const fn`. No
other attributes are required.
It's reasonable to want to, but in the current implementation this
causes multiple problems.
- All the `rmake.rs` files are formatted every time even when they
haven't changed. This is because they get whitelisted unconditionally
in the `OverrideBuilder`, before the changed files get added.
- The way `OverrideBuilder` works, if any files gets whitelisted then no
unmentioned files will get traversed. This is surprising, and means
that the `rmake.rs` entries broke the use of explicit paths to `x
fmt`, and also broke `GITHUB_ACTIONS=true git check --fmt`.
The commit removes the `rmake.rs` entries, fixes the formatting of a
couple of files that were misformatted (not previously caught due to the
`GITHUB_ACTIONS` breakage), and bans `!`-prefixed entries in
`rustfmt.toml` because they cause all these problems.