@@ -229,13 +229,10 @@ impl<'a> base::Resolver for Resolver<'a> {
229
229
} ;
230
230
231
231
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) ?;
233
233
234
234
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) ) ) ;
239
236
240
237
if let Res :: Def ( _, def_id) = res {
241
238
if after_derive {
@@ -275,47 +272,42 @@ impl<'a> Resolver<'a> {
275
272
}
276
273
}
277
274
278
- fn resolve_macro_to_res (
275
+ /// Resolve macro path with error reporting and recovery.
276
+ fn smart_resolve_macro_path (
279
277
& mut self ,
280
278
path : & ast:: Path ,
281
279
kind : MacroKind ,
282
280
parent_scope : & ParentScope < ' a > ,
283
281
trace : bool ,
284
282
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
+ } ;
287
291
288
292
// Report errors and enforce feature gates for the resolved macro.
289
293
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" ) ;
308
297
}
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
+ ) ;
316
309
}
317
- Ok ( res) => res,
318
- } ;
310
+ }
319
311
320
312
match res {
321
313
Res :: Def ( DefKind :: Macro ( _) , def_id) => {
@@ -345,20 +337,22 @@ impl<'a> Resolver<'a> {
345
337
}
346
338
}
347
339
}
340
+ Res :: Err => { }
348
341
_ => panic ! ( "expected `DefKind::Macro` or `Res::NonMacroAttr`" ) ,
349
342
} ;
350
343
351
- let ext = self . get_macro ( res) ;
344
+ self . check_stability_and_deprecation ( & ext, path) ;
345
+
352
346
Ok ( if ext. macro_kind ( ) != kind {
353
347
let expected = if kind == MacroKind :: Attr { "attribute" } else { kind. descr ( ) } ;
354
348
let msg = format ! ( "expected {}, found {} `{}`" , expected, res. descr( ) , path) ;
355
349
self . session . struct_span_err ( path. span , & msg)
356
350
. span_label ( path. span , format ! ( "not {} {}" , kind. article( ) , expected) )
357
351
. 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 )
360
354
} else {
361
- ( res , ext )
355
+ ( ext , res )
362
356
} )
363
357
}
364
358
@@ -416,14 +410,14 @@ impl<'a> Resolver<'a> {
416
410
err. emit ( ) ;
417
411
}
418
412
419
- pub fn resolve_macro_to_res_inner (
413
+ pub fn resolve_macro_path (
420
414
& mut self ,
421
415
path : & ast:: Path ,
422
416
kind : MacroKind ,
423
417
parent_scope : & ParentScope < ' a > ,
424
418
trace : bool ,
425
419
force : bool ,
426
- ) -> Result < Res , Determinacy > {
420
+ ) -> Result < ( Option < Lrc < SyntaxExtension > > , Res ) , Determinacy > {
427
421
let path_span = path. span ;
428
422
let mut path = Segment :: from_path ( path) ;
429
423
@@ -435,7 +429,7 @@ impl<'a> Resolver<'a> {
435
429
path. insert ( 0 , Segment :: from_ident ( root) ) ;
436
430
}
437
431
438
- if path. len ( ) > 1 {
432
+ let res = if path. len ( ) > 1 {
439
433
let res = match self . resolve_path ( & path, Some ( MacroNS ) , parent_scope,
440
434
false , path_span, CrateLint :: No ) {
441
435
PathResult :: NonModule ( path_res) if path_res. unresolved_segments ( ) == 0 => {
@@ -471,7 +465,9 @@ impl<'a> Resolver<'a> {
471
465
let res = binding. map ( |binding| binding. res ( ) ) ;
472
466
self . prohibit_imported_non_macro_attrs ( binding. ok ( ) , res. ok ( ) , path_span) ;
473
467
res
474
- }
468
+ } ;
469
+
470
+ res. map ( |res| ( self . get_macro ( res) , res) )
475
471
}
476
472
477
473
// Resolve an identifier in lexical scope.
@@ -600,16 +596,18 @@ impl<'a> Resolver<'a> {
600
596
let mut result = Err ( Determinacy :: Determined ) ;
601
597
for derive in & parent_scope. derives {
602
598
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 ) {
606
602
let binding = ( Res :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ,
607
603
ty:: Visibility :: Public , derive. span , Mark :: root ( ) )
608
604
. to_name_binding ( self . arenas ) ;
609
605
result = Ok ( ( binding, Flags :: empty ( ) ) ) ;
610
606
break ;
611
607
}
612
- Err ( Indeterminate ) => result = Err ( Determinacy :: Undetermined ) ,
608
+ Ok ( _) | Err ( Determinacy :: Determined ) => { }
609
+ Err ( Determinacy :: Undetermined ) =>
610
+ result = Err ( Determinacy :: Undetermined ) ,
613
611
}
614
612
}
615
613
result
@@ -1004,7 +1002,8 @@ impl<'a> Resolver<'a> {
1004
1002
}
1005
1003
}
1006
1004
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 ;
1008
1007
if let Some ( stability) = & ext. stability {
1009
1008
if let StabilityLevel :: Unstable { reason, issue } = stability. level {
1010
1009
let feature = stability. feature ;
@@ -1013,14 +1012,14 @@ impl<'a> Resolver<'a> {
1013
1012
}
1014
1013
}
1015
1014
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 ( ) ) ;
1017
1016
stability:: early_report_deprecation (
1018
1017
self . session , & message, depr. suggestion , lint, span
1019
1018
) ;
1020
1019
}
1021
1020
}
1022
1021
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 ( ) ) ;
1024
1023
stability:: early_report_deprecation ( self . session , & message, None , lint, span) ;
1025
1024
}
1026
1025
}
@@ -1101,7 +1100,7 @@ impl<'a> Resolver<'a> {
1101
1100
// Reserve some names that are not quite covered by the general check
1102
1101
// performed on `Resolver::builtin_attrs`.
1103
1102
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 ( ) ) ;
1105
1104
if macro_kind. is_some ( ) && sub_namespace_match ( macro_kind, Some ( MacroKind :: Attr ) ) {
1106
1105
self . session . span_err (
1107
1106
ident. span , & format ! ( "name `{}` is reserved in attribute namespace" , ident)
0 commit comments