diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-01-30 00:18:54 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-02-05 01:27:09 +0100 |
| commit | b2c6eeb713d4cf9b35b7dda6ff2b0274e7f24684 (patch) | |
| tree | db169a7cc1f065c0b2975a1178d3afdef5a172b4 /src/libsyntax | |
| parent | c0b7b41cff2b40d430befefc8688fb8ad847bcd4 (diff) | |
| download | rust-b2c6eeb713d4cf9b35b7dda6ff2b0274e7f24684.tar.gz rust-b2c6eeb713d4cf9b35b7dda6ff2b0274e7f24684.zip | |
parser: merge `fn` grammars wrt. bodies & headers
also refactor `FnKind` and `visit_assoc_item` visitors
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/mut_visit.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 136 |
3 files changed, 80 insertions, 78 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5a8c9f76ea9..b22406124e0 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2533,6 +2533,17 @@ pub struct FnHeader { pub ext: Extern, } +impl FnHeader { + /// Does this function header have any qualifiers or is it empty? + pub fn has_qualifiers(&self) -> bool { + let Self { unsafety, asyncness, constness, ext } = self; + matches!(unsafety, Unsafety::Unsafe) + || asyncness.node.is_async() + || matches!(constness.node, Constness::Const) + || !matches!(ext, Extern::None) + } +} + impl Default for FnHeader { fn default() -> FnHeader { FnHeader { @@ -2565,7 +2576,7 @@ pub enum ItemKind { /// A function declaration (`fn`). /// /// E.g., `fn foo(bar: usize) -> usize { .. }`. - Fn(FnSig, Generics, P<Block>), + Fn(FnSig, Generics, Option<P<Block>>), /// A module declaration (`mod`). /// /// E.g., `mod foo;` or `mod foo { .. }`. @@ -2667,7 +2678,7 @@ pub type ForeignItem = Item<ForeignItemKind>; #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum ForeignItemKind { /// A foreign function. - Fn(P<FnDecl>, Generics), + Fn(FnSig, Generics, Option<P<Block>>), /// A foreign static item (`static ext: u8`). Static(P<Ty>, Mutability), /// A foreign type. diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 3bcdf8fe286..8517f223f92 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -901,7 +901,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { ItemKind::Fn(sig, generics, body) => { visit_fn_sig(sig, vis); vis.visit_generics(generics); - vis.visit_block(body); + visit_opt(body, |body| vis.visit_block(body)); } ItemKind::Mod(m) => vis.visit_mod(m), ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), @@ -1044,9 +1044,10 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>( visitor.visit_ident(ident); visit_attrs(attrs, visitor); match kind { - ForeignItemKind::Fn(fdec, generics) => { - visitor.visit_fn_decl(fdec); + ForeignItemKind::Fn(sig, generics, body) => { + visit_fn_sig(sig, visitor); visitor.visit_generics(generics); + visit_opt(body, |body| visitor.visit_block(body)); } ForeignItemKind::Static(t, _m) => visitor.visit_ty(t), ForeignItemKind::Ty => {} diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 946a0d29cd3..73e731397c3 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -19,24 +19,47 @@ use crate::tokenstream::{TokenStream, TokenTree}; use rustc_span::Span; +#[derive(Copy, Clone, PartialEq)] +pub enum AssocCtxt { + Trait, + Impl, +} + +#[derive(Copy, Clone, PartialEq)] +pub enum FnCtxt { + Free, + Foreign, + Assoc(AssocCtxt), +} + #[derive(Copy, Clone)] pub enum FnKind<'a> { - /// E.g., `fn foo()` or `extern "Abi" fn foo()`. - ItemFn(Ident, &'a FnHeader, &'a Visibility, &'a Block), - - /// E.g., `fn foo(&self)`. - Method(Ident, &'a FnSig, &'a Visibility, &'a Block), + /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. + Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, Option<&'a Block>), /// E.g., `|x, y| body`. - Closure(&'a Expr), + Closure(&'a FnDecl, &'a Expr), } impl<'a> FnKind<'a> { pub fn header(&self) -> Option<&'a FnHeader> { match *self { - FnKind::ItemFn(_, header, _, _) => Some(header), - FnKind::Method(_, sig, _, _) => Some(&sig.header), - FnKind::Closure(_) => None, + FnKind::Fn(_, _, sig, _, _) => Some(&sig.header), + FnKind::Closure(_, _) => None, + } + } + + pub fn decl(&self) -> &'a FnDecl { + match self { + FnKind::Fn(_, _, sig, _, _) => &sig.decl, + FnKind::Closure(decl, _) => decl, + } + } + + pub fn ctxt(&self) -> Option<FnCtxt> { + match self { + FnKind::Fn(ctxt, ..) => Some(*ctxt), + FnKind::Closure(..) => None, } } } @@ -106,17 +129,11 @@ pub trait Visitor<'ast>: Sized { fn visit_where_predicate(&mut self, p: &'ast WherePredicate) { walk_where_predicate(self, p) } - fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl, s: Span, _: NodeId) { - walk_fn(self, fk, fd, s) - } - fn visit_trait_item(&mut self, i: &'ast AssocItem) { - walk_trait_item(self, i) + fn visit_fn(&mut self, fk: FnKind<'ast>, s: Span, _: NodeId) { + walk_fn(self, fk, s) } - fn visit_impl_item(&mut self, i: &'ast AssocItem) { - walk_impl_item(self, i) - } - fn visit_assoc_item(&mut self, i: &'ast AssocItem) { - walk_assoc_item(self, i) + fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) { + walk_assoc_item(self, i, ctxt) } fn visit_trait_ref(&mut self, t: &'ast TraitRef) { walk_trait_ref(self, t) @@ -287,13 +304,8 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { } ItemKind::Fn(ref sig, ref generics, ref body) => { visitor.visit_generics(generics); - visitor.visit_fn_header(&sig.header); - visitor.visit_fn( - FnKind::ItemFn(item.ident, &sig.header, &item.vis, body), - &sig.decl, - item.span, - item.id, - ) + let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref()); + visitor.visit_fn(kind, item.span, item.id) } ItemKind::Mod(ref module) => visitor.visit_mod(module, item.span, &item.attrs, item.id), ItemKind::ForeignMod(ref foreign_module) => { @@ -321,17 +333,17 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_generics(generics); walk_list!(visitor, visit_trait_ref, of_trait); visitor.visit_ty(self_ty); - walk_list!(visitor, visit_impl_item, items); + walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); } ItemKind::Struct(ref struct_definition, ref generics) | ItemKind::Union(ref struct_definition, ref generics) => { visitor.visit_generics(generics); visitor.visit_variant_data(struct_definition); } - ItemKind::Trait(.., ref generics, ref bounds, ref methods) => { + ItemKind::Trait(.., ref generics, ref bounds, ref items) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds); - walk_list!(visitor, visit_trait_item, methods); + walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); } ItemKind::TraitAlias(ref generics, ref bounds) => { visitor.visit_generics(generics); @@ -512,21 +524,22 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { } } -pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, foreign_item: &'a ForeignItem) { - visitor.visit_vis(&foreign_item.vis); - visitor.visit_ident(foreign_item.ident); +pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignItem) { + visitor.visit_vis(&item.vis); + visitor.visit_ident(item.ident); - match foreign_item.kind { - ForeignItemKind::Fn(ref function_declaration, ref generics) => { - walk_fn_decl(visitor, function_declaration); - visitor.visit_generics(generics) + match item.kind { + ForeignItemKind::Fn(ref sig, ref generics, ref body) => { + visitor.visit_generics(generics); + let kind = FnKind::Fn(FnCtxt::Foreign, item.ident, sig, &item.vis, body.as_deref()); + visitor.visit_fn(kind, item.span, item.id); } ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ), ForeignItemKind::Ty => (), ForeignItemKind::Macro(ref mac) => visitor.visit_mac(mac), } - walk_list!(visitor, visit_attribute, &foreign_item.attrs); + walk_list!(visitor, visit_attribute, &item.attrs); } pub fn walk_global_asm<'a, V: Visitor<'a>>(_: &mut V, _: &'a GlobalAsm) { @@ -594,37 +607,21 @@ pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: & visitor.visit_fn_ret_ty(&function_declaration.output); } -pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl, _span: Span) -where - V: Visitor<'a>, -{ +pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>, _span: Span) { match kind { - FnKind::ItemFn(_, header, _, body) => { - visitor.visit_fn_header(header); - walk_fn_decl(visitor, declaration); - visitor.visit_block(body); - } - FnKind::Method(_, sig, _, body) => { + FnKind::Fn(_, _, sig, _, body) => { visitor.visit_fn_header(&sig.header); - walk_fn_decl(visitor, declaration); - visitor.visit_block(body); + walk_fn_decl(visitor, &sig.decl); + walk_list!(visitor, visit_block, body); } - FnKind::Closure(body) => { - walk_fn_decl(visitor, declaration); + FnKind::Closure(decl, body) => { + walk_fn_decl(visitor, decl); visitor.visit_expr(body); } } } -pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem) { - visitor.visit_assoc_item(item); -} - -pub fn walk_trait_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem) { - visitor.visit_assoc_item(item); -} - -pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem) { +pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, ctxt: AssocCtxt) { visitor.visit_vis(&item.vis); visitor.visit_ident(item.ident); walk_list!(visitor, visit_attribute, &item.attrs); @@ -634,17 +631,9 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem) visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } - AssocItemKind::Fn(ref sig, None) => { - visitor.visit_fn_header(&sig.header); - walk_fn_decl(visitor, &sig.decl); - } - AssocItemKind::Fn(ref sig, Some(ref body)) => { - visitor.visit_fn( - FnKind::Method(item.ident, sig, &item.vis, body), - &sig.decl, - item.span, - item.id, - ); + AssocItemKind::Fn(ref sig, ref body) => { + let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), item.ident, sig, &item.vis, body.as_deref()); + visitor.visit_fn(kind, item.span, item.id); } AssocItemKind::TyAlias(ref bounds, ref ty) => { walk_list!(visitor, visit_param_bound, bounds); @@ -765,8 +754,9 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { visitor.visit_expr(subexpression); walk_list!(visitor, visit_arm, arms); } - ExprKind::Closure(_, _, _, ref function_declaration, ref body, _decl_span) => visitor - .visit_fn(FnKind::Closure(body), function_declaration, expression.span, expression.id), + ExprKind::Closure(_, _, _, ref decl, ref body, _decl_span) => { + visitor.visit_fn(FnKind::Closure(decl, body), expression.span, expression.id) + } ExprKind::Block(ref block, ref opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); |
