diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 502b1c0f74371..e949398f074fc 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -414,14 +414,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 }
             }
 
-            ast::ItemKind::Impl(_, polarity, defaultness, ..) => {
-                if polarity == ast::ImplPolarity::Negative {
-                    gate_feature_post!(&self, optin_builtin_traits,
-                                       i.span,
-                                       "negative trait bounds are not yet fully implemented; \
-                                        use marker types for now");
-                }
-
+            ast::ItemKind::Impl(_, _, defaultness, ..) => {
                 if let ast::Defaultness::Default = defaultness {
                     gate_feature_post!(&self, specialization,
                                        i.span,
@@ -429,12 +422,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 }
             }
 
-            ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => {
-                gate_feature_post!(&self, optin_builtin_traits,
-                                   i.span,
-                                   "auto traits are experimental and possibly buggy");
-            }
-
             ast::ItemKind::OpaqueTy(..) => {
                 gate_feature_post!(
                     &self,
@@ -464,11 +451,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                                        "linking to LLVM intrinsics is experimental");
                 }
             }
-            ast::ForeignItemKind::Ty => {
-                    gate_feature_post!(&self, extern_types, i.span,
-                                       "extern types are experimental");
-            }
-            ast::ForeignItemKind::Macro(..) => {}
+            _ => {}
         }
 
         visit::walk_foreign_item(self, i)
@@ -789,7 +772,11 @@ pub fn check_crate(krate: &ast::Crate,
     gate_all!(try_blocks, "`try` blocks are unstable");
     gate_all!(label_break_value, "labels on blocks are unstable");
     gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
-
+    gate_all!(auto_traits, optin_builtin_traits, "auto traits are experimental and possibly buggy");
+    gate_all!(
+        negative_impls, optin_builtin_traits,
+        "negative trait bounds are not yet fully implemented; use marker types for now"
+    );
     // To avoid noise about type ascription in common syntax errors,
     // only emit if it is the *only* error. (Also check it last.)
     if parse_sess.span_diagnostic.err_count() == 0 {
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 95bddb5afdd08..4b11beb32f9f0 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -588,6 +588,7 @@ impl<'a> Parser<'a> {
         // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
         let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) {
             self.bump(); // `!`
+            self.sess.gated_spans.negative_impls.borrow_mut().push(self.prev_span);
             ast::ImplPolarity::Negative
         } else {
             ast::ImplPolarity::Positive
@@ -865,6 +866,11 @@ impl<'a> Parser<'a> {
                     }
                 }
             }
+
+            if is_auto == IsAuto::Yes {
+                self.sess.gated_spans.auto_traits.borrow_mut().push(lo.to(self.prev_span));
+            }
+
             Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None))
         }
     }
@@ -1235,6 +1241,7 @@ impl<'a> Parser<'a> {
         let ident = self.parse_ident()?;
         let hi = self.token.span;
         self.expect(&token::Semi)?;
+        self.sess.gated_spans.extern_types.borrow_mut().push(lo.to(self.prev_span));
         Ok(ast::ForeignItem {
             ident,
             attrs,
diff --git a/src/libsyntax/sess.rs b/src/libsyntax/sess.rs
index 28a0868d5dd1e..203e57b262ed4 100644
--- a/src/libsyntax/sess.rs
+++ b/src/libsyntax/sess.rs
@@ -52,6 +52,12 @@ crate struct GatedSpans {
     pub box_syntax: Lock<Vec<Span>>,
     /// Spans collected for gating `type_ascription`, e.g. `42: usize`.
     pub type_ascription: Lock<Vec<Span>>,
+    /// Spans collected for gating `optin_builtin_traits`, e.g. `auto trait Foo {}`.
+    pub auto_traits: Lock<Vec<Span>>,
+    /// Spans collected for gating `optin_builtin_traits`, e.g. `impl !Trait for Type {}`.
+    pub negative_impls: Lock<Vec<Span>>,
+    /// Spans collected for gating `extern_types`, e.g. `extern type Foo;`.
+    pub extern_types: Lock<Vec<Span>>,
 }
 
 /// Info about a parsing session.
diff --git a/src/test/ui/feature-gates/feature-gate-extern_types.rs b/src/test/ui/feature-gates/feature-gate-extern_types.rs
index 6bdc96f55d6a5..b4b78f7172ad7 100644
--- a/src/test/ui/feature-gates/feature-gate-extern_types.rs
+++ b/src/test/ui/feature-gates/feature-gate-extern_types.rs
@@ -1,3 +1,4 @@
+#[cfg(FALSE)]
 extern {
     type T; //~ ERROR extern types are experimental
 }
diff --git a/src/test/ui/feature-gates/feature-gate-extern_types.stderr b/src/test/ui/feature-gates/feature-gate-extern_types.stderr
index f82c64f9ca66b..b2c1b897c1974 100644
--- a/src/test/ui/feature-gates/feature-gate-extern_types.stderr
+++ b/src/test/ui/feature-gates/feature-gate-extern_types.stderr
@@ -1,5 +1,5 @@
 error[E0658]: extern types are experimental
-  --> $DIR/feature-gate-extern_types.rs:2:5
+  --> $DIR/feature-gate-extern_types.rs:3:5
    |
 LL |     type T;
    |     ^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.rs b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.rs
index 35c05b75d365c..ed97a5942b1c4 100644
--- a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.rs
+++ b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.rs
@@ -9,4 +9,13 @@ auto trait AutoDummyTrait {}
 impl !AutoDummyTrait for DummyStruct {}
 //~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now
 
+macro_rules! accept_item { ($i:item) => {} }
+accept_item! {
+    auto trait Auto {}
+    //~^ ERROR auto traits are experimental and possibly buggy
+}
+accept_item! {
+    impl !AutoDummyTrait for DummyStruct {}
+    //~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now
+}
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr
index 0c3dd451b2723..7af8450a78b98 100644
--- a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr
+++ b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr
@@ -7,15 +7,33 @@ LL | auto trait AutoDummyTrait {}
    = note: for more information, see https://github.com/rust-lang/rust/issues/13231
    = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable
 
+error[E0658]: auto traits are experimental and possibly buggy
+  --> $DIR/feature-gate-optin-builtin-traits.rs:14:5
+   |
+LL |     auto trait Auto {}
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/13231
+   = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable
+
 error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now
-  --> $DIR/feature-gate-optin-builtin-traits.rs:9:1
+  --> $DIR/feature-gate-optin-builtin-traits.rs:9:6
    |
 LL | impl !AutoDummyTrait for DummyStruct {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |      ^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/13231
+   = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable
+
+error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now
+  --> $DIR/feature-gate-optin-builtin-traits.rs:18:10
+   |
+LL |     impl !AutoDummyTrait for DummyStruct {}
+   |          ^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/13231
    = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/syntax-trait-polarity-feature-gate.stderr b/src/test/ui/syntax-trait-polarity-feature-gate.stderr
index c546bc4ef7e0a..b77b5ab6789c7 100644
--- a/src/test/ui/syntax-trait-polarity-feature-gate.stderr
+++ b/src/test/ui/syntax-trait-polarity-feature-gate.stderr
@@ -1,8 +1,8 @@
 error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now
-  --> $DIR/syntax-trait-polarity-feature-gate.rs:7:1
+  --> $DIR/syntax-trait-polarity-feature-gate.rs:7:6
    |
 LL | impl !Send for TestType {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |      ^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/13231
    = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable
diff --git a/src/test/ui/traits/trait-alias/trait-alias-syntax-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-syntax-fail.stderr
index 18c22133bc780..b1516cd7b1643 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-syntax-fail.stderr
+++ b/src/test/ui/traits/trait-alias/trait-alias-syntax-fail.stderr
@@ -23,4 +23,3 @@ LL | trait D: = Eq;
    |        ^
 
 error: aborting due to 4 previous errors
-