about summary refs log tree commit diff
path: root/compiler
AgeCommit message (Collapse)AuthorLines
2025-04-04Rollup merge of #139335 - compiler-errors:error-implies, r=oli-obkMatthias Krüger-29/+34
Pass correct param-env to `error_implies` Duplicated comment from the test: In the error reporting code, when reporting fulfillment errors for goals A and B, we try to see if elaborating A will result in another goal that can equate with B. That would signal that B is "implied by" A, allowing us to skip reporting it, which is beneficial for cutting down on the number of diagnostics we report. In the new trait solver especially, but even in the old trait solver through things like defining opaque type usages, this `can_equate` call was not properly taking the param-env of the goals, resulting in nested obligations that had empty param-envs. If one of these nested obligations was a `ConstParamHasTy` goal, then we would ICE, since those goals are particularly strict about the param-env they're evaluated in. This is morally a fix for <https://github.com/rust-lang/rust/issues/139314>, but that repro uses details about how defining usages in the `check_opaque_well_formed` code can spring out of type equality, and will likely stop failing soon coincidentally once we start using `PostBorrowck` mode in that check. Instead, we use lazy normalization to end up generating an alias-eq goal whose nested goals woul trigger the ICE instead, since this is a lot more stable. Fixes https://github.com/rust-lang/rust/issues/139314 r? ``@oli-obk`` or reassign
2025-04-04Rollup merge of #139313 - oli-obk:push-uzvmpxqyvrzp, r=compiler-errorsMatthias Krüger-99/+67
Deduplicate some `rustc_middle` function bodies by calling the `rustc_type_ir` equivalent Maybe in the future we can use method delegation, but I'd rather avoid that for now (I don't even know if it can do that already)
2025-04-04Rollup merge of #138949 - madsmtm:rename-to-darwin, r=WaffleLapkinMatthias Krüger-54/+54
Rename `is_like_osx` to `is_like_darwin` Replace `is_like_osx` with `is_like_darwin`, which more closely describes reality (OS X is the pre-2016 name for macOS, and is by now quite outdated; Darwin is the overall name for the OS underlying Apple's macOS, iOS, etc.). ``@rustbot`` label O-apple r? compiler
2025-04-04Fix `Debug` impl for `LateParamRegionKind`.Nicholas Nethercote-4/+4
It uses `Br` prefixes which are inappropriate and appear to have been incorrectly copy/pasted from the `Debug` impl for `BoundRegionKind`.
2025-04-04Auto merge of #139287 - compiler-errors:folder-experiment-1, r=lqdbors-11/+42
Folder experiment: Monomorphize region resolver **NOTE:** This is one of a series of perf experiments that I've come up with while sick in bed. I'm assigning them to lqd b/c you're a good reviewer and you'll hopefully be awake when these experiments finish, lol. r? lqd This is actually two tweaks to the `RegionFolder`, monomorphizing its callback and accounting for flags to avoid folding unnecessarily.
2025-04-04adt_destructor: sanity-check returned itemMaja Kądziołka-0/+5
Fixes #139278
2025-04-04AsyncDestructor: replace fields with impl_didMaja Kądziołka-17/+6
The future and ctor fields aren't actually used, and the way they are extracted is obviously wrong – swapping the order of the items in the source code will give wrong results. Instead, store just the LocalDefId of the impl, which is enough for the only use of this data.
2025-04-04Apply `Recovery::Forbidden` when reparsing pasted macro fragments.Nicholas Nethercote-1/+16
Fixes #137874. Removes `tests/crashes/137874.rs`; the new test is simpler (defines its own macro) but tests the same thing. 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.
2025-04-04Auto merge of #120706 - Bryanskiy:leak, r=lcnrbors-85/+379
Initial support for auto traits with default bounds This PR is part of ["MCP: Low level components for async drop"](https://github.com/rust-lang/compiler-team/issues/727) Tracking issue: #138781 Summary: https://github.com/rust-lang/rust/pull/120706#issuecomment-1934006762 ### Intro Sometimes we want to use type system to express specific behavior and provide safety guarantees. This behavior can be specified by various "marker" traits. For example, we use `Send` and `Sync` to keep track of which types are thread safe. As the language develops, there are more problems that could be solved by adding new marker traits: - to forbid types with an async destructor to be dropped in a synchronous context a trait like `SyncDrop` could be used [Async destructors, async genericity and completion futures](https://sabrinajewson.org/blog/async-drop). - to support [scoped tasks](https://without.boats/blog/the-scoped-task-trilemma/) or in a more general sense to provide a [destruction guarantee](https://zetanumbers.github.io/book/myosotis.html) there is a desire among some users to see a `Leak` (or `Forget`) trait. - Withoutboats in his [post](https://without.boats/blog/changing-the-rules-of-rust/) reflected on the use of `Move` trait instead of a `Pin`. All the traits proposed above are supposed to be auto traits implemented for most types, and usually implemented automatically by compiler. For backward compatibility these traits have to be added implicitly to all bound lists in old code (see below). Adding new default bounds involves many difficulties: many standard library interfaces may need to opt out of those default bounds, and therefore be infected with confusing `?Trait` syntax, migration to a new edition may contain backward compatibility holes, supporting new traits in the compiler can be quite difficult and so forth. Anyway, it's hard to evaluate the complexity until we try the system on a practice. In this PR we introduce new optional lang items for traits that are added to all bound lists by default, similarly to existing `Sized`. The examples of such traits could be `Leak`, `Move`, `SyncDrop` or something else, it doesn't matter much right now (further I will call them `DefaultAutoTrait`'s). We want to land this change into rustc under an option, so it becomes available in bootstrap compiler. Then we'll be able to do standard library experiments with the aforementioned traits without adding hundreds of `#[cfg(not(bootstrap))]`s. Based on the experiments, we can come up with some scheme for the next edition, in which such bounds are added in a more targeted way, and not just everywhere. Most of the implementation is basically a refactoring that replaces hardcoded uses of `Sized` with iterating over a list of traits including both `Sized` and the new traits when `-Zexperimental-default-bounds` is enabled (or just `Sized` as before, if the option is not enabled). ### Default bounds for old editions All existing types, including generic parameters, are considered `Leak`/`Move`/`SyncDrop` and can be forgotten, moved or destroyed in generic contexts without specifying any bounds. New types that cannot be, for example, forgotten and do not implement `Leak` can be added at some point, and they should not be usable in such generic contexts in existing code. To both maintain this property and keep backward compatibility with existing code, the new traits should be added as default bounds _everywhere_ in previous editions. Besides the implicit `Sized` bound contexts that includes supertrait lists and trait lists in trait objects (`dyn Trait1 + ... + TraitN`). Compiler should also generate implicit `DefaultAutoTrait` implementations for foreign types (`extern { type Foo; }`) because they are also currently usable in generic contexts without any bounds. #### Supertraits Adding the new traits as supertraits to all existing traits is potentially necessary, because, for example, using a `Self` param in a trait's associated item may be a breaking change otherwise: ```rust trait Foo: Sized { fn new() -> Option<Self>; // ERROR: `Option` requires `DefaultAutoTrait`, but `Self` is not `DefaultAutoTrait` } // desugared `Option` enum Option<T: DefaultAutoTrait + Sized> { Some(T), None, } ``` However, default supertraits can significantly affect compiler performance. For example, if we know that `T: Trait`, the compiler would deduce that `T: DefaultAutoTrait`. It also implies proving `F: DefaultAutoTrait` for each field `F` of type `T` until an explicit impl is be provided. If the standard library is not modified, then even traits like `Copy` or `Send` would get these supertraits. In this PR for optimization purposes instead of adding default supertraits, bounds are added to the associated items: ```rust // Default bounds are generated in the following way: trait Trait { fn foo(&self) where Self: DefaultAutoTrait {} } // instead of this: trait Trait: DefaultAutoTrait { fn foo(&self) {} } ``` It is not always possible to do this optimization because of backward compatibility: ```rust pub trait Trait<Rhs = Self> {} pub trait Trait1 : Trait {} // ERROR: `Rhs` requires `DefaultAutoTrait`, but `Self` is not `DefaultAutoTrait` ``` or ```rust trait Trait { type Type where Self: Sized; } trait Trait2<T> : Trait<Type = T> {} // ERROR: `???` requires `DefaultAutoTrait`, but `Self` is not `DefaultAutoTrait` ``` Therefore, `DefaultAutoTrait`'s are still being added to supertraits if the `Self` params or type bindings were found in the trait header. #### Trait objects Trait objects requires explicit `+ Trait` bound to implement corresponding trait which is not backward compatible: ```rust fn use_trait_object(x: Box<dyn Trait>) { foo(x) // ERROR: `foo` requires `DefaultAutoTrait`, but `dyn Trait` is not `DefaultAutoTrait` } // implicit T: DefaultAutoTrait here fn foo<T>(_: T) {} ``` So, for a trait object `dyn Trait` we should add an implicit bound `dyn Trait + DefaultAutoTrait` to make it usable, and allow relaxing it with a question mark syntax `dyn Trait + ?DefaultAutoTrait` when it's not necessary. #### Foreign types If compiler doesn't generate auto trait implementations for a foreign type, then it's a breaking change if the default bounds are added everywhere else: ```rust // implicit T: DefaultAutoTrait here fn foo<T: ?Sized>(_: &T) {} extern "C" { type ExternTy; } fn forward_extern_ty(x: &ExternTy) { foo(x); // ERROR: `foo` requires `DefaultAutoTrait`, but `ExternTy` is not `DefaultAutoTrait` } ``` We'll have to enable implicit `DefaultAutoTrait` implementations for foreign types at least for previous editions: ```rust // implicit T: DefaultAutoTrait here fn foo<T: ?Sized>(_: &T) {} extern "C" { type ExternTy; } impl DefaultAutoTrait for ExternTy {} // implicit impl fn forward_extern_ty(x: &ExternTy) { foo(x); // OK } ``` ### Unresolved questions New default bounds affect all existing Rust code complicating an already complex type system. - Proving an auto trait predicate requires recursively traversing the type and proving the predicate for it's fields. This leads to a significant performance regression. Measurements for the stage 2 compiler build show up to 3x regression. - We hope that fast path optimizations for well known traits could mitigate such regressions at least partially. - New default bounds trigger some compiler bugs in both old and new trait solver. - With new default bounds we encounter some trait solver cycle errors that break existing code. - We hope that these cases are bugs that can be addressed in the new trait solver. Also migration to a new edition could be quite ugly and enormous, but that's actually what we want to solve. For other issues there's a chance that they could be solved by a new solver.
2025-04-04Remove an unwanted comment.Nicholas Nethercote-3/+0
I accidentally added this in #138740.
2025-04-03Auto merge of #139336 - matthiaskrgr:rollup-zsi8pgf, r=matthiaskrgrbors-498/+666
Rollup of 9 pull requests Successful merges: - #138017 (Tighten up assignment operator representations.) - #138462 (Dedup `&mut *` reborrow suggestion in loops) - #138610 (impl !PartialOrd for HirId) - #138767 (Allow boolean literals in `check-cfg`) - #139068 (io: Avoid marking some bytes as uninit) - #139255 (Remove unused variables generated in merged doctests) - #139270 (Add a mailmap entry for myself) - #139303 (Put Noratrieb on vacation) - #139312 (add Marco Ieni to mailmap) r? `@ghost` `@rustbot` modify labels: rollup
2025-04-03add autodiff batching middle-endManuel Drehwald-4/+28
2025-04-03add the autodiff batch mode frontendManuel Drehwald-127/+236
2025-04-03Rollup merge of #138767 - clubby789:check-cfg-bool, r=UrgauMatthias Krüger-0/+16
Allow boolean literals in `check-cfg` https://github.com/rust-lang/rust/pull/138632#issuecomment-2738114495 This makes it consistent with `--cfg` We could alternatively add a forward-compatible lint against `--cfg true/false` r? `@Urgau`
2025-04-03Rollup merge of #138610 - oli-obk:no-sort-hir-ids, r=compiler-errorsMatthias Krüger-207/+242
impl !PartialOrd for HirId revive of https://github.com/rust-lang/rust/pull/92233 Another checkbox of https://github.com/rust-lang/rust/issues/90317, another small step in making incremental less likely to die in horrible ways
2025-04-03Rollup merge of #138462 - ShE3py:mut-borrow-in-loop, r=oli-obkMatthias Krüger-13/+0
Dedup `&mut *` reborrow suggestion in loops #73534 added a reborrow suggestion in loops; #127579 generalized this to generic parameters, making the suggestion triggers twice: ```rs use std::io::Read; fn decode_scalar(_reader: impl Read) {} fn decode_array(reader: &mut impl Read) { for _ in 0.. { decode_scalar(reader); } } ``` ``` error[E0382]: use of moved value: `reader` --> src/lib.rs:6:23 | 4 | fn decode_array(reader: &mut impl Read) { | ------ move occurs because `reader` has type `&mut impl Read`, which does not implement the `Copy` trait 5 | for _ in 0.. { | ------------ inside of this loop 6 | decode_scalar(reader); | ^^^^^^ value moved here, in previous iteration of loop | help: consider creating a fresh reborrow of `reader` here | 6 | decode_scalar(&mut *reader); | ++++++ help: consider creating a fresh reborrow of `reader` here | 6 | decode_scalar(&mut *reader); | ++++++ ``` This PR removes the suggestion in loops, as it requires generic parameters anyway (i.e., the reborrow is automatic if there is no generic params). `@rustbot` label +A-borrow-checker +A-diagnostics +A-suggestion-diagnostics +D-papercut
2025-04-03Rollup merge of #138017 - nnethercote:tighten-assignment-op, r=spastorinoMatthias Krüger-278/+408
Tighten up assignment operator representations. This is step 3 of [MCP 831](https://github.com/rust-lang/compiler-team/issues/831). r? `@spastorino`
2025-04-03Auto merge of #132527 - DianQK:gvn-stmt-iter, r=oli-obkbors-130/+112
gvn: Invalid dereferences for all non-local mutations Fixes #132353. This PR removes the computation value by traversing SSA locals through `for_each_assignment_mut`. Because the `for_each_assignment_mut` traversal skips statements which have side effects, such as dereference assignments, the computation may be unsound. Instead of `for_each_assignment_mut`, we compute values by traversing in reverse postorder. Because we compute and use the symbolic representation of values on the fly, I invalidate all old values when encountering a dereference assignment. The current approach does not prevent the optimization of a clone to a copy. In the future, we may add an alias model, or dominance information for dereference assignments, or SSA form to help GVN. r? cjgillot cc `@jieyouxu` #132356 cc `@RalfJung` #133474
2025-04-03Pass correct param-env to error_impliesMichael Goulet-29/+34
2025-04-03Stabilize `cfg_boolean_literals`clubby789-17/+2
2025-04-03Deduplicate some `rustc_middle` function bodies by calling the ↵Oli Scherer-99/+67
`rustc_type_ir` equivalent
2025-04-03Fix testing with randomized layouts enabledbjorn3-1/+3
2025-04-03Invalid dereferences for all non-local mutationsdianqk-14/+16
2025-04-03Only preserving derefs for trivial terminators like SwitchInt and Gotodianqk-2/+8
2025-04-03Remove `unsound-mir-opts` for `simplify_aggregate_to_copy`dianqk-3/+1
2025-04-03Run coretests and alloctests with cg_clif in CIbjorn3-22/+27
2025-04-03Initial support for auto traits with default boundsBryanskiy-85/+379
2025-04-03Allow boolean literals in `check-cfg`clubby789-0/+16
2025-04-03compiler: report error when trait object type param reference selfxtex-0/+25
Fixes #139082. Emits an error when `Self` is found in the projection bounds of a trait object. In type aliases, `Self` has no meaning, so `type A = &'static dyn B` where `trait B = Fn() -> Self` will expands to `type A = &'static Fn() -> Self` which is illegal, causing the region solver to bail out when hitting the uninferred Self. Bug: #139082 Signed-off-by: xtex <xtexchooser@duck.com>
2025-04-03impl !PartialOrd for HirIdOli Scherer-22/+16
2025-04-03impl !PartialOrd for UpvarMigrationInfoOli Scherer-3/+8
2025-04-03Upvars HirIds always have the same owner, thus just use an ItemLocalIdOli Scherer-3/+7
2025-04-03Remove `LintExpectationId` from `Level` variantsOli Scherer-109/+110
2025-04-03Make LevelAndSource a structOli Scherer-73/+90
2025-04-03Split ExpectationLintId off LevelOli Scherer-34/+48
2025-04-03add `TypingMode::Borrowck`lcnr-250/+409
2025-04-03move `check_opaque_type_parameter_valid`lcnr-182/+189
2025-04-03rm RpitConstraintCheckerlcnr-72/+0
we already collect opaque types from nested items during `mir_borrowck` of the root, checking that they are consistent this way.
2025-04-03Unset RUSTC_WRAPPER in cg_clif's build systembjorn3-1/+5
2025-04-03Rollup merge of #139294 - beetrees:fix-f16-f128-literal-feature-gate, r=fmeaseMatthias Krüger-10/+12
Fix the `f16`/`f128` feature gates on integer literals The feature gating logic for `f16`/`f128` currently only checks float literals, meaning this code currently compiles with no feature gates on stable ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=b0c0e285ccb822fc7e2abc595557886b)): ```rust fn main() { let a = 1f16; let b = 1f128; dbg!(a, b); } ``` This PR fixes that. Tracking issue: #116909
2025-04-03Rollup merge of #139080 - m-ou-se:super-let-gate, r=traviscrossMatthias Krüger-1/+22
Experimental feature gate for `super let` This adds an experimental feature gate, `#![feature(super_let)]`, for the `super let` experiment. Tracking issue: https://github.com/rust-lang/rust/issues/139076 Liaison: ``@nikomatsakis`` ## Description There's a rough (inaccurate) description here: https://blog.m-ou.se/super-let/ In short, `super let` allows you to define something that lives long enough to be borrowed by the tail expression of the block. For example: ```rust let a = { super let b = temp(); &b }; ``` Here, `b` is extended to live as long as `a`, similar to how in `let a = &temp();`, the temporary will be extended to live as long as `a`. ## Properties During the temporary lifetimes work we did last year, we explored the properties of "super let" and concluded that the fundamental property should be that these two are always equivalent in any context: 1. `& $expr` 2. `{ super let a = & $expr; a }` And, additionally, that these are equivalent in any context when `$expr` is a temporary (aka rvalue): 1. `& $expr` 2. `{ super let a = $expr; & a }` This makes it possible to give a name to a temporary without affecting how temporary lifetimes work, such that a macro can transparently use a block in its expansion, without that having any effect on the outside. ## Implementing pin!() correctly With `super let`, we can properly implement the `pin!()` macro without hacks: :sparkles: ```rust pub macro pin($value:expr $(,)?) { { super let mut pinned = $value; unsafe { $crate::pin::Pin::new_unchecked(&mut pinned) } } } ``` This is important, as there is currently no way to express it without hacks in Rust 2021 and before (see [hacky definition](https://github.com/rust-lang/rust/blob/2a06022951893fe5b5384f8dbd75b4e6e3b5cee0/library/core/src/pin.rs#L1947)), and no way to express it at all in Rust 2024 (see [issue](https://github.com/rust-lang/rust/issues/138718)). ## Fixing format_args!() This will also allow us to express `format_args!()` in a way where one can assign the result to a variable, fixing a [long standing issue](https://github.com/rust-lang/rust/issues/92698): ```rust let f = format_args!("Hello {name}!"); // error today, but accepted in the future! (after separate FCP) ``` ## Experiment The precise definition of `super let`, what happens for `super let x;` (without initializer), and whether to accept `super let _ = _ else { .. }` are still open questions, to be answered by the experiment. Furthermore, once we have a more complete understanding of the feature, we might be able to come up with a better syntax. (Which could be just a different keywords, or an entirely different way of naming temporaries that doesn't involve a block and a (super) let statement.)
2025-04-03Auto merge of #139234 - compiler-errors:query-tweak, r=oli-obkbors-11/+8
Misc query tweaks Remove some redundant work around `cache_on_disk` and `ensure_ok`, since `Result<(), ErrorGuaranteed>` queries don't need to cache or recompute their "value" if they are only used for their result.
2025-04-03Fix the `f16`/`f128` feature gate on integer literalsbeetrees-10/+12
2025-04-03Micro-optimize RegionEraserVisitorMichael Goulet-1/+23
2025-04-03structure the messageTshepang Mbambo-4/+6
2025-04-02Monomorphize region resolverMichael Goulet-11/+42
2025-04-03Tighten up assignment operator representations.Nicholas Nethercote-214/+339
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-03Use `BinOpKind` instead of `BinOp` for function args where possible.Nicholas Nethercote-65/+64
Because it's nice to avoid passing in unnecessary data.
2025-04-03Remove `Op` type.Nicholas Nethercote-40/+46
First, move the `lang_item_for_op` call from the top of `lookup_op_method`'s body to its callsites. It makes those callsites a little more verbose, but also means `lookup_op_method` no longer cares whether it's handling a binop or unop. This lets us remove `Op` and split `lang_item_for_op` into `lang_item_for_{bin,un}op`, which is a little simpler. This change is a prerequisite for adding the `ast::AssignOpKind` type in a subsequent commit.
2025-04-03use lower case to match other error messagesTshepang Mbambo-3/+3