Skip to content

Commit 9798cf8

Browse files
When glueing together tokens from macros, merge their spans
1 parent 546339a commit 9798cf8

File tree

2 files changed

+31
-3
lines changed
  • crates
    • hir-def/src/macro_expansion_tests
    • syntax-bridge/src

2 files changed

+31
-3
lines changed

crates/hir-def/src/macro_expansion_tests/mbe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ macro_rules! f {
3636
}
3737
3838
struct#0:[email protected]#1# MyTraitMap2#0:[email protected]#0# {#0:[email protected]#1#
39-
map#0:[email protected]#1#:#0:[email protected]#1# #0:[email protected]#1#::#0:1@91..92#1#std#0:[email protected]#1#::#0:1@96..97#1#collections#0:[email protected]#1#::#0:1@109..110#1#HashSet#0:[email protected]#1#<#0:[email protected]#1#(#0:[email protected]#1#)#0:[email protected]#1#>#0:[email protected]#1#,#0:[email protected]#1#
39+
map#0:[email protected]#1#:#0:[email protected]#1# #0:[email protected]#1#::#0:1@91..93#1#std#0:[email protected]#1#::#0:1@96..98#1#collections#0:[email protected]#1#::#0:1@109..111#1#HashSet#0:[email protected]#1#<#0:[email protected]#1#(#0:[email protected]#1#)#0:[email protected]#1#>#0:[email protected]#1#,#0:[email protected]#1#
4040
4141
"#]],
4242
);

crates/syntax-bridge/src/lib.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ pub fn token_tree_to_syntax_node<Ctx>(
148148
) -> (Parse<SyntaxNode>, SpanMap<Ctx>)
149149
where
150150
SpanData<Ctx>: Copy + fmt::Debug,
151+
Ctx: PartialEq,
151152
{
152153
let buffer = match tt {
153154
tt::Subtree {
@@ -892,6 +893,7 @@ fn delim_to_str(d: tt::DelimiterKind, closing: bool) -> Option<&'static str> {
892893
impl<Ctx> TtTreeSink<'_, Ctx>
893894
where
894895
SpanData<Ctx>: Copy + fmt::Debug,
896+
Ctx: PartialEq,
895897
{
896898
/// Parses a float literal as if it was a one to two name ref nodes with a dot inbetween.
897899
/// This occurs when a float literal is used as a field access.
@@ -949,6 +951,7 @@ where
949951
}
950952

951953
let mut last = self.cursor;
954+
let mut combined_span = None;
952955
'tokens: for _ in 0..n_tokens {
953956
let tmp: u8;
954957
if self.cursor.eof() {
@@ -982,7 +985,10 @@ where
982985
format_to!(self.buf, "{lit}");
983986
debug_assert_ne!(self.buf.len() - buf_l, 0);
984987
self.text_pos += TextSize::new((self.buf.len() - buf_l) as u32);
985-
self.token_map.push(self.text_pos, lit.span);
988+
combined_span = match combined_span {
989+
None => Some(lit.span),
990+
Some(prev_span) => Some(Self::merge_spans(prev_span, lit.span)),
991+
};
986992
self.cursor = self.cursor.bump();
987993
continue 'tokens;
988994
}
@@ -1006,9 +1012,13 @@ where
10061012
};
10071013
self.buf += text;
10081014
self.text_pos += TextSize::of(text);
1009-
self.token_map.push(self.text_pos, span);
1015+
combined_span = match combined_span {
1016+
None => Some(span),
1017+
Some(prev_span) => Some(Self::merge_spans(prev_span, span)),
1018+
}
10101019
}
10111020

1021+
self.token_map.push(self.text_pos, combined_span.expect("expected at least one token"));
10121022
self.inner.token(kind, self.buf.as_str());
10131023
self.buf.clear();
10141024
// FIXME: Emitting whitespace for this is really just a hack, we should get rid of it.
@@ -1043,4 +1053,22 @@ where
10431053
fn error(&mut self, error: String) {
10441054
self.inner.error(error, self.text_pos)
10451055
}
1056+
1057+
fn merge_spans(a: SpanData<Ctx>, b: SpanData<Ctx>) -> SpanData<Ctx> {
1058+
// We don't do what rustc does exactly, rustc does something clever when the spans have different syntax contexts
1059+
// but this runs afoul of our separation between `span` and `hir-expand`.
1060+
SpanData {
1061+
range: if a.ctx == b.ctx {
1062+
TextRange::new(
1063+
std::cmp::min(a.range.start(), b.range.start()),
1064+
std::cmp::max(a.range.end(), b.range.end()),
1065+
)
1066+
} else {
1067+
// Combining ranges make no sense when they come from different syntax contexts.
1068+
a.range
1069+
},
1070+
anchor: a.anchor,
1071+
ctx: a.ctx,
1072+
}
1073+
}
10461074
}

0 commit comments

Comments
 (0)