about summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering/src
AgeCommit message (Collapse)AuthorLines
2025-04-30Auto merge of #121909 - Zoxc:drop-ast-task, r=petrochenkovbors-2/+8
Drop AST on a separate thread and prefetch `hir_crate` This drop AST on a separate thread and prefetches `hir_crate`. A `spawn` function is added to the `parallel` module which spawn some work on the Rayon thread pool.
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-9/+4
2025-04-28Add or-patterns to pattern typesOli Scherer-0/+5
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-58/+91
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-22Use `is_lang_item` and `as_lang_item` instead of handrolling their logicOli Scherer-9/+5
2025-04-18Rollup merge of #139615 - nnethercote:rm-name_or_empty, r=jdonszelmannMatthias Krüger-1/+1
Remove `name_or_empty` Another step towards #137978. r? ``@jdonszelmann``
2025-04-17Replace infallible `name_or_empty` methods with fallible `name` methods.Nicholas Nethercote-1/+1
I'm removing empty identifiers everywhere, because in practice they always mean "no identifier" rather than "empty identifier". (An empty identifier is impossible.) It's better to use `Option` to mean "no identifier" because you then can't forget about the "no identifier" possibility. Some specifics: - When testing an attribute for a single name, the commit uses the `has_name` method. - When testing an attribute for multiple names, the commit uses the new `has_any_name` method. - When using `match` on an attribute, the match arms now have `Some` on them. In the tests, we now avoid printing empty identifiers by not printing the identifier in the `error:` line at all, instead letting the carets point out the problem.
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-15Rollup merge of #139848 - nnethercote:kw-Empty-5, r=compiler-errorsMatthias Krüger-1/+0
Reduce kw::Empty usage, part 5 Another step towards https://github.com/rust-lang/rust/issues/137978. r? `@davidtwco`
2025-04-15Auto merge of #139845 - Zalathar:rollup-u5u5y1v, r=Zalatharbors-7/+18
Rollup of 17 pull requests Successful merges: - #138374 (Enable contracts for const functions) - #138380 (ci: add runners for vanilla LLVM 20) - #138393 (Allow const patterns of matches to contain pattern types) - #139517 (std: sys: process: uefi: Use NULL stdin by default) - #139554 (std: add Output::exit_ok) - #139660 (compiletest: Add an experimental new executor to replace libtest) - #139669 (Overhaul `AssocItem`) - #139671 (Proc macro span API redesign: Replace proc_macro::SourceFile by Span::{file, local_file}) - #139750 (std/thread: Use default stack size from menuconfig for NuttX) - #139772 (Remove `hir::Map`) - #139785 (Let CStrings be either 1 or 2 byte aligned.) - #139789 (do not unnecessarily leak auto traits in item bounds) - #139791 (drop global where-bounds before merging candidates) - #139798 (normalize: prefer `ParamEnv` over `AliasBound` candidates) - #139822 (Fix: Map EOPNOTSUPP to ErrorKind::Unsupported on Unix) - #139833 (Fix some HIR pretty-printing problems) - #139836 (Basic tests of MPMC receiver cloning) r? `@ghost` `@rustbot` modify labels: rollup
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-15Rollup merge of #139669 - nnethercote:overhaul-AssocItem, r=oli-obkStuart Cook-1/+1
Overhaul `AssocItem` `AssocItem` has multiple fields that only make sense some of the time. E.g. the `name` can be empty if it's an RPITIT associated type. It's clearer and less error prone if these fields are moved to the relevant `kind` variants. r? ``@fee1-dead``
2025-04-15Rollup merge of #138374 - celinval:issue-136925-const-contract, ↵Stuart Cook-6/+17
r=compiler-errors,oli-obk,RalfJung Enable contracts for const functions Use `const_eval_select!()` macro to enable contract checking only at runtime. The existing contract logic relies on closures, which are not supported in constant functions. This commit also removes one level of indirection for ensures clauses since we no longer build a closure around the ensures predicate. Resolves #136925 **Call-out:** This is still a draft PR since CI is broken due to a new warning message for unreachable code when the bottom of the function is indeed unreachable. It's not clear to me why the warning wasn't triggered before. r? ```@compiler-errors```
2025-04-14Use `newtype_index!`-generated types more idiomaticallyYotam Ofek-2/+1
2025-04-14Move `has_self` field to `hir::AssocKind::Fn`.Nicholas Nethercote-1/+1
`hir::AssocItem` currently has a boolean `fn_has_self_parameter` field, which is misplaced, because it's only relevant for associated fns, not for associated consts or types. This commit moves it (and renames it) to the `AssocKind::Fn` variant, where it belongs. This requires introducing a new C-style enum, `AssocTag`, which is like `AssocKind` but without the fields. This is because `AssocKind` values are passed to various functions like `find_by_ident_and_kind` to indicate what kind of associated item should be searched for, and having to specify `has_self` isn't relevant there. New methods: - Predicates `AssocItem::is_fn` and `AssocItem::is_method`. - `AssocItem::as_tag` which converts `AssocItem::kind` to `AssocTag`. Removed `find_by_name_and_kinds`, which is unused. `AssocItem::descr` can now distinguish between methods and associated functions, which slightly improves some error messages.
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-10Rollup merge of #139614 - nnethercote:fix-139512, r=oli-obkMatthias Krüger-7/+8
Avoid empty identifiers for delegate params and args. Details in individual commits. r? `@oli-obk`
2025-04-10Avoid empty identifiers for delegate params and args.Nicholas Nethercote-7/+8
Instead use `argN`. The empty identifiers could flow to `Liveness::should_warn`, where they would trigger a bounds error. Fixes #139512.
2025-04-10Rename some `name` variables as `ident`.Nicholas Nethercote-5/+5
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-08Fix unreachable expression warningCelina G. Val-3/+9
Invert the order that we pass the arguments to the `contract_check_ensures` function to avoid the warning when the tail of the function is unreachable. Note that the call itself is also unreachable, but we have already handled that case by ignoring unreachable call for contract calls.
2025-04-07Enable contracts for const functionsCelina G. Val-4/+9
Use `const_eval_select!()` macro to enable contract checking only at runtime. The existing contract logic relies on closures, which are not supported in constant functions. This commit also removes one level of indirection for ensures clauses, however, it currently has a spurious warning message when the bottom of the function is unreachable.
2025-04-07Rollup merge of #139455 - Skgland:remove_rust-intrinsic_ABI, r=oli-obkStuart Cook-4/+0
Remove support for `extern "rust-intrinsic"` blocks Part of rust-lang/rust#132735 Looked manageable and there didn't appear to have been progress in the last two weeks, so decided to give it a try.
2025-04-07Rollup merge of #139112 - m-ou-se:super-let, r=lcnrStuart Cook-1/+3
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/+4
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-06remove compiler support for `extern "rust-intrinsic"` blocksSkgland-4/+0
2025-04-06Rollup merge of #139391 - TaKO8Ki:check-if-merged-attrs-list-is-empty, ↵Guillaume Gomez-7/+9
r=jdonszelmann Check if merged attributes list is empty in expr Fixes #139373 In the example code, an [`UnrecognizedReprHint`](https://github.com/rust-lang/rust/blob/6b5ccfc87f59ab017032e430d4d358b4989735da/compiler/rustc_attr_parsing/src/attributes/repr.rs#L155) error is output, and the list of merged attributes becomes empty. This causes a [panic](https://github.com/rust-lang/rust/blob/6b5ccfc87f59ab017032e430d4d358b4989735da/compiler/rustc_ast_lowering/src/lib.rs#L618) to occur. So, it's necessary to check if merged attributes list is empty as other functions do. ref: https://github.com/rust-lang/rust/blob/6b5ccfc87f59ab017032e430d4d358b4989735da/compiler/rustc_ast_lowering/src/lib.rs#L896
2025-04-05Rollup merge of #139341 - nnethercote:fix-137874, r=petrochenkovStuart Cook-3/+0
Apply `Recovery::Forbidden` when reparsing pasted macro fragments. Fixes #137874. The changes to the output of `tests/ui/associated-consts/issue-93835.rs` partly undo the changes seen when `NtTy` was removed in #133436, which is good. r? ``@petrochenkov``
2025-04-05check if merged attributes list is emptyTakayuki Maeda-7/+9
2025-04-04Implement `super let`.Mara Bos-1/+3
2025-04-04Remove an unwanted comment.Nicholas Nethercote-3/+0
I accidentally added this in #138740.
2025-04-03Tighten up assignment operator representations.Nicholas Nethercote-1/+5
In the AST, currently we use `BinOpKind` within `ExprKind::AssignOp` and `AssocOp::AssignOp`, even though this allows some nonsensical combinations. E.g. there is no `&&=` operator. Likewise for HIR and THIR. This commit introduces `AssignOpKind` which only includes the ten assignable operators, and uses it in `ExprKind::AssignOp` and `AssocOp::AssignOp`. (And does similar things for `hir::ExprKind` and `thir::ExprKind`.) This avoids the possibility of nonsensical combinations, as seen by the removal of the `bug!` case in `lang_item_for_binop`. The commit is mostly plumbing, including: - Adds an `impl From<AssignOpKind> for BinOpKind` (AST) and `impl From<AssignOp> for BinOp` (MIR/THIR). - `BinOpCategory` can now be created from both `BinOpKind` and `AssignOpKind`. - Replaces the `IsAssign` type with `Op`, which has more information and a few methods. - `suggest_swapping_lhs_and_rhs`: moves the condition to the call site, it's easier that way. - `check_expr_inner`: had to factor out some code into a separate method. I'm on the fence about whether avoiding the nonsensical combinations is worth the extra code.
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.
2025-04-01Move `ast::Item::ident` into `ast::ItemKind`.Nicholas Nethercote-159/+202
`ast::Item` has an `ident` field. - It's always non-empty for these item kinds: `ExternCrate`, `Static`, `Const`, `Fn`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`, `Trait`, `TraitAlias`, `MacroDef`, `Delegation`. - It's always empty for these item kinds: `Use`, `ForeignMod`, `GlobalAsm`, `Impl`, `MacCall`, `DelegationMac`. There is a similar story for `AssocItemKind` and `ForeignItemKind`. Some sites that handle items check for an empty ident, some don't. This is a very C-like way of doing things, but this is Rust, we have sum types, we can do this properly and never forget to check for the exceptional case and never YOLO possibly empty identifiers (or possibly dummy spans) around and hope that things will work out. The commit is large but it's mostly obvious plumbing work. Some notable things. - `ast::Item` got 8 bytes bigger. This could be avoided by boxing the fields within some of the `ast::ItemKind` variants (specifically: `Struct`, `Union`, `Enum`). I might do that in a follow-up; this commit is big enough already. - For the visitors: `FnKind` no longer needs an `ident` field because the `Fn` within how has one. - In the parser, the `ItemInfo` typedef is no longer needed. It was used in various places to return an `Ident` alongside an `ItemKind`, but now the `Ident` (if present) is within the `ItemKind`. - In a few places I renamed identifier variables called `name` (or `foo_name`) as `ident` (or `foo_ident`), to better match the type, and because `name` is normally used for `Symbol`s. It's confusing to see something like `foo_name.name`.
2025-03-30Simplify expansion for format_args!().Mara Bos-15/+13
Instead of calling new(), we can just use a struct expression directly. Before: Placeholder::new(…, …, …, …) After: Placeholder { position: …, flags: …, width: …, precision: …, }
2025-03-28Don't use `kw::Empty` in `hir::Lifetime::ident`.Nicholas Nethercote-20/+38
`hir::Lifetime::ident` currently sometimes uses `kw::Empty` for elided lifetimes and sometimes uses `kw::UnderscoreLifetime`, and the distinction is used when creating some error suggestions, e.g. in `Lifetime::suggestion` and `ImplicitLifetimeFinder::visit_ty`. I found this *really* confusing, and it took me a while to understand what was going on. This commit replaces all uses of `kw::Empty` in `hir::Lifetime::ident` with `kw::UnderscoreLifetime`. It adds a new field `hir::Lifetime::is_path_anon` that mostly replaces the old empty/underscore distinction and makes things much clearer. Some other notable changes: - Adds a big comment to `Lifetime` talking about permissable field values. - Adds some assertions in `new_named_lifetime` about what ident values are permissible for the different `LifetimeRes` values. - Adds a `Lifetime::new` constructor that does some checking to make sure the `is_elided` and `is_anonymous` states are valid. - `add_static_impl_trait_suggestion` now looks at `Lifetime::res` instead of the ident when creating the suggestion. This is the one case where `is_path_anon` doesn't replace the old empty/underscore distinction. - A couple of minor pretty-printing improvements.
2025-03-28Remove `kw::Extra` checks that are no longer necessary.Nicholas Nethercote-7/+1
Thanks to the introduction of `PatKind::Missing`.
2025-03-28Add `{ast,hir,thir}::PatKind::Missing` variants.Nicholas Nethercote-1/+3
"Missing" patterns are possible in bare fn types (`fn f(u32)`) and similar places. Currently these are represented in the AST with `ast::PatKind::Ident` with no `by_ref`, no `mut`, an empty ident, and no sub-pattern. This flows through to `{hir,thir}::PatKind::Binding` for HIR and THIR. This is a bit nasty. It's very non-obvious, and easy to forget to check for the exceptional empty identifier case. This commit adds a new variant, `PatKind::Missing`, to do it properly. The process I followed: - Add a `Missing` variant to `{ast,hir,thir}::PatKind`. - Chang `parse_param_general` to produce `ast::PatKind::Missing` instead of `ast::PatKind::Missing`. - Look through `kw::Empty` occurrences to find functions where an existing empty ident check needs replacing with a `PatKind::Missing` check: `print_param`, `check_trait_item`, `is_named_param`. - Add a `PatKind::Missing => unreachable!(),` arm to every exhaustive match identified by the compiler. - Find which arms are actually reachable by running the test suite, changing them to something appropriate, usually by looking at what would happen to a `PatKind::Ident`/`PatKind::Binding` with no ref, no `mut`, an empty ident, and no subpattern. Quite a few of the `unreachable!()` arms were never reached. This makes sense because `PatKind::Missing` can't happen in every pattern, only in places like bare fn tys and trait fn decls. I also tried an alternative approach: modifying `ast::Param::pat` to hold an `Option<P<Pat>>` instead of a `P<Pat>`, but that quickly turned into a very large and painful change. Adding `PatKind::Missing` is much easier.
2025-03-26Rollup merge of #138954 - compiler-errors:hash-opaques, r=oli-obkStuart Cook-1/+1
Ensure `define_opaque` attrs are accounted for in HIR hash Fixes #138948 r? oli-obk
2025-03-25Rollup merge of #138911 - compiler-errors:define-opaque, r=oli-obkJacob Pratt-18/+54
Allow defining opaques in statics and consts r? oli-obk Fixes https://github.com/rust-lang/rust/issues/138902