about summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering/src/lib.rs
AgeCommit message (Collapse)AuthorLines
2025-07-22Rollup merge of #143430 - cjgillot:extra-lifetime-swap, r=oli-obk许杰友 Jieyou Xu (Joe)-11/+18
Lower extra lifetimes before normal generic params. Fixes https://github.com/rust-lang/rust/issues/143413
2025-07-20Lower extra lifetimes before normal generic params.Camille GILLOT-11/+18
2025-07-18Reword diagnostics about relaxed bounds in invalid contextsLeón Orell Valerian Liehr-5/+21
2025-07-18AST lowering: More robustly deal with relaxed boundsLeón Orell Valerian Liehr-21/+107
2025-07-15Allow `Early` stage to emit errorsJonathan Brouwer-2/+7
2025-07-06compiler: rename {ast,hir}::BareFn* to FnPtr*Jubilee Young-2/+2
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>
2025-07-03Replace kw_span by full span.Camille GILLOT-1/+1
2025-07-01Detect more cases of unused_parens around typesBenjamin Schulz-0/+1
2025-06-19Auto merge of #140748 - m-ou-se:super-format-args3, r=jdonszelmannbors-0/+20
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)
2025-06-18Rollup merge of #141610 - BoxyUwU:stabilize_generic_arg_infer, ↵Jakub Beránek-11/+2
r=lcnr,traviscross Stabilize `feature(generic_arg_infer)` Fixes rust-lang/rust#85077 r? lcnr cc ````@rust-lang/project-const-generics````
2025-06-18Allow storing `format_args!()` in `let`.Mara Bos-0/+20
This uses `super let` to allow let f = format_args!("Hello {}", world); println!("{f}"); to work.
2025-06-13Rollup merge of #142449 - oli-obk:missing-mgca-args, r=BoxyUwUJubilee-2/+2
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
2025-06-13Require generic params for const generic paramsOli Scherer-2/+2
2025-06-13Rollup merge of #142267 - workingjubilee:debug-assert-less-in-ast-lowering, ↵Matthias Krüger-13/+13
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.
2025-06-12introduce new lint infraJana Dönszelmann-13/+54
lint on duplicates during attribute parsing To do this we stuff them in the diagnostic context to be emitted after hir is constructed
2025-06-11stabilize gaiBoxy-11/+2
2025-06-09assert more often in release in ast_loweringJubilee Young-13/+13
2025-06-08Remove all unused feature gates from the compilerbjorn3-2/+0
2025-06-06Rollup merge of #142012 - oli-obk:no-optional-spans, r=fee1-deadMatthias Krüger-1/+1
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
2025-06-05Replace some `Option<Span>` with `Span` and use DUMMY_SP instead of NoneOli Scherer-1/+1
2025-06-03Rename `LifetimeSyntax` variants to lang-team-approved namesJake Goulding-3/+3
2025-06-03Overhaul `UsePath`.Nicholas Nethercote-7/+9
`UsePath` contains a `SmallVec<[Res; 3]>`. This holds up to three `Res` results, one per namespace (type, value, or macro). `lower_import_res` takes a `PerNS<Option<Res<NodeId>>>` result and lowers it into the `SmallVec`. This is pretty weird. The input `PerNS` makes it clear which `Res` belongs to which namespace, but the `SmallVec` throws that information away. And code that operates on the `SmallVec` tends to use iteration (or even just grabbing the first entry!) without knowing which namespace the `Res` belongs to. Even weirder! Also, `SmallVec` is an overly flexible type to use here, because it can contain any number of elements (even though it's optimized for 3 in this case). This commit changes `UsePath` so it also contains a `PerNS<Option<Res<HirId>>>`. This type preserves more information and is more self-documenting. The commit also changes a lot of the use sites to access the result for a particular namespace. E.g. if you're looking up a trait, it will be in the `Res` for the type namespace if it's present; it's silly to look in the `Res` for the value namespace or macro namespace. Overall I find the new code much easier to understand. However, some use sites still iterate. These now use `present_items` because that filters out the `None` results. Also, `redundant_pub_crate.rs` gets a bigger change. A `UseKind:ListStem` item gets no `Res` results, which means the old `all` call in `is_not_macro_export` would succeed (because `all` succeeds on an empty iterator) and the `ListStem` would be ignored. This is what we want, but was more by luck than design. The new code detects `ListStem` explicitly. The commit generalizes the name of that function accordingly. Finally, the commit also removes the `use_path` arena, because `PerNS<Option<Res>>` impls `Copy` (unlike `SmallVec`) and it can be allocated in the arena shared by all `Copy` types.
2025-05-20Hoist `ItemLowerer` out of a loop.Nicholas Nethercote-7/+7
2025-05-13Auto merge of #140887 - pietroalbini:pa-bootstrap-update, r=compiler-errorsbors-1/+0
Stage0 bootstrap update This PR [follows the release process](https://forge.rust-lang.org/release/process.html#master-bootstrap-update-tuesday) to update the stage0 compiler. The only thing of note is https://github.com/rust-lang/rust/commit/58651d1b316e268fac2100c3ae37bb502a36b8ba, which was flagged by clippy as a correctness fix. I think allowing that lint in our case makes sense, but it's worth to have a second pair of eyes on it. r? `@Mark-Simulacrum`
2025-05-12Fix typosomahs-1/+1
2025-05-12update cfg(bootstrap)Pietro Albini-1/+0
2025-05-05Auto merge of #140453 - Zoxc:next-disambiguator, r=oli-obkbors-6/+7
Remove global `next_disambiguator` state and handle it with a `DisambiguatorState` type This removes `Definitions.next_disambiguator` as it doesn't guarantee deterministic def paths when `create_def` is called in parallel. Instead a new `DisambiguatorState` type is passed as a mutable reference to `create_def` to help create unique def paths. `create_def` calls with distinct `DisambiguatorState` instances must ensure that that the def paths are unique without its help. Anon associated types did rely on this global state for uniqueness and are changed to use (method they're defined in + their position in the method return type) as the `DefPathData` to ensure uniqueness. This also means that the method they're defined in appears in error messages, which is nicer. `DefPathData::NestedStatic` is added to use for nested data inside statics instead of reusing `DefPathData::AnonConst` to avoid conflicts with those. cc `@oli-obk`
2025-05-02Rollup merge of #139046 - nnethercote:hir-Lifetime-better, r=lcnrStuart Cook-5/+5
Improve `Lifetime::suggestion` r? ``@lcnr``
2025-05-02Handle `Path<>` better in error messages.Nicholas Nethercote-5/+5
`Path<>` needs to be distinguished from `Path<T>`. This commit does that, improving some error messages.
2025-04-29Drop AST on a separate thread and prefetch `hir_crate`John Kåre Alsaker-2/+8
2025-04-29Remove global `next_disambiguator` state and handle it with a ↵John Kåre Alsaker-1/+5
`DisambiguatorState` type
2025-04-28We always use the current item as parent, so no need to pass itOli Scherer-5/+2
2025-04-25Auto merge of #140282 - matthiaskrgr:rollup-g6ze4jj, r=matthiaskrgrbors-1/+1
Rollup of 8 pull requests Successful merges: - #137653 (Deprecate the unstable `concat_idents!`) - #138957 (Update the index of Option to make the summary more comprehensive) - #140006 (ensure compiler existance of tools on the dist step) - #140143 (Move `sys::pal::os::Env` into `sys::env`) - #140202 (Make #![feature(let_chains)] bootstrap conditional in compiler/) - #140236 (norm nested aliases before evaluating the parent goal) - #140257 (Some drive-by housecleaning in `rustc_borrowck`) - #140278 (Don't use item name to look up associated item from trait item) r? `@ghost` `@rustbot` modify labels: rollup
2025-04-25Rollup merge of #140202 - est31:let_chains_feature_compiler, r=lcnrMatthias Krüger-1/+1
Make #![feature(let_chains)] bootstrap conditional in compiler/ Let chains have been stabilized recently in #132833, so we can remove the gating from our uses in the compiler (as the compiler uses edition 2024).
2025-04-25Rollup merge of #140229 - nnethercote:pre-DelimArgs-spacing, r=petrochenkovMatthias Krüger-1/+1
`DelimArgs` tweaks r? `@petrochenkov`
2025-04-23Extend HIR to track the source and syntax of a lifetimeJake Goulding-48/+73
An upcoming lint will want to be able to know if a lifetime is hidden (e.g. `&u8`, `ContainsLifetime`) or anonymous: (e.g. `&'_ u8`, `ContainsLifetime<'_>`). It will also want to know if the lifetime is related to a reference (`&u8`) or a path (`ContainsLifetime`).
2025-04-23Make #![feature(let_chains)] bootstrap conditional in compiler/est31-1/+1
2025-04-23Use `clone` to clone `DelimArgs` in two places.Nicholas Nethercote-1/+1
2025-04-17Rollup merge of #139770 - nnethercote:rename-LifetimeName, r=BoxyUwUMatthias Krüger-6/+6
Rename `LifetimeName` as `LifetimeKind`. It's a much better name, more consistent with how we name such things. Also rename `Lifetime::res` as `Lifetime::kind` to match. I suspect this field used to have the type `LifetimeRes` and then the type was changed but the field name remained the same. r? ``@BoxyUwU``
2025-04-16Rename `LifetimeName` as `LifetimeKind`.Nicholas Nethercote-6/+6
It's a much better name, more consistent with how we name such things. Also rename `Lifetime::res` as `Lifetime::kind` to match. I suspect this field used to have the type `LifetimeRes` and then the type was changed but the field name remained the same.
2025-04-15Remove some "name isn't empty" assertions.Nicholas Nethercote-1/+0
These were low value even before #137978 resulted in empty names being used much less. (Why check for non-emptiness in these three places? There are thousands of places in the compiler you could check.)
2025-04-14Auto merge of #124141 - ↵bors-2/+1
nnethercote:rm-Nonterminal-and-TokenKind-Interpolated, r=petrochenkov Remove `Nonterminal` and `TokenKind::Interpolated` A third attempt at this; the first attempt was #96724 and the second was #114647. r? `@ghost`
2025-04-11Rollup merge of #139641 - BoxyUwU:allow_parend_array_len_infer, ↵Stuart Cook-1/+3
r=compiler-errors Allow parenthesis around inferred array lengths In #135272 it was noticed that we weren't handling `Vec<(((((_)))))>` correctly under the new desugaring for `generic_arg_infer`, this had to be fixed in order to not regress stable code for types that should continue working. This has the side effect of *also* allowing the following to work: ```rust #![feature(generic_arg_infer)] struct Bar<const N: usize>; fn main() { let a: Bar<((_))> = Bar::<10>; } ``` However I did not make the same change for array lengths resulting in the following not compiling: ```rust #![feature(generic_arg_infer)] fn main() { let a: [u8; (((_)))] = [2; 2]; let a: [u8; 2] = [2; (((((_)))))]; } ``` This is rather inconsistent as parenthesis around `_` *are* supported for const args to non-arrays, and type args. This PR fixes this allowing the above example to compile. No stable impact. r? compiler-errors
2025-04-10Allow parenthesis around inferred array lengthsBoxy-1/+3
2025-04-10Rename some `name` variables as `ident`.Nicholas Nethercote-2/+2
It bugs me when variables of type `Ident` are called `name`. It leads to silly things like `name.name`. `Ident` variables should be called `ident`, and `name` should be used for variables of type `Symbol`. This commit improves things by by doing `s/name/ident/` on a bunch of `Ident` variables. Not all of them, but a decent chunk.
2025-04-07Rollup merge of #139112 - m-ou-se:super-let, r=lcnrStuart Cook-0/+1
Implement `super let` Tracking issue: https://github.com/rust-lang/rust/issues/139076 This implements `super let` as proposed in #139080, based on the following two equivalence rules. 1. For all expressions `$expr` in any context, these are equivalent: - `& $expr` - `{ super let a = & $expr; a }` 2. And, additionally, these are equivalent in any context when `$expr` is a temporary (aka rvalue): - `& $expr` - `{ super let a = $expr; & a }` So far, this experiment has a few interesting results: ## Interesting result 1 In this snippet: ```rust super let a = f(&temp()); ``` I originally expected temporary `temp()` would be dropped at the end of the statement (`;`), just like in a regular `let`, because `temp()` is not subject to temporary lifetime extension. However, it turns out that that would break the fundamental equivalence rules. For example, in ```rust g(&f(&temp())); ``` the temporary `temp()` will be dropped at the `;`. The first equivalence rule tells us this must be equivalent: ```rust g({ super let a = &f(&temp()); a }); ``` But that means that `temp()` must live until the last `;` (after `g()`), not just the first `;` (after `f()`). While this was somewhat surprising to me at first, it does match the exact behavior we need for `pin!()`: The following _should work_. (See also https://github.com/rust-lang/rust/issues/138718) ```rust g(pin!(f(&mut temp()))); ``` Here, `temp()` lives until the end of the statement. This makes sense from the perspective of the user, as no other `;` or `{}` are visible. Whether `pin!()` uses a `{}` block internally or not should be irrelevant. This means that _nothing_ in a `super let` statement will be dropped at the end of that super let statement. It does not even need its own scope. This raises questions that are useful for later on: - Will this make temporaries live _too long_ in cases where `super let` is used not in a hidden block in a macro, but as a visible statement in code like the following? ```rust let writer = { super let file = File::create(&format!("/home/{user}/test")); Writer::new(&file) }; ``` - Is a `let` statement in a block still the right syntax for this? Considering it has _no_ scope of its own, maybe neither a block nor a statement should be involved This leads me to think that instead of `{ super let $pat = $init; $expr }`, we might want to consider something like `let $pat = $init in $expr` or `$expr where $pat = $init`. Although there are also issues with these, as it isn't obvious anymore if `$init` should be subject to temporary lifetime extension. (Do we want both `let _ = _ in ..` and `super let _ = _ in ..`?) ## Interesting result 2 What about `super let x;` without initializer? ```rust let a = { super let x; x = temp(); &x }; ``` This works fine with the implementation in this PR: `x` is extended to live as long as `a`. While it matches my expectations, a somewhat interesting thing to realize is that these are _not_ equivalent: - `super let x = $expr;` - `super let x; x = $expr;` In the first case, all temporaries in $expr will live at least as long as (the result of) the surrounding block. In the second case, temporaries will be dropped at the end of the assignment statement. (Because the assignment statement itself "is not `super`".) This difference in behavior might be confusing, but it _might_ be useful. One might want to extend the lifetime of a variable without extending all the temporaries in the initializer expression. On the other hand, that can also be expressed as: - `let x = $expr; super let x = x;` (w/o temporary lifetime extension), or - `super let x = { $expr };` (w/ temporary lifetime extension) So, this raises these questions: - Do we want to accept `super let x;` without initializer at all? - Does it make sense for statements other than let statements to be "super"? An expression statement also drops temporaries at its `;`, so now that we discovered that `super let` basically disables that `;` (see interesting result 1), is there a use to having other statements without their own scope? (I don't think that's ever useful?) ## Interesting result 3 This works now: ```rust super let Some(x) = a.get(i) else { return }; ``` I didn't put in any special cases for `super let else`. This is just the behavior that 'naturally' falls out when implementing `super let` without thinking of the `let else` case. - Should `super let else` work? ## Interesting result 4 This 'works': ```rust fn main() { super let a = 123; } ``` I didn't put in any special cases for `super let` at function scope. I had expected the code to cause an ICE or other weird failure when used at function body scope, because there's no way to let the variable live as long as the result of the function. This raises the question: - Does this mean that this behavior is the natural/expected behavior when `super let` is used at function scope? Or is this just a quirk and should we explicitly disallow `super let` in a function body? (Probably the latter.) --- The questions above do not need an answer to land this PR. These questions should be considered when redesigning/rfc'ing/stabilizing the feature.
2025-04-07Rollup merge of #139035 - nnethercote:PatKind-Missing, r=oli-obkStuart Cook-8/+3
Add new `PatKind::Missing` variants To avoid some ugly uses of `kw::Empty` when handling "missing" patterns, e.g. in bare fn tys. Helps with #137978. Details in the individual commits. r? ``@oli-obk``
2025-04-04Implement `super let`.Mara Bos-0/+1
2025-04-02Remove `recursion_limit` increases.Nicholas Nethercote-1/+0
These are no longer needed now that `Nonterminal` is gone.
2025-04-02Remove `TokenStream::flattened` and `InvisibleOrigin::FlattenToken`.Nicholas Nethercote-1/+1
They are no longer needed. This does slightly worsen the error message for a single test, but that test contains code that is so badly broken that I'm not worried about it.