Distinguish arguments for types vs functions
diff --git a/src/item.rs b/src/item.rs
index 8592485..02a5ca7 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -206,19 +206,37 @@
     pub generics: Generics,
 }
 
+/// Header (not the body) of a function declaration.
+///
+/// E.g. `fn foo(bar: baz)`
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub struct FnDecl {
+    pub inputs: Vec<FnArg>,
+    pub output: FunctionRetTy,
+}
+
+/// An argument in a function header.
+///
+/// E.g. `bar: usize` as in `fn foo(bar: usize)`
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub struct FnArg {
+    pub pat: Pat,
+    pub ty: Ty,
+}
+
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use {FnDecl, FunctionRetTy, Generics};
+    use {FunctionRetTy, Generics};
     use attr::parsing::outer_attr;
     use data::parsing::visibility;
-    use expr::parsing::{block, expr};
+    use expr::parsing::{block, expr, pat};
     use generics::parsing::{generics, where_clause};
     use ident::parsing::ident;
     use lit::parsing::quoted_string;
     use macro_input::{Body, MacroInput};
     use macro_input::parsing::macro_input;
-    use ty::parsing::{fn_arg, mutability, ty};
+    use ty::parsing::{mutability, ty};
 
     named!(pub item -> Item, alt!(
         item_extern_crate
@@ -340,6 +358,16 @@
         })
     ));
 
+    named!(fn_arg -> FnArg, do_parse!(
+        pat: pat >>
+        punct!(":") >>
+        ty: ty >>
+        (FnArg {
+            pat: pat,
+            ty: ty,
+        })
+    ));
+
     named!(item_ty -> Item, do_parse!(
         attrs: many0!(outer_attr) >>
         vis: visibility >>
@@ -396,6 +424,7 @@
 #[cfg(feature = "printing")]
 mod printing {
     use super::*;
+    use FunctionRetTy;
     use attr::FilterAttrs;
     use data::VariantData;
     use quote::{Tokens, ToTokens};
@@ -446,7 +475,13 @@
                     tokens.append("fn");
                     self.ident.to_tokens(tokens);
                     generics.to_tokens(tokens);
-                    decl.to_tokens(tokens);
+                    tokens.append("(");
+                    tokens.append_separated(&decl.inputs, ",");
+                    tokens.append(")");
+                    if let FunctionRetTy::Ty(ref ty) = decl.output {
+                        tokens.append("->");
+                        ty.to_tokens(tokens);
+                    }
                     generics.where_clause.to_tokens(tokens);
                     block.to_tokens(tokens);
                 }
@@ -496,6 +531,14 @@
         }
     }
 
+    impl ToTokens for FnArg {
+        fn to_tokens(&self, tokens: &mut Tokens) {
+            self.pat.to_tokens(tokens);
+            tokens.append(":");
+            self.ty.to_tokens(tokens);
+        }
+    }
+
     impl ToTokens for Unsafety {
         fn to_tokens(&self, tokens: &mut Tokens) {
             match *self {
diff --git a/src/lib.rs b/src/lib.rs
index 7c7bd13..6814c98 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -83,6 +83,8 @@
     Abi,
     Constness,
     Defaultness,
+    FnArg,
+    FnDecl,
     ForeignItemKind,
     ForeignItem,
     ForeignMod,
@@ -131,9 +133,8 @@
 mod ty;
 pub use ty::{
     AngleBracketedParameterData,
+    BareFnArg,
     BareFnTy,
-    FnArg,
-    FnDecl,
     FunctionRetTy,
     MutTy,
     Mutability,
diff --git a/src/ty.rs b/src/ty.rs
index aa9c9df..11726a2 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -154,24 +154,16 @@
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct BareFnTy {
     pub lifetimes: Vec<LifetimeDef>,
-    pub decl: FnDecl,
-}
-
-/// Header (not the body) of a function declaration.
-///
-/// E.g. `fn foo(bar: baz)`
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct FnDecl {
-    pub inputs: Vec<FnArg>,
+    pub inputs: Vec<BareFnArg>,
     pub output: FunctionRetTy,
 }
 
-/// An argument in a function header.
+/// An argument in a function type.
 ///
 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
 #[derive(Debug, Clone, Eq, PartialEq)]
-pub struct FnArg {
-    pub pat: Option<Ident>,
+pub struct BareFnArg {
+    pub name: Option<Ident>,
     pub ty: Ty,
 }
 
@@ -276,12 +268,10 @@
         )) >>
         (Ty::BareFn(Box::new(BareFnTy {
             lifetimes: lifetimes,
-            decl: FnDecl {
-                inputs: inputs,
-                output: match output {
-                    Some(ty) => FunctionRetTy::Ty(ty),
-                    None => FunctionRetTy::Default,
-                },
+            inputs: inputs,
+            output: match output {
+                Some(ty) => FunctionRetTy::Ty(ty),
+                None => FunctionRetTy::Default,
             },
         })))
     ));
@@ -406,11 +396,11 @@
         })
     ));
 
-    named!(pub fn_arg -> FnArg, do_parse!(
-        pat: option!(terminated!(ident, punct!(":"))) >>
+    named!(pub fn_arg -> BareFnArg, do_parse!(
+        name: option!(terminated!(ident, punct!(":"))) >>
         ty: ty >>
-        (FnArg {
-            pat: pat,
+        (BareFnArg {
+            name: name,
             ty: ty,
         })
     ));
@@ -623,12 +613,6 @@
                 tokens.append_separated(&self.lifetimes, ",");
                 tokens.append(">");
             }
-            self.decl.to_tokens(tokens);
-        }
-    }
-
-    impl ToTokens for FnDecl {
-        fn to_tokens(&self, tokens: &mut Tokens) {
             tokens.append("(");
             tokens.append_separated(&self.inputs, ",");
             tokens.append(")");
@@ -639,10 +623,10 @@
         }
     }
 
-    impl ToTokens for FnArg {
+    impl ToTokens for BareFnArg {
         fn to_tokens(&self, tokens: &mut Tokens) {
-            if let Some(ref pat) = self.pat {
-                pat.to_tokens(tokens);
+            if let Some(ref name) = self.name {
+                name.to_tokens(tokens);
                 tokens.append(":");
             }
             self.ty.to_tokens(tokens);