44use std:: mem;
55use std:: sync:: Arc ;
66
7- use rustc_ast:: { self as ast, Crate , NodeId , attr } ;
7+ use rustc_ast:: { self as ast, Crate , DUMMY_NODE_ID , NodeId } ;
88use rustc_ast_pretty:: pprust;
9+ use rustc_attr_parsing:: AttributeParser ;
910use rustc_errors:: { Applicability , DiagCtxtHandle , StashKey } ;
1011use rustc_expand:: base:: {
1112 Annotatable , DeriveResolution , Indeterminate , ResolverExpand , SyntaxExtension ,
@@ -15,12 +16,14 @@ use rustc_expand::compile_declarative_macro;
1516use rustc_expand:: expand:: {
1617 AstFragment , AstFragmentKind , Invocation , InvocationKind , SupportsMacroExpansion ,
1718} ;
18- use rustc_hir :: StabilityLevel ;
19- use rustc_hir:: attrs:: { CfgEntry , StrippedCfgItem } ;
19+ use rustc_feature :: Features ;
20+ use rustc_hir:: attrs:: { AttributeKind , CfgEntry , StrippedCfgItem } ;
2021use rustc_hir:: def:: { self , DefKind , MacroKinds , Namespace , NonMacroAttrKind } ;
2122use rustc_hir:: def_id:: { CrateNum , DefId , LocalDefId } ;
23+ use rustc_hir:: { Attribute , StabilityLevel } ;
2224use rustc_middle:: middle:: stability;
2325use rustc_middle:: ty:: { RegisteredTools , TyCtxt } ;
26+ use rustc_session:: Session ;
2427use rustc_session:: lint:: builtin:: {
2528 LEGACY_DERIVE_HELPERS , OUT_OF_SCOPE_MACRO_CALLS , UNKNOWN_DIAGNOSTIC_ATTRIBUTES ,
2629 UNUSED_MACRO_RULES , UNUSED_MACROS ,
@@ -122,35 +125,38 @@ fn fast_print_path(path: &ast::Path) -> Symbol {
122125
123126pub ( crate ) fn registered_tools ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> RegisteredTools {
124127 let ( _, pre_configured_attrs) = & * tcx. crate_for_resolver ( ( ) ) . borrow ( ) ;
125- registered_tools_ast ( tcx. dcx ( ) , pre_configured_attrs)
128+ registered_tools_ast ( tcx. dcx ( ) , pre_configured_attrs, tcx . sess , tcx . features ( ) )
126129}
127130
128131pub fn registered_tools_ast (
129132 dcx : DiagCtxtHandle < ' _ > ,
130133 pre_configured_attrs : & [ ast:: Attribute ] ,
134+ sess : & Session ,
135+ features : & Features ,
131136) -> RegisteredTools {
132137 let mut registered_tools = RegisteredTools :: default ( ) ;
133- for attr in attr :: filter_by_name ( pre_configured_attrs , sym :: register_tool ) {
134- for meta_item_inner in attr . meta_item_list ( ) . unwrap_or_default ( ) {
135- match meta_item_inner . ident ( ) {
136- Some ( ident ) => {
137- if let Some ( old_ident ) = registered_tools . replace ( ident ) {
138- dcx . emit_err ( errors :: ToolWasAlreadyRegistered {
139- span : ident . span ,
140- tool : ident ,
141- old_ident_span : old_ident . span ,
142- } ) ;
143- }
144- }
145- None => {
146- dcx. emit_err ( errors:: ToolOnlyAcceptsIdentifiers {
147- span : meta_item_inner . span ( ) ,
148- tool : sym :: register_tool ,
149- } ) ;
150- }
138+
139+ if let Some ( Attribute :: Parsed ( AttributeKind :: RegisterTool ( tools , _ ) ) ) =
140+ AttributeParser :: parse_limited (
141+ sess ,
142+ pre_configured_attrs ,
143+ sym :: register_tool ,
144+ DUMMY_SP ,
145+ DUMMY_NODE_ID ,
146+ Some ( features ) ,
147+ )
148+ {
149+ for tool in tools {
150+ if let Some ( old_tool ) = registered_tools . replace ( tool ) {
151+ dcx. emit_err ( errors:: ToolWasAlreadyRegistered {
152+ span : tool . span ,
153+ tool,
154+ old_ident_span : old_tool . span ,
155+ } ) ;
151156 }
152157 }
153158 }
159+
154160 // We implicitly add `rustfmt`, `clippy`, `diagnostic`, `miri` and `rust_analyzer` to known
155161 // tools, but it's not an error to register them explicitly.
156162 let predefined_tools =
0 commit comments