Add a `documentation` remapping path scope for rustdoc usage
This PR adds a new remapping path scope for rustdoc usage: `documentation`, instead of rustdoc abusing the other scopes for it's usage.
Like remapping paths in rustdoc, this scope is unstable. (rustdoc doesn't even have yet an equivalent to [rustc `--remap-path-scope`](https://doc.rust-lang.org/nightly/rustc/remap-source-paths.html#--remap-path-scope)).
I also took the opportunity to add a bit of documentation in rustdoc book.
refactor rustc-hash integration
I found that rustc-hash is used in multiple compiler crates. Also some types use `FxBuildHasher` whereas others use `BuildHasherDefault<FxHasher>` (both do the same thing).
In order to simplify future hashing experiments, I changed every location to use `rustc_data_structures::fx::*` types instead, and also removed the `BuildHasherDefault` variant. This will simplify future experiments with hashing (for example trying out a hasher that doesn't implement `Default` for whatever reason).
Fix suppression of `unused_assignment` in binding of `unused_variable`
Unused assignments to an unused variable should trigger only the `unused_variables` lint and not also the `unused_assignments` lint. This was previously implemented by checking whether the span of the assignee was within the span of the binding pattern, however that failed to capture situations was imported from elsewhere (eg from the input tokenstream of a proc-macro that generates the binding pattern).
By comparing the span of the assignee to those of the variable introductions instead, a reported stable-to-stable regression is resolved.
This fix also impacted some other preexisting tests, which had (undesirably) been triggering both the `unused_variables` and `unused_assignments` lints on the same initializing assignment; those tests have therefore now been updated to expect only the former lint.
Fixesrust-lang/rust#151514
r? cjgillot (as author of reworked liveness testing in rust-lang/rust#142390)
Rename `DepKindStruct` to `DepKindVTable`
This type is used by dependency-tracking code in the query system, for looking up function pointers and other metadata associated with a particular `DepKind`.
Calling it “struct” is not particularly helpful, whereas calling it a “vtable” at least gives some basic intuition for what it is and how it is used.
Some associated identifiers have also drifted a bit over time, and this PR adjusts those as well.
There should be no change to compiler behaviour.
r? nnethercote (or compiler)
x86 soft-float feature: mark it as forbidden rather than unstable
I am not sure why I made it "unstable" in f755f4cd1a; I think at the time "forbidden" did not work for some reason.
Making it "forbidden" instead has no significant effect on `-Ctarget-feature` use, it just changes the warning. It *does* have the effect that one cannot query this using `cfg(target_feature)` on nightly any more, but that seems fine to me. It only ever worked as an accidental side-effect of f755f4cd1a anyway.
r? @workingjubilee
Various refactors to the proc_macro bridge
This reduces the amount of types, traits and other abstractions that are involved with the bridge, which should make it easier to understand and modify. This should also help a bit with getting rid of the type marking hack, which is complicating the code a fair bit.
Fixes: rust-lang/rust#139810
abi: add a rust-preserve-none calling convention
This is the conceptual opposite of the rust-cold calling convention and is particularly useful in combination with the new `explicit_tail_calls` feature.
For relatively tight loops implemented with tail calling (`become`) each of the function with the regular calling convention is still responsible for restoring the initial value of the preserved registers. So it is not unusual to end up with a situation where each step in the tail call loop is spilling and reloading registers, along the lines of:
foo:
push r12
; do things
pop r12
jmp next_step
This adds up quickly, especially when most of the clobberable registers are already used to pass arguments or other uses.
I was thinking of making the name of this ABI a little less LLVM-derived and more like a conceptual inverse of `rust-cold`, but could not come with a great name (`rust-cold` is itself not a great name: cold in what context? from which perspective? is it supposed to mean that the function is rarely called?)
add `simd_splat` intrinsic
Add `simd_splat` which lowers to the LLVM canonical splat sequence.
```llvm
insertelement <N x elem> poison, elem %x, i32 0
shufflevector <N x elem> v0, <N x elem> poison, <N x i32> zeroinitializer
```
Right now we try to fake it using one of
```rust
fn splat(x: u32) -> u32x8 {
u32x8::from_array([x; 8])
}
```
or (in `stdarch`)
```rust
fn splat(value: $elem_type) -> $name {
#[derive(Copy, Clone)]
#[repr(simd)]
struct JustOne([$elem_type; 1]);
let one = JustOne([value]);
// SAFETY: 0 is always in-bounds because we're shuffling
// a simd type with exactly one element.
unsafe { simd_shuffle!(one, one, [0; $len]) }
}
```
Both of these can confuse the LLVM optimizer, producing sub-par code. Some examples:
- https://github.com/rust-lang/rust/issues/60637
- https://github.com/rust-lang/rust/issues/137407
- https://github.com/rust-lang/rust/issues/122623
- https://github.com/rust-lang/rust/issues/97804
---
As far as I can tell there is no way to provide a fallback implementation for this intrinsic, because there is no `const` way of evaluating the number of elements (there might be issues beyond that, too). So, I added implementations for all 4 backends.
Both GCC and const-eval appear to have some issues with simd vectors containing pointers. I have a workaround for GCC, but haven't yet been able to make const-eval work. See the comments below.
Currently this just adds the intrinsic, it does not actually use it anywhere yet.
Add new Tier 3 targets for ARMv6
Adds three new targets to support ARMv6 processors running bare-metal:
* `armv6-none-eabi` - Arm ISA, soft-float
* `armv6-none-eabihf` - Arm ISA, hard-float
* `thumbv6-none-eabi` - Thumb-1 ISA, soft-float
There is no `thumbv6-none-eabihf` target because as far as I can tell, hard-float isn't support with the Thumb-1 instruction set (and you need the ARMv6T2 extension to enable Thumb-2 support).
The targets require ARMv6K as a minimum, which allows the two Arm ISA targets to have full CAS atomics. LLVM has a bug which means it emits some ARMv6K instructions even if you only call for ARMv6, and as no-one else has noticed the bug, and because basically all ARMv6 processors have ARMv6K, I think this is fine. The Thumb target also doesn't have any kind of atomics, just like the Armv5TE and Armv4 targets, because LLVM was emitting library calls to emulate them.
Testing will be added to https://github.com/rust-embedded/aarch32 once the target is accepted. I already have tests for the other non-M arm-none-eabi targets, and those tests pass on these targets.
> A tier 3 target must have a designated developer or developers (the "target maintainers") on record to be CCed when issues arise regarding the target. (The mechanism to track and CC such developers may evolve over time.)
I have listed myself. If accepted, I'll talk to the Embedded Devices Working Group about adding this one to the rosta with all the others they support.
> Targets must use naming consistent with any existing targets; for instance, a target for the same CPU or OS as an existing Rust target should use the same name for that CPU or OS. Targets should normally use the same names and naming conventions as used elsewhere in the broader ecosystem beyond Rust (such as in other toolchains), unless they have a very good reason to diverge. Changing the name of a target can be highly disruptive, especially once the target reaches a higher tier, so getting the name right is important even for a tier 3 target.
You might prefer `arm-none-eabi`, because `arm-unknown-linux-gnu` is an ARMv6 target - the implicit rule seems to be that if the Arm architecture version isn't specified, it's assumed to be v6. However, `armv6-none-eabi` seemed to fit better between `armv5te-none-eabi` and `armv7a/armv7r-none-eabi`.
The hamming distance between `thumbv6-none-eabi` and `thumbv6m-none-eabi` is unfortunately low, but I don't know how to make it better. They *are* the ARMv6 and ARMv6-M targets, and its perhaps not worse than `armv7a-none-eabi` and `armv7r-none-eabi`.
> Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users.
No different to any other arm-none-eabi target.
> Neither this policy nor any decisions made regarding targets shall create any binding agreement or estoppel by any party. If any member of an approving Rust team serves as one of the maintainers of a target, or has any legal or employment requirement (explicit or implicit) that might affect their decisions regarding a target, they must recuse themselves from any approval decisions regarding the target's tier status, though they may otherwise participate in discussions.
Noted.
> Tier 3 targets should attempt to implement as much of the standard libraries as possible and appropriate...
Same as other arm-none-eabi targets.
> The target must provide documentation for the Rust community explaining how to build for the target, using cross-compilation if possible.
Same as other arm-none-eabi targets.
> Tier 3 targets must not impose burden on the authors of pull requests, or other developers in the community, to maintain the target. In particular, do not post comments (automated or manual) on a PR that derail or suggest a block on the PR based on a tier 3 target. Do not send automated messages or notifications (via any medium, including via @) to a PR author or others involved with a PR regarding a tier 3 target, unless they have opted into such messages.
Noted.
> Patches adding or updating tier 3 targets must not break any existing tier 2 or tier 1 target, and must not knowingly break another tier 3 target without approval of either the compiler team or the maintainers of the other tier 3 target.
Noted
> Tier 3 targets must be able to produce assembly using at least one of rustc's supported backends from any host target. (Having support in a fork of the backend is not sufficient, it must be upstream.)
Noted
Three targets, covering A32 and T32 instructions, and soft-float and
hard-float ABIs. Hard-float not available in Thumb mode. Atomics
in Thumb mode require __sync* functions from compiler-builtins.
This is the conceptual opposite of the rust-cold calling convention and
is particularly useful in combination with the new `explicit_tail_calls`
feature.
For relatively tight loops implemented with tail calling (`become`) each
of the function with the regular calling convention is still responsible
for restoring the initial value of the preserved registers. So it is not
unusual to end up with a situation where each step in the tail call loop
is spilling and reloading registers, along the lines of:
foo:
push r12
; do things
pop r12
jmp next_step
This adds up quickly, especially when most of the clobberable registers
are already used to pass arguments or other uses.
I was thinking of making the name of this ABI a little less LLVM-derived
and more like a conceptual inverse of `rust-cold`, but could not come
with a great name (`rust-cold` is itself not a great name: cold in what
context? from which perspective? is it supposed to mean that the
function is rarely called?)
THIR patterns: Explicitly distinguish `&pin` from plain `&`/`&mut`
Currently, `thir::PatKind::Deref` is used for ordinary `&`/`&mut` patterns, and also for `&pin const` and `&pin mut` patterns under `feature(pin_ergonomics)`. The only way to distinguish between them is by inspecting the `Ty` attached to the pattern node.
That's non-obvious, making it easy to miss, and is also a bit confusing to read when it does occur.
This PR therefore adds an explicit `pin: hir::Pinnedness` field to `thir::PatKind::Deref`, to explicitly distinguish pin-deref nodes from ordinary builtin-deref nodes.
(I'm not deeply familiar with the future of pin-patterns, so I'm not sure whether that information is best carried as a field or as a separate `PatKind`, but I think this approach is at least an improvement over the status quo.)
r? Nadrieril (or compiler)
`const` blocks as a `mod` item
Tracking issue: rust-lang/rust#149226
This adds support for writing `const { ... }` as an item in a module. In the current implementation, this is a unique AST item that gets lowered to `const _: () = const { ... };` in HIR.
rustfmt support included.
TODO:
- `pub const { ... }` does not make sense (see rust-lang/rust#147136). Reject it. Should this be rejected by the parser or smth?
- Improve diagnostics (preferably they should not mention the fake `_` ident).
Add Tier 3 Thumb-mode targets for Armv7-A, Armv7-R and Armv8-R
We currently have targets for bare-metal Armv7-R, Armv7-A and Armv8-R, but only in Arm mode. This PR adds five new targets enabling bare-metal support on these architectures in Thumb mode.
This has been tested using https://github.com/rust-embedded/aarch32/compare/main...thejpster:aarch32:support-thumb-mode-v7-v8?expand=1 and they all seem to work as expected.
However, I wasn't sure what to do with the maintainer lists as these are five new targets, but they share the docs page with the existing Arm versions. I can ask the Embedded Devices WG Arm Team about taking on these ones too, but whether Arm themselves want to take them on I guess is a bigger question.
Unused assignments to an unused variable should trigger only the
`unused_variables` lint and not also the `unused_assignments` lint.
This was previously implemented by checking whether the span of the
assignee was within the span of the binding pattern, however that failed
to capture situations was imported from elsewhere (eg from the input
tokenstream of a proc-macro that generates the binding pattern).
By comparing the span of the assignee to those of the variable
introductions instead, a reported stable-to-stable regression is
resolved.
This fix also impacted some other preexisting tests, which had
(undesirably) been triggering both the `unused_variables` and
`unused_assignments` lints on the same initializing assignment; those
tests have therefore now been updated to expect only the former lint.
Clean up or resolve cfg-related instances of `FIXME(f16_f128)`
* Replace target-specific config that has a `FIXME` with `cfg(target_has_reliable_f*)`
* Take care of trivial intrinsic-related FIXMEs
* Split `FIXME(f16_f128)` into `FIXME(f16)`, `FIXME(f128)`, or `FIXME(f16,f128)` to more clearly identify what they block
The individual commit messages have more details.
Rename `HandleCycleError` to `CycleErrorHandling`
In https://github.com/rust-lang/rust/pull/101303, the `handle_cycle_error` field was changed from a macro-generated closure to a macro-selected enum variant. But it was not renamed to reflect the fact that it now holds data, not code.
Renaming the field and its associated enum to `cycle_error_handling: CycleErrorHandling` should make the relevant code less confusing to read.
This PR also moves the enum out of `rustc_query_system::error`, where it was easily confused with diagnostic structs.
There should be no change to compiler behaviour.
Add -Z large-data-threshold
This flag allows specifying the threshold size for placing static data in large data sections when using the medium code model on x86-64.
When using -Ccode-model=medium, data smaller than this threshold uses RIP-relative addressing (32-bit offsets), while larger data uses absolute 64-bit addressing. This allows the compiler to generate more efficient code for smaller data while still supporting data larger than 2GB.
This mirrors the -mlarge-data-threshold flag available in GCC and Clang. The default threshold is 65536 bytes (64KB) if not specified, matching LLVM's default behavior.
inline constant localized typeck constraint computation
This fixes an oversight in the previous PRs, this constraint is local to a point (and liveness does the rest) and so has a fixed direction.
I wasn't planning on trying to improve the impl for perf, versus computing loan liveness without first unifying the cfg and subset graph, but it's like a 20x improvement for typeck constraints on wg-grammar (-15% end-to-end) for a trivial fix.
r? @jackh726
In general, I want to cleanup these edges to avoid off-by-one errors in constraints at effectful statements and ensure the midpoint-avoidance strategy is sound and works well, in particular with respect to edges that flow backwards from the result into its inputs. But I'd like to start from something that passes all tests and is simpler, because the eventual solution may
1. involve localizing these edges differently than *separate* liveness and typeck lowering passes/approaches, which would need to be lowered at the same time for example. I'm already doing the latter in the loan liveness rewrite as part of creating edges on-demand during traversal, and this new structure would be a better fit to verify, or fix, these subtle edges.
2. also require changes in MIR typeck to track the flow across points more precisely, and I don't know how hard that would be. *Computing* the constraint direction is currently a workaround for that.
Therefore, in a future PR, I'll also remove this computation from the terminator constraints, but I can also do that in this PR if you'd prefer.
Fix ICE when using zero-length SIMD type in extern static
before my fix using a zero-length SIMD type in an extern static would cause an internal compiler error. now it properly shows a diagnostic error instead of panicking. it was because `LayoutError::InvalidSimd` wasn't handled in `check_static_inhabited` and fell through to a generic `delayed_bug`.
i added handling for `InvalidSimd` in `check_static_inhabited` (similar to `SizeOverflow`): when a SIMD type has an invalid layout, we call `emit_err` with `Spanned` to emit a normal error instead of an ICE. compiler now emits a clear error `"the SIMD type Simd<u8, 0> has zero elements"` with the correct span on the type, matching expected compiler behavior.
fixesrust-lang/rust#151451
Previously, using a zero-length SIMD type in an extern static would
cause an internal compiler error. Now it properly emits a diagnostic
error instead of panicking.
Avoid `-> ()` in derived functions.
`hash` and `assert_receiver_is_total_eq` have no return type. This commit removes the `-> ()` that is currently printed for them.
r? @Kobzol
llvm: Tolerate dead_on_return attribute changes
The attribute now has a size parameter and sorts differently. Adjust tests to tolerate this.
https://github.com/llvm/llvm-project/pull/171712
r? durin42
@rustbot label llvm-main
codegen: clarify some variable names around function calls
I looked at rust-lang/rust#145932 to try to understand how it works, and quickly got lost in the variable names -- what refers to the caller, what to the callee? So here's my attempt at making those more clear. Hopefully the new names are correct.^^
Cc @JamieCunliffe
Fix ICE: Don't try to evaluate type_consts when eagerly collecting items
This fixes https://github.com/rust-lang/rust/issues/151246
The change is pretty straightforward if the Monomorphization strategy is eager which `-Clink-dead-code=true` sets. This then would lead to the existing code to try and evaluate a `type const` which does not have a body to evaluate leading to an ICE. The change is pretty straight forward just skip over type consts.
This also seems like a sensible choice to me since a MonoItem can only be a Fn, Static, or Asm. A type const is none of the aforementioned.
And even if it was added to the MonoItems list it would then later fail this check:
fe98ddcfcf/compiler/rustc_monomorphize/src/collector.rs (L438-L440)
Since that explicitly checks that the MonoItem's `DefKind` is static and not anything else.
One more change is the addition of a simple test of the example code from https://github.com/rust-lang/rust/issues/151246 that checks that code compiles successfully with `-Clink-dead-code=true`.
The only other change was to make the guard checks a little easier to read by making the logic more linear instead of one big if statement.
r? @BoxyUwU
@rustbot label +F-associated_const_equality +F-min_generic_const_args