Always capture slice when pattern requires checking the length

This commit is contained in:
clubby789 2023-05-21 23:06:06 +00:00
parent 9d871b0617
commit ace794c6d7
3 changed files with 209 additions and 91 deletions

View File

@ -438,12 +438,19 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
// to borrow discr.
needs_to_be_read = true;
}
PatKind::Or(_)
| PatKind::Box(_)
| PatKind::Slice(..)
| PatKind::Ref(..)
| PatKind::Wild => {
// If the PatKind is Or, Box, Slice or Ref, the decision is made later
PatKind::Slice(lhs, wild, rhs) => {
// We don't need to test the length if the pattern is `[..]`
if matches!((lhs, wild, rhs), (&[], Some(_), &[]))
// Arrays have a statically known size, so
// there is no need to read their length
|| discr_place.place.base_ty.is_array()
{
} else {
needs_to_be_read = true;
}
}
PatKind::Or(_) | PatKind::Box(_) | PatKind::Ref(..) | PatKind::Wild => {
// If the PatKind is Or, Box, or Ref, the decision is made later
// as these patterns contains subpatterns
// If the PatKind is Wild, the decision is made based on the other patterns being
// examined

View File

@ -1,6 +1,7 @@
// edition:2021
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
// Should capture the discriminant since a variant of a multivariant enum is
// mentioned in the match arm; the discriminant is captured by the closure regardless
@ -8,9 +9,6 @@
fn test_1_should_capture() {
let variant = Some(2229);
let c = #[rustc_capture_analysis]
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|| {
//~^ First Pass analysis includes:
//~| Min Capture analysis includes:
@ -29,8 +27,6 @@ fn test_1_should_capture() {
fn test_2_should_not_capture() {
let variant = Some(2229);
let c = #[rustc_capture_analysis]
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|| {
//~^ First Pass analysis includes:
match variant {
@ -50,8 +46,6 @@ enum SingleVariant {
fn test_3_should_not_capture_single_variant() {
let variant = SingleVariant::Points(1);
let c = #[rustc_capture_analysis]
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|| {
//~^ First Pass analysis includes:
match variant {
@ -66,8 +60,6 @@ fn test_3_should_not_capture_single_variant() {
fn test_6_should_capture_single_variant() {
let variant = SingleVariant::Points(1);
let c = #[rustc_capture_analysis]
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|| {
//~^ First Pass analysis includes:
//~| Min Capture analysis includes:
@ -88,8 +80,6 @@ fn test_6_should_capture_single_variant() {
fn test_4_should_not_capture_array() {
let array: [i32; 3] = [0; 3];
let c = #[rustc_capture_analysis]
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|| {
//~^ First Pass analysis includes:
match array {
@ -112,8 +102,6 @@ enum MVariant {
fn test_5_should_capture_multi_variant() {
let variant = MVariant::A;
let c = #[rustc_capture_analysis]
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|| {
//~^ First Pass analysis includes:
//~| Min Capture analysis includes:
@ -127,6 +115,62 @@ fn test_5_should_capture_multi_variant() {
c();
}
// Even though all patterns are wild, we need to read the discriminant
// in order to test the slice length
fn test_7_should_capture_slice_len() {
let slice: &[i32] = &[1, 2, 3];
let c = #[rustc_capture_analysis]
|| {
//~^ First Pass analysis includes:
//~| Min Capture analysis includes:
match slice {
//~^ NOTE: Capturing slice[] -> ImmBorrow
//~| NOTE: Min Capture slice[] -> ImmBorrow
[_,_,_] => {},
_ => {}
}
};
c();
let c = #[rustc_capture_analysis]
|| {
//~^ First Pass analysis includes:
//~| Min Capture analysis includes:
match slice {
//~^ NOTE: Capturing slice[] -> ImmBorrow
//~| NOTE: Min Capture slice[] -> ImmBorrow
[] => {},
_ => {}
}
};
c();
let c = #[rustc_capture_analysis]
|| {
//~^ First Pass analysis includes:
//~| Min Capture analysis includes:
match slice {
//~^ NOTE: Capturing slice[] -> ImmBorrow
//~| NOTE: Min Capture slice[] -> ImmBorrow
[_, .. ,_] => {},
_ => {}
}
};
c();
}
// Wild pattern that doesn't bind, so no capture
fn test_8_capture_slice_wild() {
let slice: &[i32] = &[1, 2, 3];
let c = #[rustc_capture_analysis]
|| {
//~^ First Pass analysis includes:
match slice {
[..] => {},
_ => {}
}
};
c();
}
fn main() {
test_1_should_capture();
test_2_should_not_capture();
@ -134,4 +178,6 @@ fn main() {
test_6_should_capture_single_variant();
test_4_should_not_capture_array();
test_5_should_capture_multi_variant();
test_7_should_capture_slice_len();
test_8_capture_slice_wild();
}

View File

@ -1,59 +1,5 @@
error[E0658]: attributes on expressions are experimental
--> $DIR/patterns-capture-analysis.rs:10:14
|
LL | let c = #[rustc_capture_analysis]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
error[E0658]: attributes on expressions are experimental
--> $DIR/patterns-capture-analysis.rs:31:14
|
LL | let c = #[rustc_capture_analysis]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
error[E0658]: attributes on expressions are experimental
--> $DIR/patterns-capture-analysis.rs:52:14
|
LL | let c = #[rustc_capture_analysis]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
error[E0658]: attributes on expressions are experimental
--> $DIR/patterns-capture-analysis.rs:68:14
|
LL | let c = #[rustc_capture_analysis]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
error[E0658]: attributes on expressions are experimental
--> $DIR/patterns-capture-analysis.rs:90:14
|
LL | let c = #[rustc_capture_analysis]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
error[E0658]: attributes on expressions are experimental
--> $DIR/patterns-capture-analysis.rs:114:14
|
LL | let c = #[rustc_capture_analysis]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:14:5
--> $DIR/patterns-capture-analysis.rs:12:5
|
LL | / || {
LL | |
@ -65,13 +11,13 @@ LL | | };
| |_____^
|
note: Capturing variant[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:17:15
--> $DIR/patterns-capture-analysis.rs:15:15
|
LL | match variant {
| ^^^^^^^
error: Min Capture analysis includes:
--> $DIR/patterns-capture-analysis.rs:14:5
--> $DIR/patterns-capture-analysis.rs:12:5
|
LL | / || {
LL | |
@ -83,13 +29,13 @@ LL | | };
| |_____^
|
note: Min Capture variant[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:17:15
--> $DIR/patterns-capture-analysis.rs:15:15
|
LL | match variant {
| ^^^^^^^
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:34:5
--> $DIR/patterns-capture-analysis.rs:30:5
|
LL | / || {
LL | |
@ -100,7 +46,7 @@ LL | | };
| |_____^
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:55:5
--> $DIR/patterns-capture-analysis.rs:49:5
|
LL | / || {
LL | |
@ -111,7 +57,7 @@ LL | | };
| |_____^
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:71:5
--> $DIR/patterns-capture-analysis.rs:63:5
|
LL | / || {
LL | |
@ -123,18 +69,18 @@ LL | | };
| |_____^
|
note: Capturing variant[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:74:15
--> $DIR/patterns-capture-analysis.rs:66:15
|
LL | match variant {
| ^^^^^^^
note: Capturing variant[(0, 0)] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:74:15
--> $DIR/patterns-capture-analysis.rs:66:15
|
LL | match variant {
| ^^^^^^^
error: Min Capture analysis includes:
--> $DIR/patterns-capture-analysis.rs:71:5
--> $DIR/patterns-capture-analysis.rs:63:5
|
LL | / || {
LL | |
@ -146,13 +92,13 @@ LL | | };
| |_____^
|
note: Min Capture variant[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:74:15
--> $DIR/patterns-capture-analysis.rs:66:15
|
LL | match variant {
| ^^^^^^^
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:93:5
--> $DIR/patterns-capture-analysis.rs:83:5
|
LL | / || {
LL | |
@ -163,7 +109,7 @@ LL | | };
| |_____^
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:117:5
--> $DIR/patterns-capture-analysis.rs:105:5
|
LL | / || {
LL | |
@ -175,13 +121,13 @@ LL | | };
| |_____^
|
note: Capturing variant[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:120:15
--> $DIR/patterns-capture-analysis.rs:108:15
|
LL | match variant {
| ^^^^^^^
error: Min Capture analysis includes:
--> $DIR/patterns-capture-analysis.rs:117:5
--> $DIR/patterns-capture-analysis.rs:105:5
|
LL | / || {
LL | |
@ -193,11 +139,130 @@ LL | | };
| |_____^
|
note: Min Capture variant[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:120:15
--> $DIR/patterns-capture-analysis.rs:108:15
|
LL | match variant {
| ^^^^^^^
error: aborting due to 15 previous errors
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:123:5
|
LL | / || {
LL | |
LL | |
LL | | match slice {
... |
LL | | }
LL | | };
| |_____^
|
note: Capturing slice[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:126:15
|
LL | match slice {
| ^^^^^
error: Min Capture analysis includes:
--> $DIR/patterns-capture-analysis.rs:123:5
|
LL | / || {
LL | |
LL | |
LL | | match slice {
... |
LL | | }
LL | | };
| |_____^
|
note: Min Capture slice[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:126:15
|
LL | match slice {
| ^^^^^
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:135:5
|
LL | / || {
LL | |
LL | |
LL | | match slice {
... |
LL | | }
LL | | };
| |_____^
|
note: Capturing slice[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:138:15
|
LL | match slice {
| ^^^^^
error: Min Capture analysis includes:
--> $DIR/patterns-capture-analysis.rs:135:5
|
LL | / || {
LL | |
LL | |
LL | | match slice {
... |
LL | | }
LL | | };
| |_____^
|
note: Min Capture slice[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:138:15
|
LL | match slice {
| ^^^^^
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:147:5
|
LL | / || {
LL | |
LL | |
LL | | match slice {
... |
LL | | }
LL | | };
| |_____^
|
note: Capturing slice[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:150:15
|
LL | match slice {
| ^^^^^
error: Min Capture analysis includes:
--> $DIR/patterns-capture-analysis.rs:147:5
|
LL | / || {
LL | |
LL | |
LL | | match slice {
... |
LL | | }
LL | | };
| |_____^
|
note: Min Capture slice[] -> ImmBorrow
--> $DIR/patterns-capture-analysis.rs:150:15
|
LL | match slice {
| ^^^^^
error: First Pass analysis includes:
--> $DIR/patterns-capture-analysis.rs:164:5
|
LL | / || {
LL | |
LL | | match slice {
LL | | [..] => {},
LL | | _ => {}
LL | | }
LL | | };
| |_____^
error: aborting due to 16 previous errors
For more information about this error, try `rustc --explain E0658`.