| Age | Commit message (Collapse) | Author | Lines |
|
Lower extra lifetimes before normal generic params.
Fixes https://github.com/rust-lang/rust/issues/143413
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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](https://github.com/rust-lang/rust/blob/5e749eb66f93ee998145399fbdde337e57cd72ef/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.
|
|
Allow custom default address spaces and parse `p-` specifications in the datalayout string
Some targets, such as CHERI, use as default an address space different from the "normal" default address space `0` (in the case of CHERI, [200 is used](https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-877.pdf)). Currently, `rustc` does not allow to specify custom address spaces and does not take into consideration [`p-` specifications in the datalayout string](https://llvm.org/docs/LangRef.html#langref-datalayout).
This patch tries to mitigate these problems by allowing targets to define a custom default address space (while keeping the default value to address space `0`) and adding the code to parse the `p-` specifications in `rustc_abi`. The main changes are that `TargetDataLayout` now uses functions to refer to pointer-related informations, instead of having specific fields for the size and alignment of pointers in the default address space; furthermore, the two `pointer_size` and `pointer_align` fields in `TargetDataLayout` are replaced with an `FxHashMap` that holds info for all the possible address spaces, as parsed by the `p-` specifications.
The potential performance drawbacks of not having ad-hoc fields for the default address space will be tested in this PR's CI run.
r? workingjubilee
|
|
default data address space
|
|
Fix some comments and related types and locals where it is obvious, e.g.
- bare_fn -> fn_ptr
- LifetimeBinderKind::BareFnType -> LifetimeBinderKind::FnPtrType
Co-authored-by: León Orell Valerian Liehr <me@fmease.dev>
|
|
|
|
Replace kw_span by full span for generic const parameters.
Small simplification extracted from https://github.com/rust-lang/rust/pull/127241
|
|
|
|
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
|
|
Detect more cases of unused_parens around types
With this change, more unused parentheses around bounds and types nested within bounds are detected.
|
|
|
|
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.
|
|
|
|
|
|
r=workingjubilee
Taint body on invalid call ABI
Fixes https://github.com/rust-lang/rust/issues/142969
I'm not certain if there are any other paths that should be tainted, but they would operate similarly. Perhaps pointer coercion.
Introduces `extern "rust-invalid"` for testing purposes.
r? ```@workingjubilee``` or ```@oli-obk``` (or anyone)
|
|
|
|
|
|
We modify rustc_ast_lowering to prevent all unsupported ABIs
from leaking through the HIR without being checked for target support.
Previously ad-hoc checking on various HIR items required making sure
we check every HIR item which could contain an `extern "{abi}"` string.
This is a losing proposition compared to gating the lowering itself.
As a consequence, unsupported ABI strings will now hard-error instead of
triggering the FCW `unsupported_fn_ptr_calling_conventions`.
This FCW was upgraded to warn in dependencies in Rust 1.87 which was
released on 2025 May 17, and it is now 2025 June, so it has become
active within a stable Rust version.
As we already had errored on these ABIs in most other positions, and
have warned for fn ptrs, this breakage has had reasonable foreshadowing.
However, this does cause errors for usages of `extern "{abi}"` that were
theoretically writeable within source but could not actually be applied
in any useful way by Rust programmers without either warning or error.
For instance, trait declarations without impls were never checked.
These are the exact kinds of leakages that this new approach prevents.
A deprecation cycle is not useful for these marginal cases as upon impl,
even default impls within traits, different HIR objects would be used.
Details of our HIR analysis meant that those objects did get checked.
We choose to error twice if an ABI is also barred by a feature gate
on the presumption that usage of a target-incorrect ABI is intentional.
Co-authored-by: Ralf Jung <post@ralfj.de>
|
|
|
|
Allow storing `format_args!()` in variable
Fixes https://github.com/rust-lang/rust/issues/92698
Tracking issue for super let: https://github.com/rust-lang/rust/issues/139076
Tracking issue for format_args: https://github.com/rust-lang/rust/issues/99012
This change allows:
```rust
let name = "world";
let f = format_args!("hello {name}!"); // New: Store format_args!() for later!
println!("{f}");
```
This will need an FCP.
This implementation makes use of `super let`, which is unstable and might not exist in the future in its current form. However, it is entirely reasonable to assume future Rust will always have _a_ way of expressing temporary lifetimes like this, since the (stable) `pin!()` macro needs this too. (This was also the motivation for merging https://github.com/rust-lang/rust/pull/139114.)
(This is a second version of https://github.com/rust-lang/rust/pull/139135)
|
|
|
|
r=lcnr,traviscross
Stabilize `feature(generic_arg_infer)`
Fixes rust-lang/rust#85077
r? lcnr
cc ````@rust-lang/project-const-generics````
|
|
Diagnostics should know that the `&` for arguments in format_args!()
come from the macro expansion rather than from the original source.
|
|
This uses `super let` to allow
let f = format_args!("Hello {}", world);
println!("{f}");
to work.
|
|
|
|
jdonszelmann:attempt-to-mitigate-delayed-lint-perf-problems, r=oli-obk
collect delayed lints in hir_crate_items
r? `@oli-obk`
Attempt to mitigate perf problems in rust-lang/rust#138164
|
|
Require generic params for const generic params
I think that was just an oversight when the support for them was added
r? `@BoxyUwU` or `@camelid`
fixes rust-lang/rust#137188
fixes rust-lang/rust#138166
fixes rust-lang/rust#138240
fixes rust-lang/rust#138266
fixes rust-lang/rust#138359
|
|
|
|
|
|
r=oli-obk
assert more in release in `rustc_ast_lowering`
My understanding of the compiler's architecture is that in the `ast_lowering` crate, we are constructing the HIR as a one-time thing per crate. This is after tokenizing, parsing, resolution, expansion, possible reparsing, reresolution, reexpansion, and so on. In other words, there are many reasons that perf-focused PRs spend a lot of time touching `rustc_parse`, `rustc_expand`, `rustc_ast`, and then `rustc_hir` and "onwards", but `ast_lowering` is a little bit of an odd duck.
In this crate, we have a number of debug assertions. Some are clearly expensive checks that seem like they are prohibitive to run in actual optimized compiler builds, but then there are a number that are simple asserts on integer equalities, `is_empty`, or the like. I believe we should do some of them even in release builds, because the correctness gain is worth the performance cost: almost zero.
|
|
add `extern "custom"` functions
tracking issue: rust-lang/rust#140829
previous discussion: https://github.com/rust-lang/rust/issues/140566
In short, an `extern "custom"` function is a function with a custom ABI, that rust does not know about. Therefore, such functions can only be defined with `#[unsafe(naked)]` and `naked_asm!`, or via an `extern "C" { /* ... */ }` block. These functions cannot be called using normal rust syntax: calling them can only be done from inline assembly.
The motivation is low-level scenarios where a custom calling convention is used. Currently, we often pick `extern "C"`, but that is a lie because the function does not actually respect the C calling convention.
At the moment `"custom"` seems to be the name with the most support. That name is not final, but we need to pick something to actually implement this.
r? `@traviscross`
cc `@tgross35`
try-job: x86_64-apple-2
|
|
|
|
lint on duplicates during attribute parsing
To do this we stuff them in the diagnostic context to be emitted after
hir is constructed
|
|
|
|
|
|
|
|
|
|
Replace some `Option<Span>` with `Span` and use DUMMY_SP instead of None
Turns out many locations actually have a span available that we could use, so I used it
|
|
r=traviscross,jieyouxu
Add a new `mismatched-lifetime-syntaxes` lint
The lang-team [discussed this](https://hackmd.io/nf4ZUYd7Rp6rq-1svJZSaQ) and I attempted to [summarize](https://github.com/rust-lang/rust/pull/120808#issuecomment-2701863833) their decision. The summary-of-the-summary is:
- Using two different kinds of syntax for elided lifetimes is confusing. In rare cases, it may even [lead to unsound code](https://github.com/rust-lang/rust/issues/48686)! Some examples:
```rust
// Lint will warn about these
fn(v: ContainsLifetime) -> ContainsLifetime<'_>;
fn(&'static u8) -> &u8;
```
- Matching up references with no lifetime syntax, references with anonymous lifetime syntax, and paths with anonymous lifetime syntax is an exception to the simplest possible rule:
```rust
// Lint will not warn about these
fn(&u8) -> &'_ u8;
fn(&'_ u8) -> &u8;
fn(&u8) -> ContainsLifetime<'_>;
```
- Having a lint for consistent syntax of elided lifetimes will make the [future goal](https://github.com/rust-lang/rust/issues/91639) of warning-by-default for paths participating in elision much simpler.
---
This new lint attempts to accomplish the goal of enforcing consistent syntax. In the process, it supersedes and replaces the existing `elided-named-lifetimes` lint, which means it starts out life as warn-by-default.
|
|
|