Skip to content

Commit 8c3c446

Browse files
committed
Add more tests for slice patterns
1 parent d490c34 commit 8c3c446

9 files changed

+678
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Test that slice subslice patterns are correctly handled in const evaluation.
2+
3+
// run-pass
4+
5+
#![feature(slice_patterns, const_fn, const_if_match)]
6+
#[derive(PartialEq, Debug, Clone)]
7+
struct N(u8);
8+
9+
#[derive(PartialEq, Debug, Clone)]
10+
struct Z;
11+
12+
macro_rules! n {
13+
($($e:expr),* $(,)?) => {
14+
[$(N($e)),*]
15+
}
16+
}
17+
18+
// This macro has an unused variable so that it can be repeated base on the
19+
// number of times a repeated variable (`$e` in `z`) occurs.
20+
macro_rules! zed {
21+
($e:expr) => { Z }
22+
}
23+
24+
macro_rules! z {
25+
($($e:expr),* $(,)?) => {
26+
[$(zed!($e)),*]
27+
}
28+
}
29+
30+
// Compare constant evaluation and runtime evaluation of a given expression.
31+
macro_rules! compare_evaluation_inner {
32+
($e:expr, $t:ty $(,)?) => {{
33+
const CONST_EVAL: $t = $e;
34+
const fn const_eval() -> $t { $e }
35+
static CONST_EVAL2: $t = const_eval();
36+
let runtime_eval = $e;
37+
assert_eq!(CONST_EVAL, runtime_eval);
38+
assert_eq!(CONST_EVAL2, runtime_eval);
39+
}}
40+
}
41+
42+
// Compare the result of matching `$e` against `$p` using both `if let` and
43+
// `match`.
44+
macro_rules! compare_evaluation {
45+
($p:pat, $e:expr, $matches:expr, $t:ty $(,)?) => {{
46+
compare_evaluation_inner!(if let $p = $e as &[_] { $matches } else { None }, $t);
47+
compare_evaluation_inner!(match $e as &[_] { $p => $matches, _ => None }, $t);
48+
}}
49+
}
50+
51+
// Repeat `$test`, substituting the given macro variables with the given
52+
// identifiers.
53+
//
54+
// For example:
55+
//
56+
// repeat! {
57+
// ($name); X; Y:
58+
// struct $name;
59+
// }
60+
//
61+
// Expands to:
62+
//
63+
// struct X; struct Y;
64+
//
65+
// This is used to repeat the tests using both the `N` and `Z`
66+
// types.
67+
macro_rules! repeat {
68+
(($($dollar:tt $placeholder:ident)*); $($($values:ident),+);*: $($test:tt)*) => {
69+
macro_rules! single {
70+
($($dollar $placeholder:ident),*) => { $($test)* }
71+
}
72+
$(single!($($values),+);)*
73+
}
74+
}
75+
76+
fn main() {
77+
repeat! {
78+
($arr $Ty); n, N; z, Z:
79+
compare_evaluation!([_, x @ .., _], &$arr!(1, 2, 3, 4), Some(x), Option<&'static [$Ty]>);
80+
compare_evaluation!([x, .., _], &$arr!(1, 2, 3, 4), Some(x), Option<&'static $Ty>);
81+
compare_evaluation!([_, .., x], &$arr!(1, 2, 3, 4), Some(x), Option<&'static $Ty>);
82+
83+
compare_evaluation!([_, x @ .., _], &$arr!(1, 2), Some(x), Option<&'static [$Ty]>);
84+
compare_evaluation!([x, .., _], &$arr!(1, 2), Some(x), Option<&'static $Ty>);
85+
compare_evaluation!([_, .., x], &$arr!(1, 2), Some(x), Option<&'static $Ty>);
86+
87+
compare_evaluation!([_, x @ .., _], &$arr!(1), Some(x), Option<&'static [$Ty]>);
88+
compare_evaluation!([x, .., _], &$arr!(1), Some(x), Option<&'static $Ty>);
89+
compare_evaluation!([_, .., x], &$arr!(1), Some(x), Option<&'static $Ty>);
90+
}
91+
92+
compare_evaluation!([N(x), .., _], &n!(1, 2, 3, 4), Some(x), Option<&'static u8>);
93+
compare_evaluation!([_, .., N(x)], &n!(1, 2, 3, 4), Some(x), Option<&'static u8>);
94+
95+
compare_evaluation!([N(x), .., _], &n!(1, 2), Some(x), Option<&'static u8>);
96+
compare_evaluation!([_, .., N(x)], &n!(1, 2), Some(x), Option<&'static u8>);
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Test that array subslice patterns are correctly handled in const evaluation.
2+
3+
// run-pass
4+
5+
#![feature(slice_patterns)]
6+
7+
#[derive(PartialEq, Debug, Clone)]
8+
struct N(u8);
9+
10+
#[derive(PartialEq, Debug, Clone)]
11+
struct Z;
12+
13+
macro_rules! n {
14+
($($e:expr),* $(,)?) => {
15+
[$(N($e)),*]
16+
}
17+
}
18+
19+
// This macro has an unused variable so that it can be repeated base on the
20+
// number of times a repeated variable (`$e` in `z`) occurs.
21+
macro_rules! zed {
22+
($e:expr) => { Z }
23+
}
24+
25+
macro_rules! z {
26+
($($e:expr),* $(,)?) => {
27+
[$(zed!($e)),*]
28+
}
29+
}
30+
31+
// Compare constant evaluation and runtime evaluation of a given expression.
32+
macro_rules! compare_evaluation {
33+
($e:expr, $t:ty $(,)?) => {{
34+
const CONST_EVAL: $t = $e;
35+
const fn const_eval() -> $t { $e }
36+
static CONST_EVAL2: $t = const_eval();
37+
let runtime_eval = $e;
38+
assert_eq!(CONST_EVAL, runtime_eval);
39+
assert_eq!(CONST_EVAL2, runtime_eval);
40+
}}
41+
}
42+
43+
// Repeat `$test`, substituting the given macro variables with the given
44+
// identifiers.
45+
//
46+
// For example:
47+
//
48+
// repeat! {
49+
// ($name); X; Y:
50+
// struct $name;
51+
// }
52+
//
53+
// Expands to:
54+
//
55+
// struct X; struct Y;
56+
//
57+
// This is used to repeat the tests using both the `N` and `Z`
58+
// types.
59+
macro_rules! repeat {
60+
(($($dollar:tt $placeholder:ident)*); $($($values:ident),+);*: $($test:tt)*) => {
61+
macro_rules! single {
62+
($($dollar $placeholder:ident),*) => { $($test)* }
63+
}
64+
$(single!($($values),+);)*
65+
}
66+
}
67+
68+
fn main() {
69+
repeat! {
70+
($arr $Ty); n, N; z, Z:
71+
compare_evaluation!({ let [_, x @ .., _] = $arr!(1, 2, 3, 4); x }, [$Ty; 2]);
72+
compare_evaluation!({ let [_, ref x @ .., _] = $arr!(1, 2, 3, 4); x }, &'static [$Ty; 2]);
73+
compare_evaluation!({ let [_, x @ .., _] = &$arr!(1, 2, 3, 4); x }, &'static [$Ty; 2]);
74+
75+
compare_evaluation!({ let [_, _, x @ .., _, _] = $arr!(1, 2, 3, 4); x }, [$Ty; 0]);
76+
compare_evaluation!(
77+
{ let [_, _, ref x @ .., _, _] = $arr!(1, 2, 3, 4); x },
78+
&'static [$Ty; 0],
79+
);
80+
compare_evaluation!(
81+
{ let [_, _, x @ .., _, _] = &$arr!(1, 2, 3, 4); x },
82+
&'static [$Ty; 0],
83+
);
84+
85+
compare_evaluation!({ let [_, .., x] = $arr!(1, 2, 3, 4); x }, $Ty);
86+
compare_evaluation!({ let [_, .., ref x] = $arr!(1, 2, 3, 4); x }, &'static $Ty);
87+
compare_evaluation!({ let [_, _y @ .., x] = &$arr!(1, 2, 3, 4); x }, &'static $Ty);
88+
}
89+
90+
compare_evaluation!({ let [_, .., N(x)] = n!(1, 2, 3, 4); x }, u8);
91+
compare_evaluation!({ let [_, .., N(ref x)] = n!(1, 2, 3, 4); x }, &'static u8);
92+
compare_evaluation!({ let [_, .., N(x)] = &n!(1, 2, 3, 4); x }, &'static u8);
93+
94+
compare_evaluation!({ let [N(x), .., _] = n!(1, 2, 3, 4); x }, u8);
95+
compare_evaluation!({ let [N(ref x), .., _] = n!(1, 2, 3, 4); x }, &'static u8);
96+
compare_evaluation!({ let [N(x), .., _] = &n!(1, 2, 3, 4); x }, &'static u8);
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Check that closure captures for slice patterns are inferred correctly
2+
3+
#![feature(slice_patterns)]
4+
#![allow(unused_variables)]
5+
6+
// run-pass
7+
8+
fn arr_by_ref(x: [String; 3]) {
9+
let r = &x;
10+
let f = || {
11+
let [ref y, ref z @ ..] = x;
12+
};
13+
f();
14+
f();
15+
// Ensure `x` was borrowed
16+
drop(r);
17+
// Ensure that `x` wasn't moved from.
18+
drop(x);
19+
}
20+
21+
fn arr_by_mut(mut x: [String; 3]) {
22+
let mut f = || {
23+
let [ref mut y, ref mut z @ ..] = x;
24+
};
25+
f();
26+
f();
27+
drop(x);
28+
}
29+
30+
fn arr_by_move(x: [String; 3]) {
31+
let f = || {
32+
let [y, z @ ..] = x;
33+
};
34+
f();
35+
}
36+
37+
fn arr_ref_by_ref(x: &[String; 3]) {
38+
let r = &x;
39+
let f = || {
40+
let [ref y, ref z @ ..] = *x;
41+
};
42+
let g = || {
43+
let [y, z @ ..] = x;
44+
};
45+
f();
46+
g();
47+
f();
48+
g();
49+
drop(r);
50+
drop(x);
51+
}
52+
53+
fn arr_ref_by_mut(x: &mut [String; 3]) {
54+
let mut f = || {
55+
let [ref mut y, ref mut z @ ..] = *x;
56+
};
57+
f();
58+
f();
59+
let mut g = || {
60+
let [y, z @ ..] = x;
61+
// Ensure binding mode was chosen correctly:
62+
std::mem::swap(y, &mut z[0]);
63+
};
64+
g();
65+
g();
66+
drop(x);
67+
}
68+
69+
fn arr_box_by_move(x: Box<[String; 3]>) {
70+
let f = || {
71+
let [y, z @ ..] = *x;
72+
};
73+
f();
74+
}
75+
76+
fn slice_by_ref(x: &[String]) {
77+
let r = &x;
78+
let f = || {
79+
if let [ref y, ref z @ ..] = *x {}
80+
};
81+
let g = || {
82+
if let [y, z @ ..] = x {}
83+
};
84+
f();
85+
g();
86+
f();
87+
g();
88+
drop(r);
89+
drop(x);
90+
}
91+
92+
fn slice_by_mut(x: &mut [String]) {
93+
let mut f = || {
94+
if let [ref mut y, ref mut z @ ..] = *x {}
95+
};
96+
f();
97+
f();
98+
let mut g = || {
99+
if let [y, z @ ..] = x {
100+
// Ensure binding mode was chosen correctly:
101+
std::mem::swap(y, &mut z[0]);
102+
}
103+
};
104+
g();
105+
g();
106+
drop(x);
107+
}
108+
109+
fn main() {
110+
arr_by_ref(Default::default());
111+
arr_by_mut(Default::default());
112+
arr_by_move(Default::default());
113+
arr_ref_by_ref(&Default::default());
114+
arr_ref_by_mut(&mut Default::default());
115+
arr_box_by_move(Default::default());
116+
slice_by_ref(&<[_; 3]>::default());
117+
slice_by_mut(&mut <[_; 3]>::default());
118+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Check that closure captures for slice patterns are inferred correctly
2+
3+
#![feature(slice_patterns)]
4+
5+
fn arr_by_ref(mut x: [String; 3]) {
6+
let f = || {
7+
let [ref y, ref z @ ..] = x;
8+
};
9+
let r = &mut x;
10+
//~^ ERROR cannot borrow
11+
f();
12+
}
13+
14+
fn arr_by_mut(mut x: [String; 3]) {
15+
let mut f = || {
16+
let [ref mut y, ref mut z @ ..] = x;
17+
};
18+
let r = &x;
19+
//~^ ERROR cannot borrow
20+
f();
21+
}
22+
23+
fn arr_by_move(x: [String; 3]) {
24+
let f = || {
25+
let [y, z @ ..] = x;
26+
};
27+
&x;
28+
//~^ ERROR borrow of moved value
29+
}
30+
31+
fn arr_ref_by_ref(x: &mut [String; 3]) {
32+
let f = || {
33+
let [ref y, ref z @ ..] = *x;
34+
};
35+
let r = &mut *x;
36+
//~^ ERROR cannot borrow
37+
f();
38+
}
39+
40+
fn arr_ref_by_uniq(x: &mut [String; 3]) {
41+
let mut f = || {
42+
let [ref mut y, ref mut z @ ..] = *x;
43+
};
44+
let r = &x;
45+
//~^ ERROR cannot borrow
46+
f();
47+
}
48+
49+
fn arr_box_by_move(x: Box<[String; 3]>) {
50+
let f = || {
51+
let [y, z @ ..] = *x;
52+
};
53+
&x;
54+
//~^ ERROR borrow of moved value
55+
}
56+
57+
fn slice_by_ref(x: &mut [String]) {
58+
let f = || {
59+
if let [ref y, ref z @ ..] = *x {}
60+
};
61+
let r = &mut *x;
62+
//~^ ERROR cannot borrow
63+
f();
64+
}
65+
66+
fn slice_by_uniq(x: &mut [String]) {
67+
let mut f = || {
68+
if let [ref mut y, ref mut z @ ..] = *x {}
69+
};
70+
let r = &x;
71+
//~^ ERROR cannot borrow
72+
f();
73+
}
74+
75+
fn main() {
76+
arr_by_ref(Default::default());
77+
arr_by_mut(Default::default());
78+
arr_by_move(Default::default());
79+
arr_ref_by_ref(&mut Default::default());
80+
arr_ref_by_uniq(&mut Default::default());
81+
arr_box_by_move(Default::default());
82+
slice_by_ref(&mut <[_; 3]>::default());
83+
slice_by_uniq(&mut <[_; 3]>::default());
84+
}

0 commit comments

Comments
 (0)