Commit graph

2708 commits

Author SHA1 Message Date
bors
9f6cd6defb Auto merge of #151085 - Keith-Cancel:mgca2, r=BoxyUwU
Fix ICE: When Trying to check visibility of a #[type_const], check RHS instead.

This PR fixes https://github.com/rust-lang/rust/issues/150956 for min_const_generic_args https://github.com/rust-lang/rust/issues/132980. 

The first part of this PR checks in `reachable.rs` if we have a type const use `visit_const_item_rhs(init);` instead of calling `const_eval_poly_to_alloc()`

The second part is I noticed that if `const_eval_poly_to_alloc()` returns a `ErrorHandled::TooGeneric` then switches to `visit_const_item_rhs()`. So further up `const_eval_poly_to_alloc()` call order it eventual gets to `eval_in_interpreter()`. So I added a debug_assert in `eval_in_interpreter()` if we happen to try and run CTFE on a `type_const`.

The other bit is just a test case, and some duplicated code I noticed.

While the PR does get rid of the ICE for a type_const with `pub` visibility. If I try using the const though it will ICE with the following:
```
error: internal compiler error: /home/keith/GitHub/rust_kc/compiler/rustc_const_eval/src/check_consts/qualifs.rs:355:13: expected ConstKind::Param or ConstKind::Value here, found UnevaluatedConst { def: DefId(20:4 ~ colorkit[c783]::TYPE_CONST), args: [] }


thread 'rustc' (819687) panicked at /home/keith/GitHub/rust_kc/compiler/rustc_const_eval/src/check_consts/qualifs.rs:355:13:
```

I suspect it is a similar issue to inherent associated consts. Since if I apply the same fix I had here:
https://github.com/rust-lang/rust/pull/150799#discussion_r2676504639

I then can use the const  internally and in external crates without any issues.
Although, did not include that fix since if it is a similar issue it would need to be addressed elsewhere.

r? @BoxyUwU 
@rustbot label +F-associated_const_equality +F-min_generic_const_args
2026-01-17 09:45:42 +00:00
Keith-Cancel
4c93efae2b Fix ICE: When Trying to check visibility of a #[type_const], check RHS instead.
We want to evaluate the rhs of a type_const.

Also added an early return/guard in eval_in_interpreter which is used in functions like `eval_to_allocation_raw_provider`

Lastly add a debug assert to `thir_body()` if we have gotten there with a type_const something as gone wrong.

Get rid of a call to is_type_const() and instead use a match arm.

Change this is_type_const() check to a debug_assert!()

Change to use an if else statment instead.

Update type_const-pub.rs

Fix formatting.

Noticed that this is the same check as is_type_const() centralize it.

Add test case for pub type_const.
2026-01-16 20:30:58 -08:00
Jamie Hill-Daniel
c7031e93c5 feat: Support references in reflection type info 2026-01-17 00:25:29 +00:00
Matthias Krüger
225ba69ee2
Rollup merge of #151123 - type-info-primitives, r=oli-obk
Support primitives in type info reflection

Tracking issue: rust-lang/rust#146922 `#![feature(type_info)]`

This PR supports {`bool`,`char`,`int`,`uint`,`float`,`str`} primitive types for feature `type_info` reflection.

r? @oli-obk
2026-01-16 13:57:46 +01:00
Asuna
b2a7b18ec4 Merge type info variant Uint into Int 2026-01-15 23:04:40 +01:00
Asuna
5c057ad896 Remove their own TypeId from type info for primitives 2026-01-15 22:58:39 +01:00
Asuna
79ec275e2d Support primitives in type info reflection
Support {bool,char,int,uint,float,str} primitive types for feature
`type_info` reflection.
2026-01-14 19:15:39 +01:00
Jonathan Brouwer
db10879fd1
Rollup merge of #151096 - rm-providers-deref, r=oli-obk
Remove `Deref`/`DerefMut` impl for `Providers`.

It's described as a "backwards compatibility hack to keep the diff small". Removing it requires only a modest amount of churn, and the resulting code is clearer without the invisible derefs.

r? @oli-obk
2026-01-14 11:05:42 +01:00
Jonathan Brouwer
4e4bee8add
Rollup merge of #150406 - matches-let-chain, r=Kivooeo,oli-obk,BoxyUwU,fmease
Change some `matches!(.., .. if ..)` with let-chains

Follow up to rust-lang/rust#149933.
2026-01-14 11:05:37 +01:00
Nicholas Nethercote
3aa31788b5 Remove Deref/DerefMut impl for Providers.
It's described as a "backwards compatibility hack to keep the diff
small". Removing it requires only a modest amount of churn, and the
resulting code is clearer without the invisible derefs.
2026-01-14 15:55:59 +11:00
BD103
e027ecdbb5 feat: support arrays in type reflection 2026-01-13 12:18:57 -05:00
Esteban Küber
814647f047 Change some matches!(.., .. if ..) with let-chains 2026-01-13 17:13:22 +00:00
Nicholas Nethercote
2ae298711f Replace two BottomUpFolders with fold_regions.
Because these folders only change regions.

Note: `BottomUpFolder` folds all regions, while `fold_regions` skips
some bound regions. But that's ok because these two folders only modify
`ReVar`s.
2026-01-12 08:51:49 +11:00
Stuart Cook
e25d7a898a
Rollup merge of #150799 - mcga, r=BoxyUwU
Fix ICE: can't type-check body of DefId  for issue #148729

This commit fixes https://github.com/rust-lang/rust/issues/148729 for min_const_generic_args https://github.com/rust-lang/rust/issues/132980.

It's pretty small PR. The first commit makes sure that the `type_const`s are made into normal consts in const expressions.

The next one just handles the case https://github.com/rust-lang/rust/issues/148729 of where the type of the const was omitted at which point it was trying to treat a `type_const` again as a regular const. That obviously will fail since a type_const does not have a body.

@rustbot label +F-associated_const_equality +F-min_generic_const_args +I-ICE
2026-01-11 14:27:56 +11:00
Keith-Cancel
f982bc6a2d Fix ICE: can't type-check body of DefId, since type_consts don't have a body.
Handling for inherent associated consts is missing elsewhere, remove so it can be handled later in that handling.

Diagnostic not always be emitted on associated constant

Add a test case and Fix for a different ICE I encountered.

I noticed when trying various permuations of the test case code to see if I could find anymore ICEs. I did, but not one that I expected. So in the instances of the a named const not having any args, insantiate it directly. Since it is likely an inherent assocaiated const.

Added tests.

Centralize the is_type_const() logic.

I also noticed basically the exact same check in other part the code.

Const blocks can't be a type_const, therefore this check is uneeded.

Fix comment spelling error.

get_all_attrs is not valid to call for all DefIds it seems.

Make sure that if the type is omitted for a type_const that we don't ICE.

Co-Authored-By: Boxy <rust@boxyuwu.dev>
2026-01-09 14:45:33 -08:00
Oli Scherer
82028b0f9a Add size information 2026-01-08 12:02:59 +00:00
Oli Scherer
a3359bdd4f Compile-Time Reflection MVP: tuples 2026-01-08 11:41:00 +00:00
Jonathan Brouwer
d63068b3b4
Rollup merge of #150405 - estebank:matches-could-be-equals, r=Kivooeo
Don't use `matches!` when `==` suffices

In the codebase we sometimes use `matches!` for values that can actually just be compared. Replace them with `==`.

Subset of rust-lang/rust#149933.
2025-12-27 13:42:01 +01:00
Esteban Küber
9f566f2463 Don't use matches! when == suffices
In the codebase we sometimes use `matches!` for values that can actually just be compared. Replace them with `==`.
2025-12-26 20:28:19 +00:00
Boxy Uwu
6722805cdc Make ValTree recurse through ty::Const 2025-12-23 13:54:59 +00:00
bors
e1212ea79b Auto merge of #150187 - RalfJung:visitor-in-mem-order, r=nnethercote
interpreter/visitor: always iterate in in-memory order

Now that this is directly available in the type, there's no reason to ever iterate in any other order.
2025-12-22 13:52:39 +00:00
bors
000ccd651d Auto merge of #148766 - cjgillot:mir-const-runtime-checks, r=RalfJung,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.

Based on https://github.com/rust-lang/rust/pull/148151

This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.

These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.

This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
2025-12-22 06:58:28 +00:00
Matthias Krüger
ce3f9039d9
Rollup merge of #148991 - RalfJung:genmc-exit, r=oli-obk
miri genmc: fix exit() handling

In genmc mode, Miri does not want to stop execution when `exit` is called. Instead we want to continue running other threads to ensure we covered all possible concurrent behaviors (including the ones where the exiting thread was delayed so the other threads took their turns first). However, the core interpreter has a sanity check that prevents us from just doing nothing in `exit`. This leaves us in a pickle: there's nowhere we can jump to (exit has return type `!` so there's no next block), but if we don't jump anywhere we ICE.

The first commit fixes that by disabling the sanity check when there is no block to jump to. That still catches the mistake of forgetting to jump for the vast majority of shims.

We currently don't build Miri's genmc integration in rustc CI so I had to hack the feature into the bootstrap miri integration. That turned out to use the wrong Miri binary, which is fixed by the second commit: we can just rely on CARGO_BIN_EXE_miri, there's no need for a MIRI environment variable.

r? ``@oli-obk``
2025-12-20 13:46:00 +01:00
Ralf Jung
889ad15b62 interpreter/visitor: always iterate in in-memory order 2025-12-20 11:02:37 +01:00
Moulins
b31ee3af9c layout: Store inverse memory index in FieldsShape::Arbitrary
All usages of `memory_index` start by calling `invert_bijective_mapping`, so
storing the inverted mapping directly saves some work and simplifies the code.
2025-12-18 22:25:34 +01:00
Jonathan Brouwer
02c0e8f015
Rollup merge of #150063 - workingjubilee:remove-let-else-deny, r=Kivooeo
Remove deny of manual-let-else

During discussion on Zulip[^1], we found there was no strong consensus in favor of this in practice.

[^1]: https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/.60deny.28clippy.3A.3Amanual_let_else.29.60.20proliferation/with/564085588
2025-12-16 20:21:12 +01:00
Jonathan Brouwer
25b73c4943
Rollup merge of #150033 - izagawd:try_as_dyn, r=oli-obk
Add try_as_dyn and try_as_dyn_mut

Tracking issue: https://github.com/rust-lang/rust/issues/144361

Continuation of: https://github.com/rust-lang/rust/pull/144363
2025-12-16 20:21:10 +01:00
Jubilee Young
0004d8d421 Remove deny of manual-let-else 2025-12-16 08:42:04 -08:00
David Wood
a56b1b9283
codegen: implement repr(scalable)
Introduces `BackendRepr::ScalableVector` corresponding to scalable
vector types annotated with `repr(scalable)` which lowers to a scalable
vector type in LLVM.

Co-authored-by: Jamie Cunliffe <Jamie.Cunliffe@arm.com>
2025-12-16 11:00:12 +00:00
Ivar Flakstad
d5bf1a4c9a Introduce vtable_for intrinsic and use it to implement try_as_dyn and try_as_dyn_mut for fallible coercion from &T / &mut T to &dyn Trait. 2025-12-16 06:39:58 -04:00
Camille Gillot
fab64de727 Improve comments. 2025-12-14 17:25:53 +00:00
Camille Gillot
6319bee585 Introduce Operand::RuntimeChecks. 2025-12-14 17:25:53 +00:00
Camille Gillot
1a227bd47f Replace Rvalue::NullaryOp by a variant in mir::ConstValue. 2025-12-14 17:25:51 +00:00
bors
8188f6c808 Auto merge of #149709 - Urgau:overhaul-filenames, r=davidtwco
Overhaul filename handling for cross-compiler consistency

This PR overhauls the way we handle filenames in the compiler and `rmeta` in order to achieve achieve cross-compiler consistency (ie. having the same path no matter if the filename was created in the current compiler session or is coming from `rmeta`).

This is required as some parts of the compiler rely on consistent paths for the soundness of generated code (see rust-lang/rust#148328).

In order to achieved consistency multiple steps are being taken by this PR:
 - by making `RealFileName` immutable
 - by only having `SourceMap::to_real_filename` create `RealFileName`
   - currently `RealFileName` can be created from any `Path` and are remapped afterwards, which creates consistency issue
 - by also making `RealFileName` holds it's working directory, embeddable name and the remapped scopes
   - this removes the need for a `Session`, to know the current(!) scopes and cwd, which is invalid as they may not be equal to the scopes used when creating the filename

In order for `SourceMap::to_real_filename` to know which scopes to apply `FilePathMapping` now takes the current remapping scopes to apply, which makes `FileNameDisplayPreference` and company useless and are removed.

This PR is split-up in multiple commits (unfortunately not atomic), but should help review the changes.

Unblocks https://github.com/rust-lang/rust/pull/147611
Fixes https://github.com/rust-lang/rust/issues/148328
2025-12-13 14:32:09 +00:00
Esteban Küber
a49c175380 #![deny(clippy::manual_let_else)] in some rustc modules 2025-12-12 17:53:19 +00:00
Urgau
8cbfb26383 Overhaul filename handling for cross-compiler consistency
This commit refactors `SourceMap` and most importantly `RealFileName` to
make it self-contained in order to achieve cross-compiler consistency.

This is achieved:
 - by making `RealFileName` immutable
 - by only having `SourceMap::to_real_filename` create `RealFileName`
 - by also making `RealFileName` holds it's working directory,
   it's embeddable name and the remapped scopes
 - by making most `FileName` and `RealFileName` methods take a scope as
   an argument

In order for `SourceMap::to_real_filename` to know which scopes to apply
`FilePathMapping` now takes the current remapping scopes to apply, which
makes `FileNameDisplayPreference` and company useless and are removed.

The scopes type `RemapPathScopeComponents` was moved from
`rustc_session::config` to `rustc_span`.

The previous system for scoping the local/remapped filenames
`RemapFileNameExt::for_scope` is no longer useful as it's replaced by
methods on `FileName` and `RealFileName`.
2025-12-12 07:33:09 +01:00
Jacob Pratt
e5f552a02b
Rollup merge of #149592 - oli-obk:no_is_const_default_method_fn, r=fee1-dead
`is_const_default_method` is completely handled by the `constness` query

After  rust-lang/rust#149444 this function became obsolete

r? `@fee1-dead`
2025-12-05 23:26:37 -05:00
Matthias Krüger
a43b30c113
Rollup merge of #149671 - RalfJung:interpret-float-min-max, r=mati865
interpret: test SNaN handling of float min/max and update comments

Also see https://github.com/rust-lang/rust/pull/149563.

I also renamed these enum variants so they are not almost identical.
2025-12-05 16:17:13 +01:00
bors
97b131c900 Auto merge of #148602 - BoxyUwU:coercion_cleanup_uncontroversial, r=lcnr
misc coercion cleanups and handle safety correctly

r? lcnr

### "remove normalize call"

Fixes rust-lang/rust#132765

If the normalization fails we would sometimes get a `TypeError` containing inference variables created inside of the probe used by coercion. These would then get leaked out causing ICEs in diagnostics logic

### "leak check and lub for closure<->closure coerce-lubs of same defids"

Fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/233
```rust
fn peculiar() -> impl Fn(u8) -> u8 {
    return |x| x + 1
}
```
the `|x| x + 1` expr has a type of `Closure(?31t)` which we wind up inferring the RPIT to. The `CoerceMany` `ret_coercion` for the whole `peculiar` typeck has an expected type of `RPIT` (unnormalized). When we type check the `return |x| x + 1` expr we go from the never type to `Closure(?31t)` which then participates in the `ret_coercion` giving us a `coerce-lub(RPIT, Closure(?31t))`.

Normalizing `RPIT` gives us some `Closure(?50t)` where `?31t` and `?50t` have been unified with `?31t` as the root var. `resolve_vars_if_possible` doesn't resolve infer vars to their roots so these wind up with different structural identities so the fast path doesn't apply and we fall back to coercing to a `fn` ptr. cc rust-lang/rust#147193 which also fixes this

New solver probably just gets more inference variables here because canonicalization + generally different approach to normalization of opaques. Idk :3

### FCP worthy stuffy

there are some other FCP worthy things but they're in my FCP comment which also contains some analysis of the breaking nature of the previously listed changes in this PR: https://github.com/rust-lang/rust/pull/148602#issuecomment-3503497467
2025-12-05 11:46:41 +00:00
Ralf Jung
f040a1a915 interpret: test SNaN handling of float min/max and update comments 2025-12-05 08:53:42 +01:00
Boxy Uwu
76bd21ad66 account for safe target features in fndef<->closure and fndef<->fndef coerce-lubs 2025-12-03 14:55:41 +00:00
Oli Scherer
0ab78c1523 is_const_default_method is completely handled by the constness query 2025-12-03 12:38:24 +00:00
lcnr
02d84c8d23 generic normalization errors to TooGeneric 2025-12-01 13:00:22 +01:00
Matthias Krüger
9507d5c149
Rollup merge of #149444 - fee1-dead-contrib:push-lurmmylquwsq, r=oli-obk
collapse `constness` query `match` logic

We already have the HIR node data, so no need for asking `def_kind` again.

r? oli-obk
2025-11-30 12:03:23 +01:00
Deadbeef
cf91330b6b collapse constness query match logic
We already have the HIR node data, so no need for asking `def_kind` again.
2025-11-29 20:00:40 -05:00
Matthias Krüger
8e4c70f02b
Rollup merge of #148746 - RalfJung:mutable-ref-in-const, r=davidtwco
const validation: remove check for mutable refs in final value of const

This check rejects code that is not necessarily UB, e.g. a mutable ref to a `static mut` that is very carefully used correctly. That led to us having to describe it in the Reference, which uncovered just how ad-hoc this check is (https://github.com/rust-lang/reference/issues/2074).

Even without this check, we still reject things like
```rust
const C: &mut i32 = &mut 0;
```
This is rejected by const checking -- the part of the frontend that looks at the source code and says whether it is allowed in const context. In the Reference, this restriction is explained [here](https://doc.rust-lang.org/nightly/reference/const_eval.html#r-const-eval.const-expr.borrows).

So, the check during validation is just a safety net. And it is already a safety net with gaping holes since we only check `&mut T`, not `&UnsafeCell<T>`, due to the fact that we promote some immutable values that have `!Freeze` type so `&!Freeze` actually can occur in the final value of a const.

So... it may be time for me to acknowledge that the "mutable ref in final value of const" check is a cure that's worth than the disease. Nobody asked for that check, I just added it because I was worried about soundness issues when we allow mutable references in constants. Originally it was much stricter, but I had to slowly relax it to its current form to prevent t from firing on code we intend to allow. In the end there are only 3 tests left that trigger this error, and they are all just constants containing references to mutable statics -- not the safest code in the world, but also not so bad that we have to spend a lot of time devising a core language limitation and associated Reference wording to prevent it from ever happening.

So... `@rust-lang/wg-const-eval` `@rust-lang/lang`  I propose that we allow code like this
```rust
static mut S: i32 = 3;
const C2: &'static mut i32 = unsafe { &mut * &raw mut S };
```
`@theemathas` would be great if you could try to poke a hole into this. ;)
2025-11-29 20:54:05 +01:00
Ralf Jung
ee84ff9fe5 miri genmc: fix exit() handling 2025-11-29 16:58:03 +01:00
Stuart Cook
df6f24cc51
Rollup merge of #149239 - RalfJung:float-intrinsics, r=tgross35
clarify float min/max behavios for NaNs and signed zeros

The first comment is internal, it only documents the intrinsics to more clearly say what they do.
This makes the currently implemented semantics more explicit, so one does not have to go look for the publicly exposed version of the operation to figure out what exactly should happen.

The second commit adds a NaN test to the doc comment for `min`/`max`, which matches what we already have for `minimum`/`maximum`.
2025-11-27 12:36:52 +11:00
Ralf Jung
8b87b25c80 intrinsics: clarify float min/max behavios for NaNs and signed zeros 2025-11-24 08:21:19 +01:00
bors
e9acbd99d3 Auto merge of #147827 - saethlin:maybeuninit-codegen2, r=scottmcm
Fix MaybeUninit codegen using GVN

This is an alternative to https://github.com/rust-lang/rust/pull/142837, based on https://github.com/rust-lang/rust/pull/146355#discussion_r2421651968.

The general approach I took here is to aggressively propagate anything that is entirely uninitialized. GVN generally takes the approach of only synthesizing small types, but we need to generate large consts to fix the codegen issue.

I also added a special case to MIR dumps for this where now an entirely uninit const is printed as `const <uninit>`, because otherwise we end up with extremely verbose dumps of the new consts.

After GVN though, we still end up with a lot of MIR that looks like this:
```
StorageLive(_1);
_1 = const <uninit>;
_2 = &raw mut _1;
```
Which will break tests/codegen-llvm/maybeuninit-rvo.rs with the naive lowering. I think the ideal fix here is to somehow omit these `_1 = const <uninit>` assignments that come directly after a StorageLive, but I'm not sure how to do that. For now at least, ignoring such assignments (even if they don't come right after a StorageLive) in codegen seems to work.

Note that since GVN is based on synthesizing a `ConstValue`  which has a defined layout, this scenario still gets deoptimized by LLVM.
```rust
#![feature(rustc_attrs)]
#![crate_type = "lib"]
use std::mem::MaybeUninit;

#[unsafe(no_mangle)]
pub fn oof() -> [[MaybeUninit<u8>; 8]; 8] {
    #[rustc_no_mir_inline]
    pub fn inner<T: Copy>() -> [[MaybeUninit<T>; 8]; 8] {
        [[MaybeUninit::uninit(); 8]; 8]
    }

    inner()
}
```
This case can be handled correctly if enough inlining has happened, or it could be handled by post-mono GVN. Synthesizing `UnevaluatedConst` or some other special kind of const seems dubious.
2025-11-23 17:09:07 +00:00