about summary refs log tree commit diff
path: root/compiler/rustc_borrowck
AgeCommit message (Collapse)AuthorLines
2024-03-23rename MIR int2ptr casts to match library nameRalf Jung-2/+2
2024-03-23Auto merge of #119552 - krtab:dead_code_priv_mod_pub_field, r=cjgillot,saethlinbors-2/+0
Replace visibility test with reachability test in dead code detection Fixes https://github.com/rust-lang/rust/issues/119545 Also included is a fix for an error now flagged by the lint
2024-03-22Auto merge of #122900 - matthiaskrgr:rollup-nls90mb, r=matthiaskrgrbors-1/+1
Rollup of 8 pull requests Successful merges: - #114009 (compiler: allow transmute of ZST arrays with generics) - #122195 (Note that the caller chooses a type for type param) - #122651 (Suggest `_` for missing generic arguments in turbofish) - #122784 (Add `tag_for_variant` query) - #122839 (Split out `PredicatePolarity` from `ImplPolarity`) - #122873 (Merge my contributor emails into one using mailmap) - #122885 (Adjust better spastorino membership to triagebot's adhoc_groups) - #122888 (add a couple more tests) r? `@ghost` `@rustbot` modify labels: rollup
2024-03-22Rename `hir::Node::Local` into `hir::Node::LetStmt`Guillaume Gomez-3/+3
2024-03-22Rename `hir::Local` into `hir::LetStmt`Guillaume Gomez-5/+5
2024-03-22Split out ImplPolarity and PredicatePolarityMichael Goulet-1/+1
2024-03-22Make RawPtr take Ty and Mutbl separatelyMichael Goulet-12/+9
2024-03-22Programmatically convert some of the pat ctorsMichael Goulet-12/+8
2024-03-21Rollup merge of #122733 - oli-obk:error_prop, r=compiler-errorsMatthias Krüger-0/+5
Strip placeholders from hidden types before remapping generic parameter When remapping generic parameters in the hidden type to the generic parameters of the definition of the opaque, we assume that placeholders cannot exist. Instead of just patching that site, I decided to handle it earlier, directly in `infer_opaque_types`, where we are already doing all the careful lifetime handling. fixes #122694 the reason that ICE now occurred was that we stopped treating `operation` as being in the defining scope, so the TAIT became part of the hidden type of the `async fn`'s opaque type instead of just bailing out as ambiguos I think ```rust use std::future::Future; mod foo { type FutNothing<'a> = impl 'a + Future<Output = ()>; //~^ ERROR: unconstrained opaque type } async fn operation(_: &mut ()) -> () { //~^ ERROR: concrete type differs from previous call(operation).await //~^ ERROR: concrete type differs from previous } async fn call<F>(_f: F) where for<'any> F: FnMut(&'any mut ()) -> foo::FutNothing<'any>, { //~^ ERROR: expected generic lifetime parameter, found `'any` } ``` would have already had the same ICE before https://github.com/rust-lang/rust/pull/121796
2024-03-21Strip placeholders from hidden types before remapping generic parameter in ↵Oli Scherer-0/+5
the hidden type to the generic parameters of the definition of the opaque
2024-03-21Auto merge of #121123 - compiler-errors:item-assumptions, r=oli-obkbors-1/+1
Split an item bounds and an item's super predicates This is the moral equivalent of #107614, but instead for predicates this applies to **item bounds**. This PR splits out the item bounds (i.e. *all* predicates that are assumed to hold for the alias) from the item *super predicates*, which are the subset of item bounds which share the same self type as the alias. ## Why? Much like #107614, there are places in the compiler where we *only* care about super-predicates, and considering predicates that possibly don't have anything to do with the alias is problematic. This includes things like closure signature inference (which is at its core searching for `Self: Fn(..)` style bounds), but also lints like `#[must_use]`, error reporting for aliases, computing type outlives predicates. Even in cases where considering all of the `item_bounds` doesn't lead to bugs, unnecessarily considering irrelevant bounds does lead to a regression (#121121) due to doing extra work in the solver. ## Example 1 - Trait Aliases This is best explored via an example: ``` type TAIT<T> = impl TraitAlias<T>; trait TraitAlias<T> = A + B where T: C; ``` The item bounds list for `Tait<T>` will include: * `Tait<T>: A` * `Tait<T>: B` * `T: C` While `item_super_predicates` query will include just the first two predicates. Side-note: You may wonder why `T: C` is included in the item bounds for `TAIT`? This is because when we elaborate `TraitAlias<T>`, we will also elaborate all the predicates on the trait. ## Example 2 - Associated Type Bounds ``` type TAIT<T> = impl Iterator<Item: A>; ``` The `item_bounds` list for `TAIT<T>` will include: * `Tait<T>: Iterator` * `<Tait<T> as Iterator>::Item: A` But the `item_super_predicates` will just include the first bound, since that's the only bound that is relevant to the *alias* itself. ## So what This leads to some diagnostics duplication just like #107614, but none of it will be user-facing. We only see it in the UI test suite because we explicitly disable diagnostic deduplication. Regarding naming, I went with `super_predicates` kind of arbitrarily; this can easily be changed, but I'd consider better names as long as we don't block this PR in perpetuity.
2024-03-20Rollup merge of #122749 - aliemjay:region-err, r=compiler-errorsJacob Pratt-4/+0
make `type_flags(ReError) & HAS_ERROR` Self-explanatory. `TypeVisitableExt::references_error(ReError)` incorrectly returned `false`.
2024-03-20make `type_flags(ReError) & HAS_ERROR`Ali MJ Al-Nasrawy-4/+0
2024-03-20Split item bounds and item super predicatesMichael Goulet-1/+1
2024-03-20Auto merge of #120717 - compiler-errors:cap-closure-kind, r=oli-obkbors-1/+1
For async closures, cap closure kind, get rid of `by_mut_body` Right now we have three `AsyncFn*` traits, and three corresponding futures that are returned by the `call_*` functions for them. This is fine, but it is a bit excessive, since the future returned by `AsyncFn` and `AsyncFnMut` are identical. Really, the only distinction we need to make with these bodies is "by ref" and "by move". This PR removes `AsyncFn::CallFuture` and renames `AsyncFnMut::CallMutFuture` to `AsyncFnMut::CallRefFuture`. This simplifies MIR building for async closures, since we don't need to build an extra "by mut" body, but just a "by move" body which is materially different. We need to do a bit of delicate handling of the ClosureKind for async closures, since we need to "cap" it to `AsyncFnMut` in some cases when we only care about what body we're looking for. This also fixes a bug where `<{async closure} as Fn>::call` was returning a body that takes the async-closure receiver *by move*. This also helps align the `AsyncFn` traits to the `LendingFn` traits' eventual designs.
2024-03-19Only split by-ref/by-move futures for async closuresMichael Goulet-1/+1
2024-03-19Auto merge of #116935 - oli-obk:different_lifetime_taits_in_same_sig, ↵bors-20/+95
r=compiler-errors Prevent opaque types being instantiated twice with different regions within the same function addresses https://github.com/orgs/rust-lang/projects/22/views/1?pane=issue&itemId=41329537 r? `@compiler-errors`
2024-03-19Auto merge of #122735 - matthiaskrgr:rollup-pgb1s90, r=matthiaskrgrbors-13/+24
Rollup of 10 pull requests Successful merges: - #122435 (Don't trigger `unused_qualifications` on global paths) - #122556 (Extend format arg help for simple tuple index access expression) - #122634 (compiletest: Add support for `//@ aux-bin: foo.rs`) - #122677 (Fix incorrect mutable suggestion information for binding in ref pattern.) - #122691 (Fix ICE: `global_asm!()` Don't Panic When Unable to Evaluate Constant) - #122695 (Change only_local to a enum type.) - #122717 (Ensure stack before parsing dot-or-call) - #122719 (Ensure nested statics have a HIR node to prevent various queries from ICEing) - #122720 ([doc]:fix error code example) - #122724 (add test for casting pointer to union with unsized tail) r? `@ghost` `@rustbot` modify labels: rollup
2024-03-19Auto merge of #122392 - BoxyUwU:misc_cleanup, r=lcnrbors-6/+4
misc cleanups from debugging something rename `instantiate_canonical_with_fresh_inference_vars` to `instantiate_canonical` the substs for the canonical are not solely infer vars as that would be wildly wrong and it is rather confusing to see this method called and think that the entire canonicalization setup is completely broken when it is not :thumbsup: also update region debug printing to be more like the custom impls for Ty/Const, right now regions in debug output are horribly verbose and make it incredibly hard to read but with this atleast boundvars and placeholders when debugging the new solver do not take up excessive amounts of space. r? `@lcnr`
2024-03-19Fix incorrect mutable suggestion information for binding in ref pattern.surechen-13/+24
For ref pattern in func param, the mutability suggestion has to apply to the binding. For example: `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)` fixes #122415
2024-03-19Auto merge of #122055 - compiler-errors:stabilize-atb, r=oli-obkbors-1/+1
Stabilize associated type bounds (RFC 2289) This PR stabilizes associated type bounds, which were laid out in [RFC 2289]. This gives us a shorthand to express nested type bounds that would otherwise need to be expressed with nested `impl Trait` or broken into several `where` clauses. ### What are we stabilizing? We're stabilizing the associated item bounds syntax, which allows us to put bounds in associated type position within other bounds, i.e. `T: Trait<Assoc: Bounds...>`. See [RFC 2289] for motivation. In all position, the associated type bound syntax expands into a set of two (or more) bounds, and never anything else (see "How does this differ[...]" section for more info). Associated type bounds are stabilized in four positions: * **`where` clauses (and APIT)** - This is equivalent to breaking up the bound into two (or more) `where` clauses. For example, `where T: Trait<Assoc: Bound>` is equivalent to `where T: Trait, <T as Trait>::Assoc: Bound`. * **Supertraits** - Similar to above, `trait CopyIterator: Iterator<Item: Copy> {}`. This is almost equivalent to breaking up the bound into two (or more) `where` clauses; however, the bound on the associated item is implied whenever the trait is used. See #112573/#112629. * **Associated type item bounds** - This allows constraining the *nested* rigid projections that are associated with a trait's associated types. e.g. `trait Trait { type Assoc: Trait2<Assoc2: Copy>; }`. * **opaque item bounds (RPIT, TAIT)** - This allows constraining associated types that are associated with the opaque without having to *name* the opaque. For example, `impl Iterator<Item: Copy>` defines an iterator whose item is `Copy` without having to actually name that item bound. The latter three are not expressible in surface Rust (though for associated type item bounds, this will change in #120752, which I don't believe should block this PR), so this does represent a slight expansion of what can be expressed in trait bounds. ### How does this differ from the RFC? Compared to the RFC, the current implementation *always* desugars associated type bounds to sets of `ty::Clause`s internally. Specifically, it does *not* introduce a position-dependent desugaring as laid out in [RFC 2289], and in particular: * It does *not* desugar to anonymous associated items in associated type item bounds. * It does *not* desugar to nested RPITs in RPIT bounds, nor nested TAITs in TAIT bounds. This position-dependent desugaring laid out in the RFC existed simply to side-step limitations of the trait solver, which have mostly been fixed in #120584. The desugaring laid out in the RFC also added unnecessary complication to the design of the feature, and introduces its own limitations to, for example: * Conditionally lowering to nested `impl Trait` in certain positions such as RPIT and TAIT means that we inherit the limitations of RPIT/TAIT, namely lack of support for higher-ranked opaque inference. See this code example: https://github.com/rust-lang/rust/pull/120752#issuecomment-1979412531. * Introducing anonymous associated types makes traits no longer object safe, since anonymous associated types are not nameable, and all associated types must be named in `dyn` types. This last point motivates why this PR is *not* stabilizing support for associated type bounds in `dyn` types, e.g, `dyn Assoc<Item: Bound>`. Why? Because `dyn` types need to have *concrete* types for all associated items, this would necessitate a distinct lowering for associated type bounds, which seems both complicated and unnecessary compared to just requiring the user to write `impl Trait` themselves. See #120719. ### Implementation history: Limited to the significant behavioral changes and fixes and relevant PRs, ping me if I left something out-- * #57428 * #108063 * #110512 * #112629 * #120719 * #120584 Closes #52662 [RFC 2289]: https://rust-lang.github.io/rfcs/2289-associated-type-bounds.html
2024-03-18rename `instantiate_canonical_with_fresh_inference_vars`Boxy-6/+4
2024-03-18Prevent opaque types being instantiated twice with different regions within ↵Oli Scherer-20/+95
the same function
2024-03-17Move `suggest_hoisting_call_outside_loop` out of `suggest_cloning`Esteban Küber-6/+3
2024-03-17Move `Visitor` impl out to the `mod` levelEsteban Küber-22/+22
2024-03-17Point at `continue` and `break` that might be in the wrong placeEsteban Küber-33/+130
Sometimes move errors are because of a misplaced `continue`, but we didn't surface that anywhere. Now when there are more than one set of nested loops we show them out and point at the `continue` and `break` expressions within that might need to go elsewhere. ``` error[E0382]: use of moved value: `foo` --> $DIR/nested-loop-moved-value-wrong-continue.rs:46:18 | LL | for foo in foos { | --- | | | this reinitialization might get skipped | move occurs because `foo` has type `String`, which does not implement the `Copy` trait ... LL | for bar in &bars { | ---------------- inside of this loop ... LL | baz.push(foo); | --- value moved here, in previous iteration of loop ... LL | qux.push(foo); | ^^^ value used here after move | note: verify that your loop breaking logic is correct --> $DIR/nested-loop-moved-value-wrong-continue.rs:41:17 | LL | for foo in foos { | --------------- ... LL | for bar in &bars { | ---------------- ... LL | continue; | ^^^^^^^^ this `continue` advances the loop at line 33 help: consider moving the expression out of the loop so it is only moved once | LL ~ let mut value = baz.push(foo); LL ~ for bar in &bars { LL | ... LL | if foo == *bar { LL ~ value; | help: consider cloning the value if the performance cost is acceptable | LL | baz.push(foo.clone()); | ++++++++ ``` Fix #92531.
2024-03-17Detect when move of `!Copy` value occurs within `loop` and should likely not ↵Esteban Küber-2/+160
be cloned When encountering a move error on a value within a loop of any kind, identify if the moved value belongs to a call expression that should not be cloned and avoid the semantically incorrect suggestion. Also try to suggest moving the call expression outside of the loop instead. ``` error[E0382]: use of moved value: `vec` --> $DIR/recreating-value-in-loop-condition.rs:6:33 | LL | let vec = vec!["one", "two", "three"]; | --- move occurs because `vec` has type `Vec<&str>`, which does not implement the `Copy` trait LL | while let Some(item) = iter(vec).next() { | ----------------------------^^^-------- | | | | | value moved here, in previous iteration of loop | inside of this loop | note: consider changing this parameter type in function `iter` to borrow instead if owning the value isn't necessary --> $DIR/recreating-value-in-loop-condition.rs:1:17 | LL | fn iter<T>(vec: Vec<T>) -> impl Iterator<Item = T> { | ---- ^^^^^^ this parameter takes ownership of the value | | | in this function help: consider moving the expression out of the loop so it is only moved once | LL ~ let mut value = iter(vec); LL ~ while let Some(item) = value.next() { | ``` We use the presence of a `break` in the loop that would be affected by the moved value as a heuristic for "shouldn't be cloned". Fix #121466.
2024-03-15Rollup merge of #122254 - estebank:issue-48677, r=oli-obkMatthias Krüger-15/+129
Detect calls to .clone() on T: !Clone types on borrowck errors When encountering a lifetime error on a type that *holds* a type that doesn't implement `Clone`, explore the item's body for potential calls to `.clone()` that are only cloning the reference `&T` instead of `T` because `T: !Clone`. If we find this, suggest `T: Clone`. ``` error[E0502]: cannot borrow `*list` as mutable because it is also borrowed as immutable --> $DIR/clone-on-ref.rs:7:5 | LL | for v in list.iter() { | ---- immutable borrow occurs here LL | cloned_items.push(v.clone()) | ------- this call doesn't do anything, the result is still `&T` because `T` doesn't implement `Clone` LL | } LL | list.push(T::default()); | ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here LL | LL | drop(cloned_items); | ------------ immutable borrow later used here | help: consider further restricting this bound | LL | fn foo<T: Default + Clone>(list: &mut Vec<T>) { | +++++++ ``` ``` error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/clone-on-ref.rs:23:10 | LL | fn qux(x: A) { | - binding `x` declared here LL | let a = &x; | -- borrow of `x` occurs here LL | let b = a.clone(); | ------- this call doesn't do anything, the result is still `&A` because `A` doesn't implement `Clone` LL | drop(x); | ^ move out of `x` occurs here LL | LL | println!("{b:?}"); | ----- borrow later used here | help: consider annotating `A` with `#[derive(Clone)]` | LL + #[derive(Clone)] LL | struct A; | ``` Fix #48677.
2024-03-15Rollup merge of #122513 - petrochenkov:somehir4, r=fmeaseGuillaume Gomez-10/+4
hir: Remove `opt_local_def_id_to_hir_id` and `opt_hir_node_by_def_id` Also replace a few `hir_node()` calls with `hir_node_by_def_id()`. Follow up to https://github.com/rust-lang/rust/pull/120943.
2024-03-15Rollup merge of #122468 - beepster4096:borrowck_prefixes_cleanup, r=NadrierilGuillaume Gomez-88/+28
Cleanup `MirBorrowckCtxt::prefixes` Some of the uses of this method aren't necessary anymore and `PrefixSet::Supporting` is not used anywhere. With `PrefixSet::Supporting` removed, this could technically be moved to an extension trait on `PlaceRef`. However, it would have to be moved back to `MirBorrowckCtxt` when the `Derefer` MIR pass is moved before borrowck so I didn't.
2024-03-14hir: Remove `opt_local_def_id_to_hir_id` and `opt_hir_node_by_def_id`Vadim Petrochenkov-10/+4
Also replace a few `hir_node()` calls with `hir_node_by_def_id()`
2024-03-14Rename `hir::StmtKind::Local` into `hir::StmtKind::Let`Guillaume Gomez-3/+3
2024-03-13Account for UnOps in borrowck messageEsteban Küber-2/+17
2024-03-13Detect calls to `.clone()` on `T: !Clone` types on borrowck errorsEsteban Küber-7/+106
When encountering a lifetime error on a type that *holds* a type that doesn't implement `Clone`, explore the item's body for potential calls to `.clone()` that are only cloning the reference `&T` instead of `T` because `T: !Clone`. If we find this, suggest `T: Clone`. ``` error[E0502]: cannot borrow `*list` as mutable because it is also borrowed as immutable --> $DIR/clone-on-ref.rs:7:5 | LL | for v in list.iter() { | ---- immutable borrow occurs here LL | cloned_items.push(v.clone()) | ------- this call doesn't do anything, the result is still `&T` because `T` doesn't implement `Clone` LL | } LL | list.push(T::default()); | ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here LL | LL | drop(cloned_items); | ------------ immutable borrow later used here | help: consider further restricting this bound | LL | fn foo<T: Default + Clone>(list: &mut Vec<T>) { | +++++++ ``` ``` error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/clone-on-ref.rs:23:10 | LL | fn qux(x: A) { | - binding `x` declared here LL | let a = &x; | -- borrow of `x` occurs here LL | let b = a.clone(); | ------- this call doesn't do anything, the result is still `&A` because `A` doesn't implement `Clone` LL | drop(x); | ^ move out of `x` occurs here LL | LL | println!("{b:?}"); | ----- borrow later used here | help: consider annotating `A` with `#[derive(Clone)]` | LL + #[derive(Clone)] LL | struct A; | ```
2024-03-13cleanup prefixes iteratorbeepster4096-88/+28
2024-03-12Remove unused fields in some structuresArthur Carcano-2/+0
The dead_code lint was previously eroneously missing those. Since this lint bug has been fixed, the unused fields need to be removed.
2024-03-11Eliminate `DefiningAnchor::Error`, it is indistinguishable from ↵Oli Scherer-1/+1
`DefiningAnchor::Bind` with an empty list
2024-03-11Make `DefiningAnchor::Bind` only store the opaque types that may be ↵Oli Scherer-6/+3
constrained, instead of the current infcx root item. This makes `Bind` almost always be empty, so we can start forwarding it to queries, allowing us to remove `Bubble` entirely
2024-03-11Rename `IntoDiagnosticArg` as `IntoDiagArg`.Nicholas Nethercote-3/+3
Also rename `into_diagnostic_arg` as `into_diag_arg`, and `NotIntoDiagnosticArg` as `NotInotDiagArg`.
2024-03-10Auto merge of #121662 - saethlin:precondition-unification, r=RalfJungbors-1/+1
Distinguish between library and lang UB in assert_unsafe_precondition As described in https://github.com/rust-lang/rust/pull/121583#issuecomment-1963168186, `assert_unsafe_precondition` now explicitly distinguishes between language UB (conditions we explicitly optimize on) and library UB (things we document you shouldn't do, and maybe some library internals assume you don't do). `debug_assert_nounwind` was originally added to avoid the "only at runtime" aspect of `assert_unsafe_precondition`. Since then the difference between the macros has gotten muddied. This totally revamps the situation. Now _all_ preconditions shall be checked with `assert_unsafe_precondition`. If you have a precondition that's only checkable at runtime, do a `const_eval_select` hack, as done in this PR. r? RalfJung
2024-03-09Rollup merge of #121584 - klensy:itertools-up, r=Mark-SimulacrumGuillaume Boisseau-1/+1
bump itertools to 0.12 still depend on 0.11 (temporary dupes version): * <del>clippy</del>, https://github.com/rust-lang/rust-clippy/pull/12346 * rustfmt, sigh, https://github.com/rust-lang/rustfmt/pull/6093 https://github.com/rust-itertools/itertools/blob/v0.12.1/CHANGELOG.md removed unused `derive_more` dep from `rustc_middle`
2024-03-09Drive-by fix string fmtEsteban Küber-6/+6
2024-03-08Distinguish between library and lang UB in assert_unsafe_preconditionBen Kimock-1/+1
2024-03-08Stabilize associated type boundsMichael Goulet-1/+1
2024-03-08Rollup merge of #121563 - Jarcho:use_cf, r=petrochenkovMatthias Krüger-47/+30
Use `ControlFlow` in visitors. Follow up to #121256 This does have a few small behaviour changes in some diagnostic output where the visitor will now find the first match rather than the last match. The change in `find_anon_types.rs` has the only affected test. I don't see this being an issue as the last occurrence isn't any better of a choice than the first.
2024-03-08bump itertools to 0.12klensy-1/+1
still depend on 0.11: * clippy * rustfmt, sigh
2024-03-08Rollup merge of #122103 - compiler-errors:taits-capture-everything, r=oli-obkMatthias Krüger-8/+11
Make TAITs and ATPITs capture late-bound lifetimes in scope This generalizes the behavior that RPITs have, where they duplicate their in-scope lifetimes so that they will always *reify* late-bound lifetimes that they capture. This allows TAITs and ATPITs to properly error when they capture in-scope late-bound lifetimes. r? `@oli-obk` cc `@aliemjay` Fixes #122093 and therefore https://github.com/rust-lang/rust/pull/120700#issuecomment-1981213868
2024-03-08Rollup merge of #119365 - nbdd0121:asm-goto, r=AmanieuMatthias Krüger-6/+8
Add asm goto support to `asm!` Tracking issue: #119364 This PR implements asm-goto support, using the syntax described in "future possibilities" section of [RFC2873](https://rust-lang.github.io/rfcs/2873-inline-asm.html#asm-goto). Currently I have only implemented the `label` part, not the `fallthrough` part (i.e. fallthrough is implicit). This doesn't reduce the expressive though, since you can use label-break to get arbitrary control flow or simply set a value and rely on jump threading optimisation to get the desired control flow. I can add that later if deemed necessary. r? ``@Amanieu`` cc ``@ojeda``
2024-03-08Make TAITs capture all higher-ranked lifetimes in scopeMichael Goulet-8/+11
2024-03-06Add missing `#[rustc_lint_diagnostics]` attributes.Nicholas Nethercote-3/+11
Prior to the previous commit, `#[rust_lint_diagnostics]` attributes could only be used on methods with an `impl Into<{D,Subd}iagMessage>` parameter. But there are many other nearby diagnostic methods (e.g. `Diag::span`) that don't take such a parameter and should have the attribute. This commit adds the missing attribute to these `Diag` methods. This requires adding some missing `#[allow(rustc::diagnostic_outside_of_impl)]` markers at call sites to these methods.