Skip to content

Commit 670895a

Browse files
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]>
2 parents dd7a11e + 0563cc8 commit 670895a

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

crates/ra_mbe/src/syntax_bridge.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,9 @@ impl<'a> TreeSink for TtTreeSink<'a> {
448448
Some(tt::TokenTree::Leaf(tt::Leaf::Punct(_))),
449449
) = (last.token_tree(), next.token_tree())
450450
{
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 != ';' {
452454
self.inner.token(WHITESPACE, " ".into());
453455
self.text_pos += TextUnit::of_char(' ');
454456
}

crates/ra_mbe/src/tests.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,60 @@ fn test_repeat_bad_var() {
15931593
.assert_expand_items("foo!(b0 b1);", "b0 b1");
15941594
}
15951595

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+
15961650
#[test]
15971651
fn test_expand_bad_literal() {
15981652
parse_macro(

0 commit comments

Comments
 (0)