diff options
| author | bors <bors@rust-lang.org> | 2020-02-24 00:31:01 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-02-24 00:31:01 +0000 |
| commit | 79cd224e758f603898b64308e849fbb9be6e6f4d (patch) | |
| tree | 6baaaa0f7f57a4b5b20013878c06e9087b4ee58c /src/libsyntax | |
| parent | 6d0e58bff88f620c1a4f641a627f046bf4cde4ad (diff) | |
| parent | 1c75f5aaa177734c8dbdab91612a8d59b519bf07 (diff) | |
| download | rust-79cd224e758f603898b64308e849fbb9be6e6f4d.tar.gz rust-79cd224e758f603898b64308e849fbb9be6e6f4d.zip | |
Auto merge of #69366 - Centril:unified-items, r=petrochenkov
parse: unify item parsing & filter illegal item kinds This PR fully unifies item parsing into a single `fn parse_item_common` method which produces `Option<Item>`. The `Item` is then mapped into `ForeignItem` and `AssocItem` as necessary by transforming the `*Kind` and converting contextually bad variants into `None`, thereby filtering them away. The PR does not yet unmerge the definition of `ForeignItemKind` from `AssocItemKind`. I've left that as future work as it didn't feel like this parser-focused PR would be the best one to deal with it. Changes to the AST data structures are instead kept to a reasonable minimum. Based on https://github.com/rust-lang/rust/pull/69361. Fixes https://github.com/rust-lang/rust/issues/48137. RELNOTES: Now, `item` macro fragments can be interpolated into `impl`, `trait`, and `extern` contexts. See `src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items.rs` for the relevant test. r? @petrochenkov cc @estebank
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 70 | ||||
| -rw-r--r-- | src/libsyntax/attr/mod.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/mut_visit.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 16 |
4 files changed, 56 insertions, 49 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 849950e939a..19c705fa997 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2106,7 +2106,7 @@ pub enum Const { /// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532). #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum Defaultness { - Default, + Default(Span), Final, } @@ -2411,15 +2411,15 @@ impl VariantData { } } -/// An item. -/// -/// The name might be a dummy name in case of anonymous items. +/// An item definition. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Item<K = ItemKind> { pub attrs: Vec<Attribute>, pub id: NodeId, pub span: Span, pub vis: Visibility, + /// The name of the item. + /// It might be a dummy name in case of anonymous items. pub ident: Ident, pub kind: K, @@ -2506,11 +2506,11 @@ pub enum ItemKind { /// A constant item (`const`). /// /// E.g., `const FOO: i32 = 42;`. - Const(P<Ty>, Option<P<Expr>>), + Const(Defaultness, P<Ty>, Option<P<Expr>>), /// A function declaration (`fn`). /// /// E.g., `fn foo(bar: usize) -> usize { .. }`. - Fn(FnSig, Generics, Option<P<Block>>), + Fn(Defaultness, FnSig, Generics, Option<P<Block>>), /// A module declaration (`mod`). /// /// E.g., `mod foo;` or `mod foo { .. }`. @@ -2524,7 +2524,7 @@ pub enum ItemKind { /// A type alias (`type`). /// /// E.g., `type Foo = Bar<u8>;`. - TyAlias(Generics, GenericBounds, Option<P<Ty>>), + TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>), /// An enum definition (`enum`). /// /// E.g., `enum Foo<A, B> { C<A>, D<B> }`. @@ -2571,30 +2571,41 @@ pub enum ItemKind { } impl ItemKind { - pub fn descriptive_variant(&self) -> &str { - match *self { + pub fn article(&self) -> &str { + use ItemKind::*; + match self { + Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..) + | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..) => "a", + ExternCrate(..) | ForeignMod(..) | Mac(..) | Enum(..) | Impl { .. } => "an", + } + } + + pub fn descr(&self) -> &str { + match self { ItemKind::ExternCrate(..) => "extern crate", - ItemKind::Use(..) => "use", + ItemKind::Use(..) => "`use` import", ItemKind::Static(..) => "static item", ItemKind::Const(..) => "constant item", ItemKind::Fn(..) => "function", ItemKind::Mod(..) => "module", - ItemKind::ForeignMod(..) => "foreign module", - ItemKind::GlobalAsm(..) => "global asm", + ItemKind::ForeignMod(..) => "extern block", + ItemKind::GlobalAsm(..) => "global asm item", ItemKind::TyAlias(..) => "type alias", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl { .. } => "item", + ItemKind::Mac(..) => "item macro invocation", + ItemKind::MacroDef(..) => "macro definition", + ItemKind::Impl { .. } => "implementation", } } pub fn generics(&self) -> Option<&Generics> { match self { - Self::Fn(_, generics, _) - | Self::TyAlias(generics, ..) + Self::Fn(_, _, generics, _) + | Self::TyAlias(_, generics, ..) | Self::Enum(_, generics) | Self::Struct(_, generics) | Self::Union(_, generics) @@ -2613,19 +2624,7 @@ pub type ForeignItemKind = AssocItemKind; /// Represents associated items. /// These include items in `impl` and `trait` definitions. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub struct AssocItem { - pub attrs: Vec<Attribute>, - pub id: NodeId, - pub span: Span, - pub vis: Visibility, - pub ident: Ident, - - pub defaultness: Defaultness, - pub kind: AssocItemKind, - /// See `Item::tokens` for what this is. - pub tokens: Option<TokenStream>, -} +pub type AssocItem = Item<AssocItemKind>; /// Represents non-free item kinds. /// @@ -2638,13 +2637,22 @@ pub struct AssocItem { pub enum AssocItemKind { /// A constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`. /// If `def` is parsed, then the constant is provided, and otherwise required. - Const(P<Ty>, Option<P<Expr>>), + Const(Defaultness, P<Ty>, Option<P<Expr>>), /// A static item (`static FOO: u8`). Static(P<Ty>, Mutability, Option<P<Expr>>), /// A function. - Fn(FnSig, Generics, Option<P<Block>>), + Fn(Defaultness, FnSig, Generics, Option<P<Block>>), /// A type. - TyAlias(Generics, GenericBounds, Option<P<Ty>>), + TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>), /// A macro expanding to items. Macro(Mac), } + +impl AssocItemKind { + pub fn defaultness(&self) -> Defaultness { + match *self { + Self::Const(def, ..) | Self::Fn(def, ..) | Self::TyAlias(def, ..) => def, + Self::Macro(..) | Self::Static(..) => Defaultness::Final, + } + } +} diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 313f5269235..cd485e71378 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -722,6 +722,6 @@ macro_rules! derive_has_attrs { } derive_has_attrs! { - Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::AssocItem, ast::Arm, + Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::Arm, ast::Field, ast::FieldPat, ast::Variant, ast::Param, GenericParam } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 02f790dfbb4..05bb07cd4b9 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -890,11 +890,11 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { match kind { ItemKind::ExternCrate(_orig_name) => {} ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), - ItemKind::Static(ty, _, expr) | ItemKind::Const(ty, expr) => { + ItemKind::Static(ty, _, expr) | ItemKind::Const(_, ty, expr) => { vis.visit_ty(ty); visit_opt(expr, |expr| vis.visit_expr(expr)); } - ItemKind::Fn(sig, generics, body) => { + ItemKind::Fn(_, sig, generics, body) => { visit_fn_sig(sig, vis); vis.visit_generics(generics); visit_opt(body, |body| vis.visit_block(body)); @@ -902,7 +902,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { ItemKind::Mod(m) => vis.visit_mod(m), ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), ItemKind::GlobalAsm(_ga) => {} - ItemKind::TyAlias(generics, bounds, ty) => { + ItemKind::TyAlias(_, generics, bounds, ty) => { vis.visit_generics(generics); visit_bounds(bounds, vis); visit_opt(ty, |ty| vis.visit_ty(ty)); @@ -948,8 +948,7 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>( mut item: P<AssocItem>, visitor: &mut T, ) -> SmallVec<[P<AssocItem>; 1]> { - let AssocItem { id, ident, vis, defaultness: _, attrs, kind, span, tokens: _ } = - item.deref_mut(); + let Item { id, ident, vis, attrs, kind, span, tokens: _ } = item.deref_mut(); walk_nested_item(visitor, id, span, ident, vis, attrs, kind); smallvec![item] } @@ -968,16 +967,16 @@ pub fn walk_nested_item( visitor.visit_vis(vis); visit_attrs(attrs, visitor); match kind { - AssocItemKind::Const(ty, expr) | AssocItemKind::Static(ty, _, expr) => { + AssocItemKind::Const(_, ty, expr) | AssocItemKind::Static(ty, _, expr) => { visitor.visit_ty(ty); visit_opt(expr, |expr| visitor.visit_expr(expr)); } - AssocItemKind::Fn(sig, generics, body) => { + AssocItemKind::Fn(_, sig, generics, body) => { visitor.visit_generics(generics); visit_fn_sig(sig, visitor); visit_opt(body, |body| visitor.visit_block(body)); } - AssocItemKind::TyAlias(generics, bounds, ty) => { + AssocItemKind::TyAlias(_, generics, bounds, ty) => { visitor.visit_generics(generics); visit_bounds(bounds, visitor); visit_opt(ty, |ty| visitor.visit_ty(ty)); @@ -1049,7 +1048,7 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>( mut item: P<ForeignItem>, visitor: &mut T, ) -> SmallVec<[P<ForeignItem>; 1]> { - let ForeignItem { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut(); + let Item { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut(); walk_nested_item(visitor, id, span, ident, vis, attrs, kind); smallvec![item] } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index bd35918dba7..96149ad7947 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -298,11 +298,11 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { } } ItemKind::Use(ref use_tree) => visitor.visit_use_tree(use_tree, item.id, false), - ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(ref typ, ref expr) => { + ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(_, ref typ, ref expr) => { visitor.visit_ty(typ); walk_list!(visitor, visit_expr, expr); } - ItemKind::Fn(ref sig, ref generics, ref body) => { + ItemKind::Fn(_, ref sig, ref generics, ref body) => { visitor.visit_generics(generics); let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref()); visitor.visit_fn(kind, item.span, item.id) @@ -312,7 +312,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { walk_list!(visitor, visit_foreign_item, &foreign_module.items); } ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga), - ItemKind::TyAlias(ref generics, ref bounds, ref ty) => { + ItemKind::TyAlias(_, ref generics, ref bounds, ref ty) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_ty, ty); @@ -526,7 +526,7 @@ 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, item: &'a ForeignItem) { - let ForeignItem { id, span, ident, vis, attrs, kind, tokens: _ } = item; + let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; walk_nested_item(visitor, *id, *span, *ident, vis, attrs, kind, FnCtxt::Foreign); } @@ -610,7 +610,7 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>, _span: Spa } pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, ctxt: AssocCtxt) { - let AssocItem { id, span, ident, vis, attrs, kind, tokens: _, defaultness: _ } = item; + let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; walk_nested_item(visitor, *id, *span, *ident, vis, attrs, kind, FnCtxt::Assoc(ctxt)); } @@ -628,16 +628,16 @@ fn walk_nested_item<'a, V: Visitor<'a>>( visitor.visit_ident(ident); walk_list!(visitor, visit_attribute, attrs); match kind { - AssocItemKind::Const(ty, expr) | AssocItemKind::Static(ty, _, expr) => { + AssocItemKind::Const(_, ty, expr) | AssocItemKind::Static(ty, _, expr) => { visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } - AssocItemKind::Fn(sig, generics, body) => { + AssocItemKind::Fn(_, sig, generics, body) => { visitor.visit_generics(generics); let kind = FnKind::Fn(ctxt, ident, sig, vis, body.as_deref()); visitor.visit_fn(kind, span, id); } - AssocItemKind::TyAlias(generics, bounds, ty) => { + AssocItemKind::TyAlias(_, generics, bounds, ty) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_ty, ty); |
