about summary refs log tree commit diff
path: root/tests/ui/borrowck
AgeCommit message (Collapse)AuthorLines
2024-05-29Stop proving outlives constraints on regions we already reported errors onOli Scherer-9/+2
2024-02-20Stabilize `LazyCell` and `LazyLock` (`lazy_cell`)Peter Jaszkowiak-1/+1
2024-05-09Fix test problems discovered by the revision checkZalathar-23/+22
Most of these changes either add revision names that were apparently missing, or explicitly mark a revision name as currently unused.
2024-04-25Auto merge of #119650 - chenyukang:yukang-fix-118596-ref-mut, r=wesleywiserbors-20/+98
Suggest ref mut for pattern matching assignment Fixes #118596
2024-04-24Suggest cloning captured binding in `move` closureEsteban Küber-0/+6
``` error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure --> $DIR/borrowck-move-by-capture.rs:9:29 | LL | let bar: Box<_> = Box::new(3); | --- captured outer variable LL | let _g = to_fn_mut(|| { | -- captured by this `FnMut` closure LL | let _h = to_fn_once(move || -> isize { *bar }); | ^^^^^^^^^^^^^^^^ ---- | | | | | variable moved due to use in closure | | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait | `bar` is moved here | help: clone the value before moving it into the closure | LL ~ let value = bar.clone(); LL ~ let _h = to_fn_once(move || -> isize { value }); | ```
2024-04-24Mention when type parameter could be `Clone`Esteban Küber-16/+73
``` error[E0382]: use of moved value: `t` --> $DIR/use_of_moved_value_copy_suggestions.rs:7:9 | LL | fn duplicate_t<T>(t: T) -> (T, T) { | - move occurs because `t` has type `T`, which does not implement the `Copy` trait ... LL | (t, t) | - ^ value used here after move | | | value moved here | help: if `T` implemented `Clone`, you could clone the value --> $DIR/use_of_moved_value_copy_suggestions.rs:4:16 | LL | fn duplicate_t<T>(t: T) -> (T, T) { | ^ consider constraining this type parameter with `Clone` ... LL | (t, t) | - you could clone this value help: consider restricting type parameter `T` | LL | fn duplicate_t<T: Copy>(t: T) -> (T, T) { | ++++++ ``` The `help` is new. On ADTs, we also extend the output with span labels: ``` error[E0507]: cannot move out of static item `FOO` --> $DIR/issue-17718-static-move.rs:6:14 | LL | let _a = FOO; | ^^^ move occurs because `FOO` has type `Foo`, which does not implement the `Copy` trait | note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/issue-17718-static-move.rs:1:1 | LL | struct Foo; | ^^^^^^^^^^ consider implementing `Clone` for this type ... LL | let _a = FOO; | --- you could clone this value help: consider borrowing here | LL | let _a = &FOO; | + ```
2024-04-25Suggest ref mut for pattern matching assignmentyukang-20/+98
2024-04-21add test for ice #121463Matthias Krüger-0/+33
Fixes #121463
2024-04-15Use /* value */ as a placeholderMichael Goulet-8/+8
2024-04-13Auto merge of #122603 - estebank:clone-o-rama, r=lcnrbors-41/+552
Detect borrow checker errors where `.clone()` would be an appropriate user action When a value is moved twice, suggest cloning the earlier move: ``` error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait --> $DIR/union-move.rs:49:18 | LL | move_out(x.f1_nocopy); | ^^^^^^^^^^^ | | | cannot move out of here | move occurs because `x.f1_nocopy` has type `ManuallyDrop<RefCell<i32>>`, which does not implement the `Copy` trait | help: consider cloning the value if the performance cost is acceptable | LL | move_out(x.f1_nocopy.clone()); | ++++++++ ``` When a value is borrowed by an `fn` call, consider if cloning the result of the call would be reasonable, and suggest cloning that, instead of the argument: ``` error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/variance-issue-20533.rs:53:14 | LL | let a = AffineU32(1); | - binding `a` declared here LL | let x = bat(&a); | -- borrow of `a` occurs here LL | drop(a); | ^ move out of `a` occurs here LL | drop(x); | - borrow later used here | help: consider cloning the value if the performance cost is acceptable | LL | let x = bat(&a).clone(); | ++++++++ ``` otherwise, suggest cloning the argument: ``` error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/variance-issue-20533.rs:59:14 | LL | let a = ClonableAffineU32(1); | - binding `a` declared here LL | let x = foo(&a); | -- borrow of `a` occurs here LL | drop(a); | ^ move out of `a` occurs here LL | drop(x); | - borrow later used here | help: consider cloning the value if the performance cost is acceptable | LL - let x = foo(&a); LL + let x = foo(a.clone()); | ``` This suggestion doesn't attempt to square out the types between what's cloned and what the `fn` expects, to allow the user to make a determination on whether to change the `fn` call or `fn` definition themselves. Special case move errors caused by `FnOnce`: ``` error[E0382]: use of moved value: `blk` --> $DIR/once-cant-call-twice-on-heap.rs:8:5 | LL | fn foo<F:FnOnce()>(blk: F) { | --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait LL | blk(); | ----- `blk` moved due to this call LL | blk(); | ^^^ value used here after move | note: `FnOnce` closures can only be called once --> $DIR/once-cant-call-twice-on-heap.rs:6:10 | LL | fn foo<F:FnOnce()>(blk: F) { | ^^^^^^^^ `F` is made to be an `FnOnce` closure here LL | blk(); | ----- this value implements `FnOnce`, which causes it to be moved when called ``` Account for redundant `.clone()` calls in resulting suggestions: ``` error[E0507]: cannot move out of dereference of `S` --> $DIR/needs-clone-through-deref.rs:15:18 | LL | for _ in self.clone().into_iter() {} | ^^^^^^^^^^^^ ----------- value moved due to this method call | | | move occurs because value has type `Vec<usize>`, which does not implement the `Copy` trait | note: `into_iter` takes ownership of the receiver `self`, which moves value --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior | LL | for _ in <Vec<usize> as Clone>::clone(&self).into_iter() {} | ++++++++++++++++++++++++++++++ ~ ``` We use the presence of `&mut` values in a move error as a proxy for the user caring about side effects, so we don't emit a clone suggestion in that case: ``` error[E0505]: cannot move out of `s` because it is borrowed --> $DIR/borrowck-overloaded-index-move-index.rs:53:7 | LL | let mut s = "hello".to_string(); | ----- binding `s` declared here LL | let rs = &mut s; | ------ borrow of `s` occurs here ... LL | f[s] = 10; | ^ move out of `s` occurs here ... LL | use_mut(rs); | -- borrow later used here ``` We properly account for `foo += foo;` errors where we *don't* suggest `foo.clone() += foo;`, instead suggesting `foo += foo.clone();`. --- Each commit can be reviewed in isolation. There are some "cleanup" commits, but kept them separate in order to show *why* specific changes were being made, and their effect on tests' output. Fix #49693, CC #64167.
2024-04-12review commentsEsteban Küber-11/+11
Added comments and reworded messages
2024-04-12Better account for more cases involving closuresEsteban Küber-0/+25
2024-04-11Rollup merge of #123523 - estebank:issue-123414, r=BoxyUwUMatthias Krüger-0/+90
Account for trait/impl difference when suggesting changing argument from ref to mut ref Do not ICE when encountering a lifetime error involving an argument with an immutable reference of a method that differs from the trait definition. Fix #123414.
2024-04-11Mention when the type of the moved value doesn't implement `Clone`Esteban Küber-0/+82
2024-04-11Account for move error in the spread operator on struct literalsEsteban Küber-25/+233
We attempt to suggest an appropriate clone for move errors on expressions like `S { ..s }` where a field isn't `Copy`. If we can't suggest, we still don't emit the incorrect suggestion of `S { ..s }.clone()`. ``` error[E0509]: cannot move out of type `S<K>`, which implements the `Drop` trait --> $DIR/borrowck-struct-update-with-dtor.rs:28:19 | LL | let _s2 = S { a: 2, ..s0 }; | ^^^^^^^^^^^^^^^^ | | | cannot move out of here | move occurs because `s0.c` has type `K`, which does not implement the `Copy` trait | help: clone the value from the field instead of using the spread operator syntax | LL | let _s2 = S { a: 2, c: s0.c.clone(), ..s0 }; | +++++++++++++++++ ``` ``` error[E0509]: cannot move out of type `S<()>`, which implements the `Drop` trait --> $DIR/borrowck-struct-update-with-dtor.rs:20:19 | LL | let _s2 = S { a: 2, ..s0 }; | ^^^^^^^^^^^^^^^^ | | | cannot move out of here | move occurs because `s0.b` has type `B`, which does not implement the `Copy` trait | note: `B` doesn't implement `Copy` or `Clone` --> $DIR/borrowck-struct-update-with-dtor.rs:4:1 | LL | struct B; | ^^^^^^^^ help: if `B` implemented `Clone`, you could clone the value from the field instead of using the spread operator syntax | LL | let _s2 = S { a: 2, b: s0.b.clone(), ..s0 }; | +++++++++++++++++ ```
2024-04-11Better account for `FnOnce` in move errorsEsteban Küber-7/+5
``` error[E0382]: use of moved value: `blk` --> $DIR/once-cant-call-twice-on-heap.rs:8:5 | LL | fn foo<F:FnOnce()>(blk: F) { | --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait LL | blk(); | ----- `blk` moved due to this call LL | blk(); | ^^^ value used here after move | note: `FnOnce` closures can only be called once --> $DIR/once-cant-call-twice-on-heap.rs:6:10 | LL | fn foo<F:FnOnce()>(blk: F) { | ^^^^^^^^ `F` is made to be an `FnOnce` closure here LL | blk(); | ----- this value implements `FnOnce`, which causes it to be moved when called ```
2024-04-11Do not recomment cloning explicit `&mut` expressionsEsteban Küber-12/+0
2024-04-11Fix accuracy of `T: Clone` check in suggestionEsteban Küber-18/+19
2024-04-11More move error suggestions to cloneEsteban Küber-5/+43
``` error[E0507]: cannot move out of `val`, a captured variable in an `FnMut` closure --> $DIR/issue-87456-point-to-closure.rs:10:28 | LL | let val = String::new(); | --- captured outer variable LL | LL | take_mut(|| { | -- captured by this `FnMut` closure LL | LL | let _foo: String = val; | ^^^ move occurs because `val` has type `String`, which does not implement the `Copy` trait | help: consider borrowing here | LL | let _foo: String = &val; | + help: consider cloning the value if the performance cost is acceptable | LL | let _foo: String = val.clone(); | ++++++++ ```
2024-04-11Suggest `.clone()` in some move errorsEsteban Küber-3/+66
``` error[E0507]: cannot move out of `*x` which is behind a shared reference --> $DIR/borrowck-fn-in-const-a.rs:6:16 | LL | return *x | ^^ move occurs because `*x` has type `String`, which does not implement the `Copy` trait | help: consider cloning the value if the performance cost is acceptable | LL - return *x LL + return x.clone() | ```
2024-04-11Account for unops when suggesting cloningEsteban Küber-38/+56
2024-04-11Suggest `.clone()` when moved while borrowedEsteban Küber-2/+90
2024-04-11Minor test fmtEsteban Küber-3/+5
2024-04-11Rollup merge of #123704 - estebank:diag-changes, r=compiler-errorsMatthias Krüger-78/+117
Tweak value suggestions in `borrowck` and `hir_analysis` Unify the output of `suggest_assign_value` and `ty_kind_suggestion`. Ideally we'd make these a single function, but doing so would likely require modify the crate dependency tree.
2024-04-10Handle more cases of "values to suggest" given a typeEsteban Küber-4/+4
Add handling for `String`, `Box`, `Option` and `Result`.
2024-04-10Handle more cases of value suggestionsEsteban Küber-76/+115
2024-04-10Auto merge of #121346 - m-ou-se:temp-lifetime-if-else-match, r=compiler-errorsbors-115/+73
Propagate temporary lifetime extension into if and match. This PR makes this work: ```rust let a = if true { ..; &temp() // used to error, but now gets lifetime extended } else { ..; &temp() // used to error, but now gets lifetime extended }; ``` and ```rust let a = match () { _ => { ..; &temp() // used to error, but now gets lifetime extended } }; ``` to make it consistent with: ```rust let a = { ..; &temp() // lifetime is extended }; ``` This is one small part of [the temporary lifetimes work](https://github.com/rust-lang/lang-team/issues/253). This part is backwards compatible (so doesn't need be edition-gated), because all code affected by this change previously resulted in a hard error.
2024-04-09Tweak value suggestions in `borrowck` and `hir_analysis`Esteban Küber-26/+26
Unify the output of `suggest_assign_value` and `ty_kind_suggestion`. Ideally we'd make these a single function, but doing so would likely require modify the crate dependency tree.
2024-04-06Account for trait/impl difference when suggesting changing argument from ref ↵Esteban Küber-0/+90
to mut ref Do not ICE when encountering a lifetime error involving an argument with an immutable reference of a method that differs from the trait definition. Fix #123414.
2024-03-26Rollup merge of #122589 - wutchzone:121547, r=compiler-errorsMatthias Krüger-0/+33
Fix diagnostics for async block cloning Closes #121547 r? diagnostics
2024-03-23Fix diagnostics for async block cloningDaniel Sedlak-0/+33
2024-03-23add test for #104779 opaque types, patterns and subtyping ICE: IndexMap: ↵Matthias Krüger-0/+68
key not found Fixes #104779
2024-03-21add test for #121807Matthias Krüger-0/+80
Fixes #121807
2024-03-20Bless test fallout (duplicate diagnostics)Michael Goulet-4/+38
2024-03-18When displaying multispans, ignore empty lines adjacent to `...`Esteban Küber-2/+1
``` error[E0308]: `match` arms have incompatible types --> tests/ui/codemap_tests/huge_multispan_highlight.rs:98:18 | 6 | let _ = match true { | ---------- `match` arms have incompatible types 7 | true => ( | _________________- 8 | | // last line shown in multispan header ... | 96 | | 97 | | ), | |_________- this is found to be of type `()` 98 | false => " | __________________^ ... | 119 | | 120 | | ", | |_________^ expected `()`, found `&str` error[E0308]: `match` arms have incompatible types --> tests/ui/codemap_tests/huge_multispan_highlight.rs:215:18 | 122 | let _ = match true { | ---------- `match` arms have incompatible types 123 | true => ( | _________________- 124 | | 125 | | 1 // last line shown in multispan header ... | 213 | | 214 | | ), | |_________- this is found to be of type `{integer}` 215 | false => " | __________________^ 216 | | 217 | | 218 | | 1 last line shown in multispan ... | 237 | | 238 | | ", | |_________^ expected integer, found `&str` ```
2024-03-17Detect when move of `!Copy` value occurs within `loop` and should likely not ↵Esteban Küber-38/+8
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-0/+127
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-13Detect calls to `.clone()` on `T: !Clone` types on borrowck errorsEsteban Küber-0/+127
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-11Revert "Auto merge of #122140 - oli-obk:track_errors13, r=davidtwco"Oli Scherer-23/+23
This reverts commit 65cd843ae06ad00123c131a431ed5304e4cd577a, reversing changes made to d255c6a57c393db6221b1ff700daea478436f1cd.
2024-03-11Run a single huge `par_body_owners` instead of many small ones after each other.Oli Scherer-23/+23
This improves parallel rustc parallelism by avoiding the bottleneck after each individual `par_body_owners` (because it needs to wait for queries to finish, so if there is one long running one, a lot of cores will be idle while waiting for the single query).
2024-03-10Fix invalid compiletest directives in tests许杰友 Jieyou Xu (Joe)-1/+1
- Fix invalid directive in `normalize-hidden-types` - Update legacy directive in `two-phase-reservation-sharing-interference`
2024-03-01Rollup merge of #120646 - clubby789:uninit-destructuring-sugg, ↵Matthias Krüger-1/+49
r=michaelwoerister Fix incorrect suggestion for uninitialized binding in pattern Fixes #120634
2024-02-20Update test.Mara Bos-115/+73
2024-02-18Improve wording of static_mut_refObei Sideg-40/+40
Rename `static_mut_ref` lint to `static_mut_refs`.
2024-02-16[AUTO-GENERATED] Migrate ui tests from `//` to `//@` directives许杰友 Jieyou Xu (Joe)-151/+151
2024-02-16Rollup merge of #121020 - oli-obk:diagnostics_ice, r=davidtwcoGuillaume Gomez-0/+34
Avoid an ICE in diagnostics fixes #121004 just a slice usage in diagnostics code. Sadly we can't yet bubble the `ErrorGuaranteed` from wf check to borrowck for these cases, as that causes cycle errors iirc
2024-02-14Fix two UI tests with incorrect directive / invalid revision许杰友 Jieyou Xu (Joe)-1/+19
2024-02-13Avoid an ICE in diagnosticsOli Scherer-0/+34
2024-02-06Fix incorrect suggestion for uninitialize binding in destructuring patternclubby789-1/+49
2024-01-16borrowck: wf-check fn item argsAli MJ Al-Nasrawy-0/+127