|
| 1 | +use rustc_ast::AttrStyle; |
1 | 2 | use rustc_errors::DiagArgValue;
|
2 | 3 | use rustc_hir::attrs::MacroUseArgs;
|
3 | 4 |
|
@@ -133,3 +134,65 @@ impl<S: Stage> NoArgsAttributeParser<S> for AllowInternalUnsafeParser {
|
133 | 134 | ]);
|
134 | 135 | const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::AllowInternalUnsafe(span);
|
135 | 136 | }
|
| 137 | + |
| 138 | +pub(crate) struct MacroExportParser; |
| 139 | + |
| 140 | +impl<S: Stage> SingleAttributeParser<S> for MacroExportParser { |
| 141 | + const PATH: &[Symbol] = &[sym::macro_export]; |
| 142 | + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; |
| 143 | + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; |
| 144 | + const TEMPLATE: AttributeTemplate = template!(Word, List: &["local_inner_macros"]); |
| 145 | + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ |
| 146 | + Allow(Target::MacroDef), |
| 147 | + Error(Target::WherePredicate), |
| 148 | + Error(Target::Crate), |
| 149 | + ]); |
| 150 | + |
| 151 | + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { |
| 152 | + let suggestions = || { |
| 153 | + <Self as SingleAttributeParser<S>>::TEMPLATE |
| 154 | + .suggestions(AttrStyle::Inner, "macro_export") |
| 155 | + }; |
| 156 | + let local_inner_macros = match args { |
| 157 | + ArgParser::NoArgs => false, |
| 158 | + ArgParser::List(list) => { |
| 159 | + let Some(l) = list.single() else { |
| 160 | + let span = cx.attr_span; |
| 161 | + cx.emit_lint( |
| 162 | + AttributeLintKind::InvalidMacroExportArguments { |
| 163 | + suggestions: suggestions(), |
| 164 | + }, |
| 165 | + span, |
| 166 | + ); |
| 167 | + return None; |
| 168 | + }; |
| 169 | + match l.meta_item().and_then(|i| i.path().word_sym()) { |
| 170 | + Some(sym::local_inner_macros) => true, |
| 171 | + _ => { |
| 172 | + let span = cx.attr_span; |
| 173 | + cx.emit_lint( |
| 174 | + AttributeLintKind::InvalidMacroExportArguments { |
| 175 | + suggestions: suggestions(), |
| 176 | + }, |
| 177 | + span, |
| 178 | + ); |
| 179 | + return None; |
| 180 | + } |
| 181 | + } |
| 182 | + } |
| 183 | + ArgParser::NameValue(_) => { |
| 184 | + let span = cx.attr_span; |
| 185 | + let suggestions = suggestions(); |
| 186 | + cx.emit_err(IllFormedAttributeInputLint { |
| 187 | + num_suggestions: suggestions.len(), |
| 188 | + suggestions: DiagArgValue::StrListSepByAnd( |
| 189 | + suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), |
| 190 | + ), |
| 191 | + span, |
| 192 | + }); |
| 193 | + return None; |
| 194 | + } |
| 195 | + }; |
| 196 | + Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros }) |
| 197 | + } |
| 198 | +} |
0 commit comments