about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
AgeCommit message (Collapse)AuthorLines
2025-02-22Remove UnifyReceiver cause codeMichael Goulet-10/+0
2025-02-22Rollup merge of #137399 - lukas-code:oopsie-woopsie, r=compiler-errorsMatthias Krüger-1/+4
fix ICE in layout computation with unnormalizable const The first commit reverts half of 7a667d206c45b96676c260030a4e3d9be1cc8495, where I removed a case from `layout_of` for handling non-generic unevaluated consts in array length, that I incorrectly assumed to be unreachable. This can actually happen with the combination of `feature(generic_const_exprs)` and `feature(trivial_bounds)`, because GCE makes anon consts inherit their parent's predicates and with an impossible predicate like `u8: A` it's possible to have an array whose length is an associated const like `<u8 as A>::B` that is not generic, but also can't be normalized: ```rust #![feature(generic_const_exprs)] #![feature(trivial_bounds)] trait A { const B: usize; } // With GCE + trivial bounds this definition is not a compile error. // Computing the layout of this type shouldn't ICE. struct S([u8; <u8 as A>::B]) where u8: A; ``` --- The first commit also incidentally fixes https://github.com/rust-lang/rust/issues/137308, which also managed to get an unnormalizable assoc const into an array length: ```rust trait A { const B: usize; } impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained const B: usize = 42; } // Computing the layout of this type shouldn't ICE, even with the compile error above. struct S([u8; <u8 as A>::B]); ``` This happens, because we bail out from `codegen_select_candidate` with an error if the selected impl has unconstrained params to avoid leaking infer vars out of a query. `Instance::try_resolve` will then return `Ok(None)`, which for assoc consts roughly means "this const can't be evaluated in a generic context" and is treated as such: https://github.com/rust-lang/rust/blob/71e06b9c59d6af50fdc55aed75620493d29baf98/compiler/rustc_middle/src/mir/interpret/queries.rs#L84 (and this can ICE if the const isn't generic: https://github.com/rust-lang/rust/issues/135617). However, here `<u8 as A>::B` is definitely not "too generic" and also not unresolvable due to an unsatisfiable `u8: A` bound, so I've included the second commit to change the result of `Instance::try_resolve` from `Ok(None)` to `Err(ErrorGuaranteed)` when resolving an assoc item to an impl with unconstrained generic params. This has the effect that `<u8 as A>::B` will now be normalized to `ConstKind::Error` in the example above. This properly fixes https://github.com/rust-lang/rust/issues/137308, by no longer treating `<u8 as A>::B` as unresolvable even though it clearly has a unique impl that it resolves to. It also has the effect of changing the layout error from `Unknown` ("the type may be valid but has no sensible layout") to `ReferencesError` ("a non-layout error is reported elsewhere") which seems more appropriate. r? ```@compiler-errors```
2025-02-22Rollup merge of #137257 - compiler-errors:fake-borrow-of-packed-field, r=oli-obkMatthias Krüger-4/+4
Ignore fake borrows for packed field check We should not emit unaligned packed field reference errors for the fake borrows that we generate during match lowering. These fake borrows are there to ensure in *borrow-checking* that we don't modify the value being matched (which is why this only occurs when there's a match guard, in this case `if true`), but they are removed after the MIR is processed by `CleanupPostBorrowck`, since they're really just there to cause borrowck errors if necessary. I modified `PlaceContext::is_borrow` since that's used by the packed field check: https://github.com/rust-lang/rust/blob/17c1c329a5512d718b67ef6797538b154016cd34/compiler/rustc_mir_transform/src/check_packed_ref.rs#L40 It's only used in one other place, in the SROA optimization (by which fake borrows are removed, so it doesn't matter): https://github.com/rust-lang/rust/blob/17c1c329a5512d718b67ef6797538b154016cd34/compiler/rustc_mir_dataflow/src/value_analysis.rs#L922 Fixes https://github.com/rust-lang/rust/issues/137250
2025-02-22Rollup merge of #136458 - compiler-errors:fix-3, r=lcnrMatthias Krüger-15/+36
Do not deduplicate list of associated types provided by dyn principal ## Background The way that we handle a dyn trait type's projection bounds is very *structural* today. A dyn trait is represented as a list of `PolyExistentialPredicate`s, which in most cases will be a principal trait (like `Iterator`) and a list of projections (like `Item = u32`). Importantly, the list of projections comes from user-written associated type bounds on the type *and* from elaborating the projections from the principal's supertraits. For example, given a set of traits like: ```rust trait Foo<T> { type Assoc; } trait Bar<A, B>: Foo<A, Assoc = A> + Foo<B, Assoc = B> {} ``` For the type `dyn Bar<i32, u32>`, the list of projections will be something like `[Foo<i32>::Assoc = i32, Foo<u32>::Assoc = u32]`. We deduplicate these projections when they're identical, so for `dyn Bar<(), ()>` would be something like `[Foo<()>::Assoc = ()]`. ## Shortcomings 1: inference We face problems when we begin to mix this structural notion of projection bounds with inference and associated type normalization. For example, let's try calling a generic function that takes `dyn Bar<A, B>` with a value of type `dyn Bar<(), ()>`: ```rust trait Foo<T> { type Assoc; } trait Bar<A, B>: Foo<A, Assoc = A> + Foo<B, Assoc = B> {} fn call_bar<A, B>(_: &dyn Bar<A, B>) {} fn test(x: &dyn Bar<(), ()>) { call_bar(x); // ^ ERROR mismatched types } ``` ``` error[E0308]: mismatched types --> /home/mgx/test.rs:10:14 | 10 | call_bar(x); | -------- ^ expected trait `Bar<_, _>`, found trait `Bar<(), ()>` ``` What's going on here? Well, when calling `call_bar`, the generic signature `&dyn Bar<?A, ?B>` does not unify with `&dyn Bar<(), ()>` because the list of projections differ -- `[Foo<?A>::Assoc = ?A, Foo<?B>::Assoc = ?B]` vs `[Foo<()>::Assoc = ()]`. A simple solution to this may be to unify the principal traits first, then attempt to deduplicate them after inference. In this case, if we constrain `?A = ?B = ()`, then we would be able to deduplicate those projections in the first list. However, this idea is still pretty fragile, and it's not a complete solution. ## Shortcomings 2: normalization Consider a slightly modified example: ```rust //@ compile-flags: -Znext-solver trait Mirror { type Assoc; } impl<T> Mirror for T { type Assoc = T; } fn call_bar(_: &dyn Bar<(), <() as Mirror>::Assoc>) {} fn test(x: &dyn Bar<(), ()>) { call_bar(x); } ``` This fails in the new solver. In this example, we try to unify `dyn Bar<(), ()>` and `dyn Bar<(), <() as Mirror>::Assoc>`. We are faced with the same problem even though there are no inference variables, and making this work relies on eagerly and deeply normalizing all projections so that they can be structurally deduplicated. This is incompatible with how we handle associated types in the new trait solver, and while we could perhaps support it with some major gymnastics in the new solver, it suggests more fundamental shortcomings with how we deal with projection bounds in the new solver. ## Shortcomings 3: redundant projections Consider a final example: ```rust trait Foo { type Assoc; } trait Bar: Foo<Assoc = ()> {} fn call_bar1(_: &dyn Bar) {} fn call_bar2(_: &dyn Bar<Assoc = ()>) {} fn main() { let x: &dyn Bar<Assoc = _> = todo!(); call_bar1(x); //~^ ERROR mismatched types call_bar2(x); //~^ ERROR mismatched types } ``` In this case, we have a user-written associated type bound (`Assoc = _`) which overlaps the bound that comes from the supertrait projection of `Bar` (namely, `Foo<Assoc = ()>`). In a similar way to the two examples above, this causes us to have a projection list mismatch that the compiler is not able to deduplicate. ## Solution ### Do not deduplicate after elaborating projections when lowering `dyn` types The root cause of this issue has to do with mismatches of the deduplicated projection list before and after substitution or inference. This PR aims to avoid these issues by *never* deduplicating the projection list after elaborating the list of projections from the *identity* substituted principal trait ref. For example, ```rust trait Foo<T> { type Assoc; } trait Bar<A, B>: Foo<A, Assoc = A> + Foo<B, Assoc = B> {} ``` When computing the projections for `dyn Bar<(), ()>`, before this PR we'd elaborate `Bar<(), ()>` to find a (deduplicated) projection list of `[Foo<()>::Assoc = ()]`. After this PR, we take the principal trait and use its *identity* substitutions `Bar<A, B>` during elaboration, giving us projections `[Foo<A>::Assoc = A, Foo<B>::Assoc = B]`. Only after this elaboration do we substitute `A = (), B = ()` to get `[Foo<()>::Assoc = (), Foo<()>::Assoc = ()]`. This allows the type to be unified with the projections for `dyn Bar<?A, ?B>`, which are `[Foo<?A>::Assoc = ?A, Foo<?B>::Assoc = ?B]`. This helps us avoid shorcomings 1 noted above. ### Do not deduplicate projections when relating `dyn` types Similarly, we also do not call deduplicate when relating dyn types. This means that the list of projections does not differ depending on if the type has been normalized or not, which should avoid shortcomings 2 noted above. Following from the example above, when relating projection lists like `[Foo<()>::Assoc = (), Foo<()>::Assoc = ()]` and `[Foo<?A>::Assoc = ?A, Foo<?B>::Assoc = ?B]`, the latter won't be deduplicated to a list of length 1 which would immediately fail to relate to the latter which is a list of length 2. ### Implement proper precedence between supertrait and user-written projection bounds when lowering `dyn` types ```rust trait Foo { type Assoc; } trait Bar: Foo<Assoc = ()> {} ``` Given a type like `dyn Foo<Assoc = _>`, we used to previously include *both* the supertrait and user-written associated type bounds in the projection list, giving us `[Foo::Assoc = (), Foo::Assoc = _]`. This would never unify with `dyn Foo`. However, this PR implements a strategy which overwrites the supertrait associated type bound with the one provided by the user, giving us a projection list of `[Foo::Assoc = _]`. Why is this OK? Well, if a user wrote an associated type bound that is unsatisfiable (e.g. `dyn Bar<Assoc = i32>`) then the dyn type would never implement `Bar` or `Foo` anyways. If the user wrote something that is either structurally equal or equal modulo normalization to the supertrait bound, then it should be unaffected. And if the user wrote something that needs inference guidance (e.g. `dyn Bar<Assoc = _>`), then it'll be constrained when proving `dyn Bar<Assoc = _>: Bar`. Importantly, this differs from the strategy in https://github.com/rust-lang/rust/pull/133397, which preferred the *supertrait* bound and ignored the user-written bound. While that's also theoretically justifiable in its own way, it does lead to code which does not (and probably should not) compile either today or after this PR, like: ```rust trait IteratorOfUnit: Iterator<Item = ()> {} impl<T> IteratorOfUnit for T where T: Iterator<Item = ()> {} fn main() { let iter = [()].into_iter(); let iter: &dyn IteratorOfUnit<Item = i32> = &iter; } ``` ### Conclusion This is a far less invasive change compared to #133397, and doesn't necessarily necessitate the addition of new lints or any breakage of existing code. While we could (and possibly should) eventually introduce lints to warn users of redundant or mismatched associated type bounds, we don't *need* to do so as part of fixing this unsoundness, which leads me to believe this is a much safer solution.
2025-02-21Auto merge of #137397 - matthiaskrgr:rollup-ls2pilo, r=matthiaskrgrbors-57/+57
Rollup of 10 pull requests Successful merges: - #132876 (rustdoc book: acknowledge --document-hidden-items) - #136148 (Optionally add type names to `TypeId`s.) - #136609 (libcore/net: `IpAddr::as_octets()`) - #137336 (Stabilise `os_str_display`) - #137350 (Move methods from Map to TyCtxt, part 3.) - #137353 (Implement `read_buf` for WASI stdin) - #137361 (Refactor `OperandRef::extract_field` to prep for MCP838) - #137367 (Do not exempt nonexistent platforms from platform policy) - #137374 (Stacker now handles miri using a noop impl itself) - #137392 (remove few unused fields) r? `@ghost` `@rustbot` modify labels: rollup
2025-02-21Assert that we always construct dyn types with the right number of projectionsMichael Goulet-1/+32
2025-02-21Do not deduplicate list of associated types provided by dyn principalMichael Goulet-14/+4
2025-02-21don't leave assoc const unnormalized due to unconstrained paramsLukas Markeffsky-1/+4
2025-02-21Rollup merge of #137392 - klensy:unused, r=compiler-errorsMatthias Krüger-3/+1
remove few unused fields Remove unused field and convert hashmap to hashset in second commit.
2025-02-21Rollup merge of #137350 - nnethercote:remove-Map-3, r=ZalatharMatthias Krüger-54/+56
Move methods from Map to TyCtxt, part 3. A follow-up to #137162. r? `@Zalathar`
2025-02-21Ignore fake borrows for packed field checkMichael Goulet-4/+4
2025-02-21convert all_macro_rules from hashmap to hashsetklensy-1/+1
2025-02-21remove unused pred_rcacheklensy-2/+0
2025-02-21Rollup merge of #137305 - nnethercote:rustc_middle-2, r=lcnrMatthias Krüger-48/+23
Tweaks in and around `rustc_middle` A bunch of tiny improvements I found while working on bigger things. r? ```@lcnr```
2025-02-21Rollup merge of #137299 - nnethercote:simplify-PostOrder-customization, ↵Matthias Krüger-35/+14
r=compiler-errors Simplify `Postorder` customization. `Postorder` has a `C: Customization<'tcx>` parameter, that gives it flexibility about how it computes successors. But in practice, there are only two `impls` of `Customization`, and one is for the unit type. This commit simplifies things by removing the generic parameter and replacing it with an `Option`. r? ````@saethlin````
2025-02-21Rollup merge of #137204 - nnethercote:clarify-MIR-dialects-and-phases, ↵Matthias Krüger-60/+64
r=RalfJung Clarify MIR dialects and phases I found the existing code and docs hard to understand. r? `@Zalathar`
2025-02-21Move methods from Map to TyCtxt, part 3.Nicholas Nethercote-38/+40
Continuing the work from #137162. Every method gains a `hir_` prefix.
2025-02-21Store `TyCtxt` instead of `Map` in some iterators.Nicholas Nethercote-19/+19
2025-02-21Clarify a comment.Nicholas Nethercote-1/+1
2025-02-21Make `PassWhere` impl `Copy`.Nicholas Nethercote-1/+1
It's a very small and simple type.
2025-02-21Remove some unnecessary `FIXME` comments.Nicholas Nethercote-3/+0
The comments didn't make much sense to me. I asked Matthew Jasper on Zulip about it and they said: > I think that at the time I wanted to replace all (or most of) this > with a reference to the HIR Id of the variable. I'll give this a look > to see if it's still a reasonable idea, but removing the comments is > fine. and then: > I don't think that changing this to an HirId would be better, > recovering the information from the HIR seems like too much effort in > exchange for making the MIR a little smaller.
2025-02-21Put a `BlockTailInfo` in `BlockFrame::TailExpr`.Nicholas Nethercote-1/+1
Because it has the same fields, and avoids the need to deconstruct the latter to construct the former.
2025-02-21Rename `ClearCrossCrate::assert_crate_local`.Nicholas Nethercote-2/+2
As `unwrap_crate_local`, because it follows exactly the standard form of an `unwrap` function.
2025-02-21Remove unused `Body::span_for_ty_context` method.Nicholas Nethercote-12/+0
2025-02-21Fix a typo in a comment.Nicholas Nethercote-1/+1
2025-02-21Rename `InternedObligationCauseCode`.Nicholas Nethercote-15/+17
It's a misleading name, because it's not interned.
2025-02-20Remove `BackendRepr::Uninhabited`, replaced with an `uninhabited: bool` ↵Zachary S-1/+2
field in `LayoutData`. Also update comments that refered to BackendRepr::Uninhabited.
2025-02-20Turn order dependent trait objects future incompat warning into a hard errorOli Scherer-52/+1
2025-02-20Don't store a redundant span in user-type projectionsZalathar-16/+7
This span is already present in the corresponding `CanonicalUserTypeAnnotation`, and can be retrieved via the annotation's ID.
2025-02-20Avoid a useless clone of `UserTypeProjection`Zalathar-2/+2
2025-02-20Simplify `Postorder` customization.Nicholas Nethercote-35/+14
`Postorder` has a `C: Customization<'tcx>` parameter, that gives it flexibility about how it computes successors. But in practice, there are only two `impls` of `Customization`, and one is for the unit type. This commit simplifies things by removing the generic parameter and replacing it with an `Option`.
2025-02-20Remove unused items from `query.rs`.Nicholas Nethercote-6/+0
2025-02-20Move `StatementAsExpression` to where it's actually used.Nicholas Nethercote-6/+0
Also minimize some visibilities in the destination file.
2025-02-20Rollup merge of #137266 - nnethercote:mir-visitor-tweaks, r=compiler-errorsMatthias Krüger-173/+142
MIR visitor tweaks Some minor improvements I found while looking at this code. r? `@tmandry`
2025-02-20Rollup merge of #137262 - compiler-errors:ast-ir-begone, r=lcnrMatthias Krüger-12/+7
Make fewer crates depend on `rustc_ast_ir` I think it simplifies the crate graph and also exposes people less to confusion if downstream crates don't interact with `rustc_ast_ir` directly and instead just use its functionality reexported through more familiar paths. r? oli-obk since you introduced ast-ir
2025-02-20Improve how the MIR dialect/phase index is reported.Nicholas Nethercote-16/+10
The only visible change is to the filenames produce by `-Zdump-mir`. E.g. before and after: ``` h.main.003-000.analysis-post-cleanup.after.mir h.main.2-2-000.analysis-post-cleanup.after.mir ``` It also fixes a FIXME comment.
2025-02-20Improve MIR phase comments.Nicholas Nethercote-22/+29
I found the dialect/phase distinction quite confusing when I first read these comments. This commit clarifies things a bit.
2025-02-20Reflow `MirPhase` comments.Nicholas Nethercote-22/+25
Currently many of them exceed 100 chars, which makes them painful to read on a terminal that is 100 chars wide.
2025-02-19Add a .bss-like scheme for encoded const allocsBen Kimock-2/+115
2025-02-19Improve formatting within `make_mir_visitor` macro body.Nicholas Nethercote-142/+128
rustfmt doesn't touch it because it's a macro body, but it's large enough that the misformatting is annoying. This commit improves it. The most common problems fixed: - Unnecessary multi-line patterns reduced to one line. - Multi-line function headers adjusted so the parameter indentation doesn't depend on the length of the function name. (This is Rust code, not C.) - `|` used at the start of lines, not the end. - More consistent formatting of empty function bodies. - Overly long lines are broken.
2025-02-19Remove `MirVisitable`.Nicholas Nethercote-27/+0
The `MirVisitable` trait is just a complicated way to visit either a statement or a terminator. (And its impl for `Terminator` is unused.) It has a single use. This commit removes it, replacing it with an if/else, which is shorter and simpler.
2025-02-19Add `super_local` method to the MIR visitors.Nicholas Nethercote-4/+14
`visit_local` is the only method that doesn't call a corresponding `super_local` method. This is valid, because `super_local` would be empty. But it's inconsistent with every other case; we have multiple other empty `super` methods: `super_span`, `super_ty`, etc. This commit adds an empty `super_local` and makes `visit_local` call it.
2025-02-19Auto merge of #136539 - matthewjasper:late-normalize-errors, r=compiler-errorsbors-1/+1
Emit dropck normalization errors in borrowck Borrowck generally assumes that any queries it runs for type checking will succeed, thinking that HIR typeck will have errored first if there was a problem. However as of #98641, dropck isn't run on HIR, so there's no direct guarantee that it doesn't error. While a type being well-formed might be expected to ensure that its fields are well-formed, this is not the case for types containing a type projection: ```rust pub trait AuthUser { type Id; } pub trait AuthnBackend { type User: AuthUser; } pub struct AuthSession<Backend: AuthnBackend> { data: Option<<<Backend as AuthnBackend>::User as AuthUser>::Id>, } pub trait Authz: Sized { type AuthnBackend: AuthnBackend<User = Self>; } pub fn run_query<User: Authz>(auth: AuthSession<User::AuthnBackend>) {} // ^ No User: AuthUser bound is required or inferred. ``` While improvements to trait solving might fix this in the future, for now we go for a pragmatic solution of emitting an error from borrowck (by rerunning dropck outside of a query) and making drop elaboration check if an error has been emitted previously before panicking for a failed normalization. Closes #103899 Closes #135039 r? `@compiler-errors` (feel free to re-assign)
2025-02-19Make fewer crates depend on rustc_ast_irMichael Goulet-12/+7
2025-02-19Rollup merge of #137213 - nnethercote:rm-rustc_middle-mir-tcx, r=compiler-errorsMatthias Krüger-418/+397
Remove `rustc_middle::mir::tcx` module. This is a really weird module. For example, what does `tcx` in `rustc_middle::mir::tcx::PlaceTy` mean? The answer is "not much". The top-level module comment says: > Methods for the various MIR types. These are intended for use after > building is complete. Awfully broad for a module that has a handful of impl blocks for some MIR types, none of which really relates to `TyCtxt`. `git blame` indicates the comment is ancient, from 2015, and made sense then. This module is now vestigial. This commit removes it and moves all the code within into `rustc_middle::mir::statement`. Some specifics: - `Place`, `PlaceRef`, `Rvalue`, `Operand`, `BorrowKind`: they all have `impl` blocks in both the `tcx` and `statement` modules. The commit merges the former into the latter. - `BinOp`, `UnOp`: they only have `impl` blocks in `tcx`. The commit moves these into `statement`. - `PlaceTy`, `RvalueInitializationState`: they are defined in `tcx`. This commit moves them into `statement` *and* makes them available in `mir::*`, like many other MIR types. r? `@tmandry`
2025-02-19Remove `rustc_middle::mir::tcx` module.Nicholas Nethercote-418/+397
This is a really weird module. For example, what does `tcx` in `rustc_middle::mir::tcx::PlaceTy` mean? The answer is "not much". The top-level module comment says: > Methods for the various MIR types. These are intended for use after > building is complete. Awfully broad for a module that has a handful of impl blocks for some MIR types, none of which really relates to `TyCtxt`. `git blame` indicates the comment is ancient, from 2015, and made sense then. This module is now vestigial. This commit removes it and moves all the code within into `rustc_middle::mir::statement`. Some specifics: - `Place`, `PlaceRef`, `Rvalue`, `Operand`, `BorrowKind`: they all have `impl` blocks in both the `tcx` and `statement` modules. The commit merges the former into the latter. - `BinOp`, `UnOp`: they only have `impl` blocks in `tcx`. The commit moves these into `statement`. - `PlaceTy`, `RvalueInitializationState`: they are defined in `tcx`. This commit moves them into `statement` *and* makes them available in `mir::*`, like many other MIR types.
2025-02-18Auto merge of #137235 - matthiaskrgr:rollup-2kjua2t, r=matthiaskrgrbors-81/+33
Rollup of 10 pull requests Successful merges: - #135711 (Do not ICE on default_field_value const with lifetimes) - #136599 (librustdoc: more usages of `Joined::joined`) - #136876 (Locking documentation updates) - #137000 (Deeply normalize item bounds in new solver) - #137126 (fix docs for inherent str constructors) - #137161 (Pattern Migration 2024: fix incorrect messages/suggestions when errors arise in macro expansions) - #137191 (Update mdbook and move error_index_generator) - #137203 (Improve MIR modification) - #137206 (Make E0599 a structured error) - #137218 (misc `layout_of` cleanup) r? `@ghost` `@rustbot` modify labels: rollup
2025-02-18Rollup merge of #137218 - lukas-code:layout_of_cleanup, r=compiler-errorsMatthias Krüger-11/+32
misc `layout_of` cleanup See individual commits for details. r? `@oli-obk` but feel free to reassign
2025-02-18Rollup merge of #137203 - nnethercote:improve-MIR-modification, ↵Matthias Krüger-70/+1
r=compiler-errors Improve MIR modification A few commits that simplify code that manipulates MIR bodies. r? `@tmiasko`
2025-02-18update `cfg(bootstrap)`Josh Stone-1/+0