From `#[align]` -> `#[rustc_align]`. Attributes starting with `rustc`
are always perma-unstable and feature-gated by `feature(rustc_attrs)`.
See regression RUST-143834.
For the underlying problem where even introducing new feature-gated
unstable built-in attributes can break user code such as
```rs
macro_rules! align {
() => {
/* .. */
};
}
pub(crate) use align; // `use` here becomes ambiguous
```
refer to RUST-134963.
Since the `#[align]` attribute is still feature-gated by
`feature(fn_align)`, we can rename it as a mitigation. Note that
`#[rustc_align]` will obviously mean that current unstable user code
using `feature(fn_aling)` will need additionally `feature(rustc_attrs)`,
but this is a short-term mitigation to buy time, and is expected to be
changed to a better name with less collision potential.
See
<https://rust-lang.zulipchat.com/#narrow/channel/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202025-07-17/near/529290371>
where mitigation options were considered.
Make slice comparisons const
This needed a fix for `derive_const`, too, as it wasn't usable in libcore anymore as trait impls need const stability attributes. I think we can't use the same system as normal trait impls while `const_trait_impl` is still unstable.
r? ```@fee1-dead```
cc rust-lang/rust#143800
Only inherit local hash for paths
`DefPathHash`, as the counterpart of `DefId` that is stable across compiler invocations, is comprised of 2 parts. The first one is the `StableCrateId`, stable form of `CrateNum`. The second is 64 complementary bits to identify the crate-local definition.
The current implementation always hashes the full 128 bits when (1) trying to create a new child `DefPathHash` or (2) hashing a `CrateNum` or a `LocalDefId`. But we only need half that information: `LocalDefId` means that the `StableCrateId` is always the current crate's ; `CrateNum` means that we do not care about the local part.
As stable hashing is very hot in the query system, in particular hashing definitions, this is a big deal.
We still want the local part to change when the `StableCrateId` changes, to make incr-compilation errors less painful, ie. increase the likelihood that if will magically disappear by changing some code.
This PR sprinkles some `#[inline]` attributes on small functions that appeared in profiles.
make `cfg_select` a builtin macro
tracking issue: https://github.com/rust-lang/rust/issues/115585
This parses mostly the same as the `macro cfg_select` version, except:
1. wrapping in double brackets is no longer supported (or needed): `cfg_select {{ /* ... */ }}` is now rejected.
2. in an expression context, the rhs is no longer wrapped in a block, so that this now works:
```rust
fn main() {
println!(cfg_select! {
unix => { "foo" }
_ => { "bar" }
});
}
```
3. a single wildcard rule is now supported: `cfg_select { _ => 1 }` now works
I've also added an error if none of the rules evaluate to true, and warnings for any arms that follow the `_` wildcard rule.
cc `@traviscross` if I'm missing any feature that should/should not be included
r? `@petrochenkov` for the macro logic details
de-duplicate condition scoping logic between AST→HIR lowering and `ScopeTree` construction
There was some overlap between `rustc_ast_lowering::LoweringContext::lower_cond` and `rustc_hir_analysis::check::region::resolve_expr`, so I've removed the former and migrated its logic to the latter, with some simplifications.
Consequences:
- For `while` and `if` expressions' `let`-chains, this changes the `HirId`s for the `&&`s to properly correspond to their AST nodes. This is how guards were handled already.
- This makes match guards share previously-duplicated logic with `if`/`while` expressions. This will also be used by guard pattern[^1] guards.
- Aside from legacy syntax extensions (e.g. some builtin macros) that directly feed AST to the compiler, it's currently impossible to put attributes directly on `&&` operators in `let` chains[^2]. Nonetheless, attributes on `&&` operators in `let` chains in `if`/`while` expression conditions are no longer silently ignored and will be lowered.
- This no longer wraps conditions in `DropTemps`, so the HIR and THIR will be slightly smaller.
- `DesugaringKind::CondTemporary` is now gone. It's no longer applied to any spans, and all uses of it were dead since they were made to account for `if` and `while` being desugared to `match` on a boolean scrutinee.
- Should be a marginal perf improvement beyond that due to leveraging [`ScopeTree` construction](5e749eb66f/compiler/rustc_hir_analysis/src/check/region.rs (L312-L355))'s clever handling of `&&` and `||`:
- This removes some unnecessary terminating scopes that were placed around top-level `&&` and `||` operators in conditions. When lowered to MIR, logical operator chains don't create intermediate boolean temporaries, so there's no temporary to drop. The linked snippet handles wrapping the operands in terminating scopes as necessary, in case they create temporaries.
- The linked snippet takes care of letting `let` temporaries live and terminating other operands, so we don't need separate traversals of `&&` chains for that.
[^1]: rust-lang/rust#129967
[^2]: Case-by-case, here's my justification: `#[attr] e1 && e2` applies the attribute to `e1`. In `#[attr] (e1 && e2)` , the attribute is on the parentheses in the AST, plus it'd fail to parse if `e1` or `e2` contains a `let`. In `#[attr] expands_to_let_chain!()`, the attribute would already be ignored (rust-lang/rust#63221) and it'd fail to parse anyway; even if the expansion site is a condition, the expansion wouldn't be parsed with `Restrictions::ALLOW_LET`. If it *was* allowed, the notion of a "reparse context" from https://github.com/rust-lang/rust/issues/61733#issuecomment-509626449 would be necessary in order to make `let`-chains left-associative; multiple places in the compiler assume they are.
setup typos check in CI
This allows to check typos in CI, currently for compiler only (to reduce commit size with fixes). With current setup, exclude list is quite short, so it worth trying?
Also includes commits with actual typo fixes.
MCP: https://github.com/rust-lang/compiler-team/issues/817
typos check currently turned for:
* ./compiler
* ./library
* ./src/bootstrap
* ./src/librustdoc
After merging, PRs which enables checks for other crates (tools) can be implemented too.
Found typos will **not break** other jobs immediately: (tests, building compiler for perf run). Job will be marked as red on completion in ~ 20 secs, so you will not forget to fix it whenever you want, before merging pr.
Check typos: `python x.py test tidy --extra-checks=spellcheck`
Apply typo fixes: `python x.py test tidy --extra-checks=spellcheck:fix` (in case if there only 1 suggestion of each typo)
Current fail in this pr is expected and shows how typo errors emitted. Commit with error will be removed after r+.
Rewrite `macro_rules!` parser to not use the MBE engine itself
The `macro_rules!` parser was written to match the series of rules using the macros-by-example (MBE) engine and a hand-written equivalent of the left-hand side of a MBE macro. This was complex to read, difficult to extend, and produced confusing error messages. Because it was using the MBE engine, any parse failure would be reported as if some macro was being applied to the `macro_rules!` invocation itself; for instance, errors would talk about "macro invocation", "macro arguments", and "macro call", when they were actually about the macro *definition*.
And in practice, the `macro_rules!` parser only used the MBE engine to extract the left-hand side and right-hand side of each rule as a token tree, and then parsed the rest using a separate parser.
Rewrite it to parse the series of rules using a simple loop, instead. This makes it more extensible in the future, and improves error messages. For instance, omitting a semicolon between rules will result in "expected `;`" and "unexpected token", rather than the confusing "no rules expected this token in macro call".
This work was greatly aided by pair programming with Vincenzo Palazzo (`@vincenzopalazzo)` and Eric Holk (`@eholk).`
For review, I recommend reading the two commits separately.
It's like `Symbol` but for byte strings. The interner is now used for
both `Symbol` and `ByteSymbol`. E.g. if you intern `"dog"` and `b"dog"`
you'll get a `Symbol` and a `ByteSymbol` with the same index and the
characters will only be stored once.
The motivation for this is to eliminate the `Arc`s in `ast::LitKind`, to
make `ast::LitKind` impl `Copy`, and to avoid the need to arena-allocate
`ast::LitKind` in HIR. The latter change reduces peak memory by a
non-trivial amount on literal-heavy benchmarks such as `deep-vector` and
`tuple-stress`.
`Encoder`, `Decoder`, `SpanEncoder`, and `SpanDecoder` all get some
changes so that they can handle normal strings and byte strings.
This change does slow down compilation of programs that use
`include_bytes!` on large files, because the contents of those files are
now interned (hashed). This makes `include_bytes!` more similar to
`include_str!`, though `include_bytes!` contents still aren't escaped,
and hashing is still much cheaper than escaping.
Add SIMD funnel shift and round-to-even intrinsics
This PR adds 3 new SIMD intrinsics
- `simd_funnel_shl` - funnel shift left
- `simd_funnel_shr` - funnel shift right
- `simd_round_ties_even` (vector version of `round_ties_even_fN`)
TODO (future PR): implement `simd_fsh{l,r}` in miri, cg_gcc and cg_clif (it is surprisingly hard to implement without branches, the common tricks that rotate uses doesn't work because we have 2 elements now. e.g, the `-n&31` trick used by cg_gcc to implement rotate doesn't work with this because then `fshl(a, b, 0)` will be `a | b`)
[#t-compiler > More SIMD intrinsics](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/More.20SIMD.20intrinsics/with/522130286)
`@rustbot` label T-compiler T-libs A-intrinsics F-core_intrinsics
r? `@workingjubilee`
Use tidy to sort `sym::*` items
Use tidy to sort the symbols in the invocation of `symbols!`, instead of implementing the ordering check inside the proc macro.
(asked `````@nnethercote````` about this on zulip, he didn't have any reservations about making this change)
This has a couple of benefits:
- tidy's "version sort" (thanks to rust-lang/rust#141311 !) is nicer than the naive-cmp sort, so, e.g. `AtomicI{8, 16, 32, 64, 128}` are properly sorted by bit width.
- consistency with the rest of the repo
- allows us to remove a bit of order-verifying code from the `symbols!` proc macro impl
Insert checks for enum discriminants when debug assertions are enabled
Similar to the existing null-pointer and alignment checks, this checks for valid enum discriminants on creation of enums through unsafe transmutes. Essentially this sanitizes patterns like the following:
```rust
let val: MyEnum = unsafe { std::mem::transmute<u32, MyEnum>(42) };
```
An extension of this check will be done in a follow-up that explicitly sanitizes for extern enum values that come into Rust from e.g. C/C++.
This check is similar to Miri's capabilities of checking for valid construction of enum values.
This PR is inspired by saethlin@'s PR
https://github.com/rust-lang/rust/pull/104862. Thank you so much for keeping this code up and the detailed comments!
I also pair-programmed large parts of this together with vabr-g@.
r? `@saethlin`
add #![rustc_no_implicit_bounds]
Follow-up from rust-lang/rust#137944.
Adds a new `rustc_attrs` attribute that stops rustc from adding any default bounds. Useful for tests where default bounds just add noise and make debugging harder.
After reviewing all tests with `?Sized`, these tests seem like they could probably benefit from `#![rustc_no_implicit_bounds]`.
- Skipping most of `tests/ui/unsized` as these seem to want to test `?Sized`
- Skipping tests that used `Box<T>` because it's still bound by `T: MetaSized`
- Skipping parsing or other tests that cared about `?Sized` syntactically
- Skipping tests for `derive(CoercePointee)` because this appears to check that the pointee type is relaxed with `?Sized` explicitly
r? `@lcnr`
Similar to the existing nullpointer and alignment checks, this checks
for valid enum discriminants on creation of enums through unsafe
transmutes. Essentially this sanitizes patterns like the following:
```rust
let val: MyEnum = unsafe { std::mem::transmute<u32, MyEnum>(42) };
```
An extension of this check will be done in a follow-up that explicitly
sanitizes for extern enum values that come into Rust from e.g. C/C++.
This check is similar to Miri's capabilities of checking for valid
construction of enum values.
This PR is inspired by saethlin@'s PR
https://github.com/rust-lang/rust/pull/104862. Thank you so much for
keeping this code up and the detailed comments!
I also pair-programmed large parts of this together with vabr-g@.
The `macro_rules!` parser was written to match the series of rules using
the macros-by-example (MBE) engine and a hand-written equivalent of the
left-hand side of a MBE macro. This was complex to read, difficult to
extend, and produced confusing error messages. Because it was using the
MBE engine, any parse failure would be reported as if some macro was
being applied to the `macro_rules!` invocation itself; for instance,
errors would talk about "macro invocation", "macro arguments", and
"macro call", when they were actually about the macro *definition*.
And in practice, the `macro_rules!` parser only used the MBE engine to
extract the left-hand side and right-hand side of each rule as a token
tree, and then parsed the rest using a separate parser.
Rewrite it to parse the series of rules using a simple loop, instead.
This makes it more extensible in the future, and improves error
messages. For instance, omitting a semicolon between rules will result
in "expected `;`" and "unexpected token", rather than the confusing "no
rules expected this token in macro call".
This work was greatly aided by pair programming with Vincenzo Palazzo
and Eric Holk.
Add `#[loop_match]` for improved DFA codegen
tracking issue: https://github.com/rust-lang/rust/issues/132306
project goal: https://github.com/rust-lang/rust-project-goals/issues/258
This PR adds the `#[loop_match]` attribute, which aims to improve code generation for state machines. For some (very exciting) benchmarks, see https://github.com/rust-lang/rust-project-goals/issues/258#issuecomment-2732965199
Currently, a very restricted syntax pattern is accepted. We'd like to get feedback and merge this now before we go too far in a direction that others have concerns with.
## current state
We accept code that looks like this
```rust
#[loop_match]
loop {
state = 'blk: {
match state {
State::A => {
#[const_continue]
break 'blk State::B
}
State::B => { /* ... */ }
/* ... */
}
}
}
```
- a loop should have the same semantics with and without `#[loop_match]`: normal `continue` and `break` continue to work
- `#[const_continue]` is only allowed in loops annotated with `#[loop_match]`
- the loop body needs to have this particular shape (a single assignment to the match scrutinee, with the body a labelled block containing just a match)
## future work
- perform const evaluation on the `break` value
- support more state/scrutinee types
## maybe future work
- allow `continue 'label value` syntax, which `#[const_continue]` could then use.
- allow the match to be on an arbitrary expression (e.g. `State::Initial`)
- attempt to also optimize `break`/`continue` expressions that are not marked with `#[const_continue]`
r? ``@traviscross``
Add diagnostic items for Clippy
Clippy still uses some paths to access items from the standard library. Adding the missing diagnostic items allows removing the last remaining paths.
Closesrust-lang/rust-clippy#5393
- `Ident::from_str_and_span` -> `Ident::new` when the string is
pre-interned.
- `Ident::from_str` -> `Ident::with_dummy_span` when the string is
pre-interned.
- `_d` and `_e` are unused.
Adds a new `rustc_attrs` attribute that stops rustc from adding any
default bounds. Useful for tests where default bounds just add noise and
make debugging harder.
This commit adds a lint to prevent the use of rustc_type_ir in random
compiler crates, except for type system internals traits, which are
explicitly allowed. Moreover, this fixes diagnostic_items() to include
the CRATE_OWNER_ID, otherwise rustc_diagnostic_item attribute is ignored
on the crate root.
Introduce the `MetaSized` and `PointeeSized` traits as supertraits of
`Sized` and initially implement it on everything that currently
implements `Sized` to isolate any changes that simply adding the
traits introduces.
intrinsics: rename min_align_of to align_of
Now that `pref_align_of` is gone (https://github.com/rust-lang/rust/pull/141803), we can give the intrinsic backing `align_of` its proper name.
r? `@workingjubilee` or `@bjorn3`