use crate::mbe::macro_rules::annotate_err_with_kind;
use crate::placeholders::{placeholder, PlaceholderExpander};
use crate::config::StripUnconfigured;
-use rustc_parse::configure;
+use rustc_feature::Features;
+use rustc_parse::configure;
use rustc_parse::DirectoryOwnership;
use rustc_parse::parser::Parser;
use rustc_parse::validate_attr;
use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path};
use syntax::ast::{MacStmtStyle, StmtKind, ItemKind};
-use syntax::attr::{self, HasAttrs};
+use syntax::attr::{self, HasAttrs, is_builtin_attr};
use syntax::source_map::respan;
-use syntax::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
+use syntax::feature_gate::{self, feature_err};
use syntax::mut_visit::*;
use syntax::print::pprust;
use syntax::ptr::P;
// mention some macro variable from those arguments even if it's not used.
#[cfg_attr(bootstrap, allow(unused_macros))]
macro _repeating($flat_map_ast_elt) {}
- placeholder(AstFragmentKind::$Kind, *id).$make_ast()
+ placeholder(AstFragmentKind::$Kind, *id, None).$make_ast()
})),)?)*
_ => panic!("unexpected AST fragment kind")
}
},
}
+impl InvocationKind {
+ fn placeholder_visibility(&self) -> Option<ast::Visibility> {
+ // HACK: For unnamed fields placeholders should have the same visibility as the actual
+ // fields because for tuple structs/variants resolve determines visibilities of their
+ // constructor using these field visibilities before attributes on them are are expanded.
+ // The assumption is that the attribute expansion cannot change field visibilities,
+ // and it holds because only inert attributes are supported in this position.
+ match self {
+ InvocationKind::Attr { item: Annotatable::StructField(field), .. } |
+ InvocationKind::Derive { item: Annotatable::StructField(field), .. } |
+ InvocationKind::DeriveContainer { item: Annotatable::StructField(field), .. }
+ if field.ident.is_none() => Some(field.vis.clone()),
+ _ => None,
+ }
+ }
+}
+
impl Invocation {
pub fn span(&self) -> Span {
match &self.kind {
if self.cx.ecfg.proc_macro_hygiene() {
return
}
- emit_feature_err(
+ feature_err(
self.cx.parse_sess,
sym::proc_macro_hygiene,
span,
- GateIssue::Language,
&format!("custom attributes cannot be applied to {}", kind),
- );
+ )
+ .emit();
}
fn gate_proc_macro_input(&self, annotatable: &Annotatable) {
fn visit_item(&mut self, item: &'ast ast::Item) {
match &item.kind {
ast::ItemKind::Mod(module) if !module.inline => {
- emit_feature_err(
+ feature_err(
self.parse_sess,
sym::proc_macro_hygiene,
item.span,
- GateIssue::Language,
"non-inline modules in proc macro input are unstable",
- );
+ )
+ .emit();
}
_ => {}
}
if self.cx.ecfg.proc_macro_hygiene() {
return
}
- emit_feature_err(
+ feature_err(
self.cx.parse_sess,
sym::proc_macro_hygiene,
span,
- GateIssue::Language,
&format!("procedural macros cannot be expanded to {}", kind),
- );
+ )
+ .emit();
}
fn parse_ast_fragment(
_ => None,
};
let expn_id = ExpnId::fresh(expn_data);
+ let vis = kind.placeholder_visibility();
self.invocations.push(Invocation {
kind,
fragment_kind,
..self.cx.current_expansion.clone()
},
});
- placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id))
+ placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id), vis)
}
fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment {
if let Some(attr) = &attr {
if !self.cx.ecfg.custom_inner_attributes() &&
attr.style == ast::AttrStyle::Inner && !attr.has_name(sym::test) {
- emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes,
- attr.span, GateIssue::Language,
- "non-builtin inner attributes are unstable");
+ feature_err(
+ &self.cx.parse_sess, sym::custom_inner_attributes, attr.span,
+ "non-builtin inner attributes are unstable"
+ )
+ .emit();
}
}
attr