| 
1 | 1 | use rustc_errors::DiagArgValue;  | 
2 | 2 | use rustc_feature::{AttributeTemplate, template};  | 
3 | 3 | use rustc_hir::attrs::{AttributeKind, MacroUseArgs};  | 
 | 4 | +use rustc_hir::lints::AttributeLintKind;  | 
4 | 5 | use rustc_span::{Span, Symbol, sym};  | 
5 | 6 | use thin_vec::ThinVec;  | 
6 | 7 | 
 
  | 
7 |  | -use crate::attributes::{AcceptMapping, AttributeParser, NoArgsAttributeParser, OnDuplicate};  | 
 | 8 | +use crate::attributes::{  | 
 | 9 | +    AcceptMapping, AttributeOrder, AttributeParser, NoArgsAttributeParser, OnDuplicate,  | 
 | 10 | +    SingleAttributeParser,  | 
 | 11 | +};  | 
8 | 12 | use crate::context::{AcceptContext, FinalizeContext, Stage};  | 
9 | 13 | use crate::parser::ArgParser;  | 
10 | 14 | use crate::session_diagnostics;  | 
@@ -113,3 +117,58 @@ impl<S: Stage> AttributeParser<S> for MacroUseParser {  | 
113 | 117 |         Some(AttributeKind::MacroUse { span: self.first_span?, arguments: self.state })  | 
114 | 118 |     }  | 
115 | 119 | }  | 
 | 120 | + | 
 | 121 | +pub(crate) struct MacroExportParser;  | 
 | 122 | + | 
 | 123 | +impl<S: Stage> SingleAttributeParser<S> for crate::attributes::macro_attrs::MacroExportParser {  | 
 | 124 | +    const PATH: &[Symbol] = &[sym::macro_export];  | 
 | 125 | +    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;  | 
 | 126 | +    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;  | 
 | 127 | +    const TEMPLATE: AttributeTemplate = template!(Word, List: "local_inner_macros");  | 
 | 128 | + | 
 | 129 | +    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {  | 
 | 130 | +        let suggestions =  | 
 | 131 | +            || <Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "macro_export");  | 
 | 132 | +        let local_inner_macros = match args {  | 
 | 133 | +            ArgParser::NoArgs => false,  | 
 | 134 | +            ArgParser::List(list) => {  | 
 | 135 | +                let Some(l) = list.single() else {  | 
 | 136 | +                    let span = cx.attr_span;  | 
 | 137 | +                    cx.emit_lint(  | 
 | 138 | +                        AttributeLintKind::InvalidMacroExportArguments {  | 
 | 139 | +                            suggestions: suggestions(),  | 
 | 140 | +                        },  | 
 | 141 | +                        span,  | 
 | 142 | +                    );  | 
 | 143 | +                    return None;  | 
 | 144 | +                };  | 
 | 145 | +                match l.meta_item().and_then(|i| i.path().word_sym()) {  | 
 | 146 | +                    Some(sym::local_inner_macros) => true,  | 
 | 147 | +                    _ => {  | 
 | 148 | +                        let span = cx.attr_span;  | 
 | 149 | +                        cx.emit_lint(  | 
 | 150 | +                            AttributeLintKind::InvalidMacroExportArguments {  | 
 | 151 | +                                suggestions: suggestions(),  | 
 | 152 | +                            },  | 
 | 153 | +                            span,  | 
 | 154 | +                        );  | 
 | 155 | +                        return None;  | 
 | 156 | +                    }  | 
 | 157 | +                }  | 
 | 158 | +            }  | 
 | 159 | +            ArgParser::NameValue(_) => {  | 
 | 160 | +                let span = cx.attr_span;  | 
 | 161 | +                let suggestions = suggestions();  | 
 | 162 | +                cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {  | 
 | 163 | +                    num_suggestions: suggestions.len(),  | 
 | 164 | +                    suggestions: DiagArgValue::StrListSepByAnd(  | 
 | 165 | +                        suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),  | 
 | 166 | +                    ),  | 
 | 167 | +                    span,  | 
 | 168 | +                });  | 
 | 169 | +                return None;  | 
 | 170 | +            }  | 
 | 171 | +        };  | 
 | 172 | +        Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros })  | 
 | 173 | +    }  | 
 | 174 | +}  | 
0 commit comments