Point at trait and associated item when that associated item is used in a const context. Suggest making the trait `#[const_trait]`.
```
error[E0015]: cannot call non-const method `<() as Trait>::foo` in constant functions
--> $DIR/inline-incorrect-early-bound-in-ctfe.rs:26:8
|
LL | ().foo();
| ^^^^^
|
note: method `foo` is not const because trait `Trait` is not const
--> $DIR/inline-incorrect-early-bound-in-ctfe.rs:13:1
|
LL | trait Trait {
| ^^^^^^^^^^^ this trait is not const
LL | fn foo(self);
| ------------- this method is not const
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
help: consider making trait `Trait` const
|
LL + #[const_trait]
LL | trait Trait {
|
```
Use `mut` less in dataflow analysis
`&mut Analysis` is used a lot:
- In results visitors, even though only one visitor needs mutability.
- In all the `apply_*` methods, even though only one visitor needs mutability.
I've lost track of the number of times I've thought "why are these `mut` again?" and had to look through the code to remind myself. It's really unexpected, and most `Analysis` instances are immutable, because the `state` values are what get mutated.
This commit introduces `RefCell` in one analysis and one results visitor. This then lets another existing `RefCell` be removed, and a ton of `&mut Analysis` arguments become `&Analysis`. And then `Analysis` and `Results` can be recombined.
r? `@cjgillot`
The `state: A::Domain` value is the primary things that's modified when
performing an analysis. The `Analysis` impl is immutable in every case
but one (`MaybeRequiredStorage`) and it now uses interior mutability.
As well as changing many `&mut A` arguments to `&A`, this also:
- lets `CowMut` be replaced with the simpler `SimpleCow` in `cursor.rs`;
- removes the need for the `RefCell` in `Formatter`;
- removes the need for `MaybeBorrowedLocals` to impl `Clone`, because
it's a unit type and it's now clear that its constructor can be used
directly instead of being put into a local variable and cloned.
Add a fast path for lowering trivial consts
The objective of this PR is to improve compilation performance for crates that define a lot of trivial consts. This is a flamegraph of a build of a library crate that is just 100,000 trivial consts, taken from a nightly compiler:
<img width="842" height="280" alt="2025-10-25-164005_842x280_scrot" src="https://github.com/user-attachments/assets/e5400aaf-03bd-4461-b905-054aa82ca60f" />
My objective is to target all of the cycles in `eval_to_const_value_raw` that are not part of `mir_built`, because if you look at the `mir_built` for a trivial const, we already have the value available.
In this PR, the definition of a trivial const is this:
```rust
const A: usize = 0;
```
Specifically, we look for if the `mir_built` body is a single basic block containing one assign statement and a return terminator, where the assign statement assigns an `Operand::Constant(Const::Val)`. The MIR dumps for these look like:
```
const A: usize = {
let mut _0: usize;
bb0: {
_0 = const 0_usize;
return;
}
}
```
The implementation is built around a new query, `trivial_const(LocalDefId) -> Option<(ConstValue, Ty)>` which returns the contents of the `Const::Val` in the `mir_built` if the `LocalDefId` is a trivial const.
Then I added _debug_ assertions to the beginning of `mir_for_ctfe` and `mir_promoted` to prevent trying to get the body of a trivial const, because that would defeat the optimization here. But these are deliberately _debug_ assertions because the consequence of failing the assertion is that compilation is slow, not corrupt. If we made these hard assertions, I'm sure there are obscure scenarios people will run into where the compiler would ICE instead of continuing on compilation, just a bit slower. I'd like to know about those, but I do not think serving up an ICE is worth it.
With the assertions in place, I just added logic around all the places they were hit, to skip over trying to analyze the bodies of trivial consts.
In the future, I'd like to see this work extended by:
* Pushing detection of trivial consts before MIR building
* Including DefKind::Static and DefKind::InlineConst
* Including consts like `_1 = const 0_usize; _0 = &_1`, which would make a lot of promoteds into trivial consts
* Handling less-trivial consts like `const A: usize = B`, which have `Operand::Constant(Const::Unevaluated)`
Validate CopyForDeref and DerefTemps better and remove them from runtime MIR
(split from my WIP rust-lang/rust#145344)
This PR:
- Removes `Rvalue::CopyForDeref` and `LocalInfo::DerefTemp` from runtime MIR
- Using a new mir pass `EraseDerefTemps`
- `CopyForDeref(x)` is turned into `Use(Copy(x))`
- `DerefTemp` is turned into `Boring`
- Not sure if this part is actually necessary, it made more sense in rust-lang/rust#145344 with `DerefTemp` storing actual data that I wanted to keep from having to be kept in sync with the rest of the body in runtime MIR
- Checks in validation that `CopyForDeref` and `DerefTemp` are only used together
- Removes special handling for `CopyForDeref` from many places
- Removes `CopyForDeref` from `custom_mir` reverting rust-lang/rust#111587
- In runtime MIR simple copies can be used instead
- In post cleanup analysis MIR it was already wrong to use due to the lack of support for creating `DerefTemp` locals
- Possibly this should be its own PR?
- Adds an argument to `deref_finder` to avoid creating new `DerefTemp`s and `CopyForDeref` in runtime MIR.
- Ideally we would just avoid making intermediate derefs instead of fixing it at the end of a pass / during shim building
- Removes some usages of `deref_finder` that I found out don't actually do anything
r? oli-obk
Prefer to use repeat_n over repeat().take()
More from https://github.com/rust-lang/rust/pull/147464, but batch processed with `ast-grep` to find and replace.
second commit add notes for library: affaf532f9
r? ``@RalfJung``
Port the implemention of SIMD intrinsics from Miri to const-eval
Ported the implementation of most SIMD intrinsics from Miri to rustc_const_eval. Remaining are
- Math functions (as per `@RalfJung's` suggestions)
- FMA (non-deterministic)
- Funnel Shifts (not implemented in Miri yet)
- Unordered reduction intrinsics (not implemented in Miri yet)
Turn ProjectionElem::Subtype into CastKind::Subtype
I noticed that drop elaboration can't, in general, handle `ProjectionElem::SubType`. It creates a disjoint move path that overlaps with other move paths. (`Subslice` does too, and I'm working on a different PR to make that special case less fragile.) If its skipped and treated as the same move path as its parent then `MovePath.place` has multiple possible projections. (It would probably make sense to remove all `Subtype` projections for the canonical place but it doesn't make sense to have this special case for a problem that doesn't actually occur in real MIR.)
The only reason this doesn't break is that `Subtype` is always the sole projection of the local its applied to. For the same reason, it works fine as a `CastKind` so I figured that makes more sense than documenting and validating this hidden invariant.
cc rust-lang/rust#112651, rust-lang/rust#133258
r? Icnr (bc you've been the main person dealing with `Subtype` it looks like)
Much of the compiler calls functions on Align projected from AbiAlign.
AbiAlign impls Deref to its inner Align, so we can simplify these away.
Also, it will minimize disruption when AbiAlign is removed.
For now, preserve usages that might resolve to PartialOrd or PartialEq,
as those have odd inference.
Clean up `ty::Dynamic`
1. As a follow-up to PR rust-lang/rust#143036, remove `DynKind` entirely.
2. Inside HIR ty lowering, consolidate modules `dyn_compatibility` and `lint` into `dyn_trait`
* `dyn_compatibility` wasn't about dyn compatibility itself, it's about lowering trait object types
* `lint` contained dyn-Trait-specific diagnostics+lints only
interpret: copy_provenance: avoid large intermediate buffer for large repeat counts
Copying provenance worked in this odd way where the "preparation" phase (which is supposed to just extract the necessary information from the source range) already did all the work of repeating the result N times for the target range. This was needed to use the existing `insert_presorted` function on `SortedMap`.
This PR generalizes `insert_presorted` so that we can avoid this odd structure on copy-provenance, and maybe even improve performance.
interpret: fix overlapping aggregate initialization
This fixes the problem pointed out by ````@saethlin```` in https://github.com/rust-lang/rust/issues/146383#issuecomment-3273224645.
Also clarify when exactly current de-facto MIR semantics allow overlap of the LHS and RHS in an assignment.