about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/thir
AgeCommit message (Collapse)AuthorLines
2025-07-01loop match: run exhaustiveness checkFolkert de Vries-1/+3
2025-06-23Add `#[loop_match]` for improved DFA codegenbjorn3-1/+2
Co-authored-by: Folkert de Vries <folkert@folkertdev.nl>
2025-06-04Improve some `Visitor` comments.Nicholas Nethercote-0/+3
For AST/HIR/THIR visitors, explain the use of deconstruction.
2025-06-03Deconstruct values in the THIR visitorArtemIsmagilov-10/+16
2025-03-28Add `{ast,hir,thir}::PatKind::Missing` variants.Nicholas Nethercote-1/+2
"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-18Extract `for_each_immediate_subpat` from THIR pattern visitorsZalathar-25/+34
2025-03-06Implement .use keyword as an alias of cloneSantiago Pastorino-0/+3
2025-02-23Rollup merge of #137180 - compiler-errors:sym-regions, r=oli-obkMatthias Krüger-1/+1
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-1/+1
2025-02-22Make a fake body to store typeck results for global_asmMichael Goulet-1/+1
2025-02-04Fix an inconsistent import.Nicholas Nethercote-3/+2
2025-01-31Implement MIR, CTFE, and codegen for unsafe bindersMichael Goulet-0/+3
2024-12-09Introduce `default_field_values` featureEsteban Küber-1/+2
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-17Unify expanded constants and named constants in `PatKind`Esteban Küber-2/+2
2024-11-17Fold `PatKind::NamedConstant` into `PatKind::Constant`Esteban Küber-1/+1
2024-11-17Point at `const` definition when used instead of a binding in a `let` statementEsteban Küber-1/+1
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-10-06various fixes for `naked_asm!` implementationFolkert de Vries-1/+7
- 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-1/+3
2024-09-24use more accurate spans for user type ascriptionsLukas Markeffsky-1/+2
2024-08-18rename AddressOf -> RawBorrow inside the compilerRalf Jung-1/+1
2024-04-20Track mutability of deref patternsNadrieril-1/+1
2024-03-27Implement `mut ref`/`mut ref mut`Jules Bertholet-9/+1
2024-03-20Add barest-bones deref patternsNadrieril-0/+1
Co-authored-by: Deadbeef <ent3rm4n@gmail.com>
2024-02-24Add asm label support to THIRGary Guo-0/+1
2024-01-05Remove `thir::Guard`Matthew Jasper-8/+3
Use Expr instead. Use `ExprKind::Let` to represent if let guards.
2023-12-26`thir::Visitor` only needs to visit `&'thir` dataNadrieril-12/+27
2023-11-29Add `never_patterns` feature gateNadrieril-1/+1
2023-11-21Fix `clippy::needless_borrow` in the compilerNilstrieb-2/+2
`x clippy compiler -Aclippy::all -Wclippy::needless_borrow --fix`. Then I had to remove a few unnecessary parens and muts that were exposed now.
2023-11-06Visit patterns in THIR let expressionsMatthew Jasper-1/+2
This fixes some THIR unsafety checking errors not being emitted for let expressions in these situations.
2023-10-16Address review commentsMatthew Jasper-1/+1
Clean up code and add comments. Use InlineConstant to wrap range patterns.
2023-10-16Fix inline const pattern unsafety checking in THIRMatthew Jasper-3/+4
THIR unsafety checking was getting a cycle of function unsafety checking -> building THIR for the function -> evaluating pattern inline constants in the function -> building MIR for the inline constant -> checking unsafety of functions (so that THIR can be stolen) This is fixed by not stealing THIR when generating MIR but instead when unsafety checking. This leaves an issue with pattern inline constants not being unsafety checked because they are evaluated away when generating THIR. To fix that we now represent inline constants in THIR patterns and visit them in THIR unsafety checking.
2023-10-14Propagate pattern errors via a new `PatKind::Error` variantNadrieril-1/+1
Instead of via `Const::new_error`
2023-09-21rename mir::Constant -> mir::ConstOperand, mir::ConstKind -> mir::ConstRalf Jung-3/+3
2023-08-14Move scrutinee `HirId` into `MatchSource::TryDesugar`Esteban Küber-1/+1
2023-07-14refactor(rustc_middle): Substs -> GenericArgMahdi Dibaiee-5/+5
2023-07-07Rename `adjustment::PointerCast` and variants using it to `PointerCoercion`Nilstrieb-1/+1
It makes it sound like the `ExprKind` and `Rvalue` are supposed to represent all pointer related casts, when in reality their just used to share a some enum variants. Make it clear there these are only coercion to make it clear why only some pointer related "casts" are in the enum.
2023-06-27`thir`: Add `Become` expression kindMaybe Waffle-0/+1
2023-04-21offset_ofDrMeepster-0/+1
2023-04-03Add Span to StmtKind::Let.Camille GILLOT-0/+1
2023-02-26Move THIR printing to rustc_mir_build.Camille GILLOT-881/+0
2023-01-27address reviewb-naber-7/+7
2023-01-26output tree representation for thir-treeb-naber-0/+881
2022-09-02Use boxed slices in `PatKind`.Nicholas Nethercote-3/+3
To shrink it a little more.
2022-09-02Clean up THIR patterns.Nicholas Nethercote-2/+2
`thir::Pat::kind` is a `Box<PatKind>`, which doesn't follow the usual pattern in AST/HIR/THIR which is that the "kind" enum for a node is stored inline within the parent struct. This commit makes the `PatKind` directly inline within the `Pat`. This requires using `Box<Pat>` in all the types that hold a `Pat. Ideally, `Pat` would be stored in `Thir` like `Expr` and `Stmt` and referred to with a `PatId` rather than `Box<Pat>`. But this is hard to do because lots of `Pat`s get created after the destruction of the `Cx` that does normal THIR building. But this does get us a step closer to `PatId`, because all the `Box<Pat>` occurrences would be replaced with `PatId` if `PatId` ever happened. At 128 bytes, `Pat` is large. Subsequent commits will shrink it.
2022-08-24Rename `thir::Adt` as `thir::AdtExpr`.Nicholas Nethercote-3/+3
This matches the naming scheme used elsewhere, e.g. in the AST, and avoids name clashes with the `ExprKind::Closure` variant.
2022-08-24Box `thir::ExprKind::InlineAsm`.Nicholas Nethercote-2/+2
This shrinks `thir::Expr`.
2022-08-24Box `thir::ExprKind::Closure`.Nicholas Nethercote-2/+9
This shrinks `thir::Expr`.
2022-08-24Store blocks in `Thir`.Nicholas Nethercote-2/+2
Like expressions, statements, and match arms. This shrinks `thir::Stmt` and is a precursor to further shrinking `thir::Expr`.
2022-07-14Rollup merge of #99000 - JulianKnodt:allow_resolve_no_substs, r=lcnrDylan DPC-61/+0
Move abstract const to middle Moves AbstractConst (and all associated methods) to rustc middle for use in `rustc_infer`. This allows for const resolution in infer to use abstract consts to walk consts and check if they are resolvable. This attempts to resolve the issue where `Foo<{ concrete const }, generic T>` is incorrectly marked as conflicting, and is independent from the other issue where nested abstract consts must be resolved. r? `@lcnr`
2022-07-12Move abstract const to rustc_middle::tykadmin-61/+0