about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/thir.rs
AgeCommit message (Collapse)AuthorLines
2025-08-14Apply suggestions from code reviewRalf Jung-3/+3
Co-authored-by: Boxy <rust@boxyuwu.dev>
2025-08-14shrink TestBranch::Constant and PatRangeBoundary::FiniteRalf Jung-6/+9
2025-08-14use ty::Value instead of manual pairs of types and valtreesRalf Jung-22/+15
2025-08-14pattern testing: store constants as valtreesRalf Jung-45/+28
2025-08-14PatKind: store constants as valtreesRalf Jung-3/+6
2025-07-28Raw Pointers are Constant PatKinds tooBoxy-0/+2
2025-07-01loop match: run exhaustiveness checkFolkert de Vries-3/+11
2025-06-30Introduce `ByteSymbol`.Nicholas Nethercote-1/+1
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.
2025-06-23Add `#[loop_match]` for improved DFA codegenbjorn3-0/+13
Co-authored-by: Folkert de Vries <folkert@folkertdev.nl>
2025-05-02Add useful comments on `ExprKind::If` variants.Nicholas Nethercote-0/+3
Things that aren't obvious and took me a while to work out.
2025-04-24lower deref patterns on boxes using built-in derefsdianne-1/+6
This allows deref patterns to move out of boxes. Implementation-wise, I've opted to put the information of whether a deref pattern uses a built-in deref or a method call in the THIR. It'd be a bit less code to check `.is_box()` everywhere, but I think this way feels more robust (and we don't have a `mutability` field in the THIR that we ignore when the smart pointer's a box). I'm not sure about the naming (or using `ByRef`), though.
2025-04-07Rollup merge of #139108 - Nadrieril:simplify-expandedconstant, r=oli-obkStuart Cook-14/+8
Simplify `thir::PatKind::ExpandedConstant` I made it a bit less ad-hoc. In particular, I removed `is_inline: bool` that was just caching the output of `tcx.def_kind(def_id)`. This makes inline consts a tiny bit less special in patterns. r? `@oli-obk` cc `@Zalathar`
2025-04-07Rollup merge of #139035 - nnethercote:PatKind-Missing, r=oli-obkStuart Cook-0/+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-06Remove the `is_inline` field from `PatKind::ExpandedConstant`Nadrieril-14/+8
2025-04-03Tighten up assignment operator representations.Nicholas Nethercote-2/+2
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-03-28Add `{ast,hir,thir}::PatKind::Missing` variants.Nicholas Nethercote-0/+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-21match lowering cleanup: `non_scalar_compare` is only for `&str`dianne-3/+3
Since array and slice constants are now lowered to array and slice patterns, `non_scalar_compare` was only called for string comparisons. This specializes it to strings, renames it, and removes the unused array-unsizing logic. This also updates some outdated doc comments.
2025-03-18Extract `for_each_immediate_subpat` from THIR pattern visitorsZalathar-21/+2
2025-03-16Split `visit_primary_bindings` into two variantsZalathar-0/+4
The existing method does some non-obvious extra work to collect user types and build user-type projections, which is specifically needed by `declare_bindings` and not by the other two callers.
2025-03-07Rollup merge of #134797 - spastorino:ergonomic-ref-counting-1, r=nikomatsakisMatthias Krüger-0/+8
Ergonomic ref counting This is an experimental first version of ergonomic ref counting. This first version implements most of the RFC but doesn't implement any of the optimizations. This was left for following iterations. RFC: https://github.com/rust-lang/rfcs/pull/3680 Tracking issue: https://github.com/rust-lang/rust/issues/132290 Project goal: https://github.com/rust-lang/rust-project-goals/issues/107 r? ```@nikomatsakis```
2025-03-06Implement .use keyword as an alias of cloneSantiago Pastorino-0/+8
2025-02-27Add note to Thir struct about necessity of Clone deriveNiels Saurer-0/+3
2025-02-27Revert "Derive `Clone` on fewer THIR types."Niels Saurer-22/+22
This reverts commit f0b6d660c9c13ab7b19da9e12aeb4dcab45e544b.
2025-02-23Rollup merge of #137180 - compiler-errors:sym-regions, r=oli-obkMatthias Krüger-2/+2
Give `global_asm` a fake body to store typeck results, represent `sym fn` as a hir expr to fix `sym fn` operands with lifetimes There are a few intertwined problems with `sym fn` operands in both inline and global asm macros. Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length). Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like `'static`, since we may want to use real (free) regions: ```rust fn foo<'a>() { asm!("/* ... */", sym bar::<&'a ()>); } ``` The first idea may be to represent `sym fn` operands using *inline* consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the `'a` in the example above). However, this introduces a problem with `global_asm!`, which doesn't *have* a parent body; inline consts *must* be associated with a parent body since they are not a body owner of their own. In #116087, I attempted to fix this by using two separate `sym` operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication. In this PR, I adjust the lowering of `global_asm!` so that it's lowered in a "fake" HIR body. This body contains a single expression which is `ExprKind::InlineAsm`; we don't *use* this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of `sym fn` operands. I then adjust the lowering of `sym fn` to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's *just* a path expression, and also more importantly to sidestep yet another ICE (https://github.com/rust-lang/rust/issues/137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is *not* that anon const. This is somewhat related to https://github.com/rust-lang/rust/pull/130443#issuecomment-2445678945, which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue. As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify `InlineAsmCtxt` a bit. It also allows us to delete a bit of hacky code from anon const `type_of` which was there to detect `sym fn` operands specifically. This also could be generalized to support `const` asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts). r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this. Fixes #111709 Fixes #96304 Fixes #137179
2025-02-22Fix binding mode problemsMichael Goulet-2/+1
2025-02-22Make a fake body to store typeck results for global_asmMichael Goulet-2/+2
2025-02-18Remove scrutinee_hir_id from ExprKind::Matchbjorn3-1/+0
It is unused
2025-02-11Simplify intra-crate qualifiers.Nicholas Nethercote-9/+10
The following is a weird pattern for a file within `rustc_middle`: ``` use rustc_middle::aaa; use crate::bbb; ``` More sensible and standard would be this: ``` use crate::{aaa, bbb}; ``` I.e. we generally prefer using `crate::` to using a crate's own name. (Exceptions are things like in macros where `crate::` doesn't work because the macro is used in multiple crates.) This commit fixes a bunch of these weird qualifiers.
2025-02-06Rollup merge of #136435 - Zalathar:thir-pat-stuff, r=NadrierilMatthias Krüger-8/+9
Simplify some code for lowering THIR patterns I've been playing around with some radically different ways of storing THIR patterns, and while those experiments haven't yet produced a clear win, I have noticed various smaller things in the existing code that can be made a bit nicer. Some of the more significant changes: - With a little bit of extra effort (and thoughtful use of Arc), we can completely remove an entire layer of `'pat` lifetimes from the intermediate data structures used for match lowering. - In several places, lists of THIR patterns were being double-boxed for no apparent reason.
2025-02-04Rollup merge of #136465 - nnethercote:rustc_middle-MORE, r=jieyouxuJacob Pratt-13/+3
Some `rustc_middle` cleanups Small cleanups I found while looking closely at this code. r? `@jieyouxu`
2025-02-04Simplify `thir_with_elements` macro.Nicholas Nethercote-13/+3
The `field_name`/`field_ty` don't need to be parameters, they can be hardcoded.
2025-02-03Rollup merge of #136455 - nnethercote:less-Clone, r=compiler-errors许杰友 Jieyou Xu (Joe)-22/+22
Remove some `Clone` bounds and derives. r? `@cjgillot`
2025-02-03Avoid double-boxing lists of THIR subpatternsZalathar-7/+7
2025-02-03Remove `'pat` lifetime from some match-lowering data structuresZalathar-1/+2
By storing `PatRange` in an Arc, and copying a few fields out of `Pat`, we can greatly simplify the lifetimes involved in match lowering.
2025-02-03Derive `Clone` on fewer THIR types.Nicholas Nethercote-22/+22
Some of these were never necessary, and some were facilitated by the previous commit.
2025-01-31Implement MIR, CTFE, and codegen for unsafe bindersMichael Goulet-0/+13
2024-12-09Introduce `default_field_values` featureEsteban Küber-2/+15
Initial implementation of `#[feature(default_field_values]`, proposed in https://github.com/rust-lang/rfcs/pull/3681. Support default fields in enum struct variant Allow default values in an enum struct variant definition: ```rust pub enum Bar { Foo { bar: S = S, baz: i32 = 42 + 3, } } ``` Allow using `..` without a base on an enum struct variant ```rust Bar::Foo { .. } ``` `#[derive(Default)]` doesn't account for these as it is still gating `#[default]` only being allowed on unit variants. Support `#[derive(Default)]` on enum struct variants with all defaulted fields ```rust pub enum Bar { #[default] Foo { bar: S = S, baz: i32 = 42 + 3, } } ``` Check for missing fields in typeck instead of mir_build. Expand test with `const` param case (needs `generic_const_exprs` enabled). Properly instantiate MIR const The following works: ```rust struct S<A> { a: Vec<A> = Vec::new(), } S::<i32> { .. } ``` Add lint for default fields that will always fail const-eval We *allow* this to happen for API writers that might want to rely on users' getting a compile error when using the default field, different to the error that they would get when the field isn't default. We could change this to *always* error instead of being a lint, if we wanted. This will *not* catch errors for partially evaluated consts, like when the expression relies on a const parameter. Suggestions when encountering `Foo { .. }` without `#[feature(default_field_values)]`: - Suggest adding a base expression if there are missing fields. - Suggest enabling the feature if all the missing fields have optional values. - Suggest removing `..` if there are no missing fields.
2024-11-20Auto merge of #133261 - matthiaskrgr:rollup-ekui4we, r=matthiaskrgrbors-6/+11
Rollup of 6 pull requests Successful merges: - #129838 (uefi: process: Add args support) - #130800 (Mark `get_mut` and `set_position` in `std::io::Cursor` as const.) - #132708 (Point at `const` definition when used instead of a binding in a `let` statement) - #133226 (Make `PointerLike` opt-in instead of built-in) - #133244 (Account for `wasm32v1-none` when exporting TLS symbols) - #133257 (Add `UnordMap::clear` method) r? `@ghost` `@rustbot` modify labels: rollup
2024-11-20Rollup merge of #132708 - estebank:const-as-binding, r=NadrierilMatthias Krüger-6/+11
Point at `const` definition when used instead of a binding in a `let` statement Modify `PatKind::InlineConstant` to be `ExpandedConstant` standing in not only for inline `const` blocks but also for `const` items. This allows us to track named `const`s used in patterns when the pattern is a single binding. When we detect that there is a refutable pattern involving a `const` that could have been a binding instead, we point at the `const` item, and suggest renaming. We do this for both `let` bindings and `match` expressions missing a catch-all arm if there's at least one single binding pattern referenced. After: ``` error[E0005]: refutable pattern in local binding --> $DIR/bad-pattern.rs:19:13 | LL | const PAT: u32 = 0; | -------------- missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable ... LL | let PAT = v1; | ^^^ pattern `1_u32..=u32::MAX` not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `u32` help: introduce a variable instead | LL | let PAT_var = v1; | ~~~~~~~ ``` Before: ``` error[E0005]: refutable pattern in local binding --> $DIR/bad-pattern.rs:19:13 | LL | let PAT = v1; | ^^^ | | | pattern `1_u32..=u32::MAX` not covered | missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable | help: introduce a variable instead: `PAT_var` | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `u32` ``` CC #132582.
2024-11-20reduce false positives of tail-expr-drop-order from consumed valuesDing Xiang Fei-3/+14
take 2 open up coroutines tweak the wordings the lint works up until 2021 We were missing one case, for ADTs, which was causing `Result` to yield incorrect results. only include field spans with significant types deduplicate and eliminate field spans switch to emit spans to impl Drops Co-authored-by: Niko Matsakis <nikomat@amazon.com> collect drops instead of taking liveness diff apply some suggestions and add explantory notes small fix on the cache let the query recurse through coroutine new suggestion format with extracted variable name fine-tune the drop span and messages bugfix on runtime borrows tweak message wording filter out ecosystem types earlier apply suggestions clippy check lint level at session level further restrict applicability of the lint translate bid into nop for stable mir detect cycle in type structure
2024-11-18use `TypingEnv` when no `infcx` is availablelcnr-12/+17
the behavior of the type system not only depends on the current assumptions, but also the currentnphase of the compiler. This is mostly necessary as we need to decide whether and how to reveal opaque types. We track this via the `TypingMode`.
2024-11-17review comment: modify doc commentEsteban Küber-4/+2
2024-11-17review commentsEsteban Küber-2/+5
2024-11-17Unify expanded constants and named constants in `PatKind`Esteban Küber-10/+12
2024-11-17Fold `PatKind::NamedConstant` into `PatKind::Constant`Esteban Küber-7/+2
2024-11-17Point at `const` definition when used instead of a binding in a `let` statementEsteban Küber-2/+9
After: ``` error[E0005]: refutable pattern in local binding --> $DIR/bad-pattern.rs:19:13 | LL | const PAT: u32 = 0; | -------------- missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable ... LL | let PAT = v1; | ^^^ | | | pattern `1_u32..=u32::MAX` not covered | help: introduce a variable instead: `PAT_var` | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `u32` ``` Before: ``` error[E0005]: refutable pattern in local binding --> $DIR/bad-pattern.rs:19:13 | LL | let PAT = v1; | ^^^ | | | pattern `1_u32..=u32::MAX` not covered | missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable | help: introduce a variable instead: `PAT_var` | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `u32` ```
2024-11-03compiler: Directly use rustc_abi in metadata and middleJubilee Young-2/+2
Stop reexporting ReprOptions from middle::ty
2024-10-06various fixes for `naked_asm!` implementationFolkert de Vries-1/+2
- fix for divergence - fix error message - fix another cranelift test - fix some cranelift things - don't set the NORETURN option for naked asm - fix use of naked_asm! in doc comment - fix use of naked_asm! in run-make test - use `span_bug` in unreachable branch
2024-09-24be even more precise about "cast" vs "coercion"Lukas Markeffsky-0/+2
2024-09-24use more accurate spans for user type ascriptionsLukas Markeffsky-1/+3