@@ -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
@@ -533,11 +534,36 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
533534 let path = & mac. node . path ;
534535
535536 let ident = ident. unwrap_or_else ( || keywords:: Invalid . ident ( ) ) ;
536- let validate_and_set_expn_info = |def_site_span,
537+ let validate_and_set_expn_info = |this : & mut Self , // arg instead of capture
538+ def_site_span : Option < Span > ,
537539 allow_internal_unstable,
538- allow_internal_unsafe| {
540+ allow_internal_unsafe,
541+ // can't infer this type
542+ unstable_feature : Option < ( Symbol , u32 ) > | {
543+
544+ // feature-gate the macro invocation
545+ if let Some ( ( feature, issue) ) = unstable_feature {
546+ let crate_span = this. cx . current_expansion . crate_span . unwrap ( ) ;
547+ // don't stability-check macros in the same crate
548+ // (the only time this is null is for syntax extensions registered as macros)
549+ if def_site_span. map_or ( false , |def_span| !crate_span. contains ( def_span) )
550+ && !span. allows_unstable ( ) && this. cx . ecfg . features . map_or ( true , |feats| {
551+ // macro features will count as lib features
552+ !feats. declared_lib_features . iter ( ) . any ( |& ( feat, _) | feat == feature)
553+ } ) {
554+ let explain = format ! ( "macro {}! is unstable" , path) ;
555+ emit_feature_err ( this. cx . parse_sess , & * feature. as_str ( ) , span,
556+ GateIssue :: Library ( Some ( issue) ) , & explain) ;
557+ this. cx . trace_macros_diag ( ) ;
558+ return Err ( kind. dummy ( span) ) ;
559+ }
560+ }
561+
539562 if ident. name != keywords:: Invalid . name ( ) {
540- return Err ( format ! ( "macro {}! expects no ident argument, given '{}'" , path, ident) ) ;
563+ let msg = format ! ( "macro {}! expects no ident argument, given '{}'" , path, ident) ;
564+ this. cx . span_err ( path. span , & msg) ;
565+ this. cx . trace_macros_diag ( ) ;
566+ return Err ( kind. dummy ( span) ) ;
541567 }
542568 mark. set_expn_info ( ExpnInfo {
543569 call_site : span,
@@ -553,11 +579,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
553579
554580 let opt_expanded = match * ext {
555581 DeclMacro ( ref expand, def_span) => {
556- if let Err ( msg) = validate_and_set_expn_info ( def_span. map ( |( _, s) | s) ,
557- false , false ) {
558- self . cx . span_err ( path. span , & msg) ;
559- self . cx . trace_macros_diag ( ) ;
560- kind. dummy ( span)
582+ if let Err ( dummy_span) = validate_and_set_expn_info ( self , def_span. map ( |( _, s) | s) ,
583+ false , false , None ) {
584+ dummy_span
561585 } else {
562586 kind. make_from ( expand. expand ( self . cx , span, mac. node . stream ( ) ) )
563587 }
@@ -567,14 +591,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
567591 ref expander,
568592 def_info,
569593 allow_internal_unstable,
570- allow_internal_unsafe
594+ allow_internal_unsafe,
595+ unstable_feature,
571596 } => {
572- if let Err ( msg) = validate_and_set_expn_info ( def_info. map ( |( _, s) | s) ,
573- allow_internal_unstable,
574- allow_internal_unsafe) {
575- self . cx . span_err ( path. span , & msg) ;
576- self . cx . trace_macros_diag ( ) ;
577- kind. dummy ( span)
597+ if let Err ( dummy_span) = validate_and_set_expn_info ( self , def_info. map ( |( _, s) | s) ,
598+ allow_internal_unstable,
599+ allow_internal_unsafe,
600+ unstable_feature) {
601+ dummy_span
578602 } else {
579603 kind. make_from ( expander. expand ( self . cx , span, mac. node . stream ( ) ) )
580604 }
0 commit comments