Use `HashStable` derive in more places
This applies `HashStable` derive in a couple more places. Also `stable_hasher` is declared for `HashStable_NoContext`.
rustc_expand: improve diagnostics for non-repeatable metavars in repetition
Enhance `NoSyntaxVarsExprRepeat` by suggesting similarly named metavariables, distinguishing repeatable vs non-repeatable bindings, and listing available repeatable variables when no match exists.
Reflection TypeKind::FnPtr
This is for https://github.com/rust-lang/rust/issues/146922.
Const-eval currently lacks full support for function pointer (fn) types. We should implement handling of FnPtr TypeKind, covering safe and unsafe functions, Rust and custom ABIs, input and output types, higher-ranked lifetimes, and variadic functions.
- Implement handling of FnPtr TypeKind in const-eval, including:
- Unsafety flag (safe vs unsafe fn)
- ABI variants (Rust, Named(C), Named(custom))
- Input and output types
- Variadic function pointers
- Add const-eval tests covering:
- Basic Rust fn() pointers
- Unsafe fn() pointers
- Extern C and custom ABI pointers
- Functions with multiple inputs and output types
- Variadic functions
- Use const TypeId checks to verify correctness of inputs, outputs, and payloads
Enhance `NoSyntaxVarsExprRepeat` by suggesting similarly named
metavariables, distinguishing repeatable vs non-repeatable bindings,
and listing available repeatable variables when no match exists.
Co-authored-by: Esteban Küber <esteban@kuber.com.ar>
Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Implement RFC 3678: Final trait methods
Tracking: https://github.com/rust-lang/rust/issues/131179
This PR is based on rust-lang/rust#130802, with some minor changes and conflict resolution.
Futhermore, this PR excludes final methods from the vtable of a dyn Trait.
And some excerpt from the original PR description:
> Implements the surface part of https://github.com/rust-lang/rfcs/pull/3678.
>
> I'm using the word "method" in the title, but in the diagnostics and the feature gate I used "associated function", since that's more accurate.
cc @joshtriplett
replace box_new with lower-level intrinsics
The `box_new` intrinsic is super special: during THIR construction it turns into an `ExprKind::Box` (formerly known as the `box` keyword), which then during MIR building turns into a special instruction sequence that invokes the exchange_malloc lang item (which has a name from a different time) and a special MIR statement to represent a shallowly-initialized `Box` (which raises [interesting opsem questions](https://github.com/rust-lang/rust/issues/97270)).
This PR is the n-th attempt to get rid of `box_new`. That's non-trivial because it usually causes a perf regression: replacing `box_new` by naive unsafe code will incur extra copies in debug builds, making the resulting binaries a lot slower, and will generate a lot more MIR, making compilation measurably slower. Furthermore, `vec!` is a macro, so the exact code it expands to is highly relevant for borrow checking, type inference, and temporary scopes.
To avoid those problems, this PR does its best to make the MIR almost exactly the same as what it was before. `box_new` is used in two places, `Box::new` and `vec!`:
- For `Box::new` that is fairly easy: the `move_by_value` intrinsic is basically all we need. However, to avoid the extra copy that would usually be generated for the argument of a function call, we need to special-case this intrinsic during MIR building. That's what the first commit does.
- `vec!` is a lot more tricky. As a macro, its details leak to stable code, so almost every variant I tried broke either type inference or the lifetimes of temporaries in some ui test or ended up accepting unsound code due to the borrow checker not enforcing all the constraints I hoped it would enforce. I ended up with a variant that involves a new intrinsic, `fn write_box_via_move<T>(b: Box<MaybeUninit<T>>, x: T) -> Box<MaybeUninit<T>>`, that writes a value into a `Box<MaybeUninit<T>>` and returns that box again. In exchange we can get rid of somewhat similar code in the lowering for `ExprKind::Box`, and the `exchange_malloc` lang item. (We can also get rid of `Rvalue::ShallowInitBox`; I didn't include that in this PR -- I think @cjgillot has a commit for this somewhere [around here](https://github.com/rust-lang/rust/pull/147862/commits).)
See [here](https://github.com/rust-lang/rust/pull/148190#issuecomment-3457454814) for the latest perf numbers. Most of the regressions are in deep-vector which consists entirely of an invocation of `vec!`, so any change to that macro affects this benchmark disproportionally.
This is my first time even looking at MIR building code, so I am very low confidence in that part of the patch, in particular when it comes to scopes and drops and things like that.
I also had do nerf some clippy tests because clippy gets confused by the new expansion of `vec!` so it makes fewer suggestions when `vec!` is involved.
### `vec!` FAQ
- Why does `write_box_via_move` return the `Box` again? Because we need to expand `vec!` to a bunch of method invocations without any blocks or let-statements, or else the temporary scopes (and type inference) don't work out.
- Why is `box_assume_init_into_vec_unsafe` (unsoundly!) a safe function? Because we can't use an unsafe block in `vec!` as that would necessarily also include the `$x` (due to it all being one big method invocation) and therefore interpret the user's code as being inside `unsafe`, which would be bad (and 10 years later, we still don't have safe blocks for macros like this).
- Why does `write_box_via_move` use `Box` as input/output type, and not, say, raw pointers? Because that is the only way to get the correct behavior when `$x` panics or has control effects: we need the `Box` to be dropped in that case. (As a nice side-effect this also makes the intrinsic safe, which is imported as explained in the previous bullet.)
- Can't we make it safe by having `write_box_via_move` return `Box<T>`? Yes we could, but there's no easy way for the intrinsic to convert its `Box<MaybeUninit<T>>` to a `Box<T>`. Transmuting would be unsound as the borrow checker would no longer properly enforce that lifetimes involved in a `vec!` invocation behave correctly.
- Is this macro truly cursed? Yes, yes it is.
support c-variadic functions in `rustc_const_eval`
tracking issue: https://github.com/rust-lang/rust/issues/44930
The new `GlobalAlloc::VaList` is used to create an `AllocId` that represents the variable argument list of a frame. The allocation itself does not store any data, all we need is the unique identifier.
The actual variable argument list is stored in `Memory`, and keyed by the `AllocId`. The `Frame` also stores this `AllocId`, so that when a frame is popped, it can deallocate the variable arguments.
At "runtime" a `VaList` value stores a pointer to the global allocation in its first bytes. The provenance on this pointer can be used to retrieve its `AllocId`, and the offset of the pointer is used to store the index of the next argument to read from the variable argument list.
Miri does not yet support `va_arg`, but I think that can be done separetely?
r? @RalfJung
cc @workingjubilee
Pass alignments through the shim as `Alignment` (not `usize`)
We're using `Layout` on both sides, so might as well skip the transmutes back and forth to `usize`.
The mir-opt test shows that doing so allows simplifying the boxed-slice drop slightly, for example.
We're using `Layout` on both sides, so might as well skip the transmutes back and forth to `usize`.
The mir-opt test shows that doing so allows simplifying the boxed-slice drop slightly, for example.
Support ADT types in type info reflection
Tracking issue: rust-lang/rust#146922 `#![feature(type_info)]`
This PR supports ADT types for feature `type_info` reflection.
(It's still a draft PR, with implementation in progress)
Note that this PR does not take SemVer into consideration (I left a FIXME comment). As discussed earlier ([comment](https://github.com/rust-lang/rust/pull/146923#discussion_r2372249477)), this requires further discussion. However, I hope we could get an initial implementation to land first, so we can start playing with it.
### Progress / Checklist
- [x] Struct support.
- [x] Enum
- [x] Union
- [x] Generics
- [ ] ~Methods~ Implemented and to be implemented in other PRs
- [ ] ~Traits~ Implemented and to be implemented in other PRs
- [x] Rebasing PR to `main` branch
~~(It's currently based on PR rust-lang/rust#151123, so here's an extra commit)~~
- [x] Cleanup and Rebase.
- [x] Fix field info for references. (see [comment](https://github.com/rust-lang/rust/pull/151142#discussion_r2777920512))
r? @oli-obk
Remove `SubdiagMessage` in favour of the identical `DiagMessage`
For https://github.com/rust-lang/rust/issues/151366
Just some more cleanup :)
SubdiagMessage is now identical to DiagMessage, so there's no point in having both of them
Revert, but without type const.
Update symbol for feature err, then update suggestion output, and lastly update tests that change because of those.
Update these new tests with the correct syntax, and few existing tests with the new outputs the merge with main added.
Fix for tidyfmt and some errors when manually resolving a merge conflicts.
Update these tests to use update error messages and type const syntax.
Update comments and error message to use new syntax instead of old type_const attribute.
Remove the type_const attribute
update some more tests to use the new syntax.
Update these test cases.
update feature gate test
Change gate logic for `mgca_type_const_syntax` to work also if `min_generic_const_args` is enabled.
Create a new feature gate that checks for the feature before expansion.
Make rustfmt handle the `type const` syntax correctly.
Add a convience method to check if a RhsKind is type const.
Rename `Const` discriminant to `Body` for `ConstItemRhsKind`
Give the `TraitItemKind` flag an enum instead of a simple bool to better describe what the flag is for.
Update formatting for these match statements.
Update clippy test to use type const syntax.
Update test to use type const syntax.
update rustfmt to match ast items.
Update clippy to match ast and hir items.
Few more test cases that used old attribute, instead of 'type const'
Update to match the output from the feature gate checks.
tidyfmt adjustments.
Update the is_type_const, so I can constrain record!(..) in encoder.rs
Update conditional compilation test.
Move the feature gate to after expansion to allow for cfg(...) to work.
Update some more tests to use the new syntax.
Update type const tests in associated-const-bindings to use new syntax.
Don't check based off the attribute, but the item here.
Update some tests outside of the const_generics folder that were using #[type_const]
update the tests in associated consts that use #[type_const] to use type const
Update these mgca tests with the type const syntax.
Add a flag to TraitItemKind for detecting type const for now. Maybe later change ItemConstRhs to have optional consts but that touches a lot more lines of code.
Don't need into for these now that it's a query.
Add is_type_const query to handle foreign def ids.
update this test to use type const syntax.
Fix logic here, we only want to lower if there is expression in this case.
Update built-in macros to use ConstItemRhsKind
Update more instance of the old ConstItemRhs.
Rename ConstItemKind to ConstItemRhsKind, I noticed there is a typed called ConstantItemKind, so add the Rhs to the name to avoid confusion.
Update lower to use ConstItemKind
Add an other helper method to check if the rhs kinda has an expr.
Update item parse to use ConstItemKind enum.
Felt the field name could a be little clear when editing a few other things.
Change the ConstItem struct see know if we have a type const or regular const.
Make sure this syntax is properly feature gated.
Implement MVP for opaque generic const arguments
This is meant to be the interim successor to generic const expressions.
Essentially, const item RHS's will be allowed to do arbitrary const
operations using generics. The limitation is that these const items will
be treated opaquely, like ADTs in nominal typing, such that uses of them
will only be equal if the same const item is referenced. In other words,
two const items with the exact same RHS will not be considered equal.
I also added some logic to check feature gates that depend on others
being enabled (like oGCA depending on mGCA).
### Coherence
During coherence, OGCA consts should be normalized ambiguously because
they are opaque but eventually resolved to a real value. We don't want
two OGCAs that have the same value to be treated as distinct for
coherence purposes. (Just like opaque types.)
This actually doesn't work yet because there are pre-existing
fundamental issues with equate relations involving consts that need to
be normalized. The problem is that we normalize only one layer of the
const item and don't actually process the resulting anon const. Normally
the created inference variable should be handled, which in this case
would cause us to hit the anon const, but that's not happening.
Specifically, `visit_const` on `Generalizer` should be updated to be
similar to `visit_ty`.
r? @BoxyUwU
Streamline `rustc_span::HashStableContext`.
Currently this trait has five methods. But it only really needs three.
For example, currently stable hashing of spans is implemented in `rustc_span`, except a couple of sub-operations are delegated to `rustc_query_system`: `def_span` and `span_data_to_lines_and_cols`. These two delegated sub-operations can be reduced to a single delegated operation that does the full hash computation.
Likewise, `assert_default_hashing_controls` depends on two delegated sub-operations, `hashing_controls` and
`unstable_opts_incremental_ignore_spans`, and can be simplified.
I find the resulting code simpler and clearer -- when necessary, we do a whole operation in `rustc_query_system` instead of doing it partly in `rustc_span` and partly in `rustc_query_system`.
r? @cjgillot
Fix `SourceFile::normalized_byte_pos`
This method was broken by 258ace6, which changed `self.normalized_pos` to use relative offsets however this method continued to compare against an absolute offset.
Also adds a regression test for the issue that this method was originally introduced to fix.
Closesrust-lang/rust#149568
Fixes regression of rust-lang/rust#110885
r? cjgillot (as author of the breaking commit)
This is meant to be the interim successor to generic const expressions.
Essentially, const item RHS's will be allowed to do arbitrary const
operations using generics. The limitation is that these const items will
be treated opaquely, like ADTs in nominal typing, such that uses of them
will only be equal if the same const item is referenced. In other words,
two const items with the exact same RHS will not be considered equal.
I also added some logic to check feature gates that depend on others
being enabled (like oGCA depending on mGCA).
= Coherence =
During coherence, OGCA consts should be normalized ambiguously because
they are opaque but eventually resolved to a real value. We don't want
two OGCAs that have the same value to be treated as distinct for
coherence purposes. (Just like opaque types.)
This actually doesn't work yet because there are pre-existing
fundamental issues with equate relations involving consts that need to
be normalized. The problem is that we normalize only one layer of the
const item and don't actually process the resulting anon const. Normally
the created inference variable should be handled, which in this case
would cause us to hit the anon const, but that's not happening.
Specifically, `visit_const` on `Generalizer` should be updated to be
similar to `visit_ty`.
Currently this trait has five methods. But it only really needs three.
For example, currently stable hashing of spans is implemented in
`rustc_span`, except a couple of sub-operations are delegated to
`rustc_query_system`: `def_span` and `span_data_to_lines_and_cols`.
These two delegated sub-operations can be reduced to a single delegated
operation that does the full hash computation.
Likewise, `assert_default_hashing_controls` depends on two delegated
sub-operations, `hashing_controls` and
`unstable_opts_incremental_ignore_spans`, and can be simplified.
I find the resulting code simpler and clearer -- when necessary, we do a
whole operation in `rustc_query_system` instead of doing it partly in
`rustc_span` and partly in `rustc_query_system`.
Add avr_target_feature
This adds the following unstable target features (tracking issue: https://github.com/rust-lang/rust/issues/146889):
- The following two are particularly important for properly supporting inline assembly:
- `tinyencoding`: AVR has devices that reduce the number of registers, similar to RISC-V's RV32E. This feature is necessary to support inline assembly in such devices. (see also https://github.com/rust-lang/rust/pull/146901)
- `lowbytefirst`: AVR's memory access is per 8-bit, and when writing 16-bit ports, the bytes must be written in a specific order. This order depends on devices, making this feature necessary to write proper inline assembly for such use cases. (see also https://github.com/llvm/llvm-project/commit/2a528760bf20004066effcf8f91fedaabd261903)
- The followings help recognizing whether specific instructions are available:
- `addsubiw`
- `break`
- `eijmpcall`
- `elpm`
- `elpmx`
- `ijmpcall`
- `jmpcall`
- `lpm`
- `lpmx`
- `movw`
- `mul`
- `rmw`
- `spm`
- `spmx`
Of these, all except `addsubiw`, `break`, `ijmpcall`, `lpm`, `rmw`, `spm`, and `spmx` have [corresponding conditional codes in avr-libc](https://github.com/search?q=repo%3Aavrdudes%2Favr-libc+%2F__AVR_HAVE_%2F&type=code&p=1). LLVM also has `des` feature, but I excluded it from this PR because [DES](https://en.wikipedia.org/wiki/Data_Encryption_Standard) is insecure.
- Report future-incompatible warning (https://github.com/rust-lang/rust/issues/116344) for -C target-feature=-sram and -C target-cpu=<device_without_sram> cases because SRAM is minimum requirement for non-assembly language in both avr-gcc and LLVM.
- See https://github.com/rust-lang/rust/pull/146900#issuecomment-3323558005 for details.
LLVM also has `smallstack`, `wrappingrjmp`, and `memmappedregs` features, but I skipped them because they didn't seem to belong to either of the above categories, but I might have missed something.
(The feature names are match with [definitions in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-21.1.0/llvm/lib/Target/AVR/AVRDevices.td).)
cc @Patryk27 @Rahix
r? workingjubilee
@rustbot label +O-AVR +A-target-feature
Calling `match` on a struct is a really weird thing to do. As the name
suggests, it's an assert, so let's write it as one. Also clarify the
comment a little.
Port depgraph testing attributes to parser
Tracking issue: rust-lang/rust#131229
Ports `#[rustc_clean]`, `#[rustc_if_this_changed]` and `#[rustc_then_this_would_need]` attributes.
Removes references to `rustc_dirty` as that attribute was folded into `rustc_clean` some time ago and rename some code accordingly.
r? JonathanBrouwer
Rename trait `DepNodeParams` to `DepNodeKey`
In query system plumbing, we usually refer to a query's explicit argument value as a “key”.
The first few commits do some preliminary cleanup that would conflict with the rename; the rename itself is in the final commit.
r? nnethercote (or compiler)