@@ -18,7 +18,7 @@ use ext::base::*;
1818use ext:: derive:: { add_derived_markers, collect_derives} ;
1919use ext:: hygiene:: { Mark , SyntaxContext } ;
2020use ext:: placeholders:: { placeholder, PlaceholderExpander } ;
21- use feature_gate:: { self , Features , is_builtin_attr} ;
21+ use feature_gate:: { self , Features , GateIssue , is_builtin_attr, emit_feature_err } ;
2222use fold;
2323use fold:: * ;
2424use parse:: { DirectoryOwnership , PResult } ;
@@ -229,6 +229,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
229229 module. directory . pop ( ) ;
230230 self . cx . root_path = module. directory . clone ( ) ;
231231 self . cx . current_expansion . module = Rc :: new ( module) ;
232+ self . cx . current_expansion . crate_span = Some ( krate. span ) ;
232233
233234 let orig_mod_span = krate. module . inner ;
234235
@@ -531,11 +532,36 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
531532 let path = & mac. node . path ;
532533
533534 let ident = ident. unwrap_or_else ( || keywords:: Invalid . ident ( ) ) ;
534- let validate_and_set_expn_info = |def_site_span,
535+ let validate_and_set_expn_info = |this : & mut Self , // arg instead of capture
536+ def_site_span : Option < Span > ,
535537 allow_internal_unstable,
536- allow_internal_unsafe| {
538+ allow_internal_unsafe,
539+ // can't infer this type
540+ unstable_feature : Option < ( Symbol , u32 ) > | {
541+
542+ // feature-gate the macro invocation
543+ if let Some ( ( feature, issue) ) = unstable_feature {
544+ let crate_span = this. cx . current_expansion . crate_span . unwrap ( ) ;
545+ // don't stability-check macros in the same crate
546+ // (the only time this is null is for syntax extensions registered as macros)
547+ if def_site_span. map_or ( false , |def_span| !crate_span. contains ( def_span) )
548+ && !span. allows_unstable ( ) && this. cx . ecfg . features . map_or ( true , |feats| {
549+ // macro features will count as lib features
550+ !feats. declared_lib_features . iter ( ) . any ( |& ( feat, _) | feat == feature)
551+ } ) {
552+ let explain = format ! ( "macro {}! is unstable" , path) ;
553+ emit_feature_err ( this. cx . parse_sess , & * feature. as_str ( ) , span,
554+ GateIssue :: Library ( Some ( issue) ) , & explain) ;
555+ this. cx . trace_macros_diag ( ) ;
556+ return Err ( kind. dummy ( span) ) ;
557+ }
558+ }
559+
537560 if ident. name != keywords:: Invalid . name ( ) {
538- return Err ( format ! ( "macro {}! expects no ident argument, given '{}'" , path, ident) ) ;
561+ let msg = format ! ( "macro {}! expects no ident argument, given '{}'" , path, ident) ;
562+ this. cx . span_err ( path. span , & msg) ;
563+ this. cx . trace_macros_diag ( ) ;
564+ return Err ( kind. dummy ( span) ) ;
539565 }
540566 mark. set_expn_info ( ExpnInfo {
541567 call_site : span,
@@ -551,11 +577,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
551577
552578 let opt_expanded = match * ext {
553579 DeclMacro ( ref expand, def_span) => {
554- if let Err ( msg) = validate_and_set_expn_info ( def_span. map ( |( _, s) | s) ,
555- false , false ) {
556- self . cx . span_err ( path. span , & msg) ;
557- self . cx . trace_macros_diag ( ) ;
558- kind. dummy ( span)
580+ if let Err ( dummy_span) = validate_and_set_expn_info ( self , def_span. map ( |( _, s) | s) ,
581+ false , false , None ) {
582+ dummy_span
559583 } else {
560584 kind. make_from ( expand. expand ( self . cx , span, mac. node . stream ( ) ) )
561585 }
@@ -565,14 +589,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
565589 ref expander,
566590 def_info,
567591 allow_internal_unstable,
568- allow_internal_unsafe
592+ allow_internal_unsafe,
593+ unstable_feature,
569594 } => {
570- if let Err ( msg) = validate_and_set_expn_info ( def_info. map ( |( _, s) | s) ,
571- allow_internal_unstable,
572- allow_internal_unsafe) {
573- self . cx . span_err ( path. span , & msg) ;
574- self . cx . trace_macros_diag ( ) ;
575- kind. dummy ( span)
595+ if let Err ( dummy_span) = validate_and_set_expn_info ( self , def_info. map ( |( _, s) | s) ,
596+ allow_internal_unstable,
597+ allow_internal_unsafe,
598+ unstable_feature) {
599+ dummy_span
576600 } else {
577601 kind. make_from ( expander. expand ( self . cx , span, mac. node . stream ( ) ) )
578602 }
0 commit comments