Include unsafety and abi in bare fn types
diff --git a/src/item.rs b/src/item.rs
index a140f8e..f87c459 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -118,12 +118,6 @@
 }
 
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub enum Unsafety {
-    Unsafe,
-    Normal,
-}
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
 pub enum Constness {
     Const,
     NotConst,
@@ -135,15 +129,12 @@
     Final,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct Abi(pub String);
-
 /// Foreign module declaration.
 ///
 /// E.g. `extern { .. }` or `extern "C" { .. }`
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct ForeignMod {
-    pub abi: Option<Abi>,
+    pub abi: Abi,
     pub items: Vec<ForeignItem>,
 }
 
@@ -248,11 +239,10 @@
     use expr::parsing::{block, expr, pat};
     use generics::parsing::{generics, lifetime, ty_param_bound, where_clause};
     use ident::parsing::ident;
-    use lit::parsing::quoted_string;
     use mac::parsing::delimited;
     use macro_input::{Body, MacroInput};
     use macro_input::parsing::macro_input;
-    use ty::parsing::{mutability, path, ty};
+    use ty::parsing::{abi, mutability, path, ty, unsafety};
 
     named!(pub item -> Item, alt!(
         item_extern_crate
@@ -445,7 +435,7 @@
         vis: visibility >>
         constness: constness >>
         unsafety: unsafety >>
-        abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
+        abi: option!(abi) >>
         keyword!("fn") >>
         name: ident >>
         generics: generics >>
@@ -466,7 +456,7 @@
                 }),
                 unsafety,
                 constness,
-                abi.map(Abi),
+                abi,
                 Generics {
                     where_clause: where_clause,
                     .. generics
@@ -542,8 +532,7 @@
 
     named!(item_foreign_mod -> Item, do_parse!(
         attrs: many0!(outer_attr) >>
-        keyword!("extern") >>
-        abi: option!(quoted_string) >>
+        abi: abi >>
         punct!("{") >>
         items: many0!(foreign_item) >>
         punct!("}") >>
@@ -552,7 +541,7 @@
             vis: Visibility::Inherited,
             attrs: attrs,
             node: ItemKind::ForeignMod(ForeignMod {
-                abi: abi.map(Abi),
+                abi: abi,
                 items: items,
             }),
         })
@@ -743,7 +732,7 @@
         attrs: many0!(outer_attr) >>
         constness: constness >>
         unsafety: unsafety >>
-        abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
+        abi: option!(abi) >>
         keyword!("fn") >>
         name: ident >>
         generics: generics >>
@@ -761,7 +750,7 @@
                 MethodSig {
                     unsafety: unsafety,
                     constness: constness,
-                    abi: abi.map(Abi),
+                    abi: abi,
                     decl: FnDecl {
                         inputs: inputs,
                         output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
@@ -886,7 +875,7 @@
         defaultness: defaultness >>
         constness: constness >>
         unsafety: unsafety >>
-        abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
+        abi: option!(abi) >>
         keyword!("fn") >>
         name: ident >>
         generics: generics >>
@@ -905,7 +894,7 @@
                 MethodSig {
                     unsafety: unsafety,
                     constness: constness,
-                    abi: abi.map(Abi),
+                    abi: abi,
                     decl: FnDecl {
                         inputs: inputs,
                         output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
@@ -971,12 +960,6 @@
         epsilon!() => { |_| Constness::NotConst }
     ));
 
-    named!(unsafety -> Unsafety, alt!(
-        keyword!("unsafe") => { |_| Unsafety::Unsafe }
-        |
-        epsilon!() => { |_| Unsafety::Normal }
-    ));
-
     named!(defaultness -> Defaultness, alt!(
         keyword!("default") => { |_| Defaultness::Default }
         |
@@ -1067,10 +1050,7 @@
                 }
                 ItemKind::ForeignMod(ref foreign_mod) => {
                     self.vis.to_tokens(tokens);
-                    match foreign_mod.abi {
-                        Some(ref abi) => abi.to_tokens(tokens),
-                        None => tokens.append("extern"),
-                    }
+                    foreign_mod.abi.to_tokens(tokens);
                     tokens.append("{");
                     tokens.append_all(&foreign_mod.items);
                     tokens.append("}");
@@ -1396,17 +1376,6 @@
         }
     }
 
-    impl ToTokens for Unsafety {
-        fn to_tokens(&self, tokens: &mut Tokens) {
-            match *self {
-                Unsafety::Unsafe => tokens.append("unsafe"),
-                Unsafety::Normal => {
-                    // nothing
-                }
-            }
-        }
-    }
-
     impl ToTokens for Constness {
         fn to_tokens(&self, tokens: &mut Tokens) {
             match *self {
@@ -1439,11 +1408,4 @@
             }
         }
     }
-
-    impl ToTokens for Abi {
-        fn to_tokens(&self, tokens: &mut Tokens) {
-            tokens.append("extern");
-            self.0.to_tokens(tokens);
-        }
-    }
 }
diff --git a/src/lib.rs b/src/lib.rs
index 3af64bf..a59e8b6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -54,9 +54,9 @@
 #[cfg(feature = "full")]
 mod item;
 #[cfg(feature = "full")]
-pub use item::{Abi, Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem,
+pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem,
                ForeignMod, ImplItem, ImplItemKind, ImplPolarity, Item, ItemKind, MethodSig,
-               PathListItem, TraitItem, TraitItemKind, Unsafety, ViewPath};
+               PathListItem, TraitItem, TraitItemKind, ViewPath};
 
 mod lit;
 pub use lit::{FloatTy, IntTy, Lit, StrStyle};
@@ -81,9 +81,9 @@
 mod space;
 
 mod ty;
-pub use ty::{AngleBracketedParameterData, BareFnArg, BareFnTy, FunctionRetTy, MutTy, Mutability,
-             ParenthesizedParameterData, Path, PathParameters, PathSegment, PolyTraitRef, QSelf,
-             Ty, TypeBinding};
+pub use ty::{Abi, AngleBracketedParameterData, BareFnArg, BareFnTy, FunctionRetTy, MutTy,
+             Mutability, ParenthesizedParameterData, Path, PathParameters, PathSegment,
+             PolyTraitRef, QSelf, Ty, TypeBinding, Unsafety};
 
 #[cfg(feature = "aster")]
 pub mod aster;
diff --git a/src/ty.rs b/src/ty.rs
index 03f8891..2d29dee 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -166,11 +166,25 @@
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct BareFnTy {
+    pub unsafety: Unsafety,
+    pub abi: Option<Abi>,
     pub lifetimes: Vec<LifetimeDef>,
     pub inputs: Vec<BareFnArg>,
     pub output: FunctionRetTy,
 }
 
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum Unsafety {
+    Unsafe,
+    Normal,
+}
+
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub enum Abi {
+    Named(String),
+    Extern,
+}
+
 /// An argument in a function type.
 ///
 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
@@ -199,6 +213,7 @@
     use constant::parsing::const_expr;
     use generics::parsing::{lifetime, lifetime_def, ty_param_bound, bound_lifetimes};
     use ident::parsing::ident;
+    use lit::parsing::quoted_string;
     use std::str;
 
     named!(pub ty -> Ty, alt!(
@@ -274,6 +289,8 @@
             punct!(">") >>
             (lifetimes)
         )) >>
+        unsafety: unsafety >>
+        abi: option!(abi) >>
         keyword!("fn") >>
         punct!("(") >>
         inputs: terminated_list!(punct!(","), fn_arg) >>
@@ -283,6 +300,8 @@
             ty
         )) >>
         (Ty::BareFn(Box::new(BareFnTy {
+            unsafety: unsafety,
+            abi: abi,
             lifetimes: lifetimes,
             inputs: inputs,
             output: match output {
@@ -498,6 +517,21 @@
             ty: ty,
         })
     ));
+
+    named!(pub unsafety -> Unsafety, alt!(
+        keyword!("unsafe") => { |_| Unsafety::Unsafe }
+        |
+        epsilon!() => { |_| Unsafety::Normal }
+    ));
+
+    named!(pub abi -> Abi, do_parse!(
+        keyword!("extern") >>
+        name: option!(quoted_string) >>
+        (match name {
+            Some(name) => Abi::Named(name),
+            None => Abi::Extern,
+        })
+    ));
 }
 
 #[cfg(feature = "printing")]
@@ -715,6 +749,8 @@
                 tokens.append_separated(&self.lifetimes, ",");
                 tokens.append(">");
             }
+            self.unsafety.to_tokens(tokens);
+            self.abi.to_tokens(tokens);
             tokens.append("fn");
             tokens.append("(");
             tokens.append_separated(&self.inputs, ",");
@@ -735,4 +771,25 @@
             self.ty.to_tokens(tokens);
         }
     }
+
+    impl ToTokens for Unsafety {
+        fn to_tokens(&self, tokens: &mut Tokens) {
+            match *self {
+                Unsafety::Unsafe => tokens.append("unsafe"),
+                Unsafety::Normal => {
+                    // nothing
+                }
+            }
+        }
+    }
+
+    impl ToTokens for Abi {
+        fn to_tokens(&self, tokens: &mut Tokens) {
+            tokens.append("extern");
+            match *self {
+                Abi::Named(ref named) => named.to_tokens(tokens),
+                Abi::Extern => {}
+            }
+        }
+    }
 }