diff options
| author | bors <bors@rust-lang.org> | 2022-01-13 18:51:07 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-01-13 18:51:07 +0000 |
| commit | 22e491ac7ed454d34669151a8b6464cb643c9b41 (patch) | |
| tree | 8e30fdbc16b29cd272052aad7f885453ff789841 /src | |
| parent | 256721ee519f6ff15dc5c1cfaf3ebf9af75efa4a (diff) | |
| parent | c84cea9c25e8db73b1b580ab9c7f72985a05da4d (diff) | |
| download | rust-22e491ac7ed454d34669151a8b6464cb643c9b41.tar.gz rust-22e491ac7ed454d34669151a8b6464cb643c9b41.zip | |
Auto merge of #89861 - nbdd0121:closure, r=wesleywiser
Closure capture cleanup & refactor Follow up of #89648 Each commit is self-contained and the rationale/changes are documented in the commit message, so it's advisable to review commit by commit. The code is significantly cleaner (at least IMO), but that could have some perf implication, so I'd suggest a perf run. r? `@wesleywiser` cc `@arora-aman`
Diffstat (limited to 'src')
11 files changed, 103 insertions, 30 deletions
diff --git a/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.rs b/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.rs index 7a4b21f0223..2bcbd792e3a 100644 --- a/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.rs +++ b/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.rs @@ -15,6 +15,7 @@ fn main() { //~^ NOTE: Capturing m[] -> MutBorrow //~| NOTE: Min Capture m[] -> MutBorrow m[1] += 40; + //~^ NOTE: Capturing m[] -> MutBorrow }; c(); diff --git a/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr b/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr index 69ec53447b8..129b26456ce 100644 --- a/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr +++ b/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr @@ -15,7 +15,7 @@ LL | | LL | | LL | | m[0] += 10; ... | -LL | | m[1] += 40; +LL | | LL | | }; | |_____^ | @@ -24,6 +24,11 @@ note: Capturing m[] -> MutBorrow | LL | m[0] += 10; | ^ +note: Capturing m[] -> MutBorrow + --> $DIR/arrays-completely-captured.rs:17:9 + | +LL | m[1] += 40; + | ^ error: Min Capture analysis includes: --> $DIR/arrays-completely-captured.rs:11:5 @@ -33,7 +38,7 @@ LL | | LL | | LL | | m[0] += 10; ... | -LL | | m[1] += 40; +LL | | LL | | }; | |_____^ | diff --git a/src/test/ui/closures/2229_closure_analysis/destructure_patterns.rs b/src/test/ui/closures/2229_closure_analysis/destructure_patterns.rs index 9918802334e..6c65a7bf87b 100644 --- a/src/test/ui/closures/2229_closure_analysis/destructure_patterns.rs +++ b/src/test/ui/closures/2229_closure_analysis/destructure_patterns.rs @@ -15,6 +15,8 @@ fn arrays() { //~| ERROR: Min Capture analysis includes: let [a, b, .., e] = arr; //~^ NOTE: Capturing arr[Index] -> ByValue + //~| NOTE: Capturing arr[Index] -> ByValue + //~| NOTE: Capturing arr[Index] -> ByValue //~| NOTE: Min Capture arr[] -> ByValue assert_eq!(a, "A"); assert_eq!(b, "B"); diff --git a/src/test/ui/closures/2229_closure_analysis/destructure_patterns.stderr b/src/test/ui/closures/2229_closure_analysis/destructure_patterns.stderr index b53adb52481..44fbe6d8158 100644 --- a/src/test/ui/closures/2229_closure_analysis/destructure_patterns.stderr +++ b/src/test/ui/closures/2229_closure_analysis/destructure_patterns.stderr @@ -8,7 +8,7 @@ LL | let c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental - --> $DIR/destructure_patterns.rs:36:13 + --> $DIR/destructure_patterns.rs:38:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental - --> $DIR/destructure_patterns.rs:56:13 + --> $DIR/destructure_patterns.rs:58:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,6 +42,16 @@ note: Capturing arr[Index] -> ByValue | LL | let [a, b, .., e] = arr; | ^^^ +note: Capturing arr[Index] -> ByValue + --> $DIR/destructure_patterns.rs:16:29 + | +LL | let [a, b, .., e] = arr; + | ^^^ +note: Capturing arr[Index] -> ByValue + --> $DIR/destructure_patterns.rs:16:29 + | +LL | let [a, b, .., e] = arr; + | ^^^ error: Min Capture analysis includes: --> $DIR/destructure_patterns.rs:13:5 @@ -62,7 +72,7 @@ LL | let [a, b, .., e] = arr; | ^^^ error: First Pass analysis includes: - --> $DIR/destructure_patterns.rs:39:5 + --> $DIR/destructure_patterns.rs:41:5 | LL | / || { LL | | @@ -74,18 +84,18 @@ LL | | }; | |_____^ | note: Capturing p[(0, 0)] -> MutBorrow - --> $DIR/destructure_patterns.rs:42:58 + --> $DIR/destructure_patterns.rs:44:58 | LL | let Point { x: ref mut x, y: _, id: moved_id } = p; | ^ note: Capturing p[(2, 0)] -> ByValue - --> $DIR/destructure_patterns.rs:42:58 + --> $DIR/destructure_patterns.rs:44:58 | LL | let Point { x: ref mut x, y: _, id: moved_id } = p; | ^ error: Min Capture analysis includes: - --> $DIR/destructure_patterns.rs:39:5 + --> $DIR/destructure_patterns.rs:41:5 | LL | / || { LL | | @@ -97,18 +107,18 @@ LL | | }; | |_____^ | note: Min Capture p[(0, 0)] -> MutBorrow - --> $DIR/destructure_patterns.rs:42:58 + --> $DIR/destructure_patterns.rs:44:58 | LL | let Point { x: ref mut x, y: _, id: moved_id } = p; | ^ note: Min Capture p[(2, 0)] -> ByValue - --> $DIR/destructure_patterns.rs:42:58 + --> $DIR/destructure_patterns.rs:44:58 | LL | let Point { x: ref mut x, y: _, id: moved_id } = p; | ^ error: First Pass analysis includes: - --> $DIR/destructure_patterns.rs:59:5 + --> $DIR/destructure_patterns.rs:61:5 | LL | / || { LL | | @@ -120,23 +130,23 @@ LL | | }; | |_____^ | note: Capturing t[(0, 0)] -> MutBorrow - --> $DIR/destructure_patterns.rs:62:54 + --> $DIR/destructure_patterns.rs:64:54 | LL | let (ref mut x, ref ref_str, (moved_s, _)) = t; | ^ note: Capturing t[(1, 0)] -> ImmBorrow - --> $DIR/destructure_patterns.rs:62:54 + --> $DIR/destructure_patterns.rs:64:54 | LL | let (ref mut x, ref ref_str, (moved_s, _)) = t; | ^ note: Capturing t[(2, 0),(0, 0)] -> ByValue - --> $DIR/destructure_patterns.rs:62:54 + --> $DIR/destructure_patterns.rs:64:54 | LL | let (ref mut x, ref ref_str, (moved_s, _)) = t; | ^ error: Min Capture analysis includes: - --> $DIR/destructure_patterns.rs:59:5 + --> $DIR/destructure_patterns.rs:61:5 | LL | / || { LL | | @@ -148,17 +158,17 @@ LL | | }; | |_____^ | note: Min Capture t[(0, 0)] -> MutBorrow - --> $DIR/destructure_patterns.rs:62:54 + --> $DIR/destructure_patterns.rs:64:54 | LL | let (ref mut x, ref ref_str, (moved_s, _)) = t; | ^ note: Min Capture t[(1, 0)] -> ImmBorrow - --> $DIR/destructure_patterns.rs:62:54 + --> $DIR/destructure_patterns.rs:64:54 | LL | let (ref mut x, ref ref_str, (moved_s, _)) = t; | ^ note: Min Capture t[(2, 0),(0, 0)] -> ByValue - --> $DIR/destructure_patterns.rs:62:54 + --> $DIR/destructure_patterns.rs:64:54 | LL | let (ref mut x, ref ref_str, (moved_s, _)) = t; | ^ diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/union.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/union.rs new file mode 100644 index 00000000000..46b54846e32 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/union.rs @@ -0,0 +1,25 @@ +// edition:2021 + +// Test that we point to the correct location that results a union being captured. +// Union is special because it can't be disjointly captured. + +union A { + y: u32, + x: (), +} + +fn main() { + let mut a = A { y: 1 }; + let mut c = || { + //~^ borrow of `a.y` occurs here + let _ = unsafe { &a.y }; + let _ = &mut a; + //~^ borrow occurs due to use in closure + let _ = unsafe { &mut a.y }; + }; + a.y = 1; + //~^ cannot assign to `a.y` because it is borrowed [E0506] + //~| assignment to borrowed `a.y` occurs here + c(); + //~^ borrow later used here +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/union.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/union.stderr new file mode 100644 index 00000000000..7c34e2336c8 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/union.stderr @@ -0,0 +1,18 @@ +error[E0506]: cannot assign to `a.y` because it is borrowed + --> $DIR/union.rs:20:5 + | +LL | let mut c = || { + | -- borrow of `a.y` occurs here +... +LL | let _ = &mut a; + | - borrow occurs due to use in closure +... +LL | a.y = 1; + | ^^^^^^^ assignment to borrowed `a.y` occurs here +... +LL | c(); + | - borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/closures/2229_closure_analysis/nested-closure.rs b/src/test/ui/closures/2229_closure_analysis/nested-closure.rs index f6775b3a3a5..22eae744b80 100644 --- a/src/test/ui/closures/2229_closure_analysis/nested-closure.rs +++ b/src/test/ui/closures/2229_closure_analysis/nested-closure.rs @@ -40,6 +40,7 @@ fn main() { //~| NOTE: Min Capture p[(1, 0)] -> MutBorrow c2(); println!("{}", p.y); + //~^ NOTE: Capturing p[(1, 0)] -> ImmBorrow }; c1(); diff --git a/src/test/ui/closures/2229_closure_analysis/nested-closure.stderr b/src/test/ui/closures/2229_closure_analysis/nested-closure.stderr index 013bc74e67e..a50d0c6a182 100644 --- a/src/test/ui/closures/2229_closure_analysis/nested-closure.stderr +++ b/src/test/ui/closures/2229_closure_analysis/nested-closure.stderr @@ -58,7 +58,7 @@ LL | | LL | | LL | | println!("{}", p.x); ... | -LL | | println!("{}", p.y); +LL | | LL | | }; | |_____^ | @@ -72,6 +72,11 @@ note: Capturing p[(1, 0)] -> MutBorrow | LL | || p.y += incr; | ^^^ +note: Capturing p[(1, 0)] -> ImmBorrow + --> $DIR/nested-closure.rs:42:24 + | +LL | println!("{}", p.y); + | ^^^ error: Min Capture analysis includes: --> $DIR/nested-closure.rs:22:5 @@ -81,7 +86,7 @@ LL | | LL | | LL | | println!("{}", p.x); ... | -LL | | println!("{}", p.y); +LL | | LL | | }; | |_____^ | diff --git a/src/test/ui/closures/2229_closure_analysis/repr_packed.rs b/src/test/ui/closures/2229_closure_analysis/repr_packed.rs index 7d472ad020f..3ed780f51c7 100644 --- a/src/test/ui/closures/2229_closure_analysis/repr_packed.rs +++ b/src/test/ui/closures/2229_closure_analysis/repr_packed.rs @@ -48,6 +48,7 @@ fn test_alignment_affected() { //~^ ERROR: First Pass analysis includes: //~| ERROR: Min Capture analysis includes: let z1: &String = &foo.x; + //~^ NOTE: Capturing foo[] -> ImmBorrow let z2: &mut u16 = &mut foo.y; //~^ NOTE: Capturing foo[] -> MutBorrow //~| NOTE: Min Capture foo[] -> MutBorrow diff --git a/src/test/ui/closures/2229_closure_analysis/repr_packed.stderr b/src/test/ui/closures/2229_closure_analysis/repr_packed.stderr index 405f66210aa..580061ebc6e 100644 --- a/src/test/ui/closures/2229_closure_analysis/repr_packed.stderr +++ b/src/test/ui/closures/2229_closure_analysis/repr_packed.stderr @@ -17,7 +17,7 @@ LL | let mut c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental - --> $DIR/repr_packed.rs:78:13 + --> $DIR/repr_packed.rs:79:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,8 +83,13 @@ LL | | println!("({}, {})", z1, z2); LL | | }; | |_____^ | +note: Capturing foo[] -> ImmBorrow + --> $DIR/repr_packed.rs:50:28 + | +LL | let z1: &String = &foo.x; + | ^^^^^ note: Capturing foo[] -> MutBorrow - --> $DIR/repr_packed.rs:51:33 + --> $DIR/repr_packed.rs:52:33 | LL | let z2: &mut u16 = &mut foo.y; | ^^^^^ @@ -102,13 +107,13 @@ LL | | }; | |_____^ | note: Min Capture foo[] -> MutBorrow - --> $DIR/repr_packed.rs:51:33 + --> $DIR/repr_packed.rs:52:33 | LL | let z2: &mut u16 = &mut foo.y; | ^^^^^ error: First Pass analysis includes: - --> $DIR/repr_packed.rs:81:5 + --> $DIR/repr_packed.rs:82:5 | LL | / || { LL | | @@ -120,18 +125,18 @@ LL | | }; | |_____^ | note: Capturing foo[] -> ImmBorrow - --> $DIR/repr_packed.rs:84:24 + --> $DIR/repr_packed.rs:85:24 | LL | println!("{}", foo.x); | ^^^^^ note: Capturing foo[(0, 0)] -> ByValue - --> $DIR/repr_packed.rs:88:18 + --> $DIR/repr_packed.rs:89:18 | LL | let _z = foo.x; | ^^^^^ error: Min Capture analysis includes: - --> $DIR/repr_packed.rs:81:5 + --> $DIR/repr_packed.rs:82:5 | LL | / || { LL | | @@ -143,7 +148,7 @@ LL | | }; | |_____^ | note: Min Capture foo[] -> ByValue - --> $DIR/repr_packed.rs:84:24 + --> $DIR/repr_packed.rs:85:24 | LL | println!("{}", foo.x); | ^^^^^ foo[] used here diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 91ebc7ea89c..90f5baffd22 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -976,8 +976,8 @@ pub fn can_move_expr_to_closure(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> }; if !self.locals.contains(&local_id) { let capture = match capture.info.capture_kind { - UpvarCapture::ByValue(_) => CaptureKind::Value, - UpvarCapture::ByRef(borrow) => match borrow.kind { + UpvarCapture::ByValue => CaptureKind::Value, + UpvarCapture::ByRef(kind) => match kind { BorrowKind::ImmBorrow => CaptureKind::Ref(Mutability::Not), BorrowKind::UniqueImmBorrow | BorrowKind::MutBorrow => { CaptureKind::Ref(Mutability::Mut) |
