diff --git a/src/chains.rs b/src/chains.rs
index 77835d0414e..1220d43356e 100644
--- a/src/chains.rs
+++ b/src/chains.rs
@@ -416,7 +416,13 @@ fn rewrite_method_call(method_name: ast::Ident,
             .map(|ty| ty.rewrite(context, width, offset))
             .collect());
 
-        (types.last().unwrap().span.hi, format!("::<{}>", type_list.join(", ")))
+        let type_str = if context.config.spaces_within_angle_brackets && type_list.len() > 0 {
+            format!("::< {} >", type_list.join(", "))
+        } else {
+            format!("::<{}>", type_list.join(", "))
+        };
+
+        (types.last().unwrap().span.hi, type_str)
     };
 
     let callee_str = format!(".{}{}", method_name, type_str);
diff --git a/src/config.rs b/src/config.rs
index ad14f81a819..b02af269f04 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -416,6 +416,7 @@ create_config! {
     space_after_bound_colon: bool, true,
         "Leave a space after the colon in a trait or lifetime bound";
     spaces_around_ranges: bool, false, "Put spaces around the  .. and ... range operators";
+    spaces_within_angle_brackets: bool, false, "Put spaces within non-empty generic arguments";
     spaces_within_parens: bool, false, "Put spaces within non-empty parentheses";
     use_try_shorthand: bool, false, "Replace uses of the try! macro by the ? shorthand";
     write_mode: WriteMode, WriteMode::Replace,
diff --git a/src/items.rs b/src/items.rs
index c3e58cba835..c24dde55189 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -1800,7 +1800,11 @@ fn rewrite_generics(context: &RewriteContext,
                              span.hi);
     let list_str = try_opt!(format_item_list(items, h_budget, offset, context.config));
 
-    Some(format!("<{}>", list_str))
+    Some(if context.config.spaces_within_angle_brackets {
+        format!("< {} >", list_str)
+    } else {
+        format!("<{}>", list_str)
+    })
 }
 
 fn rewrite_trait_bounds(context: &RewriteContext,
diff --git a/src/types.rs b/src/types.rs
index 624f17f6be8..c210ae4627f 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -45,6 +45,10 @@ pub fn rewrite_path(context: &RewriteContext,
 
     if let Some(qself) = qself {
         result.push('<');
+        if context.config.spaces_within_angle_brackets {
+            result.push_str(" ")
+        }
+
         let fmt_ty = try_opt!(qself.ty.rewrite(context, width, offset));
         result.push_str(&fmt_ty);
 
@@ -68,6 +72,10 @@ pub fn rewrite_path(context: &RewriteContext,
                                                     offset + extra_offset));
         }
 
+        if context.config.spaces_within_angle_brackets {
+            result.push_str(" ")
+        }
+
         result.push_str(">::");
         span_lo = qself.ty.span.hi + BytePos(1);
     }
@@ -212,7 +220,11 @@ fn rewrite_segment(expr_context: bool,
             // Update position of last bracket.
             *span_lo = next_span_lo;
 
-            format!("{}<{}>", separator, list_str)
+            if context.config.spaces_within_angle_brackets && list_str.len() > 0 {
+                format!("{}< {} >", separator, list_str)
+            } else {
+                format!("{}<{}>", separator, list_str)
+            }
         }
         ast::PathParameters::Parenthesized(ref data) => {
             let output = match data.output {
@@ -350,7 +362,11 @@ impl Rewrite for ast::WherePredicate {
                                                     .intersperse(Some(" + ".to_string()))
                                                     .collect());
 
-                    format!("for<{}> {}: {}", lifetime_str, type_str, bounds_str)
+                    if context.config.spaces_within_angle_brackets && lifetime_str.len() > 0 {
+                        format!("for< {} > {}: {}", lifetime_str, type_str, bounds_str)
+                    } else {
+                        format!("for<{}> {}: {}", lifetime_str, type_str, bounds_str)
+                    }
                 } else {
                     // 2 = ": ".len()
                     let used_width = type_str.len() + 2;
@@ -513,7 +529,11 @@ impl Rewrite for ast::PolyTraitRef {
             let path_str = try_opt!(self.trait_ref
                 .rewrite(context, max_path_width, offset + extra_offset));
 
-            Some(format!("for<{}> {}", lifetime_str, path_str))
+            Some(if context.config.spaces_within_angle_brackets && lifetime_str.len() > 0 {
+                format!("for< {} > {}", lifetime_str, path_str)
+            } else {
+                format!("for<{}> {}", lifetime_str, path_str)
+            })
         } else {
             self.trait_ref.rewrite(context, width, offset)
         }
diff --git a/tests/source/spaces-within-angle-brackets.rs b/tests/source/spaces-within-angle-brackets.rs
new file mode 100644
index 00000000000..07640e11e0e
--- /dev/null
+++ b/tests/source/spaces-within-angle-brackets.rs
@@ -0,0 +1,56 @@
+// rustfmt-spaces_within_angle_brackets: true
+
+struct Foo<T> {
+    i: T,
+}
+
+struct Bar<T, E> {
+    i: T,
+    e: E,
+}
+
+struct Foo<'a> {
+    i: &'a str,
+}
+
+enum E<T> {
+    T(T),
+}
+
+enum E<T, S> {
+    T(T),
+    S(S),
+}
+
+fn foo<T>(a: T) {
+    foo::<u32>(10);
+}
+
+fn foo<T, E>(a: T, b: E) {
+    foo::<u32, str>(10, "bar");
+}
+
+fn foo<T: Send, E: Send>(a: T, b: E) {
+
+    foo::<u32, str>(10, "bar");
+
+    let opt: Option<u32>;
+    let res: Result<u32, String>;
+}
+
+fn foo<'a>(a: &'a str) {
+    foo("foo");
+}
+
+fn foo<'a, 'b>(a: &'a str, b: &'b str) {
+    foo("foo", "bar");
+}
+
+impl Foo {
+    fn bar() {
+        <Foo as Foo>::bar();
+    }
+}
+
+trait MyTrait<A, D> {}
+impl<A: Send, D: Send> MyTrait<A, D> for Foo {}
diff --git a/tests/target/spaces-within-angle-brackets.rs b/tests/target/spaces-within-angle-brackets.rs
new file mode 100644
index 00000000000..67cfc1fac7f
--- /dev/null
+++ b/tests/target/spaces-within-angle-brackets.rs
@@ -0,0 +1,56 @@
+// rustfmt-spaces_within_angle_brackets: true
+
+struct Foo< T > {
+    i: T,
+}
+
+struct Bar< T, E > {
+    i: T,
+    e: E,
+}
+
+struct Foo< 'a > {
+    i: &'a str,
+}
+
+enum E< T > {
+    T(T),
+}
+
+enum E< T, S > {
+    T(T),
+    S(S),
+}
+
+fn foo< T >(a: T) {
+    foo::< u32 >(10);
+}
+
+fn foo< T, E >(a: T, b: E) {
+    foo::< u32, str >(10, "bar");
+}
+
+fn foo< T: Send, E: Send >(a: T, b: E) {
+
+    foo::< u32, str >(10, "bar");
+
+    let opt: Option< u32 >;
+    let res: Result< u32, String >;
+}
+
+fn foo< 'a >(a: &'a str) {
+    foo("foo");
+}
+
+fn foo< 'a, 'b >(a: &'a str, b: &'b str) {
+    foo("foo", "bar");
+}
+
+impl Foo {
+    fn bar() {
+        < Foo as Foo >::bar();
+    }
+}
+
+trait MyTrait< A, D > {}
+impl< A: Send, D: Send > MyTrait< A, D > for Foo {}