-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
regression-from-stable-to-betaPerformance or correctness regression from stable to beta.Performance or correctness regression from stable to beta.
Description
Possible regression in nightly from stable 1.4 with respect to the use of macro hygiene to recursively construct patterns and expressions.
Code:
// zip!(a1,a2,a3,a4) is equivalent to:
// a1.zip(a2).zip(a3).zip(a4).map(|(((x1,x2),x3),x4)| (x1,x2,x3,x4))
macro_rules! zip {
// Entry point
([$a:expr, $b:expr, $($rest:expr),*]) => {
zip!([$($rest),*], $a.zip($b), (x,y), [x,y])
};
// Intermediate steps to build the zipped expression, the match pattern, and
// and the output tuple of the closure, using macro hygene to repeatedly
// introduce new variables named 'x'.
([$a:expr, $($rest:expr),*], $zip:expr, $pat:pat, [$($flat:expr),*]) => {
zip!([$($rest),*], $zip.zip($a), ($pat,x), [$($flat),*, x])
};
// Final step
([], $zip:expr, $pat:pat, [$($flat:expr),+]) => {
$zip.map(|$pat| ($($flat),+))
};
// Comma
([$a:expr], $zip:expr, $pat:pat, [$($flat:expr),*]) => {
zip!([$a,], $zip, $pat, [$($flat),*])
};
}
fn main() {
let p1 = vec![1i32, 2].into_iter();
let p2 = vec!["10", "20"].into_iter();
let p3 = vec![100u16, 200].into_iter();
let p4 = vec![1000i64, 2000].into_iter();
let e = zip!([p1,p2,p3,p4]).collect::<Vec<_>>();
assert_eq!(e[0], (1i32,"10",100u16,1000i64));
}
On stable:
Successful build and run
On nightly:
<anon>:14:42: 14:43 error: mismatched types:
expected `i32`,
found `u16`
(expected i32,
found u16) [E0308]
<anon>:14 zip!([$($rest),*], $zip.zip($a), ($pat,x), [$($flat),*, x])
^
<anon>:14:3: 14:62 note: in this expansion of zip! (defined in <anon>)
<anon>:24:3: 24:40 note: in this expansion of zip! (defined in <anon>)
<anon>:14:3: 14:62 note: in this expansion of zip! (defined in <anon>)
<anon>:7:3: 7:47 note: in this expansion of zip! (defined in <anon>)
<anon>:34:10: 34:29 note: in this expansion of zip! (defined in <anon>)
<anon>:14:42: 14:43 help: see the detailed explanation for E0308
<anon>:14:42: 14:43 error: mismatched types:
expected `i64`,
found `i32`
(expected i64,
found i32) [E0308]
<anon>:14 zip!([$($rest),*], $zip.zip($a), ($pat,x), [$($flat),*, x])
^
<anon>:14:3: 14:62 note: in this expansion of zip! (defined in <anon>)
<anon>:24:3: 24:40 note: in this expansion of zip! (defined in <anon>)
<anon>:14:3: 14:62 note: in this expansion of zip! (defined in <anon>)
<anon>:7:3: 7:47 note: in this expansion of zip! (defined in <anon>)
<anon>:34:10: 34:29 note: in this expansion of zip! (defined in <anon>)
<anon>:14:42: 14:43 help: see the detailed explanation for E0308
<std macros>:5:22: 5:33 error: mismatched types:
expected `(i32, &str, u16, i32)`,
found `(i32, &str, u16, i64)`
(expected i32,
found i64) [E0308]
<std macros>:5 if ! ( * left_val == * right_val ) {
^~~~~~~~~~~
<anon>:35:2: 35:47 note: in this expansion of assert_eq! (defined in <std macros>)
<std macros>:5:22: 5:33 help: see the detailed explanation for E0308
error: aborting due to 3 previous errors
playpen: application terminated with error code 101
Note: When all vecs in the example are the same type, the error does not occur.
A simpler (but far more contrived) example can be found here: http://is.gd/EHUV1z
A git bisect identified this commit in PR#28642.
Metadata
Metadata
Assignees
Labels
regression-from-stable-to-betaPerformance or correctness regression from stable to beta.Performance or correctness regression from stable to beta.