Skip to content

Commit

Permalink
Auto merge of #69586 - petrochenkov:unmerge, r=Centril
Browse files Browse the repository at this point in the history
ast: Unmerge structures for associated items and foreign items

Follow-up to #69194.
r? @Centril
  • Loading branch information
bors committed Mar 6, 2020
2 parents b818ccc + 9c885d4 commit 4a1b69d
Show file tree
Hide file tree
Showing 16 changed files with 183 additions and 133 deletions.
89 changes: 66 additions & 23 deletions src/librustc_ast/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -2443,10 +2444,10 @@ impl Item {
}
}

impl<K: IntoItemKind> Item<K> {
impl<K: Into<ItemKind>> Item<K> {
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 }
}
}

Expand Down Expand Up @@ -2626,20 +2627,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<AssocItemKind>;
pub type ForeignItemKind = AssocItemKind;

/// Represents associated items.
/// These include items in `impl` and `trait` definitions.
pub type AssocItem = Item<AssocItemKind>;

/// 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.
Expand All @@ -2648,36 +2640,87 @@ pub type AssocItem = Item<AssocItemKind>;
/// 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<Ty>, Option<P<Expr>>),
/// A static item (`static FOO: u8`).
Static(P<Ty>, Mutability, Option<P<Expr>>),
/// A function.
/// An associated function.
Fn(Defaultness, FnSig, Generics, Option<P<Block>>),
/// A type.
/// An associated type.
TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>),
/// A macro expanding to items.
/// A macro expanding to associated 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,
Self::Macro(..) => Defaultness::Final,
}
}
}

impl IntoItemKind for AssocItemKind {
fn into_item_kind(self) -> ItemKind {
match self {
impl From<AssocItemKind> 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),
}
}
}

impl TryFrom<ItemKind> for AssocItemKind {
type Error = ItemKind;

fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
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 {
/// A foreign static item (`static FOO: u8`).
Static(P<Ty>, Mutability, Option<P<Expr>>),
/// A foreign function.
Fn(Defaultness, FnSig, Generics, Option<P<Block>>),
/// A foreign type.
TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>),
/// A macro expanding to foreign items.
Macro(Mac),
}

impl From<ForeignItemKind> 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),
}
}
}

impl TryFrom<ItemKind> for ForeignItemKind {
type Error = ItemKind;

fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
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<ForeignItemKind>;
2 changes: 1 addition & 1 deletion src/librustc_ast/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,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
}
39 changes: 24 additions & 15 deletions src/librustc_ast/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,25 +936,12 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
visitor: &mut T,
) -> SmallVec<[P<AssocItem>; 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<Attribute>,
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));
}
Expand All @@ -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<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
Expand Down Expand Up @@ -1036,7 +1024,28 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
visitor: &mut T,
) -> SmallVec<[P<ForeignItem>; 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]
}

Expand Down
44 changes: 26 additions & 18 deletions src/librustc_ast/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) => {
Expand Down
20 changes: 6 additions & 14 deletions src/librustc_ast_lowering/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
},
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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())
}
Expand All @@ -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(),
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast_passes/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 4a1b69d

Please sign in to comment.