Inherent const impl
Some constifications are annoying because we need to repeat `T: Trait` bounds from an impl block on the individual constified `const fn`s as `T: [const] Trait`. We've brainstormed solutions before, and one would be to have separate `const impl` blocks or sth. However the final syntax will look, I decided to just impl this syntax and either have sth nice on nightly to work with or at least move the discussion along.
Also interacts with the discussion around `impl const Trait for Type` vs `const impl Trait for Type`, as we may want to use the latter to keep inherent and trait impls in sync (unless we come up with even another scheme).
* [ ] rustdoc + tests
* [ ] macro stability /regression tests
r? `@fee1-dead`
cc `@traviscross` `@rust-lang/project-const-traits`
Port `cfg_select!` to the new attribute parsing system
Best reviewed commit by commit, since it involves some moving around of code
r? `````@jdonszelmann`````
Implement `&pin` patterns and `ref pin` binding modes
Implement `&pin` patterns and `ref pin` binding modes, part of [pin ergonomics](https://github.com/rust-lang/rust/issues/130494).
r? `@Nadrieril`
cc `@traviscross` `@eholk`
stop specializing on `Copy`
fixes https://github.com/rust-lang/rust/issues/132442
`std` specializes on `Copy` to optimize certain library functions such as `clone_from_slice`. This is unsound, however, as the `Copy` implementation may not be always applicable because of lifetime bounds, which specialization does not take into account; the result being that values are copied even though they are not `Copy`. For instance, this code:
```rust
struct SometimesCopy<'a>(&'a Cell<bool>);
impl<'a> Clone for SometimesCopy<'a> {
fn clone(&self) -> Self {
self.0.set(true);
Self(self.0)
}
}
impl Copy for SometimesCopy<'static> {}
let clone_called = Cell::new(false);
// As SometimesCopy<'clone_called> is not 'static, this must run `clone`,
// setting the value to `true`.
let _ = [SometimesCopy(&clone_called)].clone();
assert!(clone_called.get());
```
should not panic, but does ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6be7a48cad849d8bd064491616fdb43c)).
To solve this, this PR introduces a new `unsafe` trait: `TrivialClone`. This trait may be implemented whenever the `Clone` implementation is equivalent to copying the value (so e.g. `fn clone(&self) -> Self { *self }`). Because of lifetime erasure, there is no way for the `Clone` implementation to observe lifetime bounds, meaning that even if the `TrivialClone` has stricter bounds than the `Clone` implementation, its invariant still holds. Therefore, it is sound to specialize on `TrivialClone`.
I've changed all `Copy` specializations in the standard library to specialize on `TrivialClone` instead. Unfortunately, the unsound `#[rustc_unsafe_specialization_marker]` attribute on `Copy` cannot be removed in this PR as `hashbrown` still depends on it. I'll make a PR updating `hashbrown` once this lands.
With `Copy` no longer being considered for specialization, this change alone would result in the standard library optimizations not being applied for user types unaware of `TrivialClone`. To avoid this and restore the optimizations in most cases, I have changed the expansion of `#[derive(Clone)]`: Currently, whenever both `Clone` and `Copy` are derived, the `clone` method performs a copy of the value. With this PR, the derive macro also adds a `TrivialClone` implementation to make this case observable using specialization. I anticipate that most users will use `#[derive(Clone, Copy)]` whenever both are applicable, so most users will still profit from the library optimizations.
Unfortunately, Hyrum's law applies to this PR: there are some popular crates which rely on the precise specialization behaviour of `core` to implement "specialization at home", e.g. [`libAFL`](89cff63702/libafl_bolts/src/tuples.rs (L27-L49)). I have no remorse for breaking such horrible code, but perhaps we should open other, better ways to satisfy their needs – for example by dropping the `'static` bound on `TypeId::of`...
mgca: Finish implementation of `#[type_const]`
tracking issue: rust-lang/rust#132980fixesrust-lang/rust#140729fixesrust-lang/rust#140860
- **Fix `#[type_const]` attribute placement validation**
- **Perform WF-checking on type_const RHS's**
- **Check type_const type is ConstParamTy_ and that RHS matches it**
- **Check that impls of `#[type_const]` consts also have the attr**
r? ```@BoxyUwU```
Remove `#[const_trait]`
Remove `#[const_trait]` since we now have `const trait`. Update all structured diagnostics that still suggested the attribute.
r? ```@rust-lang/project-const-traits```
mgca: Add ConstArg representation for const items
tracking issue: rust-lang/rust#132980fixesrust-lang/rust#131046fixesrust-lang/rust#134641
As part of implementing `min_generic_const_args`, we need to distinguish const items that can be used in the type system, such as in associated const equality projections, from const items containing arbitrary const code, which must be kept out of the type system. Specifically, all "type consts" must be either concrete (no generics) or generic with a trivial expression like `N` or a path to another type const item.
To syntactically distinguish these cases, we require, for now at least, that users annotate all type consts with the `#[type_const]` attribute. Then, we validate that the const's right-hand side is indeed eligible to be a type const and represent it differently in the HIR.
We accomplish this representation using a new `ConstItemRhs` enum in the HIR, and a similar but simpler enum in the AST. When `#[type_const]` is **not** applied to a const (e.g. on stable), we represent const item right-hand sides (rhs's) as HIR bodies, like before. However, when the attribute is applied, we instead lower to a `hir::ConstArg`. This syntactically distinguishes between trivial const args (paths) and arbitrary expressions, which are represented using `AnonConst`s. Then in `generics_of`, we can take advantage of the existing machinery to bar the `AnonConst` rhs's from using parent generics.
Add LLVM realtime sanitizer
This is a new attempt at adding the [LLVM real-time sanitizer](https://clang.llvm.org/docs/RealtimeSanitizer.html) to rust.
Previously this was attempted in https://github.com/rust-lang/rfcs/pull/3766.
Since then the `sanitize` attribute was introduced in https://github.com/rust-lang/rust/pull/142681 and it is a lot more flexible than the old `no_santize` attribute. This allows adding real-time sanitizer without the need for a new attribute, like it was proposed in the RFC. Because i only add a new value to a existing command line flag and to a attribute i don't think an MCP is necessary.
Currently real-time santizer is usable in rust code with the [rtsan-standalone](https://crates.io/crates/rtsan-standalone) crate. This downloads or builds the sanitizer runtime and then links it into the rust binary.
The first commit adds support for more detailed sanitizer information.
The second commit then actually adds real-time sanitizer.
The third adds a warning against using real-time sanitizer with async functions, cloures and blocks because it doesn't behave as expected when used with async functions. I am not sure if this is actually wanted, so i kept it in a seperate commit.
The fourth commit adds the documentation for real-time sanitizer.
This implements a new unstable compiler flag `-Zannotate-moves` that makes
move and copy operations visible in profilers by creating synthetic debug
information. This is achieved with zero runtime cost by manipulating debug
info scopes to make moves/copies appear as calls to `compiler_move<T, SIZE>`
and `compiler_copy<T, SIZE>` marker functions in profiling tools.
This allows developers to identify expensive move/copy operations in their
code using standard profiling tools, without requiring specialized tooling
or runtime instrumentation.
The implementation works at codegen time. When processing MIR operands
(`Operand::Move` and `Operand::Copy`), the codegen creates an `OperandRef`
with an optional `move_annotation` field containing an `Instance` of the
appropriate profiling marker function. When storing the operand,
`store_with_annotation()` wraps the store operation in a synthetic debug
scope that makes it appear inlined from the marker.
Two marker functions (`compiler_move` and `compiler_copy`) are defined
in `library/core/src/profiling.rs`. These are never actually called -
they exist solely as debug info anchors.
Operations are only annotated if the type:
- Meets the size threshold (default: 65 bytes, configurable via
`-Zannotate-moves=SIZE`)
- Has a non-scalar backend representation (scalars use registers,
not memcpy)
This has a very small size impact on object file size. With the default
limit it's well under 0.1%, and even with a very small limit of 8 bytes
it's still ~1.5%. This could be enabled by default.
Stabilize `fmt::from_fn`
Resolvesrust-lang/rust#146705, pending its FCP.
As discussed in that tracking issue and rust-lang/rust#117729, this splits `fmt::from_fn` out from the `debug_closure_helpers` feature.
Implement pin-project in pattern matching for `&pin mut|const T`
This PR implements part of rust-lang/rust#130494. It supports pin-project in pattern matching for `&pin mut|const T`.
~Pin-projection by field access (i.e. `&pin mut|const place.field`) is not fully supported yet since pinned-borrow is not ready (rust-lang/rust#135731).~
CC ``````@traviscross``````
Constify trait aliases
Allow `const trait Foo = Bar + [const] Baz;` trait alias declarations. Their rules are the same as with super traits of const traits. So `[const] Baz` or `const Baz` is only required for `[const] Foo` or `const Foo` bounds respectively.
tracking issue rust-lang/rust#41517 (part of the general trait alias feature gate, but I can split it out into a separate const trait alias feature gate. I just assumed that const traits would stabilize before trait aliases, and we'd want to stabilize trait aliases together with const trait aliases at the same time)
r? ``@compiler-errors`` ``@fee1-dead``
Mark desugared range expression spans with DesugaringKind::RangeExpr
This is a prerequisite to removing `QPath::LangItem` (rust-lang/rust#115178) because otherwise there would be no way to detect a range expression in the HIR.
There are some non-obvious Clippy changes so a Clippy team review would be good.
Clairify docs for `AttributeKind::DocComment`
Makes it clear that this represents `#[doc = "content"]`, but not `#[doc(hidden)]` (or other uses of the `#[doc(...)]` attribute).
r? `@jdonszelmann`