@@ -148,6 +148,7 @@ pub fn token_tree_to_syntax_node<Ctx>(
148148) -> ( Parse < SyntaxNode > , SpanMap < Ctx > )
149149where
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> {
892893impl < Ctx > TtTreeSink < ' _ , Ctx >
893894where
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