|  | 
| 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