aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-03-06 10:03:54 +0000
committerGitHub <[email protected]>2020-03-06 10:03:54 +0000
commit670895a49c271751bf275f0ca1303a1bca7aad5a (patch)
tree58964cef2042a7e0088c81339770a2c8005023a7 /crates
parentdd7a11eec7cfc4703214c6278d4023cc372faa90 (diff)
parent0563cc8291227e9d84c8d931ceb2b3768512b770 (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')
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs4
-rw-r--r--crates/ra_mbe/src/tests.rs54
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]
1597fn 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]
1597fn test_expand_bad_literal() { 1651fn test_expand_bad_literal() {
1598 parse_macro( 1652 parse_macro(
1599 r#" 1653 r#"