@@ -319,9 +319,9 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
319
319
None
320
320
}
321
321
322
- fn resolve_invoc ( & mut self , invoc : & Invocation , scope : Mark , force : bool )
323
- -> Result < Option < Lrc < SyntaxExtension > > , Determinacy > {
324
- let ( path, macro_kind , derives_in_scope) = match invoc. kind {
322
+ fn resolve_macro_invocation ( & mut self , invoc : & Invocation , scope : Mark , force : bool )
323
+ -> Result < Option < Lrc < SyntaxExtension > > , Determinacy > {
324
+ let ( path, kind , derives_in_scope) = match invoc. kind {
325
325
InvocationKind :: Attr { attr : None , .. } =>
326
326
return Ok ( None ) ,
327
327
InvocationKind :: Attr { attr : Some ( ref attr) , ref traits, .. } =>
@@ -331,90 +331,26 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
331
331
InvocationKind :: Derive { ref path, .. } =>
332
332
( path, MacroKind :: Derive , & [ ] [ ..] ) ,
333
333
} ;
334
- let def = self . resolve_macro_to_def ( scope, path, macro_kind, derives_in_scope, force) ?;
335
-
336
- if let Def :: Macro ( _, MacroKind :: ProcMacroStub ) = def {
337
- self . report_proc_macro_stub ( invoc. span ( ) ) ;
338
- return Err ( Determinacy :: Determined ) ;
339
- } else if let Def :: NonMacroAttr ( attr_kind) = def {
340
- // Note that not only attributes, but anything in macro namespace can result in a
341
- // `Def::NonMacroAttr` definition (e.g. `inline!()`), so we must report the error
342
- // below for these cases.
343
- let is_attr_invoc =
344
- if let InvocationKind :: Attr { .. } = invoc. kind { true } else { false } ;
345
- let path = invoc. path ( ) . expect ( "no path for non-macro attr" ) ;
346
- match attr_kind {
347
- NonMacroAttrKind :: Tool | NonMacroAttrKind :: DeriveHelper |
348
- NonMacroAttrKind :: Custom if is_attr_invoc => {
349
- let features = self . session . features_untracked ( ) ;
350
- if attr_kind == NonMacroAttrKind :: Tool &&
351
- !features. tool_attributes {
352
- feature_err ( & self . session . parse_sess , "tool_attributes" ,
353
- invoc. span ( ) , GateIssue :: Language ,
354
- "tool attributes are unstable" ) . emit ( ) ;
355
- }
356
- if attr_kind == NonMacroAttrKind :: Custom {
357
- assert ! ( path. segments. len( ) == 1 ) ;
358
- let name = path. segments [ 0 ] . ident . name . as_str ( ) ;
359
- if name. starts_with ( "rustc_" ) {
360
- if !features. rustc_attrs {
361
- let msg = "unless otherwise specified, attributes with the prefix \
362
- `rustc_` are reserved for internal compiler diagnostics";
363
- feature_err ( & self . session . parse_sess , "rustc_attrs" , invoc. span ( ) ,
364
- GateIssue :: Language , & msg) . emit ( ) ;
365
- }
366
- } else if name. starts_with ( "derive_" ) {
367
- if !features. custom_derive {
368
- feature_err ( & self . session . parse_sess , "custom_derive" , invoc. span ( ) ,
369
- GateIssue :: Language , EXPLAIN_DERIVE_UNDERSCORE ) . emit ( ) ;
370
- }
371
- } else if !features. custom_attribute {
372
- let msg = format ! ( "The attribute `{}` is currently unknown to the \
373
- compiler and may have meaning added to it in the \
374
- future", path) ;
375
- feature_err ( & self . session . parse_sess , "custom_attribute" , invoc. span ( ) ,
376
- GateIssue :: Language , & msg) . emit ( ) ;
377
- }
378
- }
379
334
380
- return Ok ( Some ( Lrc :: new ( SyntaxExtension :: NonMacroAttr {
381
- mark_used : attr_kind == NonMacroAttrKind :: Tool ,
382
- } ) ) ) ;
383
- }
384
- _ => {
385
- self . report_non_macro_attr ( path. span , def) ;
386
- return Err ( Determinacy :: Determined ) ;
387
- }
388
- }
335
+ let ( def, ext) = self . resolve_macro_to_def ( path, kind, scope, derives_in_scope, force) ?;
336
+
337
+ if let Def :: Macro ( def_id, _) = def {
338
+ self . macro_defs . insert ( invoc. expansion_data . mark , def_id) ;
339
+ let normal_module_def_id =
340
+ self . macro_def_scope ( invoc. expansion_data . mark ) . normal_ancestor_id ;
341
+ self . definitions . add_parent_module_of_macro_def ( invoc. expansion_data . mark ,
342
+ normal_module_def_id) ;
343
+ invoc. expansion_data . mark . set_default_transparency ( ext. default_transparency ( ) ) ;
344
+ invoc. expansion_data . mark . set_is_builtin ( def_id. krate == BUILTIN_MACROS_CRATE ) ;
389
345
}
390
- let def_id = def. def_id ( ) ;
391
-
392
- self . macro_defs . insert ( invoc. expansion_data . mark , def_id) ;
393
- let normal_module_def_id =
394
- self . macro_def_scope ( invoc. expansion_data . mark ) . normal_ancestor_id ;
395
- self . definitions . add_parent_module_of_macro_def ( invoc. expansion_data . mark ,
396
- normal_module_def_id) ;
397
-
398
- self . unused_macros . remove ( & def_id) ;
399
- let ext = self . get_macro ( def) ;
400
- invoc. expansion_data . mark . set_default_transparency ( ext. default_transparency ( ) ) ;
401
- invoc. expansion_data . mark . set_is_builtin ( def_id. krate == BUILTIN_MACROS_CRATE ) ;
346
+
402
347
Ok ( Some ( ext) )
403
348
}
404
349
405
- fn resolve_macro ( & mut self , scope : Mark , path : & ast:: Path , kind : MacroKind , force : bool )
406
- -> Result < Lrc < SyntaxExtension > , Determinacy > {
407
- self . resolve_macro_to_def ( scope, path, kind, & [ ] , force) . and_then ( |def| {
408
- if let Def :: Macro ( _, MacroKind :: ProcMacroStub ) = def {
409
- self . report_proc_macro_stub ( path. span ) ;
410
- return Err ( Determinacy :: Determined ) ;
411
- } else if let Def :: NonMacroAttr ( ..) = def {
412
- self . report_non_macro_attr ( path. span , def) ;
413
- return Err ( Determinacy :: Determined ) ;
414
- }
415
- self . unused_macros . remove ( & def. def_id ( ) ) ;
416
- Ok ( self . get_macro ( def) )
417
- } )
350
+ fn resolve_macro_path ( & mut self , path : & ast:: Path , kind : MacroKind , scope : Mark ,
351
+ derives_in_scope : & [ ast:: Path ] , force : bool )
352
+ -> Result < Lrc < SyntaxExtension > , Determinacy > {
353
+ Ok ( self . resolve_macro_to_def ( path, kind, scope, derives_in_scope, force) ?. 1 )
418
354
}
419
355
420
356
fn check_unused_macros ( & self ) {
@@ -436,43 +372,89 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
436
372
}
437
373
438
374
impl < ' a , ' cl > Resolver < ' a , ' cl > {
439
- fn report_proc_macro_stub ( & self , span : Span ) {
440
- self . session . span_err ( span,
441
- "can't use a procedural macro from the same crate that defines it" ) ;
442
- }
443
-
444
- fn report_non_macro_attr ( & self , span : Span , def : Def ) {
445
- self . session . span_err ( span, & format ! ( "expected a macro, found {}" , def. kind_name( ) ) ) ;
446
- }
447
-
448
- fn resolve_macro_to_def ( & mut self , scope : Mark , path : & ast:: Path , kind : MacroKind ,
375
+ fn resolve_macro_to_def ( & mut self , path : & ast:: Path , kind : MacroKind , scope : Mark ,
449
376
derives_in_scope : & [ ast:: Path ] , force : bool )
450
- -> Result < Def , Determinacy > {
451
- let def = self . resolve_macro_to_def_inner ( scope, path, kind, derives_in_scope, force) ;
377
+ -> Result < ( Def , Lrc < SyntaxExtension > ) , Determinacy > {
378
+ let def = self . resolve_macro_to_def_inner ( path, kind, scope, derives_in_scope, force) ;
379
+
380
+ // Report errors and enforce feature gates for the resolved macro.
452
381
if def != Err ( Determinacy :: Undetermined ) {
453
382
// Do not report duplicated errors on every undetermined resolution.
454
- path. segments . iter ( ) . find ( |segment| segment. args . is_some ( ) ) . map ( |segment| {
455
- self . session . span_err ( segment. args . as_ref ( ) . unwrap ( ) . span ( ) ,
456
- "generic arguments in macro path" ) ;
457
- } ) ;
383
+ for segment in & path. segments {
384
+ if let Some ( args) = & segment. args {
385
+ self . session . span_err ( args. span ( ) , "generic arguments in macro path" ) ;
386
+ }
387
+ }
458
388
}
459
- if kind != MacroKind :: Bang && path . segments . len ( ) > 1 &&
460
- def != Ok ( Def :: NonMacroAttr ( NonMacroAttrKind :: Tool ) ) {
461
- if ! self . session . features_untracked ( ) . proc_macro_path_invoc {
462
- emit_feature_err (
463
- & self . session . parse_sess ,
464
- "proc_macro_path_invoc" ,
465
- path . span ,
466
- GateIssue :: Language ,
467
- "paths of length greater than one in macro invocations are \
468
- currently unstable" ,
469
- ) ;
389
+
390
+ let def = def? ;
391
+
392
+ if path . segments . len ( ) > 1 {
393
+ if kind != MacroKind :: Bang {
394
+ if def != Def :: NonMacroAttr ( NonMacroAttrKind :: Tool ) &&
395
+ ! self . session . features_untracked ( ) . proc_macro_path_invoc {
396
+ let msg = format ! ( "non-ident {} paths are unstable" , kind . descr ( ) ) ;
397
+ emit_feature_err ( & self . session . parse_sess , "proc_macro_path_invoc" ,
398
+ path . span , GateIssue :: Language , & msg ) ;
399
+ }
470
400
}
471
401
}
472
- def
402
+
403
+ match def {
404
+ Def :: Macro ( def_id, macro_kind) => {
405
+ self . unused_macros . remove ( & def_id) ;
406
+ if macro_kind == MacroKind :: ProcMacroStub {
407
+ let msg = "can't use a procedural macro from the same crate that defines it" ;
408
+ self . session . span_err ( path. span , msg) ;
409
+ return Err ( Determinacy :: Determined ) ;
410
+ }
411
+ }
412
+ Def :: NonMacroAttr ( attr_kind) => {
413
+ if kind == MacroKind :: Attr {
414
+ let features = self . session . features_untracked ( ) ;
415
+ if attr_kind == NonMacroAttrKind :: Tool && !features. tool_attributes {
416
+ feature_err ( & self . session . parse_sess , "tool_attributes" , path. span ,
417
+ GateIssue :: Language , "tool attributes are unstable" ) . emit ( ) ;
418
+ }
419
+ if attr_kind == NonMacroAttrKind :: Custom {
420
+ assert ! ( path. segments. len( ) == 1 ) ;
421
+ let name = path. segments [ 0 ] . ident . name . as_str ( ) ;
422
+ if name. starts_with ( "rustc_" ) {
423
+ if !features. rustc_attrs {
424
+ let msg = "unless otherwise specified, attributes with the prefix \
425
+ `rustc_` are reserved for internal compiler diagnostics";
426
+ feature_err ( & self . session . parse_sess , "rustc_attrs" , path. span ,
427
+ GateIssue :: Language , & msg) . emit ( ) ;
428
+ }
429
+ } else if name. starts_with ( "derive_" ) {
430
+ if !features. custom_derive {
431
+ feature_err ( & self . session . parse_sess , "custom_derive" , path. span ,
432
+ GateIssue :: Language , EXPLAIN_DERIVE_UNDERSCORE ) . emit ( ) ;
433
+ }
434
+ } else if !features. custom_attribute {
435
+ let msg = format ! ( "The attribute `{}` is currently unknown to the \
436
+ compiler and may have meaning added to it in the \
437
+ future", path) ;
438
+ feature_err ( & self . session . parse_sess , "custom_attribute" , path. span ,
439
+ GateIssue :: Language , & msg) . emit ( ) ;
440
+ }
441
+ }
442
+ } else {
443
+ // Not only attributes, but anything in macro namespace can result in
444
+ // `Def::NonMacroAttr` definition (e.g. `inline!()`), so we must report
445
+ // an error for those cases.
446
+ let msg = format ! ( "expected a macro, found {}" , def. kind_name( ) ) ;
447
+ self . session . span_err ( path. span , & msg) ;
448
+ return Err ( Determinacy :: Determined ) ;
449
+ }
450
+ }
451
+ _ => panic ! ( "expected `Def::Macro` or `Def::NonMacroAttr`" ) ,
452
+ }
453
+
454
+ Ok ( ( def, self . get_macro ( def) ) )
473
455
}
474
456
475
- pub fn resolve_macro_to_def_inner ( & mut self , scope : Mark , path : & ast:: Path , kind : MacroKind ,
457
+ pub fn resolve_macro_to_def_inner ( & mut self , path : & ast:: Path , kind : MacroKind , scope : Mark ,
476
458
derives_in_scope : & [ ast:: Path ] , force : bool )
477
459
-> Result < Def , Determinacy > {
478
460
let ast:: Path { ref segments, span } = * path;
@@ -550,7 +532,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
550
532
enum ConvertToDeriveHelper { Yes , No , DontKnow }
551
533
let mut convert_to_derive_helper = ConvertToDeriveHelper :: No ;
552
534
for derive in derives_in_scope {
553
- match self . resolve_macro ( scope , derive, MacroKind :: Derive , force) {
535
+ match self . resolve_macro_path ( derive, MacroKind :: Derive , scope , & [ ] , force) {
554
536
Ok ( ext) => if let SyntaxExtension :: ProcMacroDerive ( _, ref inert_attrs, _) = * ext {
555
537
if inert_attrs. contains ( & path[ 0 ] . name ) {
556
538
convert_to_derive_helper = ConvertToDeriveHelper :: Yes ;
0 commit comments