@@ -229,13 +229,10 @@ impl<'a> base::Resolver for Resolver<'a> {
229229 } ;
230230
231231 let parent_scope = self . invoc_parent_scope ( invoc_id, derives_in_scope) ;
232- let ( res , ext ) = self . resolve_macro_to_res ( path, kind, & parent_scope, true , force) ?;
232+ let ( ext , res ) = self . smart_resolve_macro_path ( path, kind, & parent_scope, true , force) ?;
233233
234234 let span = invoc. span ( ) ;
235- let descr = fast_print_path ( path) ;
236- invoc. expansion_data . mark . set_expn_info ( ext. expn_info ( span, descr) ) ;
237-
238- self . check_stability_and_deprecation ( & ext, descr, span) ;
235+ invoc. expansion_data . mark . set_expn_info ( ext. expn_info ( span, fast_print_path ( path) ) ) ;
239236
240237 if let Res :: Def ( _, def_id) = res {
241238 if after_derive {
@@ -275,47 +272,42 @@ impl<'a> Resolver<'a> {
275272 }
276273 }
277274
278- fn resolve_macro_to_res (
275+ /// Resolve macro path with error reporting and recovery.
276+ fn smart_resolve_macro_path (
279277 & mut self ,
280278 path : & ast:: Path ,
281279 kind : MacroKind ,
282280 parent_scope : & ParentScope < ' a > ,
283281 trace : bool ,
284282 force : bool ,
285- ) -> Result < ( Res , Lrc < SyntaxExtension > ) , Indeterminate > {
286- let res = self . resolve_macro_to_res_inner ( path, kind, parent_scope, trace, force) ;
283+ ) -> Result < ( Lrc < SyntaxExtension > , Res ) , Indeterminate > {
284+ let ( ext, res) = match self . resolve_macro_path ( path, kind, parent_scope, trace, force) {
285+ Ok ( ( Some ( ext) , res) ) => ( ext, res) ,
286+ // Use dummy syntax extensions for unresolved macros for better recovery.
287+ Ok ( ( None , res) ) => ( self . dummy_ext ( kind) , res) ,
288+ Err ( Determinacy :: Determined ) => ( self . dummy_ext ( kind) , Res :: Err ) ,
289+ Err ( Determinacy :: Undetermined ) => return Err ( Indeterminate ) ,
290+ } ;
287291
288292 // Report errors and enforce feature gates for the resolved macro.
289293 let features = self . session . features_untracked ( ) ;
290- if res != Err ( Determinacy :: Undetermined ) {
291- // Do not report duplicated errors on every undetermined resolution.
292- for segment in & path. segments {
293- if let Some ( args) = & segment. args {
294- self . session . span_err ( args. span ( ) , "generic arguments in macro path" ) ;
295- }
296- if kind == MacroKind :: Attr && !features. rustc_attrs &&
297- segment. ident . as_str ( ) . starts_with ( "rustc" ) {
298- let msg = "attributes starting with `rustc` are \
299- reserved for use by the `rustc` compiler";
300- emit_feature_err (
301- & self . session . parse_sess ,
302- sym:: rustc_attrs,
303- segment. ident . span ,
304- GateIssue :: Language ,
305- msg,
306- ) ;
307- }
294+ for segment in & path. segments {
295+ if let Some ( args) = & segment. args {
296+ self . session . span_err ( args. span ( ) , "generic arguments in macro path" ) ;
308297 }
309- }
310-
311- let res = match res {
312- Err ( Determinacy :: Undetermined ) => return Err ( Indeterminate ) ,
313- Ok ( Res :: Err ) | Err ( Determinacy :: Determined ) => {
314- // Return dummy syntax extensions for unresolved macros for better recovery.
315- return Ok ( ( Res :: Err , self . dummy_ext ( kind) ) ) ;
298+ if kind == MacroKind :: Attr && !features. rustc_attrs &&
299+ segment. ident . as_str ( ) . starts_with ( "rustc" ) {
300+ let msg =
301+ "attributes starting with `rustc` are reserved for use by the `rustc` compiler" ;
302+ emit_feature_err (
303+ & self . session . parse_sess ,
304+ sym:: rustc_attrs,
305+ segment. ident . span ,
306+ GateIssue :: Language ,
307+ msg,
308+ ) ;
316309 }
317- Ok ( res) => res,
318- } ;
310+ }
319311
320312 match res {
321313 Res :: Def ( DefKind :: Macro ( _) , def_id) => {
@@ -345,20 +337,22 @@ impl<'a> Resolver<'a> {
345337 }
346338 }
347339 }
340+ Res :: Err => { }
348341 _ => panic ! ( "expected `DefKind::Macro` or `Res::NonMacroAttr`" ) ,
349342 } ;
350343
351- let ext = self . get_macro ( res) ;
344+ self . check_stability_and_deprecation ( & ext, path) ;
345+
352346 Ok ( if ext. macro_kind ( ) != kind {
353347 let expected = if kind == MacroKind :: Attr { "attribute" } else { kind. descr ( ) } ;
354348 let msg = format ! ( "expected {}, found {} `{}`" , expected, res. descr( ) , path) ;
355349 self . session . struct_span_err ( path. span , & msg)
356350 . span_label ( path. span , format ! ( "not {} {}" , kind. article( ) , expected) )
357351 . emit ( ) ;
358- // Return dummy syntax extensions for unexpected macro kinds for better recovery.
359- ( Res :: Err , self . dummy_ext ( kind) )
352+ // Use dummy syntax extensions for unexpected macro kinds for better recovery.
353+ ( self . dummy_ext ( kind) , Res :: Err )
360354 } else {
361- ( res , ext )
355+ ( ext , res )
362356 } )
363357 }
364358
@@ -416,14 +410,14 @@ impl<'a> Resolver<'a> {
416410 err. emit ( ) ;
417411 }
418412
419- pub fn resolve_macro_to_res_inner (
413+ pub fn resolve_macro_path (
420414 & mut self ,
421415 path : & ast:: Path ,
422416 kind : MacroKind ,
423417 parent_scope : & ParentScope < ' a > ,
424418 trace : bool ,
425419 force : bool ,
426- ) -> Result < Res , Determinacy > {
420+ ) -> Result < ( Option < Lrc < SyntaxExtension > > , Res ) , Determinacy > {
427421 let path_span = path. span ;
428422 let mut path = Segment :: from_path ( path) ;
429423
@@ -435,7 +429,7 @@ impl<'a> Resolver<'a> {
435429 path. insert ( 0 , Segment :: from_ident ( root) ) ;
436430 }
437431
438- if path. len ( ) > 1 {
432+ let res = if path. len ( ) > 1 {
439433 let res = match self . resolve_path ( & path, Some ( MacroNS ) , parent_scope,
440434 false , path_span, CrateLint :: No ) {
441435 PathResult :: NonModule ( path_res) if path_res. unresolved_segments ( ) == 0 => {
@@ -471,7 +465,9 @@ impl<'a> Resolver<'a> {
471465 let res = binding. map ( |binding| binding. res ( ) ) ;
472466 self . prohibit_imported_non_macro_attrs ( binding. ok ( ) , res. ok ( ) , path_span) ;
473467 res
474- }
468+ } ;
469+
470+ res. map ( |res| ( self . get_macro ( res) , res) )
475471 }
476472
477473 // Resolve an identifier in lexical scope.
@@ -600,16 +596,18 @@ impl<'a> Resolver<'a> {
600596 let mut result = Err ( Determinacy :: Determined ) ;
601597 for derive in & parent_scope. derives {
602598 let parent_scope = ParentScope { derives : Vec :: new ( ) , ..* parent_scope } ;
603- match self . resolve_macro_to_res ( derive, MacroKind :: Derive ,
604- & parent_scope, true , force) {
605- Ok ( ( _ , ext ) ) => if ext. helper_attrs . contains ( & ident. name ) {
599+ match self . resolve_macro_path ( derive, MacroKind :: Derive ,
600+ & parent_scope, true , force) {
601+ Ok ( ( Some ( ext ) , _ ) ) => if ext. helper_attrs . contains ( & ident. name ) {
606602 let binding = ( Res :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ,
607603 ty:: Visibility :: Public , derive. span , Mark :: root ( ) )
608604 . to_name_binding ( self . arenas ) ;
609605 result = Ok ( ( binding, Flags :: empty ( ) ) ) ;
610606 break ;
611607 }
612- Err ( Indeterminate ) => result = Err ( Determinacy :: Undetermined ) ,
608+ Ok ( _) | Err ( Determinacy :: Determined ) => { }
609+ Err ( Determinacy :: Undetermined ) =>
610+ result = Err ( Determinacy :: Undetermined ) ,
613611 }
614612 }
615613 result
@@ -1004,7 +1002,8 @@ impl<'a> Resolver<'a> {
10041002 }
10051003 }
10061004
1007- fn check_stability_and_deprecation ( & self , ext : & SyntaxExtension , descr : Symbol , span : Span ) {
1005+ fn check_stability_and_deprecation ( & self , ext : & SyntaxExtension , path : & ast:: Path ) {
1006+ let span = path. span ;
10081007 if let Some ( stability) = & ext. stability {
10091008 if let StabilityLevel :: Unstable { reason, issue } = stability. level {
10101009 let feature = stability. feature ;
@@ -1013,14 +1012,14 @@ impl<'a> Resolver<'a> {
10131012 }
10141013 }
10151014 if let Some ( depr) = & stability. rustc_depr {
1016- let ( message, lint) = stability:: rustc_deprecation_message ( depr, & descr . as_str ( ) ) ;
1015+ let ( message, lint) = stability:: rustc_deprecation_message ( depr, & path . to_string ( ) ) ;
10171016 stability:: early_report_deprecation (
10181017 self . session , & message, depr. suggestion , lint, span
10191018 ) ;
10201019 }
10211020 }
10221021 if let Some ( depr) = & ext. deprecation {
1023- let ( message, lint) = stability:: deprecation_message ( depr, & descr . as_str ( ) ) ;
1022+ let ( message, lint) = stability:: deprecation_message ( depr, & path . to_string ( ) ) ;
10241023 stability:: early_report_deprecation ( self . session , & message, None , lint, span) ;
10251024 }
10261025 }
@@ -1101,7 +1100,7 @@ impl<'a> Resolver<'a> {
11011100 // Reserve some names that are not quite covered by the general check
11021101 // performed on `Resolver::builtin_attrs`.
11031102 if ident. name == sym:: cfg || ident. name == sym:: cfg_attr || ident. name == sym:: derive {
1104- let macro_kind = self . opt_get_macro ( res) . map ( |ext| ext. macro_kind ( ) ) ;
1103+ let macro_kind = self . get_macro ( res) . map ( |ext| ext. macro_kind ( ) ) ;
11051104 if macro_kind. is_some ( ) && sub_namespace_match ( macro_kind, Some ( MacroKind :: Attr ) ) {
11061105 self . session . span_err (
11071106 ident. span , & format ! ( "name `{}` is reserved in attribute namespace" , ident)
0 commit comments