about summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src
AgeCommit message (Collapse)AuthorLines
2024-04-25Suggest ref mut for pattern matching assignmentyukang-1/+16
2024-04-23Rollup merge of #122598 - Nadrieril:full-derefpats, r=matthewjasperLeón Orell Valerian Liehr-34/+54
deref patterns: lower deref patterns to MIR This lowers deref patterns to MIR. This is a bit tricky because this is the first kind of pattern that requires storing a value in a temporary. Thanks to https://github.com/rust-lang/rust/pull/123324 false edges are no longer a problem. The thing I'm not confident about is the handling of fake borrows. This PR ignores any fake borrows inside a deref pattern. We are guaranteed to at least fake borrow the place of the first pointer value, which could be enough, but I'm not certain.
2024-04-22Rollup merge of #124183 - compiler-errors:unnecessary-by-ref, r=oli-obkGuillaume Gomez-2/+2
Stop taking `ParamTy`/`ParamConst`/`EarlyParamRegion`/`AliasTy` by ref It's unnecessary and is annoying when we have it by value.
2024-04-21Add `AggregateKind::RawPtr` and enough support to compileScott McMurray-3/+9
2024-04-20Add a non-shallow fake borrowNadrieril-34/+54
2024-04-19Stop taking ParamTy/ParamConst/EarlyParamRegion/AliasTy by refMichael Goulet-2/+2
2024-04-19remove optionality from MoveData::base_localbeepster4096-3/+1
2024-04-17Rename `BindingAnnotation` to `BindingMode`Jules Bertholet-8/+8
2024-04-16Auto merge of #123537 - compiler-errors:shallow, r=lcnrbors-1/+1
Simplify shallow resolver to just fold ty/consts Probably faster than using a whole folder?
2024-04-16Rollup merge of #123990 - compiler-errors:suggest-closure-ret-deref, r=oli-obkGuillaume Gomez-73/+64
Make `suggest_deref_closure_return` more idiomatic/easier to understand The only functional change here really is just making it not use a fresh type variable for upvars. I'll point that out in the code. The rest of the changes are just stylistic, because reading this code was really confusing me (variable names were vague, ways of accessing types were unidiomatic, order of operations was kind of strange, etc). This is stacked on #123989. r? oli-obk since you approved #122213
2024-04-16Rollup merge of #123797 - amandasystems:better-graphviz, r=oli-obkGuillaume Gomez-6/+38
Better graphviz output for SCCs and NLL constraints This PR modifies the output for `-Z dump-mir-graphviz=yes`. Specifically, it changes the output of the files `.-------.nll.0.regioncx.all.dot` and `nll.0.regioncx.scc.dot` to be easier to read and contain some information that helped me during debugging. In particular: - SCC indices are contracted to `SCC(n)` instead of `ConstraintSccIndex(n)` to compress the nodes - SCC regions are in `{}` rather than `[]` (controversial since they are technically ordered by index, but I figured they're more sets than arrays conceptually since they're equivalence classes). - For regions in other universes than the root, also show the region universe (as ?8/U1) - For regions with external names, show the external name in parenthesis - For the region graph where edges are locations, render the All variant of the enum without the file since it's extremely long and often destroys the rendering - For region graph edge annotations for single locations, remove the wrapping around the Location variant and just add its contents since this can be unambiguously done Example output (from the function `foo()` of `tests/ui/error-codes/E0582.rs`) for an SCC graph: ![a graph showing SCCs](https://github.com/rust-lang/rust/assets/102855/0b998338-0379-4829-b99e-d8105c094897) ...and for the constraints: ![a graph showing regions and their constraints](https://github.com/rust-lang/rust/assets/102855/e984c4ca-7aa2-4db2-9878-bf38fe8208d5) This PR also gives `UniverseIndex`es the `is_root()` method since this is now an operation that happens three times in the borrowck crate.
2024-04-15Make suggest_deref_closure_return more idiomatic/easier to understandMichael Goulet-73/+64
2024-04-16Rollup merge of #123989 - compiler-errors:type-dependent-def-id, r=oli-obkLeón Orell Valerian Liehr-26/+20
Just use `type_dependent_def_id` to figure out what the method is for an expr The calls to `lookup_method_for_diagnostic` are overkill. r? oli-obk
2024-04-16Rollup merge of #123016 - compiler-errors:no-type-var-origin, r=lcnrLeón Orell Valerian Liehr-17/+10
Remove `TypeVariableOriginKind` and `ConstVariableOriginKind` It's annoying to have to import `TypeVariableOriginKind` just to fill it with `MiscVariable` for almost every use. Every other usage other than `TypeParameterDefinition` wasn't even used -- I can see how it may have been useful once for debugging, but I do quite a lot of typeck debugging and I've never really needed it. So let's just remove it, and keep around the only useful thing which is the `DefId` of the param for `var_for_def`. This is based on #123006, which removed the special use of `TypeVariableOriginKind::OpaqueInference`, which I'm pretty sure I was the one that added. r? lcnr or re-roll to types
2024-04-15Simplify shallow resolver to just fold ty/constsMichael Goulet-1/+1
2024-04-15Rebase falloutMichael Goulet-5/+4
2024-04-15Just use type_dependent_def_id to figure out what the method is for an exprMichael Goulet-26/+20
2024-04-15Remove TypeVariableOriginKindMichael Goulet-12/+6
2024-04-15Rollup merge of #123924 - compiler-errors:tuple-sugg, r=estebankMichael Goulet-63/+2
Fix various bugs in `ty_kind_suggestion` Consolidates two implementations of `ty_kind_suggestion` Fixes some misuse of the empty param-env Fixes a problem where we suggested `(42)` instead of `(42,)` for tuple suggestions Suggest a value when `return;`, making it consistent with `break;` Fixes #123906
2024-04-15Rollup merge of #123934 - WaffleLapkin:graph-mini-refactor, r=fmease许杰友 Jieyou Xu (Joe)-18/+10
`rustc_data_structures::graph` mini refactor Who doesn't love to breathe dust from the ancient times?
2024-04-15Use RPITIT for `Successors` and `Predecessors` traitsMaybe Waffle-3/+1
Now with RPITIT instead of GAT!
2024-04-14Make `depth_first_search` into a standalone functionMaybe Waffle-7/+8
Does not necessarily change much, but we never overwrite it, so I see no reason for it to be in the `Successors` trait. (+we already have a similar `is_cyclic`)
2024-04-14Merge `{With,Graph}{Successors,Predecessors}` into `{Successors,Predecessors}`Maybe Waffle-12/+7
Now with GAT!
2024-04-14Merge `WithNumNodes` into DirectedGraphMaybe Waffle-2/+0
2024-04-14Consolidate two copies of ty_kind_suggestionMichael Goulet-63/+2
2024-04-13Auto merge of #122603 - estebank:clone-o-rama, r=lcnrbors-62/+481
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-8/+36
Added comments and reworded messages
2024-04-12Better account for more cases involving closuresEsteban Küber-14/+36
2024-04-12Fix rebaseEsteban Küber-2/+2
2024-04-12Rollup merge of #123599 - matthiaskrgr:rm, r=cjgillotMatthias Krüger-1/+1
remove some things that do not need to be
2024-04-11Rollup merge of #123523 - estebank:issue-123414, r=BoxyUwUMatthias Krüger-35/+54
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-11remove some things that do not need to beMatthias Krüger-1/+1
2024-04-11Mention when the type of the moved value doesn't implement `Clone`Esteban Küber-2/+13
2024-04-11Account for move error in the spread operator on struct literalsEsteban Küber-11/+107
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/+72
``` 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-11Account for assign binops in clone suggestionsEsteban Küber-2/+32
Explicitly look for `expr += other_expr;` and avoid suggesting `expr.clone() += other_expr;`, instead suggesting `expr += other_expr.clone();`.
2024-04-11When possible, suggest cloning the result of a call instead of an argumentEsteban Küber-13/+92
``` error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/variance-issue-20533.rs:28:14 | LL | let a = AffineU32(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).clone(); | ++++++++ ```
2024-04-11Do not recomment cloning explicit `&mut` expressionsEsteban Küber-0/+5
2024-04-11Fix accuracy of `T: Clone` check in suggestionEsteban Küber-0/+1
2024-04-11Remove unnecessary argument from `suggest_cloning`Esteban Küber-21/+9
2024-04-11Silence redundant clone suggestionEsteban Küber-0/+5
2024-04-11More move error suggestions to cloneEsteban Küber-0/+4
``` 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-0/+10
``` 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-19/+24
2024-04-11Suggest `.clone()` when moved while borrowedEsteban Küber-17/+56
2024-04-11Account for `.clone()` when suggesting `<T as Clone>::clone`Esteban Küber-2/+33
2024-04-11Slightly more readable NLL/constraint graph dumpsAmanda Stjerna-6/+38
2024-04-11Rollup merge of #123704 - estebank:diag-changes, r=compiler-errorsMatthias Krüger-26/+70
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-11Auto merge of #122213 - estebank:issue-50195, r=oli-obk,estebankbors-4/+153
Provide suggestion to dereference closure tail if appropriate When encoutnering a case like ```rust use std::collections::HashMap; fn main() { let vs = vec![0, 0, 1, 1, 3, 4, 5, 6, 3, 3, 3]; let mut counts = HashMap::new(); for num in vs { let count = counts.entry(num).or_insert(0); *count += 1; } let _ = counts.iter().max_by_key(|(_, v)| v); ``` produce the following suggestion ``` error: lifetime may not live long enough --> $DIR/return-value-lifetime-error.rs:13:47 | LL | let _ = counts.iter().max_by_key(|(_, v)| v); | ------- ^ returning this value requires that `'1` must outlive `'2` | | | | | return type of closure is &'2 &i32 | has type `&'1 (&i32, &i32)` | help: dereference the return value | LL | let _ = counts.iter().max_by_key(|(_, v)| **v); | ++ ``` Fix #50195.
2024-04-10Handle more cases of "values to suggest" given a typeEsteban Küber-3/+16
Add handling for `String`, `Box`, `Option` and `Result`.