diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-07-26 18:56:52 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-26 18:56:52 +0200 |
| commit | c6c8693b4c2c6a63a86478112ff617a67e1f6bf6 (patch) | |
| tree | 52ad0fa8395e630d9b91c82ad1cb68bf3debb986 /src/libsyntax | |
| parent | 183aab3575ebd7c82ce1e982fa335b9a84388d12 (diff) | |
| parent | df4b23e7212b8f7a3f62f469f666021226e29c17 (diff) | |
| download | rust-c6c8693b4c2c6a63a86478112ff617a67e1f6bf6.tar.gz rust-c6c8693b4c2c6a63a86478112ff617a67e1f6bf6.zip | |
Rollup merge of #62956 - ia0:fix_62831, r=petrochenkov
Implement slow-path for FirstSets::first When 2 or more sequences share the same span, we can't use the precomputed map for their first set. So we compute it recursively. Fixes #62831.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 53 |
1 files changed, 26 insertions, 27 deletions
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 4503cea0f10..1731c0f713b 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -625,38 +625,37 @@ impl FirstSets { return first; } TokenTree::Sequence(sp, ref seq_rep) => { - match self.first.get(&sp.entire()) { - Some(&Some(ref subfirst)) => { - // If the sequence contents can be empty, then the first - // token could be the separator token itself. - - if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) { - first.add_one_maybe(TokenTree::Token(sep.clone())); - } - - assert!(first.maybe_empty); - first.add_all(subfirst); - if subfirst.maybe_empty - || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore - || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne - { - // continue scanning for more first - // tokens, but also make sure we - // restore empty-tracking state - first.maybe_empty = true; - continue; - } else { - return first; - } - } - + let subfirst_owned; + let subfirst = match self.first.get(&sp.entire()) { + Some(&Some(ref subfirst)) => subfirst, Some(&None) => { - panic!("assume all sequences have (unique) spans for now"); + subfirst_owned = self.first(&seq_rep.tts[..]); + &subfirst_owned } - None => { panic!("We missed a sequence during FirstSets construction"); } + }; + + // If the sequence contents can be empty, then the first + // token could be the separator token itself. + if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) { + first.add_one_maybe(TokenTree::Token(sep.clone())); + } + + assert!(first.maybe_empty); + first.add_all(subfirst); + if subfirst.maybe_empty + || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore + || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne + { + // Continue scanning for more first + // tokens, but also make sure we + // restore empty-tracking state. + first.maybe_empty = true; + continue; + } else { + return first; } } } |
