@@ -10,6 +10,7 @@ use std::collections::VecDeque;
10
10
use std:: fmt:: { self , Display , Write } ;
11
11
use std:: iter;
12
12
13
+ use arrayvec:: ArrayVec ;
13
14
use rustc_data_structures:: fx:: FxIndexMap ;
14
15
use rustc_lexer:: { Cursor , FrontmatterAllowed , LiteralKind , TokenKind } ;
15
16
use rustc_span:: edition:: Edition ;
@@ -818,7 +819,7 @@ impl<'src> Classifier<'src> {
818
819
}
819
820
820
821
/// Concatenate colons and idents as one when possible.
821
- fn get_full_ident_path ( & mut self ) -> Vec < ( TokenKind , usize , usize ) > {
822
+ fn get_full_ident_path ( & mut self ) -> ArrayVec < ( TokenKind , usize , usize ) , 2 > {
822
823
let start = self . byte_pos as usize ;
823
824
let mut pos = start;
824
825
let mut has_ident = false ;
@@ -832,13 +833,16 @@ impl<'src> Classifier<'src> {
832
833
// Ident path can start with "::" but if we already have content in the ident path,
833
834
// the "::" is mandatory.
834
835
if has_ident && nb == 0 {
835
- return vec ! [ ( TokenKind :: Ident , start, pos) ] ;
836
+ return ArrayVec :: from_iter ( [ ( TokenKind :: Ident , start, pos) ] ) ;
836
837
} else if nb != 0 && nb != 2 {
837
- if has_ident {
838
- return vec ! [ ( TokenKind :: Ident , start, pos) , ( TokenKind :: Colon , pos, pos + nb) ] ;
838
+ return if has_ident {
839
+ ArrayVec :: from_iter ( [
840
+ ( TokenKind :: Ident , start, pos) ,
841
+ ( TokenKind :: Colon , pos, pos + nb) ,
842
+ ] )
839
843
} else {
840
- return vec ! [ ( TokenKind :: Colon , start, pos + nb) ] ;
841
- }
844
+ ArrayVec :: from_iter ( [ ( TokenKind :: Colon , start, pos + nb) ] )
845
+ } ;
842
846
}
843
847
844
848
if let Some ( ( None , text) ) = self . tokens . peek ( ) . map ( |( token, text) | {
@@ -854,15 +858,21 @@ impl<'src> Classifier<'src> {
854
858
pos += text. len ( ) + nb;
855
859
has_ident = true ;
856
860
self . tokens . next ( ) ;
857
- } else if nb > 0 && has_ident {
858
- return vec ! [ ( TokenKind :: Ident , start, pos) , ( TokenKind :: Colon , pos, pos + nb) ] ;
861
+ continue ;
862
+ }
863
+
864
+ return if nb > 0 && has_ident {
865
+ ArrayVec :: from_iter ( [
866
+ ( TokenKind :: Ident , start, pos) ,
867
+ ( TokenKind :: Colon , pos, pos + nb) ,
868
+ ] )
859
869
} else if nb > 0 {
860
- return vec ! [ ( TokenKind :: Colon , start, start + nb) ] ;
870
+ ArrayVec :: from_iter ( [ ( TokenKind :: Colon , start, start + nb) ] )
861
871
} else if has_ident {
862
- return vec ! [ ( TokenKind :: Ident , start, pos) ] ;
872
+ ArrayVec :: from_iter ( [ ( TokenKind :: Ident , start, pos) ] )
863
873
} else {
864
- return Vec :: new ( ) ;
865
- }
874
+ ArrayVec :: new ( )
875
+ } ;
866
876
}
867
877
}
868
878
@@ -885,7 +895,7 @@ impl<'src> Classifier<'src> {
885
895
/// The general structure for this method is to iterate over each token,
886
896
/// possibly giving it an HTML span with a class specifying what flavor of
887
897
/// token is used.
888
- fn highlight ( mut self , sink : & mut dyn FnMut ( Span , Highlight < ' src > ) ) {
898
+ fn highlight ( mut self , mut sink : impl FnMut ( Span , Highlight < ' src > ) ) {
889
899
loop {
890
900
if let Some ( decs) = self . decorations . as_mut ( ) {
891
901
let byte_pos = self . byte_pos ;
@@ -903,21 +913,20 @@ impl<'src> Classifier<'src> {
903
913
if self
904
914
. tokens
905
915
. peek ( )
906
- . map ( |t| matches ! ( t. 0 , TokenKind :: Colon | TokenKind :: Ident ) )
907
- . unwrap_or ( false )
916
+ . is_some_and ( |( kind, _) | matches ! ( kind, TokenKind :: Colon | TokenKind :: Ident ) )
908
917
{
909
918
let tokens = self . get_full_ident_path ( ) ;
910
919
for ( token, start, end) in & tokens {
911
920
let text = & self . src [ * start..* end] ;
912
- self . advance ( * token, text, sink, * start as u32 ) ;
921
+ self . advance ( * token, text, & mut sink, * start as u32 ) ;
913
922
self . byte_pos += text. len ( ) as u32 ;
914
923
}
915
924
if !tokens. is_empty ( ) {
916
925
continue ;
917
926
}
918
927
}
919
928
if let Some ( ( token, text, before) ) = self . next ( ) {
920
- self . advance ( token, text, sink, before) ;
929
+ self . advance ( token, text, & mut sink, before) ;
921
930
} else {
922
931
break ;
923
932
}
@@ -934,26 +943,28 @@ impl<'src> Classifier<'src> {
934
943
& mut self ,
935
944
token : TokenKind ,
936
945
text : & ' src str ,
937
- sink : & mut dyn FnMut ( Span , Highlight < ' src > ) ,
946
+ mut sink : impl FnMut ( Span , Highlight < ' src > ) ,
938
947
before : u32 ,
939
948
) {
940
949
let lookahead = self . peek ( ) ;
941
950
let file_span = self . file_span ;
942
- let no_highlight = |sink : & mut dyn FnMut ( _, _) | {
943
- sink ( new_span ( before, text, file_span) , Highlight :: Token { text, class : None } )
944
- } ;
945
- let whitespace = |sink : & mut dyn FnMut ( _, _) | {
951
+ let no_highlight =
952
+ || ( new_span ( before, text, file_span) , Highlight :: Token { text, class : None } ) ;
953
+ let mut whitespace = |class| {
946
954
let mut start = 0u32 ;
947
955
for part in text. split ( '\n' ) . intersperse ( "\n " ) . filter ( |s| !s. is_empty ( ) ) {
948
956
sink (
949
957
new_span ( before + start, part, file_span) ,
950
- Highlight :: Token { text : part, class : None } ,
958
+ Highlight :: Token { text : part, class } ,
951
959
) ;
952
960
start += part. len ( ) as u32 ;
953
961
}
954
962
} ;
955
963
let class = match token {
956
- TokenKind :: Whitespace => return whitespace ( sink) ,
964
+ TokenKind :: Whitespace => {
965
+ whitespace ( None ) ;
966
+ return ;
967
+ }
957
968
TokenKind :: LineComment { doc_style } | TokenKind :: BlockComment { doc_style, .. } => {
958
969
if doc_style. is_some ( ) {
959
970
Class :: DocComment
@@ -974,7 +985,10 @@ impl<'src> Classifier<'src> {
974
985
// or a reference or pointer type. Unless, of course, it looks like
975
986
// a logical and or a multiplication operator: `&&` or `* `.
976
987
TokenKind :: Star => match self . tokens . peek ( ) {
977
- Some ( ( TokenKind :: Whitespace , _) ) => return whitespace ( sink) ,
988
+ Some ( ( TokenKind :: Whitespace , _) ) => {
989
+ whitespace ( None ) ;
990
+ return ;
991
+ }
978
992
Some ( ( TokenKind :: Ident , "mut" ) ) => {
979
993
self . next ( ) ;
980
994
sink (
@@ -1004,7 +1018,10 @@ impl<'src> Classifier<'src> {
1004
1018
sink ( DUMMY_SP , Highlight :: Token { text : "&=" , class : None } ) ;
1005
1019
return ;
1006
1020
}
1007
- Some ( ( TokenKind :: Whitespace , _) ) => return whitespace ( sink) ,
1021
+ Some ( ( TokenKind :: Whitespace , _) ) => {
1022
+ whitespace ( None ) ;
1023
+ return ;
1024
+ }
1008
1025
Some ( ( TokenKind :: Ident , "mut" ) ) => {
1009
1026
self . next ( ) ;
1010
1027
sink (
@@ -1028,7 +1045,11 @@ impl<'src> Classifier<'src> {
1028
1045
sink ( DUMMY_SP , Highlight :: Token { text : "=>" , class : None } ) ;
1029
1046
return ;
1030
1047
}
1031
- _ => return no_highlight ( sink) ,
1048
+ _ => {
1049
+ let ( span, highlight) = no_highlight ( ) ;
1050
+ sink ( span, highlight) ;
1051
+ return ;
1052
+ }
1032
1053
} ,
1033
1054
TokenKind :: Minus if lookahead == Some ( TokenKind :: Gt ) => {
1034
1055
self . next ( ) ;
@@ -1045,7 +1066,11 @@ impl<'src> Classifier<'src> {
1045
1066
| TokenKind :: Percent
1046
1067
| TokenKind :: Bang
1047
1068
| TokenKind :: Lt
1048
- | TokenKind :: Gt => return no_highlight ( sink) ,
1069
+ | TokenKind :: Gt => {
1070
+ let ( span, highlight) = no_highlight ( ) ;
1071
+ sink ( span, highlight) ;
1072
+ return ;
1073
+ }
1049
1074
1050
1075
// Miscellaneous, no highlighting.
1051
1076
TokenKind :: Dot
@@ -1060,7 +1085,11 @@ impl<'src> Classifier<'src> {
1060
1085
| TokenKind :: Tilde
1061
1086
| TokenKind :: Colon
1062
1087
| TokenKind :: Frontmatter { .. }
1063
- | TokenKind :: Unknown => return no_highlight ( sink) ,
1088
+ | TokenKind :: Unknown => {
1089
+ let ( span, highlight) = no_highlight ( ) ;
1090
+ sink ( span, highlight) ;
1091
+ return ;
1092
+ }
1064
1093
1065
1094
TokenKind :: Question => Class :: QuestionMark ,
1066
1095
@@ -1069,7 +1098,11 @@ impl<'src> Classifier<'src> {
1069
1098
self . in_macro_nonterminal = true ;
1070
1099
Class :: MacroNonTerminal
1071
1100
}
1072
- _ => return no_highlight ( sink) ,
1101
+ _ => {
1102
+ let ( span, highlight) = no_highlight ( ) ;
1103
+ sink ( span, highlight) ;
1104
+ return ;
1105
+ }
1073
1106
} ,
1074
1107
1075
1108
// This might be the start of an attribute. We're going to want to
@@ -1100,9 +1133,11 @@ impl<'src> Classifier<'src> {
1100
1133
Highlight :: EnterSpan { class : Class :: Attribute } ,
1101
1134
) ;
1102
1135
}
1103
- _ => ( ) ,
1136
+ _ => { }
1104
1137
}
1105
- return no_highlight ( sink) ;
1138
+ let ( span, highlight) = no_highlight ( ) ;
1139
+ sink ( span, highlight) ;
1140
+ return ;
1106
1141
}
1107
1142
TokenKind :: CloseBracket => {
1108
1143
if self . in_attribute {
@@ -1114,7 +1149,9 @@ impl<'src> Classifier<'src> {
1114
1149
sink ( DUMMY_SP , Highlight :: ExitSpan ) ;
1115
1150
return ;
1116
1151
}
1117
- return no_highlight ( sink) ;
1152
+ let ( span, highlight) = no_highlight ( ) ;
1153
+ sink ( span, highlight) ;
1154
+ return ;
1118
1155
}
1119
1156
TokenKind :: Literal { kind, .. } => match kind {
1120
1157
// Text literals.
@@ -1129,7 +1166,11 @@ impl<'src> Classifier<'src> {
1129
1166
// Number literals.
1130
1167
LiteralKind :: Float { .. } | LiteralKind :: Int { .. } => Class :: Number ,
1131
1168
} ,
1132
- TokenKind :: GuardedStrPrefix => return no_highlight ( sink) ,
1169
+ TokenKind :: GuardedStrPrefix => {
1170
+ let ( span, highlight) = no_highlight ( ) ;
1171
+ sink ( span, highlight) ;
1172
+ return ;
1173
+ }
1133
1174
TokenKind :: Ident | TokenKind :: RawIdent if lookahead == Some ( TokenKind :: Bang ) => {
1134
1175
self . in_macro = true ;
1135
1176
let span = new_span ( before, text, file_span) ;
@@ -1165,14 +1206,7 @@ impl<'src> Classifier<'src> {
1165
1206
} ;
1166
1207
// Anything that didn't return above is the simple case where we the
1167
1208
// class just spans a single token, so we can use the `string` method.
1168
- let mut start = 0u32 ;
1169
- for part in text. split ( '\n' ) . intersperse ( "\n " ) . filter ( |s| !s. is_empty ( ) ) {
1170
- sink (
1171
- new_span ( before + start, part, file_span) ,
1172
- Highlight :: Token { text : part, class : Some ( class) } ,
1173
- ) ;
1174
- start += part. len ( ) as u32 ;
1175
- }
1209
+ whitespace ( Some ( class) ) ;
1176
1210
}
1177
1211
1178
1212
fn peek ( & mut self ) -> Option < TokenKind > {
0 commit comments