From 857e34c7a39f3bdab948888d36c2ee614fc73857 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 29 Feb 2020 15:51:08 +0300 Subject: [PATCH 1/2] ast: Unmerge structures for associated items and foreign items --- src/librustc_ast/ast.rs | 60 +++++++++++++-------- src/librustc_ast/attr/mod.rs | 2 +- src/librustc_ast/mut_visit.rs | 39 ++++++++------ src/librustc_ast/visit.rs | 44 ++++++++------- src/librustc_ast_lowering/item.rs | 20 +++---- src/librustc_ast_passes/ast_validation.rs | 2 +- src/librustc_ast_passes/feature_gate.rs | 2 +- src/librustc_ast_pretty/pprust.rs | 42 ++++++++------- src/librustc_expand/expand.rs | 7 +-- src/librustc_resolve/build_reduced_graph.rs | 5 +- src/librustc_resolve/def_collector.rs | 4 +- src/librustc_resolve/late.rs | 7 ++- src/librustc_save_analysis/dump_visitor.rs | 9 ++-- src/librustc_save_analysis/lib.rs | 3 +- src/librustc_save_analysis/sig.rs | 1 - 15 files changed, 134 insertions(+), 113 deletions(-) diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index 62ff4f5183a70..a0ea09720b45d 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -2441,10 +2441,10 @@ impl Item { } } -impl Item { +impl> Item { pub fn into_item(self) -> Item { let Item { attrs, id, span, vis, ident, kind, tokens } = self; - Item { attrs, id, span, vis, ident, kind: kind.into_item_kind(), tokens } + Item { attrs, id, span, vis, ident, kind: kind.into(), tokens } } } @@ -2624,20 +2624,11 @@ impl ItemKind { } } -pub trait IntoItemKind { - fn into_item_kind(self) -> ItemKind; -} - -// FIXME(Centril): These definitions should be unmerged; -// see https://github.com/rust-lang/rust/pull/69194#discussion_r379899975 -pub type ForeignItem = Item; -pub type ForeignItemKind = AssocItemKind; - /// Represents associated items. /// These include items in `impl` and `trait` definitions. pub type AssocItem = Item; -/// Represents non-free item kinds. +/// Represents associated item kinds. /// /// The term "provided" in the variants below refers to the item having a default /// definition / body. Meanwhile, a "required" item lacks a definition / body. @@ -2646,16 +2637,14 @@ pub type AssocItem = Item; /// means "provided" and conversely `None` means "required". #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum AssocItemKind { - /// A constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`. + /// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`. /// If `def` is parsed, then the constant is provided, and otherwise required. Const(Defaultness, P, Option>), - /// A static item (`static FOO: u8`). - Static(P, Mutability, Option>), - /// A function. + /// An associated function. Fn(Defaultness, FnSig, Generics, Option>), - /// A type. + /// An associated type. TyAlias(Defaultness, Generics, GenericBounds, Option>), - /// A macro expanding to items. + /// A macro expanding to associated items. Macro(Mac), } @@ -2663,19 +2652,44 @@ 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, + Self::Macro(..) => Defaultness::Final, } } } -impl IntoItemKind for AssocItemKind { - fn into_item_kind(self) -> ItemKind { - match self { +impl From for ItemKind { + fn from(assoc_item_kind: AssocItemKind) -> ItemKind { + match assoc_item_kind { AssocItemKind::Const(a, b, c) => ItemKind::Const(a, b, c), - AssocItemKind::Static(a, b, c) => ItemKind::Static(a, b, c), AssocItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d), AssocItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d), AssocItemKind::Macro(a) => ItemKind::Mac(a), } } } + +/// An item in `extern` block. +#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +pub enum ForeignItemKind { + /// A foreign static item (`static FOO: u8`). + Static(P, Mutability, Option>), + /// A foreign function. + Fn(Defaultness, FnSig, Generics, Option>), + /// A foreign type. + TyAlias(Defaultness, Generics, GenericBounds, Option>), + /// A macro expanding to foreign items. + Macro(Mac), +} + +impl From for ItemKind { + fn from(foreign_item_kind: ForeignItemKind) -> ItemKind { + match foreign_item_kind { + ForeignItemKind::Static(a, b, c) => ItemKind::Static(a, b, c), + ForeignItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d), + ForeignItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d), + ForeignItemKind::Macro(a) => ItemKind::Mac(a), + } + } +} + +pub type ForeignItem = Item; diff --git a/src/librustc_ast/attr/mod.rs b/src/librustc_ast/attr/mod.rs index bc5c86b02b3c0..2b50b9465803c 100644 --- a/src/librustc_ast/attr/mod.rs +++ b/src/librustc_ast/attr/mod.rs @@ -722,6 +722,6 @@ macro_rules! derive_has_attrs { } derive_has_attrs! { - Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::Arm, + Item, Expr, Local, ast::AssocItem, ast::ForeignItem, ast::StructField, ast::Arm, ast::Field, ast::FieldPat, ast::Variant, ast::Param, GenericParam } diff --git a/src/librustc_ast/mut_visit.rs b/src/librustc_ast/mut_visit.rs index b3abd4fc755e4..09964dd29c30b 100644 --- a/src/librustc_ast/mut_visit.rs +++ b/src/librustc_ast/mut_visit.rs @@ -936,25 +936,12 @@ pub fn noop_flat_map_assoc_item( visitor: &mut T, ) -> SmallVec<[P; 1]> { let Item { id, ident, vis, attrs, kind, span, tokens: _ } = item.deref_mut(); - walk_nested_item(visitor, id, span, ident, vis, attrs, kind); - smallvec![item] -} - -pub fn walk_nested_item( - visitor: &mut impl MutVisitor, - id: &mut NodeId, - span: &mut Span, - ident: &mut Ident, - vis: &mut Visibility, - attrs: &mut Vec, - kind: &mut AssocItemKind, -) { visitor.visit_id(id); visitor.visit_ident(ident); visitor.visit_vis(vis); visit_attrs(attrs, visitor); match kind { - AssocItemKind::Const(_, ty, expr) | AssocItemKind::Static(ty, _, expr) => { + AssocItemKind::Const(_, ty, expr) => { visitor.visit_ty(ty); visit_opt(expr, |expr| visitor.visit_expr(expr)); } @@ -971,6 +958,7 @@ pub fn walk_nested_item( AssocItemKind::Macro(mac) => visitor.visit_mac(mac), } visitor.visit_span(span); + smallvec![item] } pub fn noop_visit_fn_header(header: &mut FnHeader, vis: &mut T) { @@ -1036,7 +1024,28 @@ pub fn noop_flat_map_foreign_item( visitor: &mut T, ) -> SmallVec<[P; 1]> { let Item { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut(); - walk_nested_item(visitor, id, span, ident, vis, attrs, kind); + visitor.visit_id(id); + visitor.visit_ident(ident); + visitor.visit_vis(vis); + visit_attrs(attrs, visitor); + match kind { + ForeignItemKind::Static(ty, _, expr) => { + visitor.visit_ty(ty); + visit_opt(expr, |expr| visitor.visit_expr(expr)); + } + ForeignItemKind::Fn(_, sig, generics, body) => { + visitor.visit_generics(generics); + visit_fn_sig(sig, visitor); + visit_opt(body, |body| visitor.visit_block(body)); + } + ForeignItemKind::TyAlias(_, generics, bounds, ty) => { + visitor.visit_generics(generics); + visit_bounds(bounds, visitor); + visit_opt(ty, |ty| visitor.visit_ty(ty)); + } + ForeignItemKind::Macro(mac) => visitor.visit_mac(mac), + } + visitor.visit_span(span); smallvec![item] } diff --git a/src/librustc_ast/visit.rs b/src/librustc_ast/visit.rs index 96149ad7947ce..89e917dc53d76 100644 --- a/src/librustc_ast/visit.rs +++ b/src/librustc_ast/visit.rs @@ -526,8 +526,29 @@ 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 Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; - walk_nested_item(visitor, *id, *span, *ident, vis, attrs, kind, FnCtxt::Foreign); + let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = *item; + visitor.visit_vis(vis); + visitor.visit_ident(ident); + walk_list!(visitor, visit_attribute, attrs); + match kind { + ForeignItemKind::Static(ty, _, expr) => { + visitor.visit_ty(ty); + walk_list!(visitor, visit_expr, expr); + } + ForeignItemKind::Fn(_, sig, generics, body) => { + visitor.visit_generics(generics); + let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref()); + visitor.visit_fn(kind, span, id); + } + ForeignItemKind::TyAlias(_, generics, bounds, ty) => { + visitor.visit_generics(generics); + walk_list!(visitor, visit_param_bound, bounds); + walk_list!(visitor, visit_ty, ty); + } + ForeignItemKind::Macro(mac) => { + visitor.visit_mac(mac); + } + } } pub fn walk_global_asm<'a, V: Visitor<'a>>(_: &mut V, _: &'a GlobalAsm) { @@ -610,31 +631,18 @@ 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 Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; - walk_nested_item(visitor, *id, *span, *ident, vis, attrs, kind, FnCtxt::Assoc(ctxt)); -} - -fn walk_nested_item<'a, V: Visitor<'a>>( - visitor: &mut V, - id: NodeId, - span: Span, - ident: Ident, - vis: &'a Visibility, - attrs: &'a [Attribute], - kind: &'a AssocItemKind, - ctxt: FnCtxt, -) { + let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = *item; visitor.visit_vis(vis); visitor.visit_ident(ident); walk_list!(visitor, visit_attribute, attrs); match kind { - AssocItemKind::Const(_, ty, expr) | AssocItemKind::Static(ty, _, expr) => { + AssocItemKind::Const(_, ty, expr) => { visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } AssocItemKind::Fn(_, sig, generics, body) => { visitor.visit_generics(generics); - let kind = FnKind::Fn(ctxt, ident, sig, vis, body.as_deref()); + let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref()); visitor.visit_fn(kind, span, id); } AssocItemKind::TyAlias(_, generics, bounds, ty) => { diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 13148d97a67f3..46aad99f13130 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -675,11 +675,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let ty = self.lower_ty(t, ImplTraitContext::disallowed()); hir::ForeignItemKind::Static(ty, m) } - ForeignItemKind::Const(_, ref t, _) => { - // For recovery purposes. - let ty = self.lower_ty(t, ImplTraitContext::disallowed()); - hir::ForeignItemKind::Static(ty, Mutability::Not) - } ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type, ForeignItemKind::Macro(_) => panic!("macro shouldn't exist here"), }, @@ -757,8 +752,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let trait_item_def_id = self.resolver.definitions().local_def_id(i.id); let (generics, kind) = match i.kind { - AssocItemKind::Static(ref ty, _, ref default) // Let's pretend this is a `const`. - | AssocItemKind::Const(_, ref ty, ref default) => { + AssocItemKind::Const(_, ref ty, ref default) => { let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body)) @@ -800,11 +794,10 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { let (kind, has_default) = match &i.kind { - AssocItemKind::Static(_, _, default) // Let's pretend this is a `const` for recovery. - | AssocItemKind::Const(_, _, default) => { - (hir::AssocItemKind::Const, default.is_some()) + AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()), + AssocItemKind::TyAlias(_, _, _, default) => { + (hir::AssocItemKind::Type, default.is_some()) } - AssocItemKind::TyAlias(_, _, _, default) => (hir::AssocItemKind::Type, default.is_some()), AssocItemKind::Fn(_, sig, _, default) => { (hir::AssocItemKind::Method { has_self: sig.decl.has_self() }, default.is_some()) } @@ -824,7 +817,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let impl_item_def_id = self.resolver.definitions().local_def_id(i.id); let (generics, kind) = match &i.kind { - AssocItemKind::Static(ty, _, expr) | AssocItemKind::Const(_, ty, expr) => { + AssocItemKind::Const(_, ty, expr) => { let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); ( hir::Generics::empty(), @@ -892,8 +885,7 @@ impl<'hir> LoweringContext<'_, 'hir> { vis: self.lower_visibility(&i.vis, Some(i.id)), defaultness: self.lower_defaultness(i.kind.defaultness(), true /* [1] */), kind: match &i.kind { - AssocItemKind::Static(..) // Let's pretend this is a `const` for recovery. - | AssocItemKind::Const(..) => hir::AssocItemKind::Const, + AssocItemKind::Const(..) => hir::AssocItemKind::Const, AssocItemKind::TyAlias(.., ty) => { match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) { None => hir::AssocItemKind::Type, diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 9f04c01bfa8f4..69d5610e01601 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -976,7 +976,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ForeignItemKind::Static(_, _, body) => { self.check_foreign_kind_bodyless(fi.ident, "static", body.as_ref().map(|b| b.span)); } - ForeignItemKind::Const(..) | ForeignItemKind::Macro(..) => {} + ForeignItemKind::Macro(..) => {} } visit::walk_foreign_item(self, fi) diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 05e69d0cfd74e..97c88d4f1d966 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -400,7 +400,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ForeignItemKind::TyAlias(..) => { gate_feature_post!(&self, extern_types, i.span, "extern types are experimental"); } - ast::ForeignItemKind::Macro(..) | ast::ForeignItemKind::Const(..) => {} + ast::ForeignItemKind::Macro(..) => {} } visit::walk_foreign_item(self, i) diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index ea8535eabef3f..16558ccb3c36c 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -971,19 +971,7 @@ impl<'a> State<'a> { } crate fn print_foreign_item(&mut self, item: &ast::ForeignItem) { - let ast::Item { id, span, ident, attrs, kind, vis, tokens: _ } = item; - self.print_nested_item_kind(*id, *span, *ident, attrs, kind, vis); - } - - fn print_nested_item_kind( - &mut self, - id: ast::NodeId, - span: Span, - ident: ast::Ident, - attrs: &[Attribute], - kind: &ast::AssocItemKind, - vis: &ast::Visibility, - ) { + let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; self.ann.pre(self, AnnNode::SubItem(id)); self.hardbreak_if_not_bol(); self.maybe_print_comment(span.lo()); @@ -992,9 +980,6 @@ impl<'a> State<'a> { ast::ForeignItemKind::Fn(def, sig, gen, body) => { self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs); } - ast::ForeignItemKind::Const(def, ty, body) => { - self.print_item_const(ident, None, ty, body.as_deref(), vis, *def); - } ast::ForeignItemKind::Static(ty, mutbl, body) => { let def = ast::Defaultness::Final; self.print_item_const(ident, Some(*mutbl), ty, body.as_deref(), vis, def); @@ -1413,8 +1398,29 @@ impl<'a> State<'a> { } crate fn print_assoc_item(&mut self, item: &ast::AssocItem) { - let ast::Item { id, span, ident, attrs, kind, vis, tokens: _ } = item; - self.print_nested_item_kind(*id, *span, *ident, attrs, kind, vis); + let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; + self.ann.pre(self, AnnNode::SubItem(id)); + self.hardbreak_if_not_bol(); + self.maybe_print_comment(span.lo()); + self.print_outer_attributes(attrs); + match kind { + ast::AssocItemKind::Fn(def, sig, gen, body) => { + self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs); + } + ast::AssocItemKind::Const(def, ty, body) => { + self.print_item_const(ident, None, ty, body.as_deref(), vis, *def); + } + ast::AssocItemKind::TyAlias(def, generics, bounds, ty) => { + self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def); + } + ast::AssocItemKind::Macro(m) => { + self.print_mac(m); + if m.args.need_semicolon() { + self.s.word(";"); + } + } + } + self.ann.post(self, AnnNode::SubItem(id)) } crate fn print_stmt(&mut self, st: &ast::Stmt) { diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index a2c512fda91ba..b16659725db73 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -674,11 +674,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let item_tok = TokenTree::token( token::Interpolated(Lrc::new(match item { Annotatable::Item(item) => token::NtItem(item), - Annotatable::TraitItem(item) - | Annotatable::ImplItem(item) - | Annotatable::ForeignItem(item) => { + Annotatable::TraitItem(item) | Annotatable::ImplItem(item) => { token::NtItem(P(item.and_then(ast::AssocItem::into_item))) } + Annotatable::ForeignItem(item) => { + token::NtItem(P(item.and_then(ast::ForeignItem::into_item))) + } Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()), Annotatable::Expr(expr) => token::NtExpr(expr), Annotatable::Arm(..) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 86816fd9f3a2a..43cfe05ac230e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -826,7 +826,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ForeignItemKind::Fn(..) => { (Res::Def(DefKind::Fn, self.r.definitions.local_def_id(item.id)), ValueNS) } - ForeignItemKind::Static(..) | ForeignItemKind::Const(..) => { + ForeignItemKind::Static(..) => { (Res::Def(DefKind::Static, self.r.definitions.local_def_id(item.id)), ValueNS) } ForeignItemKind::TyAlias(..) => { @@ -1251,8 +1251,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { // Add the item to the trait info. let item_def_id = self.r.definitions.local_def_id(item.id); let (res, ns) = match item.kind { - AssocItemKind::Static(..) // Let's pretend it's a `const` for recovery. - | AssocItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS), + AssocItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS), AssocItemKind::Fn(_, ref sig, _, _) => { if sig.decl.has_self() { self.r.has_self.insert(item_def_id); diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index 2e687c88941fa..0d276e6861452 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -228,9 +228,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { body.as_deref(), ); } - AssocItemKind::Fn(..) | AssocItemKind::Const(..) | AssocItemKind::Static(..) => { - DefPathData::ValueNs(i.ident.name) - } + AssocItemKind::Fn(..) | AssocItemKind::Const(..) => DefPathData::ValueNs(i.ident.name), AssocItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), AssocItemKind::Macro(..) => return self.visit_macro_invoc(i.id), }; diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index e5aa9c7d8962a..a3554ea2ee0a3 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -444,7 +444,7 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { visit::walk_foreign_item(this, foreign_item); }); } - ForeignItemKind::Const(..) | ForeignItemKind::Static(..) => { + ForeignItemKind::Static(..) => { self.with_item_rib(HasGenericParams::No, |this| { visit::walk_foreign_item(this, foreign_item); }); @@ -838,8 +838,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { for item in trait_items { this.with_trait_items(trait_items, |this| { match &item.kind { - AssocItemKind::Static(ty, _, default) - | AssocItemKind::Const(_, ty, default) => { + AssocItemKind::Const(_, ty, default) => { this.visit_ty(ty); // Only impose the restrictions of `ConstRibKind` for an // actual constant expression in a provided default. @@ -1114,7 +1113,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { for item in impl_items { use crate::ResolutionError::*; match &item.kind { - AssocItemKind::Static(..) | AssocItemKind::Const(..) => { + AssocItemKind::Const(..) => { debug!("resolve_implementation AssocItemKind::Const",); // If this is a trait impl, ensure the const // exists in trait diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index e8cd5ea832db0..72c962749c8be 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1004,8 +1004,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { self.process_macro_use(trait_item.span); let vis_span = trait_item.span.shrink_to_lo(); match trait_item.kind { - ast::AssocItemKind::Static(ref ty, _, ref expr) - | ast::AssocItemKind::Const(_, ref ty, ref expr) => { + ast::AssocItemKind::Const(_, ref ty, ref expr) => { self.process_assoc_const( trait_item.id, trait_item.ident, @@ -1075,8 +1074,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { fn process_impl_item(&mut self, impl_item: &'l ast::AssocItem, impl_id: DefId) { self.process_macro_use(impl_item.span); match impl_item.kind { - ast::AssocItemKind::Static(ref ty, _, ref expr) - | ast::AssocItemKind::Const(_, ref ty, ref expr) => { + ast::AssocItemKind::Const(_, ref ty, ref expr) => { self.process_assoc_const( impl_item.id, impl_item.ident, @@ -1537,8 +1535,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { self.visit_ty(&ret_ty); } } - ast::ForeignItemKind::Const(_, ref ty, _) - | ast::ForeignItemKind::Static(ref ty, _, _) => { + ast::ForeignItemKind::Static(ref ty, _, _) => { if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(var_data, DefData, item.span); self.dumper.dump_def(&access, var_data); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index dddee1c99268e..d364c45c40d74 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -151,8 +151,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ForeignItemKind::Const(_, ref ty, _) - | ast::ForeignItemKind::Static(ref ty, _, _) => { + ast::ForeignItemKind::Static(ref ty, _, _) => { filter!(self.span_utils, item.ident.span); let id = id_from_node_id(item.id, self); diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 32da62adc3c02..a295e1637aa4c 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -795,7 +795,6 @@ impl Sig for ast::ForeignItem { Ok(Signature { text: text, defs: defs, refs: vec![] }) } - ast::ForeignItemKind::Const(..) => Err("foreign const"), ast::ForeignItemKind::Macro(..) => Err("macro"), } } From 9c885d40fb2b216dee5ebd42c35929ad8b54bf4a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 29 Feb 2020 18:29:44 +0300 Subject: [PATCH 2/2] ast: Implement `TryFrom` for associated and foreign items --- src/librustc_ast/ast.rs | 29 ++++++++++++++++++++++ src/librustc_parse/parser/item.rs | 40 +++++++++++++++---------------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index a0ea09720b45d..685b21a171724 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -38,6 +38,7 @@ use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use std::convert::TryFrom; use std::fmt; use std::iter; @@ -2668,6 +2669,20 @@ impl From for ItemKind { } } +impl TryFrom for AssocItemKind { + type Error = ItemKind; + + fn try_from(item_kind: ItemKind) -> Result { + Ok(match item_kind { + ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c), + ItemKind::Fn(a, b, c, d) => AssocItemKind::Fn(a, b, c, d), + ItemKind::TyAlias(a, b, c, d) => AssocItemKind::TyAlias(a, b, c, d), + ItemKind::Mac(a) => AssocItemKind::Macro(a), + _ => return Err(item_kind), + }) + } +} + /// An item in `extern` block. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum ForeignItemKind { @@ -2692,4 +2707,18 @@ impl From for ItemKind { } } +impl TryFrom for ForeignItemKind { + type Error = ItemKind; + + fn try_from(item_kind: ItemKind) -> Result { + Ok(match item_kind { + ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c), + ItemKind::Fn(a, b, c, d) => ForeignItemKind::Fn(a, b, c, d), + ItemKind::TyAlias(a, b, c, d) => ForeignItemKind::TyAlias(a, b, c, d), + ItemKind::Mac(a) => ForeignItemKind::Macro(a), + _ => return Err(item_kind), + }) + } +} + pub type ForeignItem = Item; diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index cf07e452acb53..08e74034e86a1 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -24,6 +24,7 @@ use rustc_span::source_map::{self, Span}; use rustc_span::symbol::{kw, sym, Symbol}; use log::debug; +use std::convert::TryFrom; use std::mem; pub(super) type ItemInfo = (Ident, ItemKind); @@ -647,16 +648,16 @@ impl<'a> Parser<'a> { /// Parses associated items. fn parse_assoc_item(&mut self, req_name: ReqName) -> PResult<'a, Option>>> { Ok(self.parse_item_(req_name)?.map(|Item { attrs, id, span, vis, ident, kind, tokens }| { - let kind = match kind { - ItemKind::Mac(a) => AssocItemKind::Macro(a), - ItemKind::Fn(a, b, c, d) => AssocItemKind::Fn(a, b, c, d), - ItemKind::TyAlias(a, b, c, d) => AssocItemKind::TyAlias(a, b, c, d), - ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c), - ItemKind::Static(a, _, b) => { - self.struct_span_err(span, "associated `static` items are not allowed").emit(); - AssocItemKind::Const(Defaultness::Final, a, b) - } - _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"), + let kind = match AssocItemKind::try_from(kind) { + Ok(kind) => kind, + Err(kind) => match kind { + ItemKind::Static(a, _, b) => { + self.struct_span_err(span, "associated `static` items are not allowed") + .emit(); + AssocItemKind::Const(Defaultness::Final, a, b) + } + _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"), + }, }; Some(P(Item { attrs, id, span, vis, ident, kind, tokens })) })) @@ -833,16 +834,15 @@ impl<'a> Parser<'a> { /// Parses a foreign item (one in an `extern { ... }` block). pub fn parse_foreign_item(&mut self) -> PResult<'a, Option>>> { Ok(self.parse_item_(|_| true)?.map(|Item { attrs, id, span, vis, ident, kind, tokens }| { - let kind = match kind { - ItemKind::Mac(a) => ForeignItemKind::Macro(a), - ItemKind::Fn(a, b, c, d) => ForeignItemKind::Fn(a, b, c, d), - ItemKind::TyAlias(a, b, c, d) => ForeignItemKind::TyAlias(a, b, c, d), - ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c), - ItemKind::Const(_, a, b) => { - self.error_on_foreign_const(span, ident); - ForeignItemKind::Static(a, Mutability::Not, b) - } - _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"), + let kind = match ForeignItemKind::try_from(kind) { + Ok(kind) => kind, + Err(kind) => match kind { + ItemKind::Const(_, a, b) => { + self.error_on_foreign_const(span, ident); + ForeignItemKind::Static(a, Mutability::Not, b) + } + _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"), + }, }; Some(P(Item { attrs, id, span, vis, ident, kind, tokens })) }))