Implment #[cfg]
and #[cfg_attr]
in where
clauses
This commit is contained in:
parent
30508faeb3
commit
42f51d4fd4
38 changed files with 3296 additions and 88 deletions
|
@ -53,6 +53,7 @@ pub enum Annotatable {
|
|||
Param(ast::Param),
|
||||
FieldDef(ast::FieldDef),
|
||||
Variant(ast::Variant),
|
||||
WherePredicate(ast::WherePredicate),
|
||||
Crate(ast::Crate),
|
||||
}
|
||||
|
||||
|
@ -71,6 +72,7 @@ impl Annotatable {
|
|||
Annotatable::Param(p) => p.span,
|
||||
Annotatable::FieldDef(sf) => sf.span,
|
||||
Annotatable::Variant(v) => v.span,
|
||||
Annotatable::WherePredicate(wp) => wp.span,
|
||||
Annotatable::Crate(c) => c.spans.inner_span,
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +91,7 @@ impl Annotatable {
|
|||
Annotatable::Param(p) => p.visit_attrs(f),
|
||||
Annotatable::FieldDef(sf) => sf.visit_attrs(f),
|
||||
Annotatable::Variant(v) => v.visit_attrs(f),
|
||||
Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
|
||||
Annotatable::Crate(c) => c.visit_attrs(f),
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +110,7 @@ impl Annotatable {
|
|||
Annotatable::Param(p) => visitor.visit_param(p),
|
||||
Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
|
||||
Annotatable::Variant(v) => visitor.visit_variant(v),
|
||||
Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
|
||||
Annotatable::Crate(c) => visitor.visit_crate(c),
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +132,7 @@ impl Annotatable {
|
|||
| Annotatable::Param(..)
|
||||
| Annotatable::FieldDef(..)
|
||||
| Annotatable::Variant(..)
|
||||
| Annotatable::WherePredicate(..)
|
||||
| Annotatable::Crate(..) => panic!("unexpected annotatable"),
|
||||
}
|
||||
}
|
||||
|
@ -223,6 +228,13 @@ impl Annotatable {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expect_where_predicate(self) -> ast::WherePredicate {
|
||||
match self {
|
||||
Annotatable::WherePredicate(wp) => wp,
|
||||
_ => panic!("expected where predicate"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_crate(self) -> ast::Crate {
|
||||
match self {
|
||||
Annotatable::Crate(krate) => krate,
|
||||
|
@ -446,6 +458,10 @@ pub trait MacResult {
|
|||
None
|
||||
}
|
||||
|
||||
fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
|
||||
// Fn-like macros cannot produce a crate.
|
||||
unreachable!()
|
||||
|
|
|
@ -227,6 +227,12 @@ ast_fragments! {
|
|||
Variants(SmallVec<[ast::Variant; 1]>) {
|
||||
"variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants;
|
||||
}
|
||||
WherePredicates(SmallVec<[ast::WherePredicate; 1]>) {
|
||||
"where predicate";
|
||||
many fn flat_map_where_predicate;
|
||||
fn visit_where_predicate();
|
||||
fn make_where_predicates;
|
||||
}
|
||||
Crate(ast::Crate) { "crate"; one fn visit_crate; fn visit_crate; fn make_crate; }
|
||||
}
|
||||
|
||||
|
@ -259,7 +265,8 @@ impl AstFragmentKind {
|
|||
| AstFragmentKind::GenericParams
|
||||
| AstFragmentKind::Params
|
||||
| AstFragmentKind::FieldDefs
|
||||
| AstFragmentKind::Variants => SupportsMacroExpansion::No,
|
||||
| AstFragmentKind::Variants
|
||||
| AstFragmentKind::WherePredicates => SupportsMacroExpansion::No,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,6 +297,9 @@ impl AstFragmentKind {
|
|||
AstFragmentKind::Variants => {
|
||||
AstFragment::Variants(items.map(Annotatable::expect_variant).collect())
|
||||
}
|
||||
AstFragmentKind::WherePredicates => AstFragment::WherePredicates(
|
||||
items.map(Annotatable::expect_where_predicate).collect(),
|
||||
),
|
||||
AstFragmentKind::Items => {
|
||||
AstFragment::Items(items.map(Annotatable::expect_item).collect())
|
||||
}
|
||||
|
@ -865,7 +875,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
| Annotatable::GenericParam(..)
|
||||
| Annotatable::Param(..)
|
||||
| Annotatable::FieldDef(..)
|
||||
| Annotatable::Variant(..) => panic!("unexpected annotatable"),
|
||||
| Annotatable::Variant(..)
|
||||
| Annotatable::WherePredicate(..) => panic!("unexpected annotatable"),
|
||||
};
|
||||
if self.cx.ecfg.features.proc_macro_hygiene() {
|
||||
return;
|
||||
|
@ -1002,7 +1013,8 @@ pub fn parse_ast_fragment<'a>(
|
|||
| AstFragmentKind::GenericParams
|
||||
| AstFragmentKind::Params
|
||||
| AstFragmentKind::FieldDefs
|
||||
| AstFragmentKind::Variants => panic!("unexpected AST fragment kind"),
|
||||
| AstFragmentKind::Variants
|
||||
| AstFragmentKind::WherePredicates => panic!("unexpected AST fragment kind"),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1414,6 +1426,19 @@ impl InvocationCollectorNode for ast::Variant {
|
|||
}
|
||||
}
|
||||
|
||||
impl InvocationCollectorNode for ast::WherePredicate {
|
||||
const KIND: AstFragmentKind = AstFragmentKind::WherePredicates;
|
||||
fn to_annotatable(self) -> Annotatable {
|
||||
Annotatable::WherePredicate(self)
|
||||
}
|
||||
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
|
||||
fragment.make_where_predicates()
|
||||
}
|
||||
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
|
||||
walk_flat_map_where_predicate(visitor, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl InvocationCollectorNode for ast::FieldDef {
|
||||
const KIND: AstFragmentKind = AstFragmentKind::FieldDefs;
|
||||
fn to_annotatable(self) -> Annotatable {
|
||||
|
@ -2116,6 +2141,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
|||
self.flat_map_node(node)
|
||||
}
|
||||
|
||||
fn flat_map_where_predicate(
|
||||
&mut self,
|
||||
node: ast::WherePredicate,
|
||||
) -> SmallVec<[ast::WherePredicate; 1]> {
|
||||
self.flat_map_node(node)
|
||||
}
|
||||
|
||||
fn flat_map_field_def(&mut self, node: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> {
|
||||
self.flat_map_node(node)
|
||||
}
|
||||
|
|
|
@ -188,6 +188,19 @@ pub(crate) fn placeholder(
|
|||
vis,
|
||||
is_placeholder: true,
|
||||
}]),
|
||||
AstFragmentKind::WherePredicates => {
|
||||
AstFragment::WherePredicates(smallvec![ast::WherePredicate {
|
||||
attrs: Default::default(),
|
||||
id,
|
||||
span,
|
||||
kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
|
||||
bound_generic_params: Default::default(),
|
||||
bounded_ty: ty(),
|
||||
bounds: Default::default(),
|
||||
}),
|
||||
is_placeholder: true,
|
||||
}])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,6 +280,17 @@ impl MutVisitor for PlaceholderExpander {
|
|||
}
|
||||
}
|
||||
|
||||
fn flat_map_where_predicate(
|
||||
&mut self,
|
||||
predicate: ast::WherePredicate,
|
||||
) -> SmallVec<[ast::WherePredicate; 1]> {
|
||||
if predicate.is_placeholder {
|
||||
self.remove(predicate.id).make_where_predicates()
|
||||
} else {
|
||||
walk_flat_map_where_predicate(self, predicate)
|
||||
}
|
||||
}
|
||||
|
||||
fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
|
||||
match item.kind {
|
||||
ast::ItemKind::MacCall(_) => self.remove(item.id).make_items(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue