@@ -148,6 +148,7 @@ pub fn token_tree_to_syntax_node<Ctx>(
148
148
) -> ( Parse < SyntaxNode > , SpanMap < Ctx > )
149
149
where
150
150
SpanData < Ctx > : Copy + fmt:: Debug ,
151
+ Ctx : PartialEq ,
151
152
{
152
153
let buffer = match tt {
153
154
tt:: Subtree {
@@ -892,6 +893,7 @@ fn delim_to_str(d: tt::DelimiterKind, closing: bool) -> Option<&'static str> {
892
893
impl < Ctx > TtTreeSink < ' _ , Ctx >
893
894
where
894
895
SpanData < Ctx > : Copy + fmt:: Debug ,
896
+ Ctx : PartialEq ,
895
897
{
896
898
/// Parses a float literal as if it was a one to two name ref nodes with a dot inbetween.
897
899
/// This occurs when a float literal is used as a field access.
@@ -949,6 +951,7 @@ where
949
951
}
950
952
951
953
let mut last = self . cursor ;
954
+ let mut combined_span = None ;
952
955
' tokens: for _ in 0 ..n_tokens {
953
956
let tmp: u8 ;
954
957
if self . cursor . eof ( ) {
@@ -982,7 +985,10 @@ where
982
985
format_to ! ( self . buf, "{lit}" ) ;
983
986
debug_assert_ne ! ( self . buf. len( ) - buf_l, 0 ) ;
984
987
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
+ } ;
986
992
self . cursor = self . cursor . bump ( ) ;
987
993
continue ' tokens;
988
994
}
@@ -1006,9 +1012,13 @@ where
1006
1012
} ;
1007
1013
self . buf += text;
1008
1014
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
+ }
1010
1019
}
1011
1020
1021
+ self . token_map . push ( self . text_pos , combined_span. expect ( "expected at least one token" ) ) ;
1012
1022
self . inner . token ( kind, self . buf . as_str ( ) ) ;
1013
1023
self . buf . clear ( ) ;
1014
1024
// FIXME: Emitting whitespace for this is really just a hack, we should get rid of it.
@@ -1043,4 +1053,22 @@ where
1043
1053
fn error ( & mut self , error : String ) {
1044
1054
self . inner . error ( error, self . text_pos )
1045
1055
}
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
+ }
1046
1074
}
0 commit comments