@@ -764,7 +764,8 @@ fn get_real_ident_class(text: &str, allow_path_keywords: bool) -> Option<Class>
764764 Some ( match text {
765765 "ref" | "mut" => Class :: RefKeyWord ,
766766 "false" | "true" => Class :: Bool ,
767- _ if Symbol :: intern ( text) . is_reserved ( || Edition :: Edition2021 ) => Class :: KeyWord ,
767+ // FIXME(#148221): Don't hard-code the edition. The classifier should take it as an argument.
768+ _ if Symbol :: intern ( text) . is_reserved ( || Edition :: Edition2024 ) => Class :: KeyWord ,
768769 _ => return None ,
769770 } )
770771}
@@ -1201,34 +1202,30 @@ impl<'src> Classifier<'src> {
12011202 } ,
12021203 TokenKind :: GuardedStrPrefix => return no_highlight ( sink) ,
12031204 TokenKind :: Ident | TokenKind :: RawIdent
1204- if self . peek_non_whitespace ( ) == Some ( TokenKind :: Bang ) =>
1205+ if let Some ( ( TokenKind :: Bang , _ ) ) = self . peek_non_trivia ( ) =>
12051206 {
12061207 self . in_macro = true ;
12071208 let span = new_span ( before, text, file_span) ;
12081209 sink ( DUMMY_SP , Highlight :: EnterSpan { class : Class :: Macro ( span) } ) ;
12091210 sink ( span, Highlight :: Token { text, class : None } ) ;
12101211 return ;
12111212 }
1212- TokenKind :: Ident => {
1213- match get_real_ident_class ( text, false ) {
1214- None => match text {
1215- "Option" | "Result" => Class :: PreludeTy ( new_span ( before, text, file_span) ) ,
1216- "Some" | "None" | "Ok" | "Err" => {
1217- Class :: PreludeVal ( new_span ( before, text, file_span) )
1218- }
1219- // "union" is a weak keyword and is only considered as a keyword when declaring
1220- // a union type.
1221- "union" if self . check_if_is_union_keyword ( ) => Class :: KeyWord ,
1222- _ if self . in_macro_nonterminal => {
1223- self . in_macro_nonterminal = false ;
1224- Class :: MacroNonTerminal
1225- }
1226- "self" | "Self" => Class :: Self_ ( new_span ( before, text, file_span) ) ,
1227- _ => Class :: Ident ( new_span ( before, text, file_span) ) ,
1228- } ,
1229- Some ( c) => c,
1230- }
1231- }
1213+ TokenKind :: Ident => match get_real_ident_class ( text, false ) {
1214+ None => match text {
1215+ "Option" | "Result" => Class :: PreludeTy ( new_span ( before, text, file_span) ) ,
1216+ "Some" | "None" | "Ok" | "Err" => {
1217+ Class :: PreludeVal ( new_span ( before, text, file_span) )
1218+ }
1219+ _ if self . is_weak_keyword ( text) => Class :: KeyWord ,
1220+ _ if self . in_macro_nonterminal => {
1221+ self . in_macro_nonterminal = false ;
1222+ Class :: MacroNonTerminal
1223+ }
1224+ "self" | "Self" => Class :: Self_ ( new_span ( before, text, file_span) ) ,
1225+ _ => Class :: Ident ( new_span ( before, text, file_span) ) ,
1226+ } ,
1227+ Some ( c) => c,
1228+ } ,
12321229 TokenKind :: RawIdent | TokenKind :: UnknownPrefix | TokenKind :: InvalidIdent => {
12331230 Class :: Ident ( new_span ( before, text, file_span) )
12341231 }
@@ -1249,25 +1246,40 @@ impl<'src> Classifier<'src> {
12491246 }
12501247 }
12511248
1249+ fn is_weak_keyword ( & mut self , text : & str ) -> bool {
1250+ // NOTE: `yeet` (`do yeet $expr`), `catch` (`do catch $block`), `default` (specialization),
1251+ // `contract_{ensures,requires}`, `builtin` (builtin_syntax) & `reuse` (fn_delegation) are
1252+ // too difficult or annoying to properly detect under this simple scheme.
1253+
1254+ let matches = match text {
1255+ "auto" => |text| text == "trait" , // `auto trait Trait {}` (`auto_traits`)
1256+ "pin" => |text| text == "const" || text == "mut" , // `&pin mut Type` (`pin_ergonomics`)
1257+ "raw" => |text| text == "const" || text == "mut" , // `&raw const local`
1258+ "safe" => |text| text == "fn" || text == "extern" , // `unsafe extern { safe fn f(); }`
1259+ "union" => |_| true , // `union Untagged { field: () }`
1260+ _ => return false ,
1261+ } ;
1262+ matches ! ( self . peek_non_trivia( ) , Some ( ( TokenKind :: Ident , text) ) if matches( text) )
1263+ }
1264+
12521265 fn peek ( & mut self ) -> Option < TokenKind > {
1253- self . tokens . peek ( ) . map ( |( token_kind , _text ) | * token_kind )
1266+ self . tokens . peek ( ) . map ( |& ( kind , _ ) | kind )
12541267 }
12551268
1256- fn peek_non_whitespace ( & mut self ) -> Option < TokenKind > {
1257- while let Some ( ( token_kind, _) ) = self . tokens . peek_next ( ) {
1258- if * token_kind != TokenKind :: Whitespace {
1259- let token_kind = * token_kind;
1260- self . tokens . stop_peeking ( ) ;
1261- return Some ( token_kind) ;
1269+ fn peek_non_trivia ( & mut self ) -> Option < ( TokenKind , & str ) > {
1270+ while let Some ( & token @ ( kind, _) ) = self . tokens . peek_next ( ) {
1271+ if let TokenKind :: Whitespace
1272+ | TokenKind :: LineComment { doc_style : None }
1273+ | TokenKind :: BlockComment { doc_style : None , .. } = kind
1274+ {
1275+ continue ;
12621276 }
1277+ self . tokens . stop_peeking ( ) ;
1278+ return Some ( token) ;
12631279 }
12641280 self . tokens . stop_peeking ( ) ;
12651281 None
12661282 }
1267-
1268- fn check_if_is_union_keyword ( & mut self ) -> bool {
1269- self . peek_non_whitespace ( ) . is_some_and ( |kind| kind == TokenKind :: Ident )
1270- }
12711283}
12721284
12731285fn generate_link_to_def (
0 commit comments