diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-03-06 10:03:54 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-03-06 10:03:54 +0000 |
commit | 670895a49c271751bf275f0ca1303a1bca7aad5a (patch) | |
tree | 58964cef2042a7e0088c81339770a2c8005023a7 /crates/ra_mbe/src | |
parent | dd7a11eec7cfc4703214c6278d4023cc372faa90 (diff) | |
parent | 0563cc8291227e9d84c8d931ceb2b3768512b770 (diff) |
Merge #3482
3482: Fix regression from #3451 r=matklad a=edwin0cheng
There is a regression from #3451 such that the following code has failed to parse in raw item collecting phase:
```rust
macro_rules! with_std {
($($i:item)*) => ($(#[cfg(feature = "std")]$i)*)
}
with_std! {
mod macros;
mod others;
}
```
### Rationale
We always assume the last token of an statement will not end with a whitespace, which is true. It is because in parsing phase, we always emit `SyntaxNode` before any whitespace. Such that in various parts of RA code, we solely check the semi-colon by using `SyntaxNode::last_child_token() == ";"` .
However, in #3451, we insert some whitespaces between puncts such that we broke above assumption. This PR fixed this bug by make sure we don't add any whitespace if it is a semicolon.
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_mbe/src')
-rw-r--r-- | crates/ra_mbe/src/syntax_bridge.rs | 4 | ||||
-rw-r--r-- | crates/ra_mbe/src/tests.rs | 54 |
2 files changed, 57 insertions, 1 deletions
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index d8ee74faa..fb9fa5314 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -448,7 +448,9 @@ impl<'a> TreeSink for TtTreeSink<'a> { | |||
448 | Some(tt::TokenTree::Leaf(tt::Leaf::Punct(_))), | 448 | Some(tt::TokenTree::Leaf(tt::Leaf::Punct(_))), |
449 | ) = (last.token_tree(), next.token_tree()) | 449 | ) = (last.token_tree(), next.token_tree()) |
450 | { | 450 | { |
451 | if curr.spacing == tt::Spacing::Alone { | 451 | // Note: We always assume the semi-colon would be the last token in |
452 | // other parts of RA such that we don't add whitespace here. | ||
453 | if curr.spacing == tt::Spacing::Alone && curr.char != ';' { | ||
452 | self.inner.token(WHITESPACE, " ".into()); | 454 | self.inner.token(WHITESPACE, " ".into()); |
453 | self.text_pos += TextUnit::of_char(' '); | 455 | self.text_pos += TextUnit::of_char(' '); |
454 | } | 456 | } |
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs index 304867881..066ce150b 100644 --- a/crates/ra_mbe/src/tests.rs +++ b/crates/ra_mbe/src/tests.rs | |||
@@ -1594,6 +1594,60 @@ fn test_repeat_bad_var() { | |||
1594 | } | 1594 | } |
1595 | 1595 | ||
1596 | #[test] | 1596 | #[test] |
1597 | fn test_no_space_after_semi_colon() { | ||
1598 | let expanded = parse_macro( | ||
1599 | r#" | ||
1600 | macro_rules! with_std { ($($i:item)*) => ($(#[cfg(feature = "std")]$i)*) } | ||
1601 | "#, | ||
1602 | ) | ||
1603 | .expand_items(r#"with_std! {mod m;mod f;}"#); | ||
1604 | |||
1605 | let dump = format!("{:#?}", expanded); | ||
1606 | assert_eq_text!( | ||
1607 | dump.trim(), | ||
1608 | r###"MACRO_ITEMS@[0; 52) | ||
1609 | MODULE@[0; 26) | ||
1610 | ATTR@[0; 21) | ||
1611 | POUND@[0; 1) "#" | ||
1612 | L_BRACK@[1; 2) "[" | ||
1613 | PATH@[2; 5) | ||
1614 | PATH_SEGMENT@[2; 5) | ||
1615 | NAME_REF@[2; 5) | ||
1616 | IDENT@[2; 5) "cfg" | ||
1617 | TOKEN_TREE@[5; 20) | ||
1618 | L_PAREN@[5; 6) "(" | ||
1619 | IDENT@[6; 13) "feature" | ||
1620 | EQ@[13; 14) "=" | ||
1621 | STRING@[14; 19) "\"std\"" | ||
1622 | R_PAREN@[19; 20) ")" | ||
1623 | R_BRACK@[20; 21) "]" | ||
1624 | MOD_KW@[21; 24) "mod" | ||
1625 | NAME@[24; 25) | ||
1626 | IDENT@[24; 25) "m" | ||
1627 | SEMI@[25; 26) ";" | ||
1628 | MODULE@[26; 52) | ||
1629 | ATTR@[26; 47) | ||
1630 | POUND@[26; 27) "#" | ||
1631 | L_BRACK@[27; 28) "[" | ||
1632 | PATH@[28; 31) | ||
1633 | PATH_SEGMENT@[28; 31) | ||
1634 | NAME_REF@[28; 31) | ||
1635 | IDENT@[28; 31) "cfg" | ||
1636 | TOKEN_TREE@[31; 46) | ||
1637 | L_PAREN@[31; 32) "(" | ||
1638 | IDENT@[32; 39) "feature" | ||
1639 | EQ@[39; 40) "=" | ||
1640 | STRING@[40; 45) "\"std\"" | ||
1641 | R_PAREN@[45; 46) ")" | ||
1642 | R_BRACK@[46; 47) "]" | ||
1643 | MOD_KW@[47; 50) "mod" | ||
1644 | NAME@[50; 51) | ||
1645 | IDENT@[50; 51) "f" | ||
1646 | SEMI@[51; 52) ";""###, | ||
1647 | ); | ||
1648 | } | ||
1649 | |||
1650 | #[test] | ||
1597 | fn test_expand_bad_literal() { | 1651 | fn test_expand_bad_literal() { |
1598 | parse_macro( | 1652 | parse_macro( |
1599 | r#" | 1653 | r#" |