1
Fork 0

Rollup merge of #61046 - mark-i-m:transcribe-fix, r=petrochenkov

Fix ICE with inconsistent macro matchers

Fixes #61033

r? @petrochenkov
This commit is contained in:
Mazdak Farrokhzad 2019-05-23 08:37:15 +02:00 committed by GitHub
commit 1ea0b1d274
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 8 deletions

View file

@ -170,9 +170,11 @@ pub fn transcribe(
} }
LockstepIterSize::Contradiction(ref msg) => { LockstepIterSize::Contradiction(ref msg) => {
// This should never happen because the macro parser should generate // FIXME: this really ought to be caught at macro definition time... It
// properly-sized matches for all meta-vars. // happens when two meta-variables are used in the same repetition in a
cx.span_bug(seq.span(), &msg[..]); // sequence, but they come from different sequence matchers and repeat
// different amounts.
cx.span_fatal(seq.span(), &msg[..]);
} }
LockstepIterSize::Constraint(len, _) => { LockstepIterSize::Constraint(len, _) => {
@ -187,9 +189,10 @@ pub fn transcribe(
// Is the repetition empty? // Is the repetition empty?
if len == 0 { if len == 0 {
if seq.op == quoted::KleeneOp::OneOrMore { if seq.op == quoted::KleeneOp::OneOrMore {
// This should be impossible because the macro parser would not // FIXME: this really ought to be caught at macro definition
// match the given macro arm. // time... It happens when the Kleene operator in the matcher and
cx.span_bug(sp.entire(), "this must repeat at least once"); // the body for the same meta-variable do not match.
cx.span_fatal(sp.entire(), "this must repeat at least once");
} }
} else { } else {
// 0 is the initial counter (we have done 0 repretitions so far). `len` // 0 is the initial counter (we have done 0 repretitions so far). `len`
@ -327,8 +330,7 @@ impl LockstepIterSize {
LockstepIterSize::Constraint(r_len, _) if l_len == r_len => self, LockstepIterSize::Constraint(r_len, _) if l_len == r_len => self,
LockstepIterSize::Constraint(r_len, r_id) => { LockstepIterSize::Constraint(r_len, r_id) => {
let msg = format!( let msg = format!(
"inconsistent lockstep iteration: \ "meta-variable `{}` repeats {} times, but `{}` repeats {} times",
'{}' has {} items, but '{}' has {}",
l_id, l_len, r_id, r_len l_id, l_len, r_id, r_len
); );
LockstepIterSize::Contradiction(msg) LockstepIterSize::Contradiction(msg)

View file

@ -0,0 +1,9 @@
// Regression test for issue #61033.
macro_rules! test1 {
($x:ident, $($tt:tt)*) => { $($tt)+ } //~ERROR this must repeat at least once
}
fn main() {
test1!(x,);
}

View file

@ -0,0 +1,8 @@
error: this must repeat at least once
--> $DIR/issue-61033-1.rs:4:34
|
LL | ($x:ident, $($tt:tt)*) => { $($tt)+ }
| ^^^^^
error: aborting due to previous error

View file

@ -0,0 +1,19 @@
// Regression test for issue #61033.
macro_rules! test2 {
(
$(* $id1:ident)*
$(+ $id2:ident)*
) => {
$( //~ERROR meta-variable `id1` repeats 2 times
$id1 + $id2 // $id1 and $id2 may repeat different numbers of times
)*
}
}
fn main() {
test2! {
* a * b
+ a + b + c
}
}

View file

@ -0,0 +1,11 @@
error: meta-variable `id1` repeats 2 times, but `id2` repeats 3 times
--> $DIR/issue-61033-2.rs:8:10
|
LL | $(
| __________^
LL | | $id1 + $id2 // $id1 and $id2 may repeat different numbers of times
LL | | )*
| |_________^
error: aborting due to previous error