about summary refs log tree commit diff
path: root/src/librustc_ast/ast.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_ast/ast.rs')
-rw-r--r--src/librustc_ast/ast.rs299
1 files changed, 145 insertions, 154 deletions
diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs
index 88564647d61..6586280d214 100644
--- a/src/librustc_ast/ast.rs
+++ b/src/librustc_ast/ast.rs
@@ -14,7 +14,7 @@
 //! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters.
 //! - [`EnumDef`] and [`Variant`]: Enum declaration.
 //! - [`Lit`] and [`LitKind`]: Literal expressions.
-//! - [`MacroDef`], [`MacStmtStyle`], [`Mac`], [`MacDelimeter`]: Macro definition and invocation.
+//! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`], [`MacDelimeter`]: Macro definition and invocation.
 //! - [`Attribute`]: Metadata associated with item.
 //! - [`UnOp`], [`UnOpKind`], [`BinOp`], [`BinOpKind`]: Unary and binary operators.
 
@@ -31,13 +31,13 @@ use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::thin_vec::ThinVec;
-use rustc_index::vec::Idx;
 use rustc_macros::HashStable_Generic;
 use rustc_serialize::{self, Decoder, Encoder};
 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;
 
@@ -214,11 +214,18 @@ impl GenericArg {
 pub struct AngleBracketedArgs {
     /// The overall span.
     pub span: Span,
-    /// The arguments for this path segment.
-    pub args: Vec<GenericArg>,
-    /// Constraints on associated types, if any.
-    /// E.g., `Foo<A = Bar, B: Baz>`.
-    pub constraints: Vec<AssocTyConstraint>,
+    /// The comma separated parts in the `<...>`.
+    pub args: Vec<AngleBracketedArg>,
+}
+
+/// Either an argument for a parameter e.g., `'a`, `Vec<u8>`, `0`,
+/// or a constraint on an associated item, e.g., `Item = String` or `Item: Bound`.
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+pub enum AngleBracketedArg {
+    /// Argument for a generic parameter.
+    Arg(GenericArg),
+    /// Constraint for an associated item.
+    Constraint(AssocTyConstraint),
 }
 
 impl Into<Option<P<GenericArgs>>> for AngleBracketedArgs {
@@ -248,11 +255,13 @@ pub struct ParenthesizedArgs {
 
 impl ParenthesizedArgs {
     pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
-        AngleBracketedArgs {
-            span: self.span,
-            args: self.inputs.iter().cloned().map(|input| GenericArg::Type(input)).collect(),
-            constraints: vec![],
-        }
+        let args = self
+            .inputs
+            .iter()
+            .cloned()
+            .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
+            .collect();
+        AngleBracketedArgs { span: self.span, args }
     }
 }
 
@@ -512,7 +521,7 @@ impl Pat {
                 TyKind::Path(None, Path::from_ident(*ident))
             }
             PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
-            PatKind::Mac(mac) => TyKind::Mac(mac.clone()),
+            PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
             // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
             PatKind::Ref(pat, mutbl) => {
                 pat.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?
@@ -566,7 +575,7 @@ impl Pat {
             | PatKind::Range(..)
             | PatKind::Ident(..)
             | PatKind::Path(..)
-            | PatKind::Mac(_) => {}
+            | PatKind::MacCall(_) => {}
         }
     }
 
@@ -681,22 +690,11 @@ pub enum PatKind {
     Paren(P<Pat>),
 
     /// A macro pattern; pre-expansion.
-    Mac(Mac),
+    MacCall(MacCall),
 }
 
-#[derive(
-    Clone,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    Debug,
-    Copy,
-    HashStable_Generic
-)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(HashStable_Generic)]
 pub enum Mutability {
     Mut,
     Not,
@@ -880,9 +878,9 @@ impl Stmt {
     pub fn add_trailing_semicolon(mut self) -> Self {
         self.kind = match self.kind {
             StmtKind::Expr(expr) => StmtKind::Semi(expr),
-            StmtKind::Mac(mac) => {
-                StmtKind::Mac(mac.map(|(mac, _style, attrs)| (mac, MacStmtStyle::Semicolon, attrs)))
-            }
+            StmtKind::MacCall(mac) => StmtKind::MacCall(
+                mac.map(|(mac, _style, attrs)| (mac, MacStmtStyle::Semicolon, attrs)),
+            ),
             kind => kind,
         };
         self
@@ -916,7 +914,7 @@ pub enum StmtKind {
     /// Just a trailing semi-colon.
     Empty,
     /// Macro.
-    Mac(P<(Mac, MacStmtStyle, AttrVec)>),
+    MacCall(P<(MacCall, MacStmtStyle, AttrVec)>),
 }
 
 #[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
@@ -1056,7 +1054,7 @@ impl Expr {
         let kind = match &self.kind {
             // Trivial conversions.
             ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
-            ExprKind::Mac(mac) => TyKind::Mac(mac.clone()),
+            ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
 
             ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
 
@@ -1077,7 +1075,7 @@ impl Expr {
 
             // If binary operator is `Add` and both `lhs` and `rhs` are trait bounds,
             // then type of result is trait object.
-            // Othewise we don't assume the result type.
+            // Otherwise we don't assume the result type.
             ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
                 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
                     TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
@@ -1125,8 +1123,8 @@ impl Expr {
             ExprKind::Break(..) => ExprPrecedence::Break,
             ExprKind::Continue(..) => ExprPrecedence::Continue,
             ExprKind::Ret(..) => ExprPrecedence::Ret,
-            ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
-            ExprKind::Mac(..) => ExprPrecedence::Mac,
+            ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
+            ExprKind::MacCall(..) => ExprPrecedence::Mac,
             ExprKind::Struct(..) => ExprPrecedence::Struct,
             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
             ExprKind::Paren(..) => ExprPrecedence::Paren,
@@ -1254,11 +1252,11 @@ pub enum ExprKind {
     /// A `return`, with an optional value to be returned.
     Ret(Option<P<Expr>>),
 
-    /// Output of the `asm!()` macro.
-    InlineAsm(P<InlineAsm>),
+    /// Output of the `llvm_asm!()` macro.
+    LlvmInlineAsm(P<LlvmInlineAsm>),
 
     /// A macro invocation; pre-expansion.
-    Mac(Mac),
+    MacCall(MacCall),
 
     /// A struct literal expression.
     ///
@@ -1321,19 +1319,8 @@ pub enum CaptureBy {
 
 /// The movability of a generator / closure literal:
 /// whether a generator contains self-references, causing it to be `!Unpin`.
-#[derive(
-    Clone,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    Debug,
-    Copy,
-    HashStable_Generic
-)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(HashStable_Generic)]
 pub enum Movability {
     /// May contain self-references, `!Unpin`.
     Static,
@@ -1344,13 +1331,13 @@ pub enum Movability {
 /// Represents a macro invocation. The `path` indicates which macro
 /// is being invoked, and the `args` are arguments passed to it.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct Mac {
+pub struct MacCall {
     pub path: Path,
     pub args: P<MacArgs>,
     pub prior_type_ascription: Option<(Span, bool)>,
 }
 
-impl Mac {
+impl MacCall {
     pub fn span(&self) -> Span {
         self.path.span.to(self.args.span().unwrap_or(self.path.span))
     }
@@ -1445,11 +1432,11 @@ impl MacDelimiter {
 }
 
 /// Represents a macro definition.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub struct MacroDef {
     pub body: P<MacArgs>,
     /// `true` if macro was defined with `macro_rules`.
-    pub legacy: bool,
+    pub macro_rules: bool,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, Eq, PartialEq)]
@@ -1614,19 +1601,8 @@ pub struct FnSig {
     pub decl: P<FnDecl>,
 }
 
-#[derive(
-    Clone,
-    Copy,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    HashStable_Generic,
-    RustcEncodable,
-    RustcDecodable,
-    Debug
-)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(HashStable_Generic)]
 pub enum FloatTy {
     F32,
     F64,
@@ -1647,7 +1623,7 @@ impl FloatTy {
         }
     }
 
-    pub fn bit_width(self) -> usize {
+    pub fn bit_width(self) -> u64 {
         match self {
             FloatTy::F32 => 32,
             FloatTy::F64 => 64,
@@ -1655,19 +1631,8 @@ impl FloatTy {
     }
 }
 
-#[derive(
-    Clone,
-    Copy,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    HashStable_Generic,
-    RustcEncodable,
-    RustcDecodable,
-    Debug
-)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(HashStable_Generic)]
 pub enum IntTy {
     Isize,
     I8,
@@ -1707,7 +1672,7 @@ impl IntTy {
         format!("{}{}", val as u128, self.name_str())
     }
 
-    pub fn bit_width(&self) -> Option<usize> {
+    pub fn bit_width(&self) -> Option<u64> {
         Some(match *self {
             IntTy::Isize => return None,
             IntTy::I8 => 8,
@@ -1731,19 +1696,8 @@ impl IntTy {
     }
 }
 
-#[derive(
-    Clone,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    HashStable_Generic,
-    RustcEncodable,
-    RustcDecodable,
-    Copy,
-    Debug
-)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy, Debug)]
+#[derive(HashStable_Generic)]
 pub enum UintTy {
     Usize,
     U8,
@@ -1780,7 +1734,7 @@ impl UintTy {
         format!("{}{}", val, self.name_str())
     }
 
-    pub fn bit_width(&self) -> Option<usize> {
+    pub fn bit_width(&self) -> Option<u64> {
         Some(match *self {
             UintTy::Usize => return None,
             UintTy::U8 => 8,
@@ -1880,7 +1834,7 @@ pub enum TyKind {
     /// Inferred type of a `self` or `&self` argument in a method.
     ImplicitSelf,
     /// A macro in the type position.
-    Mac(Mac),
+    MacCall(MacCall),
     /// Placeholder for a kind that has failed to be defined.
     Err,
     /// Placeholder for a `va_list`.
@@ -1915,37 +1869,37 @@ pub enum TraitObjectSyntax {
 
 /// Inline assembly dialect.
 ///
-/// E.g., `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
+/// E.g., `"intel"` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)]
-pub enum AsmDialect {
+pub enum LlvmAsmDialect {
     Att,
     Intel,
 }
 
-/// Inline assembly.
+/// LLVM-style inline assembly.
 ///
-/// E.g., `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
+/// E.g., `"={eax}"(result)` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct InlineAsmOutput {
+pub struct LlvmInlineAsmOutput {
     pub constraint: Symbol,
     pub expr: P<Expr>,
     pub is_rw: bool,
     pub is_indirect: bool,
 }
 
-/// Inline assembly.
+/// LLVM-style inline assembly.
 ///
-/// E.g., `asm!("NOP");`.
+/// E.g., `llvm_asm!("NOP");`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct InlineAsm {
+pub struct LlvmInlineAsm {
     pub asm: Symbol,
     pub asm_str_style: StrStyle,
-    pub outputs: Vec<InlineAsmOutput>,
+    pub outputs: Vec<LlvmInlineAsmOutput>,
     pub inputs: Vec<(Symbol, P<Expr>)>,
     pub clobbers: Vec<Symbol>,
     pub volatile: bool,
     pub alignstack: bool,
-    pub dialect: AsmDialect,
+    pub dialect: LlvmAsmDialect,
 }
 
 /// A parameter in a function header.
@@ -2088,7 +2042,7 @@ impl Async {
         if let Async::Yes { .. } = self { true } else { false }
     }
 
-    /// In ths case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
+    /// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
     pub fn opt_return_id(self) -> Option<NodeId> {
         match self {
             Async::Yes { return_impl_trait_id, .. } => Some(return_impl_trait_id),
@@ -2117,14 +2071,14 @@ pub enum ImplPolarity {
     /// `impl Trait for Type`
     Positive,
     /// `impl !Trait for Type`
-    Negative,
+    Negative(Span),
 }
 
 impl fmt::Debug for ImplPolarity {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             ImplPolarity::Positive => "positive".fmt(f),
-            ImplPolarity::Negative => "negative".fmt(f),
+            ImplPolarity::Negative(_) => "negative".fmt(f),
         }
     }
 }
@@ -2152,7 +2106,7 @@ impl FnRetTy {
 /// Module declaration.
 ///
 /// E.g., `mod foo;` or `mod foo { .. }`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
 pub struct Mod {
     /// A span from the first token past `{` to the last token until `}`.
     /// For `mod foo;`, the inner span ranges from the first token
@@ -2250,27 +2204,22 @@ pub enum AttrStyle {
     Inner,
 }
 
-#[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, Copy)]
-pub struct AttrId(pub usize);
-
-impl Idx for AttrId {
-    fn new(idx: usize) -> Self {
-        AttrId(idx)
-    }
-    fn index(self) -> usize {
-        self.0
+rustc_index::newtype_index! {
+    pub struct AttrId {
+        ENCODABLE = custom
+        DEBUG_FORMAT = "AttrId({})"
     }
 }
 
 impl rustc_serialize::Encodable for AttrId {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_unit()
+    fn encode<S: Encoder>(&self, _: &mut S) -> Result<(), S::Error> {
+        Ok(())
     }
 }
 
 impl rustc_serialize::Decodable for AttrId {
-    fn decode<D: Decoder>(d: &mut D) -> Result<AttrId, D::Error> {
-        d.read_nil().map(|_| crate::attr::mk_attr_id())
+    fn decode<D: Decoder>(_: &mut D) -> Result<AttrId, D::Error> {
+        Ok(crate::attr::mk_attr_id())
     }
 }
 
@@ -2443,10 +2392,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 }
     }
 }
 
@@ -2573,7 +2522,7 @@ pub enum ItemKind {
     /// A macro invocation.
     ///
     /// E.g., `foo!(..)`.
-    Mac(Mac),
+    MacCall(MacCall),
 
     /// A macro definition.
     MacroDef(MacroDef),
@@ -2585,7 +2534,7 @@ impl ItemKind {
         match self {
             Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
             | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..) => "a",
-            ExternCrate(..) | ForeignMod(..) | Mac(..) | Enum(..) | Impl { .. } => "an",
+            ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
         }
     }
 
@@ -2605,7 +2554,7 @@ impl ItemKind {
             ItemKind::Union(..) => "union",
             ItemKind::Trait(..) => "trait",
             ItemKind::TraitAlias(..) => "trait alias",
-            ItemKind::Mac(..) => "item macro invocation",
+            ItemKind::MacCall(..) => "item macro invocation",
             ItemKind::MacroDef(..) => "macro definition",
             ItemKind::Impl { .. } => "implementation",
         }
@@ -2626,20 +2575,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.
@@ -2648,36 +2588,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.
-    Macro(Mac),
+    /// A macro expanding to associated items.
+    MacCall(MacCall),
 }
 
 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::MacCall(..) => 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),
+            AssocItemKind::MacCall(a) => ItemKind::MacCall(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::MacCall(a) => AssocItemKind::MacCall(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.
+    MacCall(MacCall),
+}
+
+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::MacCall(a) => ItemKind::MacCall(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::MacCall(a) => ForeignItemKind::MacCall(a),
+            _ => return Err(item_kind),
+        })
+    }
+}
+
+pub type ForeignItem = Item<ForeignItemKind>;