Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ pub trait MacResult {
None
}

fn make_method_receiver_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
self.make_expr()
}

/// Creates zero or more items.
fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
None
Expand Down
109 changes: 56 additions & 53 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,11 @@ macro_rules! ast_fragments {
$($Kind:ident($AstTy:ty) {
$kind_name:expr;
$(one
fn $mut_visit_ast:ident;
fn $visit_ast:ident;
fn $ast_to_string:path;
)?
$(many
fn $flat_map_ast_elt:ident;
fn $visit_ast_elt:ident($($args:tt)*);
fn $ast_to_string_elt:path;
)?
fn $make_ast:ident;
})*
Expand All @@ -71,23 +68,20 @@ macro_rules! ast_fragments {
/// Can also serve as an input and intermediate result for macro expansion operations.
pub enum AstFragment {
OptExpr(Option<Box<ast::Expr>>),
MethodReceiverExpr(Box<ast::Expr>),
$($Kind($AstTy),)*
}

/// "Discriminant" of an AST fragment.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum AstFragmentKind {
OptExpr,
MethodReceiverExpr,
$($Kind,)*
}

impl AstFragmentKind {
pub fn name(self) -> &'static str {
match self {
AstFragmentKind::OptExpr => "expression",
AstFragmentKind::MethodReceiverExpr => "expression",
$(AstFragmentKind::$Kind => $kind_name,)*
}
}
Expand All @@ -96,8 +90,6 @@ macro_rules! ast_fragments {
match self {
AstFragmentKind::OptExpr =>
result.make_expr().map(Some).map(AstFragment::OptExpr),
AstFragmentKind::MethodReceiverExpr =>
result.make_expr().map(AstFragment::MethodReceiverExpr),
$(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)*
}
}
Expand All @@ -120,21 +112,14 @@ macro_rules! ast_fragments {
pub(crate) fn make_opt_expr(self) -> Option<Box<ast::Expr>> {
match self {
AstFragment::OptExpr(expr) => expr,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
}
}

pub(crate) fn make_method_receiver_expr(self) -> Box<ast::Expr> {
match self {
AstFragment::MethodReceiverExpr(expr) => expr,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
_ => panic!("AstFragment::make_opt_expr called on the wrong kind of fragment"),
}
}

$(pub fn $make_ast(self) -> $AstTy {
match self {
AstFragment::$Kind(ast) => ast,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
_ => panic!("AstFragment::{} called on the wrong kind of fragment", stringify!($make_ast)),
}
})*

Expand All @@ -149,8 +134,7 @@ macro_rules! ast_fragments {
*opt_expr = vis.filter_map_expr(expr)
}
}
AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr),
$($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)*
$($(AstFragment::$Kind(ast) => vis.$visit_ast(ast),)?)*
$($(AstFragment::$Kind(ast) =>
ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast, $($args)*)),)?)*
}
Expand All @@ -160,27 +144,11 @@ macro_rules! ast_fragments {
match self {
AstFragment::OptExpr(Some(expr)) => try_visit!(visitor.visit_expr(expr)),
AstFragment::OptExpr(None) => {}
AstFragment::MethodReceiverExpr(expr) => try_visit!(visitor.visit_method_receiver_expr(expr)),
$($(AstFragment::$Kind(ast) => try_visit!(visitor.$visit_ast(ast)),)?)*
$($(AstFragment::$Kind(ast) => walk_list!(visitor, $visit_ast_elt, &ast[..], $($args)*),)?)*
}
V::Result::output()
}

pub(crate) fn to_string(&self) -> String {
match self {
AstFragment::OptExpr(Some(expr)) => pprust::expr_to_string(expr),
AstFragment::OptExpr(None) => unreachable!(),
AstFragment::MethodReceiverExpr(expr) => pprust::expr_to_string(expr),
$($(AstFragment::$Kind(ast) => $ast_to_string(ast),)?)*
$($(
AstFragment::$Kind(ast) => {
// The closure unwraps a `P` if present, or does nothing otherwise.
elems_to_string(&*ast, |ast| $ast_to_string_elt(&*ast))
}
)?)*
}
}
}

impl<'a, 'b> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a, 'b> {
Expand All @@ -195,98 +163,133 @@ macro_rules! ast_fragments {
ast_fragments! {
Expr(Box<ast::Expr>) {
"expression";
one fn visit_expr; fn visit_expr; fn pprust::expr_to_string;
one fn visit_expr;
fn make_expr;
}
MethodReceiverExpr(Box<ast::Expr>) {
"expression";
one fn visit_method_receiver_expr;
fn make_method_receiver_expr;
}
Pat(Box<ast::Pat>) {
"pattern";
one fn visit_pat; fn visit_pat; fn pprust::pat_to_string;
one fn visit_pat;
fn make_pat;
}
Ty(Box<ast::Ty>) {
"type";
one fn visit_ty; fn visit_ty; fn pprust::ty_to_string;
one fn visit_ty;
fn make_ty;
}
Stmts(SmallVec<[ast::Stmt; 1]>) {
"statement";
many fn flat_map_stmt; fn visit_stmt(); fn pprust::stmt_to_string;
many fn flat_map_stmt; fn visit_stmt();
fn make_stmts;
}
Items(SmallVec<[Box<ast::Item>; 1]>) {
"item";
many fn flat_map_item; fn visit_item(); fn pprust::item_to_string;
many fn flat_map_item; fn visit_item();
fn make_items;
}
TraitItems(SmallVec<[Box<ast::AssocItem>; 1]>) {
"trait item";
many fn flat_map_assoc_item; fn visit_assoc_item(AssocCtxt::Trait);
fn pprust::assoc_item_to_string;
fn make_trait_items;
}
ImplItems(SmallVec<[Box<ast::AssocItem>; 1]>) {
"impl item";
many fn flat_map_assoc_item; fn visit_assoc_item(AssocCtxt::Impl { of_trait: false });
fn pprust::assoc_item_to_string;
fn make_impl_items;
}
TraitImplItems(SmallVec<[Box<ast::AssocItem>; 1]>) {
"impl item";
many fn flat_map_assoc_item; fn visit_assoc_item(AssocCtxt::Impl { of_trait: true });
fn pprust::assoc_item_to_string;
fn make_trait_impl_items;
}
ForeignItems(SmallVec<[Box<ast::ForeignItem>; 1]>) {
"foreign item";
many fn flat_map_foreign_item; fn visit_foreign_item(); fn pprust::foreign_item_to_string;
many fn flat_map_foreign_item; fn visit_foreign_item();
fn make_foreign_items;
}
Arms(SmallVec<[ast::Arm; 1]>) {
"match arm";
many fn flat_map_arm; fn visit_arm(); fn unreachable_to_string;
many fn flat_map_arm; fn visit_arm();
fn make_arms;
}
ExprFields(SmallVec<[ast::ExprField; 1]>) {
"field expression";
many fn flat_map_expr_field; fn visit_expr_field(); fn unreachable_to_string;
many fn flat_map_expr_field; fn visit_expr_field();
fn make_expr_fields;
}
PatFields(SmallVec<[ast::PatField; 1]>) {
"field pattern";
many fn flat_map_pat_field; fn visit_pat_field(); fn unreachable_to_string;
many fn flat_map_pat_field; fn visit_pat_field();
fn make_pat_fields;
}
GenericParams(SmallVec<[ast::GenericParam; 1]>) {
"generic parameter";
many fn flat_map_generic_param; fn visit_generic_param(); fn unreachable_to_string;
many fn flat_map_generic_param; fn visit_generic_param();
fn make_generic_params;
}
Params(SmallVec<[ast::Param; 1]>) {
"function parameter";
many fn flat_map_param; fn visit_param(); fn unreachable_to_string;
many fn flat_map_param; fn visit_param();
fn make_params;
}
FieldDefs(SmallVec<[ast::FieldDef; 1]>) {
"field";
many fn flat_map_field_def; fn visit_field_def(); fn unreachable_to_string;
many fn flat_map_field_def; fn visit_field_def();
fn make_field_defs;
}
Variants(SmallVec<[ast::Variant; 1]>) {
"variant"; many fn flat_map_variant; fn visit_variant(); fn unreachable_to_string;
"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 unreachable_to_string;
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 unreachable_to_string;
one fn visit_crate;
fn make_crate;
}
}

impl AstFragment {
pub(crate) fn to_string(&self) -> String {
match self {
AstFragment::OptExpr(Some(expr))
| AstFragment::MethodReceiverExpr(expr)
| AstFragment::Expr(expr) => pprust::expr_to_string(expr),
AstFragment::Pat(ast) => pprust::pat_to_string(ast),
AstFragment::Ty(ast) => pprust::ty_to_string(ast),
AstFragment::Stmts(ast) => elems_to_string(ast, pprust::stmt_to_string),
AstFragment::Items(ast) => elems_to_string(ast, |ast| pprust::item_to_string(ast)),
AstFragment::TraitItems(ast)
| AstFragment::ImplItems(ast)
| AstFragment::TraitImplItems(ast) => {
elems_to_string(ast, |ast| pprust::assoc_item_to_string(ast))
}
AstFragment::ForeignItems(ast) => {
elems_to_string(ast, |ast| pprust::foreign_item_to_string(ast))
}
AstFragment::OptExpr(None)
| AstFragment::Crate(_)
| AstFragment::Arms(_)
| AstFragment::ExprFields(_)
| AstFragment::PatFields(_)
| AstFragment::GenericParams(_)
| AstFragment::Params(_)
| AstFragment::FieldDefs(_)
| AstFragment::Variants(_)
| AstFragment::WherePredicates(_) => unreachable!(),
Comment thread
petrochenkov marked this conversation as resolved.
Outdated
}
}
}

pub enum SupportsMacroExpansion {
No,
Yes { supports_inner_attrs: bool },
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_expand/src/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ pub(crate) fn elems_to_string<T>(elems: &SmallVec<[T; 1]>, f: impl Fn(&T) -> Str
s
}

pub(crate) fn unreachable_to_string<T>(_: &T) -> String {
unreachable!()
}

pub(crate) fn update_bang_macro_stats(
ecx: &mut ExtCtxt<'_>,
fragment_kind: AstFragmentKind,
Expand Down
Loading