Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ast: Unmerge structures for associated items and foreign items #69586

Merged
merged 2 commits into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
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 @@ -2441,10 +2442,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 @@ -2624,20 +2625,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 @@ -2646,36 +2638,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 @@ -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
}
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