@@ -319,9 +319,9 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
319319 None
320320 }
321321
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 {
325325 InvocationKind :: Attr { attr : None , .. } =>
326326 return Ok ( None ) ,
327327 InvocationKind :: Attr { attr : Some ( ref attr) , ref traits, .. } =>
@@ -331,90 +331,26 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
331331 InvocationKind :: Derive { ref path, .. } =>
332332 ( path, MacroKind :: Derive , & [ ] [ ..] ) ,
333333 } ;
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- }
379334
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 ) ;
389345 }
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+
402347 Ok ( Some ( ext) )
403348 }
404349
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 )
418354 }
419355
420356 fn check_unused_macros ( & self ) {
@@ -436,43 +372,89 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
436372}
437373
438374impl < ' 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 ,
449376 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.
452381 if def != Err ( Determinacy :: Undetermined ) {
453382 // 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+ }
458388 }
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+ }
470400 }
471401 }
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) ) )
473455 }
474456
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 ,
476458 derives_in_scope : & [ ast:: Path ] , force : bool )
477459 -> Result < Def , Determinacy > {
478460 let ast:: Path { ref segments, span } = * path;
@@ -550,7 +532,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
550532 enum ConvertToDeriveHelper { Yes , No , DontKnow }
551533 let mut convert_to_derive_helper = ConvertToDeriveHelper :: No ;
552534 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) {
554536 Ok ( ext) => if let SyntaxExtension :: ProcMacroDerive ( _, ref inert_attrs, _) = * ext {
555537 if inert_attrs. contains ( & path[ 0 ] . name ) {
556538 convert_to_derive_helper = ConvertToDeriveHelper :: Yes ;
0 commit comments