diff --git a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md
index ee24dd87d90c3..97b57c690fcc8 100644
--- a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md
+++ b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md
@@ -24,9 +24,7 @@ Example:
 ```rust
 #![feature(optin_builtin_traits)]
 
-trait Valid {}
-
-impl Valid for .. {}
+auto trait Valid {}
 
 struct True;
 struct False;
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index f56a9a4033298..e47b99ed552d3 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -46,6 +46,8 @@ pub unsafe trait Send {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 unsafe impl Send for .. { }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -349,6 +351,8 @@ pub unsafe trait Sync {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 unsafe impl Sync for .. { }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -562,6 +566,8 @@ mod impls {
 #[lang = "freeze"]
 unsafe trait Freeze {}
 
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 unsafe impl Freeze for .. {}
 
 impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 4a763d4144edc..70cfe57d15023 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -498,7 +498,7 @@ define_dep_nodes!( <'tcx>
     [] SuperPredicatesOfItem(DefId),
     [] TraitDefOfItem(DefId),
     [] AdtDefOfItem(DefId),
-    [] IsDefaultImpl(DefId),
+    [] IsAutoImpl(DefId),
     [] ImplTraitRef(DefId),
     [] ImplPolarity(DefId),
     [] ClosureKind(DefId),
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index ae25924ab420c..c23a5fb1f7ebb 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -503,7 +503,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             // visit_enum_def() takes care of visiting the Item's NodeId
             visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
         }
-        ItemDefaultImpl(_, ref trait_ref) => {
+        ItemAutoImpl(_, ref trait_ref) => {
             visitor.visit_id(item.id);
             visitor.visit_trait_ref(trait_ref)
         }
@@ -520,7 +520,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             visitor.visit_id(item.id);
             visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span);
         }
-        ItemTrait(_, ref generics, ref bounds, ref trait_item_refs) => {
+        ItemTrait(.., ref generics, ref bounds, ref trait_item_refs) => {
             visitor.visit_id(item.id);
             visitor.visit_generics(generics);
             walk_list!(visitor, visit_ty_param_bound, bounds);
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 3834852cac5a9..a69d41d16033f 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -96,7 +96,7 @@ pub struct LoweringContext<'a> {
     exported_macros: Vec<hir::MacroDef>,
 
     trait_impls: BTreeMap<DefId, Vec<NodeId>>,
-    trait_default_impl: BTreeMap<DefId, NodeId>,
+    trait_auto_impl: BTreeMap<DefId, NodeId>,
 
     is_generator: bool,
 
@@ -146,7 +146,7 @@ pub fn lower_crate(sess: &Session,
         impl_items: BTreeMap::new(),
         bodies: BTreeMap::new(),
         trait_impls: BTreeMap::new(),
-        trait_default_impl: BTreeMap::new(),
+        trait_auto_impl: BTreeMap::new(),
         exported_macros: Vec::new(),
         catch_scopes: Vec::new(),
         loop_scopes: Vec::new(),
@@ -198,7 +198,7 @@ impl<'a> LoweringContext<'a> {
                     ItemKind::Union(_, ref generics) |
                     ItemKind::Enum(_, ref generics) |
                     ItemKind::Ty(_, ref generics) |
-                    ItemKind::Trait(_, ref generics, ..) => {
+                    ItemKind::Trait(_, _, ref generics, ..) => {
                         let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
                         let count = generics.lifetimes.len();
                         self.lctx.type_def_lifetime_params.insert(def_id, count);
@@ -284,7 +284,7 @@ impl<'a> LoweringContext<'a> {
             bodies: self.bodies,
             body_ids,
             trait_impls: self.trait_impls,
-            trait_default_impl: self.trait_default_impl,
+            trait_auto_impl: self.trait_auto_impl,
         }
     }
 
@@ -1479,14 +1479,14 @@ impl<'a> LoweringContext<'a> {
                 let vdata = self.lower_variant_data(vdata);
                 hir::ItemUnion(vdata, self.lower_generics(generics))
             }
-            ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
+            ItemKind::AutoImpl(unsafety, ref trait_ref) => {
                 let trait_ref = self.lower_trait_ref(trait_ref);
 
                 if let Def::Trait(def_id) = trait_ref.path.def {
-                    self.trait_default_impl.insert(def_id, id);
+                    self.trait_auto_impl.insert(def_id, id);
                 }
 
-                hir::ItemDefaultImpl(self.lower_unsafety(unsafety),
+                hir::ItemAutoImpl(self.lower_unsafety(unsafety),
                                      trait_ref)
             }
             ItemKind::Impl(unsafety,
@@ -1515,10 +1515,11 @@ impl<'a> LoweringContext<'a> {
                               self.lower_ty(ty),
                               new_impl_items)
             }
-            ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => {
+            ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
                 let bounds = self.lower_bounds(bounds);
                 let items = items.iter().map(|item| self.lower_trait_item_ref(item)).collect();
-                hir::ItemTrait(self.lower_unsafety(unsafety),
+                hir::ItemTrait(self.lower_is_auto(is_auto),
+                               self.lower_unsafety(unsafety),
                                self.lower_generics(generics),
                                bounds,
                                items)
@@ -1741,6 +1742,13 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
+    fn lower_is_auto(&mut self, a: IsAuto) -> hir::IsAuto {
+        match a {
+            IsAuto::Yes => hir::IsAuto::Yes,
+            IsAuto::No => hir::IsAuto::No,
+        }
+    }
+
     fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
         match u {
             Unsafety::Unsafe => hir::Unsafety::Unsafe,
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 2f4b62dcbf782..5c1e74dcf43b9 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -71,7 +71,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
                 impl_items: _,
                 bodies: _,
                 trait_impls: _,
-                trait_default_impl: _,
+                trait_auto_impl: _,
                 body_ids: _,
             } = *krate;
 
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index 9d49776749bcb..d8590c1de94e9 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -104,7 +104,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
         // Pick the def data. This need not be unique, but the more
         // information we encapsulate into
         let def_data = match i.node {
-            ItemKind::DefaultImpl(..) | ItemKind::Impl(..) =>
+            ItemKind::AutoImpl(..) | ItemKind::Impl(..) =>
                 DefPathData::Impl,
             ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) |
             ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index a23658664dc6a..1236602aecf55 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -474,16 +474,16 @@ impl<'hir> Map<'hir> {
         self.forest.krate.trait_impls.get(&trait_did).map_or(&[], |xs| &xs[..])
     }
 
-    pub fn trait_default_impl(&self, trait_did: DefId) -> Option<NodeId> {
+    pub fn trait_auto_impl(&self, trait_did: DefId) -> Option<NodeId> {
         self.dep_graph.read(DepNode::new_no_params(DepKind::AllLocalTraitImpls));
 
         // NB: intentionally bypass `self.forest.krate()` so that we
         // do not trigger a read of the whole krate here
-        self.forest.krate.trait_default_impl.get(&trait_did).cloned()
+        self.forest.krate.trait_auto_impl.get(&trait_did).cloned()
     }
 
     pub fn trait_is_auto(&self, trait_did: DefId) -> bool {
-        self.trait_default_impl(trait_did).is_some()
+        self.trait_auto_impl(trait_did).is_some()
     }
 
     /// Get the attributes on the krate. This is preferable to
@@ -1140,7 +1140,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                 ItemUnion(..) => "union",
                 ItemTrait(..) => "trait",
                 ItemImpl(..) => "impl",
-                ItemDefaultImpl(..) => "default impl",
+                ItemAutoImpl(..) => "default impl",
             };
             format!("{} {}{}", item_str, path_str(), id_str)
         }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index e23e2acefb732..c9b1d70e7b60d 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -499,7 +499,7 @@ pub struct Crate {
     pub impl_items: BTreeMap<ImplItemId, ImplItem>,
     pub bodies: BTreeMap<BodyId, Body>,
     pub trait_impls: BTreeMap<DefId, Vec<NodeId>>,
-    pub trait_default_impl: BTreeMap<DefId, NodeId>,
+    pub trait_auto_impl: BTreeMap<DefId, NodeId>,
 
     /// A list of the body ids written out in the order in which they
     /// appear in the crate. If you're going to process all the bodies
@@ -1500,6 +1500,13 @@ pub struct FnDecl {
     pub has_implicit_self: bool,
 }
 
+/// Is the trait definition an auto trait?
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum IsAuto {
+    Yes,
+    No
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Unsafety {
     Unsafe,
@@ -1811,12 +1818,12 @@ pub enum Item_ {
     /// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
     ItemUnion(VariantData, Generics),
     /// Represents a Trait Declaration
-    ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
+    ItemTrait(IsAuto, Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
 
-    // Default trait implementations
+    /// Auto trait implementations
     ///
     /// `impl Trait for .. {}`
-    ItemDefaultImpl(Unsafety, TraitRef),
+    ItemAutoImpl(Unsafety, TraitRef),
     /// An implementation, eg `impl<A> Trait for Foo { .. }`
     ItemImpl(Unsafety,
              ImplPolarity,
@@ -1844,7 +1851,7 @@ impl Item_ {
             ItemUnion(..) => "union",
             ItemTrait(..) => "trait",
             ItemImpl(..) |
-            ItemDefaultImpl(..) => "item",
+            ItemAutoImpl(..) => "item",
         }
     }
 
@@ -1864,7 +1871,7 @@ impl Item_ {
             ItemEnum(_, ref generics) |
             ItemStruct(_, ref generics) |
             ItemUnion(_, ref generics) |
-            ItemTrait(_, ref generics, _, _) |
+            ItemTrait(_, _, ref generics, _, _) |
             ItemImpl(_, _, _, ref generics, _, _, _)=> generics,
             _ => return None
         })
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 24a0b5fcea9b8..7b4881f5486dc 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -660,7 +660,7 @@ impl<'a> State<'a> {
                 self.head(&visibility_qualified(&item.vis, "union"))?;
                 self.print_struct(struct_def, generics, item.name, item.span, true)?;
             }
-            hir::ItemDefaultImpl(unsafety, ref trait_ref) => {
+            hir::ItemAutoImpl(unsafety, ref trait_ref) => {
                 self.head("")?;
                 self.print_visibility(&item.vis)?;
                 self.print_unsafety(unsafety)?;
@@ -717,9 +717,10 @@ impl<'a> State<'a> {
                 }
                 self.bclose(item.span)?;
             }
-            hir::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => {
+            hir::ItemTrait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
                 self.head("")?;
                 self.print_visibility(&item.vis)?;
+                self.print_is_auto(is_auto)?;
                 self.print_unsafety(unsafety)?;
                 self.word_nbsp("trait")?;
                 self.print_name(item.name)?;
@@ -2274,6 +2275,13 @@ impl<'a> State<'a> {
             hir::Unsafety::Unsafe => self.word_nbsp("unsafe"),
         }
     }
+
+    pub fn print_is_auto(&mut self, s: hir::IsAuto) -> io::Result<()> {
+        match s {
+            hir::IsAuto::Yes => self.word_nbsp("auto"),
+            hir::IsAuto::No => Ok(()),
+        }
+    }
 }
 
 // Dup'ed from parse::classify, but adapted for the HIR.
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 5a36c42046244..f0fe6205fb6d0 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -898,7 +898,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Item {
             hir::ItemForeignMod(..)  |
             hir::ItemGlobalAsm(..)   |
             hir::ItemMod(..)         |
-            hir::ItemDefaultImpl(..) |
+            hir::ItemAutoImpl(..) |
             hir::ItemTrait(..)       |
             hir::ItemImpl(..)        |
             hir::ItemTy(..)          |
@@ -944,8 +944,8 @@ impl_stable_hash_for!(enum hir::Item_ {
     ItemEnum(enum_def, generics),
     ItemStruct(variant_data, generics),
     ItemUnion(variant_data, generics),
-    ItemTrait(unsafety, generics, bounds, item_refs),
-    ItemDefaultImpl(unsafety, trait_ref),
+    ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
+    ItemAutoImpl(unsafety, trait_ref),
     ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
 });
 
@@ -1126,6 +1126,10 @@ impl_stable_hash_for!(enum hir::Mutability {
     MutImmutable
 });
 
+impl_stable_hash_for!(enum hir::IsAuto {
+    Yes,
+    No
+});
 
 impl_stable_hash_for!(enum hir::Unsafety {
     Unsafe,
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 48d3017f59763..e7627b110fae4 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -731,13 +731,13 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::TraitDef {
             def_id: _,
             unsafety,
             paren_sugar,
-            has_default_impl,
+            has_auto_impl,
             def_path_hash,
         } = *self;
 
         unsafety.hash_stable(hcx, hasher);
         paren_sugar.hash_stable(hcx, hasher);
-        has_default_impl.hash_stable(hcx, hasher);
+        has_auto_impl.hash_stable(hcx, hasher);
         def_path_hash.hash_stable(hcx, hasher);
     }
 }
@@ -856,7 +856,7 @@ for traits::Vtable<'gcx, N> where N: HashStable<StableHashingContext<'gcx>> {
 
         match self {
             &VtableImpl(ref table_impl) => table_impl.hash_stable(hcx, hasher),
-            &VtableDefaultImpl(ref table_def_impl) => table_def_impl.hash_stable(hcx, hasher),
+            &VtableAutoImpl(ref table_def_impl) => table_def_impl.hash_stable(hcx, hasher),
             &VtableParam(ref table_param) => table_param.hash_stable(hcx, hasher),
             &VtableObject(ref table_obj) => table_obj.hash_stable(hcx, hasher),
             &VtableBuiltin(ref table_builtin) => table_builtin.hash_stable(hcx, hasher),
@@ -884,11 +884,11 @@ for traits::VtableImplData<'gcx, N> where N: HashStable<StableHashingContext<'gc
 }
 
 impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
-for traits::VtableDefaultImplData<N> where N: HashStable<StableHashingContext<'gcx>> {
+for traits::VtableAutoImplData<N> where N: HashStable<StableHashingContext<'gcx>> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'gcx>,
                                           hasher: &mut StableHasher<W>) {
-        let traits::VtableDefaultImplData {
+        let traits::VtableAutoImplData {
             trait_def_id,
             ref nested,
         } = *self;
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 259794e9d0ee4..a42ff543227a8 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -562,7 +562,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) |
                 hir::ItemTrait(..) |
-                hir::ItemDefaultImpl(..) |
+                hir::ItemAutoImpl(..) |
                 hir::ItemImpl(..) => self.tcx.sess.codemap().def_span(item.span),
                 _ => item.span,
             };
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 2037bc01a5bc9..d5f26d1117c5b 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -270,7 +270,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     hir::ItemMod(..) | hir::ItemForeignMod(..) |
                     hir::ItemImpl(..) | hir::ItemTrait(..) |
                     hir::ItemStruct(..) | hir::ItemEnum(..) |
-                    hir::ItemUnion(..) | hir::ItemDefaultImpl(..) |
+                    hir::ItemUnion(..) | hir::ItemAutoImpl(..) |
                     hir::ItemGlobalAsm(..) => {}
                 }
             }
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index ee0e580920e1f..4c7ce4c09e25b 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -313,7 +313,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
             hir::ItemExternCrate(_) |
             hir::ItemUse(..) |
             hir::ItemMod(..) |
-            hir::ItemDefaultImpl(..) |
+            hir::ItemAutoImpl(..) |
             hir::ItemForeignMod(..) |
             hir::ItemGlobalAsm(..) => {
                 // These sorts of items have no lifetime parameters at all.
@@ -332,7 +332,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
             hir::ItemEnum(_, ref generics) |
             hir::ItemStruct(_, ref generics) |
             hir::ItemUnion(_, ref generics) |
-            hir::ItemTrait(_, ref generics, ..) |
+            hir::ItemTrait(_, _, ref generics, ..) |
             hir::ItemImpl(_, _, _, ref generics, ..) => {
                 // These kinds of items have only early bound lifetime parameters.
                 let mut index = if let hir::ItemTrait(..) = item.node {
@@ -688,7 +688,7 @@ fn compute_object_lifetime_defaults(sess: &Session, hir_map: &Map)
             hir::ItemUnion(_, ref generics) |
             hir::ItemEnum(_, ref generics) |
             hir::ItemTy(_, ref generics) |
-            hir::ItemTrait(_, ref generics, ..) => {
+            hir::ItemTrait(_, _, ref generics, ..) => {
                 let result = object_lifetime_defaults_for_item(hir_map, generics);
 
                 // Debugging aid.
@@ -844,7 +844,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 index += 1; // Self comes first.
             }
             match parent.node {
-                hir::ItemTrait(_, ref generics, ..) |
+                hir::ItemTrait(_, _, ref generics, ..) |
                 hir::ItemImpl(_, _, _, ref generics, ..) => {
                     index += (generics.lifetimes.len() + generics.ty_params.len()) as u32;
                 }
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 1fddb1864175f..c08fe187f99bf 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -288,11 +288,11 @@ pub enum Vtable<'tcx, N> {
     /// Vtable identifying a particular impl.
     VtableImpl(VtableImplData<'tcx, N>),
 
-    /// Vtable for default trait implementations
+    /// Vtable for auto trait implementations
     /// This carries the information and nested obligations with regards
-    /// to a default implementation for a trait `Trait`. The nested obligations
+    /// to an auto implementation for a trait `Trait`. The nested obligations
     /// ensure the trait implementation holds for all the constituent types.
-    VtableDefaultImpl(VtableDefaultImplData<N>),
+    VtableAutoImpl(VtableAutoImplData<N>),
 
     /// Successful resolution to an obligation provided by the caller
     /// for some type parameter. The `Vec<N>` represents the
@@ -354,7 +354,7 @@ pub struct VtableClosureData<'tcx, N> {
 }
 
 #[derive(Clone)]
-pub struct VtableDefaultImplData<N> {
+pub struct VtableAutoImplData<N> {
     pub trait_def_id: DefId,
     pub nested: Vec<N>
 }
@@ -758,7 +758,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
             VtableImpl(i) => i.nested,
             VtableParam(n) => n,
             VtableBuiltin(i) => i.nested,
-            VtableDefaultImpl(d) => d.nested,
+            VtableAutoImpl(d) => d.nested,
             VtableClosure(c) => c.nested,
             VtableGenerator(c) => c.nested,
             VtableObject(d) => d.nested,
@@ -771,7 +771,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
             &mut VtableImpl(ref mut i) => &mut i.nested,
             &mut VtableParam(ref mut n) => n,
             &mut VtableBuiltin(ref mut i) => &mut i.nested,
-            &mut VtableDefaultImpl(ref mut d) => &mut d.nested,
+            &mut VtableAutoImpl(ref mut d) => &mut d.nested,
             &mut VtableGenerator(ref mut c) => &mut c.nested,
             &mut VtableClosure(ref mut c) => &mut c.nested,
             &mut VtableObject(ref mut d) => &mut d.nested,
@@ -795,7 +795,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
                 vtable_base: o.vtable_base,
                 nested: o.nested.into_iter().map(f).collect(),
             }),
-            VtableDefaultImpl(d) => VtableDefaultImpl(VtableDefaultImplData {
+            VtableAutoImpl(d) => VtableAutoImpl(VtableAutoImplData {
                 trait_def_id: d.trait_def_id,
                 nested: d.nested.into_iter().map(f).collect(),
             }),
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 0fa1b32ceb7f6..9c56df058c3dd 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -1116,7 +1116,7 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
                 // projection. And the projection where clause is handled
                 // in `assemble_candidates_from_param_env`.
             }
-            super::VtableDefaultImpl(..) |
+            super::VtableAutoImpl(..) |
             super::VtableBuiltin(..) => {
                 // These traits have no associated types.
                 span_bug!(
@@ -1182,7 +1182,7 @@ fn confirm_select_candidate<'cx, 'gcx, 'tcx>(
             confirm_fn_pointer_candidate(selcx, obligation, data),
         super::VtableObject(_) =>
             confirm_object_candidate(selcx, obligation, obligation_trait_ref),
-        super::VtableDefaultImpl(..) |
+        super::VtableAutoImpl(..) |
         super::VtableParam(..) |
         super::VtableBuiltin(..) =>
             // we don't create Select candidates with this kind of resolution
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 6c573acf07d63..7716770d318ba 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -25,9 +25,9 @@ use super::TraitNotObjectSafe;
 use super::Selection;
 use super::SelectionResult;
 use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure, VtableGenerator,
-            VtableFnPointer, VtableObject, VtableDefaultImpl};
+            VtableFnPointer, VtableObject, VtableAutoImpl};
 use super::{VtableImplData, VtableObjectData, VtableBuiltinData, VtableGeneratorData,
-            VtableClosureData, VtableDefaultImplData, VtableFnPointerData};
+            VtableClosureData, VtableAutoImplData, VtableFnPointerData};
 use super::util;
 
 use dep_graph::{DepNodeIndex, DepKind};
@@ -225,7 +225,7 @@ enum SelectionCandidate<'tcx> {
     BuiltinCandidate { has_nested: bool },
     ParamCandidate(ty::PolyTraitRef<'tcx>),
     ImplCandidate(DefId),
-    DefaultImplCandidate(DefId),
+    AutoImplCandidate(DefId),
 
     /// This is a trait matching with a projected type as `Self`, and
     /// we found an applicable bound in the trait definition.
@@ -260,7 +260,7 @@ impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> {
                 }
             }
             ImplCandidate(def_id) => ImplCandidate(def_id),
-            DefaultImplCandidate(def_id) => DefaultImplCandidate(def_id),
+            AutoImplCandidate(def_id) => AutoImplCandidate(def_id),
             ProjectionCandidate => ProjectionCandidate,
             FnPointerCandidate => FnPointerCandidate,
             ObjectCandidate => ObjectCandidate,
@@ -910,7 +910,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
         let result = match predicate {
             ty::Predicate::Trait(ref data) => {
-                self.tcx().trait_has_default_impl(data.def_id())
+                self.tcx().trait_is_auto(data.def_id())
             }
             _ => {
                 false
@@ -1368,10 +1368,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
 
         self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
         self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
-        // Default implementations have lower priority, so we only
+        // Auto implementations have lower priority, so we only
         // consider triggering a default if there is no other impl that can apply.
         if candidates.vec.is_empty() {
-            self.assemble_candidates_from_default_impls(obligation, &mut candidates)?;
+            self.assemble_candidates_from_auto_impls(obligation, &mut candidates)?;
         }
         debug!("candidate list size: {}", candidates.vec.len());
         Ok(candidates)
@@ -1686,18 +1686,18 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         Ok(())
     }
 
-    fn assemble_candidates_from_default_impls(&mut self,
+    fn assemble_candidates_from_auto_impls(&mut self,
                                               obligation: &TraitObligation<'tcx>,
                                               candidates: &mut SelectionCandidateSet<'tcx>)
                                               -> Result<(), SelectionError<'tcx>>
     {
         // OK to skip binder here because the tests we do below do not involve bound regions
         let self_ty = *obligation.self_ty().skip_binder();
-        debug!("assemble_candidates_from_default_impls(self_ty={:?})", self_ty);
+        debug!("assemble_candidates_from_auto_impls(self_ty={:?})", self_ty);
 
         let def_id = obligation.predicate.def_id();
 
-        if self.tcx().trait_has_default_impl(def_id) {
+        if self.tcx().trait_is_auto(def_id) {
             match self_ty.sty {
                 ty::TyDynamic(..) => {
                     // For object types, we don't know what the closed
@@ -1728,11 +1728,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                     // this path.
                 }
                 ty::TyInfer(ty::TyVar(_)) => {
-                    // the defaulted impl might apply, we don't know
+                    // the auto impl might apply, we don't know
                     candidates.ambiguous = true;
                 }
                 _ => {
-                    candidates.vec.push(DefaultImplCandidate(def_id.clone()))
+                    candidates.vec.push(AutoImplCandidate(def_id.clone()))
                 }
             }
         }
@@ -1933,7 +1933,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         match other.candidate {
             ObjectCandidate |
             ParamCandidate(_) | ProjectionCandidate => match victim.candidate {
-                DefaultImplCandidate(..) => {
+                AutoImplCandidate(..) => {
                     bug!(
                         "default implementations shouldn't be recorded \
                          when there are other valid candidates");
@@ -2282,9 +2282,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                 Ok(VtableParam(obligations))
             }
 
-            DefaultImplCandidate(trait_def_id) => {
-                let data = self.confirm_default_impl_candidate(obligation, trait_def_id);
-                Ok(VtableDefaultImpl(data))
+            AutoImplCandidate(trait_def_id) => {
+                let data = self.confirm_auto_impl_candidate(obligation, trait_def_id);
+                Ok(VtableAutoImpl(data))
             }
 
             ImplCandidate(impl_def_id) => {
@@ -2417,29 +2417,29 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     ///
     /// 1. For each constituent type `Y` in `X`, `Y : Foo` holds
     /// 2. For each where-clause `C` declared on `Foo`, `[Self => X] C` holds.
-    fn confirm_default_impl_candidate(&mut self,
+    fn confirm_auto_impl_candidate(&mut self,
                                       obligation: &TraitObligation<'tcx>,
                                       trait_def_id: DefId)
-                                      -> VtableDefaultImplData<PredicateObligation<'tcx>>
+                                      -> VtableAutoImplData<PredicateObligation<'tcx>>
     {
-        debug!("confirm_default_impl_candidate({:?}, {:?})",
+        debug!("confirm_auto_impl_candidate({:?}, {:?})",
                obligation,
                trait_def_id);
 
         // binder is moved below
         let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
         let types = self.constituent_types_for_ty(self_ty);
-        self.vtable_default_impl(obligation, trait_def_id, ty::Binder(types))
+        self.vtable_auto_impl(obligation, trait_def_id, ty::Binder(types))
     }
 
-    /// See `confirm_default_impl_candidate`
-    fn vtable_default_impl(&mut self,
+    /// See `confirm_auto_impl_candidate`
+    fn vtable_auto_impl(&mut self,
                            obligation: &TraitObligation<'tcx>,
                            trait_def_id: DefId,
                            nested: ty::Binder<Vec<Ty<'tcx>>>)
-                           -> VtableDefaultImplData<PredicateObligation<'tcx>>
+                           -> VtableAutoImplData<PredicateObligation<'tcx>>
     {
-        debug!("vtable_default_impl: nested={:?}", nested);
+        debug!("vtable_auto_impl: nested={:?}", nested);
 
         let cause = obligation.derived_cause(BuiltinDerivedObligation);
         let mut obligations = self.collect_predicates_for_types(
@@ -2465,9 +2465,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
 
         obligations.extend(trait_obligations);
 
-        debug!("vtable_default_impl: obligations={:?}", obligations);
+        debug!("vtable_auto_impl: obligations={:?}", obligations);
 
-        VtableDefaultImplData {
+        VtableAutoImplData {
             trait_def_id,
             nested: obligations
         }
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 19ed03aa14917..fd93aa162a612 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -47,7 +47,7 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::Vtable<'tcx, N> {
             super::VtableImpl(ref v) =>
                 write!(f, "{:?}", v),
 
-            super::VtableDefaultImpl(ref t) =>
+            super::VtableAutoImpl(ref t) =>
                 write!(f, "{:?}", t),
 
             super::VtableClosure(ref d) =>
@@ -104,9 +104,9 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> {
     }
 }
 
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableDefaultImplData<N> {
+impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableAutoImplData<N> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "VtableDefaultImplData(trait_def_id={:?}, nested={:?})",
+        write!(f, "VtableAutoImplData(trait_def_id={:?}, nested={:?})",
                self.trait_def_id,
                self.nested)
     }
@@ -292,7 +292,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
                     })
                 })
             }
-            traits::VtableDefaultImpl(t) => Some(traits::VtableDefaultImpl(t)),
+            traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
             traits::VtableGenerator(traits::VtableGeneratorData {
                 closure_def_id,
                 substs,
@@ -407,9 +407,9 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureDa
     }
 }
 
-impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultImplData<N> {
+impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
-        traits::VtableDefaultImplData {
+        traits::VtableAutoImplData {
             trait_def_id: self.trait_def_id,
             nested: self.nested.fold_with(folder),
         }
@@ -463,7 +463,7 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N>
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         match *self {
             traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
-            traits::VtableDefaultImpl(ref t) => traits::VtableDefaultImpl(t.fold_with(folder)),
+            traits::VtableAutoImpl(ref t) => traits::VtableAutoImpl(t.fold_with(folder)),
             traits::VtableGenerator(ref d) => {
                 traits::VtableGenerator(d.fold_with(folder))
             }
@@ -482,7 +482,7 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N>
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
         match *self {
             traits::VtableImpl(ref v) => v.visit_with(visitor),
-            traits::VtableDefaultImpl(ref t) => t.visit_with(visitor),
+            traits::VtableAutoImpl(ref t) => t.visit_with(visitor),
             traits::VtableGenerator(ref d) => d.visit_with(visitor),
             traits::VtableClosure(ref d) => d.visit_with(visitor),
             traits::VtableFnPointer(ref d) => d.visit_with(visitor),
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 442c79393fdc7..253bee167c482 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -256,7 +256,7 @@ fn resolve_associated_item<'a, 'tcx>(
                 None
             }
         }
-        traits::VtableDefaultImpl(..) | traits::VtableParam(..) => None
+        traits::VtableAutoImpl(..) | traits::VtableParam(..) => None
     }
 }
 
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index 98c55331f8a10..24c19bfc3f3f0 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -218,7 +218,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
         // Always use types for non-local impls, where types are always
         // available, and filename/line-number is mostly uninteresting.
-        let use_types = !self.is_default_impl(impl_def_id) && (!impl_def_id.is_local() || {
+        let use_types = !self.is_auto_impl(impl_def_id) && (!impl_def_id.is_local() || {
             // Otherwise, use filename/line-number if forced.
             let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
             !force_no_types
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index c77175bbbdcc9..7d8586741fb15 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -113,8 +113,8 @@ define_maps! { <'tcx>
     /// True if this is a foreign item (i.e., linked via `extern { ... }`).
     [] fn is_foreign_item: IsForeignItem(DefId) -> bool,
 
-    /// True if this is a default impl (aka impl Foo for ..)
-    [] fn is_default_impl: IsDefaultImpl(DefId) -> bool,
+    /// True if this is an auto impl (aka impl Foo for ..)
+    [] fn is_auto_impl: IsAutoImpl(DefId) -> bool,
 
     /// Get a map with the variance of every item; use `item_variance`
     /// instead.
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index 2f10b9e8b9a83..cc698cf03da98 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -731,7 +731,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
         DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
         DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }
-        DepKind::IsDefaultImpl => { force!(is_default_impl, def_id!()); }
+        DepKind::IsAutoImpl => { force!(is_auto_impl, def_id!()); }
         DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); }
         DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
         DepKind::ClosureKind => { force!(closure_kind, def_id!()); }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index ee1668d6fa25f..81827192cf814 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2308,8 +2308,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self.get_attrs(did).iter().any(|item| item.check_name(attr))
     }
 
-    pub fn trait_has_default_impl(self, trait_def_id: DefId) -> bool {
-        self.trait_def(trait_def_id).has_default_impl
+    /// Returns true if this is an `auto trait`.
+    ///
+    /// NB. For a limited time, also returns true if `impl Trait for .. { }` is in the code-base.
+    pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
+        self.trait_def(trait_def_id).has_auto_impl
     }
 
     pub fn generator_layout(self, def_id: DefId) -> &'tcx GeneratorLayout<'tcx> {
diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs
index e0b05c2ba39ac..0fbf9f1bd587b 100644
--- a/src/librustc/ty/trait_def.rs
+++ b/src/librustc/ty/trait_def.rs
@@ -34,7 +34,7 @@ pub struct TraitDef {
     /// be usable with the sugar (or without it).
     pub paren_sugar: bool,
 
-    pub has_default_impl: bool,
+    pub has_auto_impl: bool,
 
     /// The ICH of this trait's DefPath, cached here so it doesn't have to be
     /// recomputed all the time.
@@ -51,14 +51,14 @@ impl<'a, 'gcx, 'tcx> TraitDef {
     pub fn new(def_id: DefId,
                unsafety: hir::Unsafety,
                paren_sugar: bool,
-               has_default_impl: bool,
+               has_auto_impl: bool,
                def_path_hash: DefPathHash)
                -> TraitDef {
         TraitDef {
             def_id,
             paren_sugar,
             unsafety,
-            has_default_impl,
+            has_auto_impl,
             def_path_hash,
         }
     }
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index d86d51f374722..5ff75351b635b 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -253,7 +253,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
                 hir::ItemUnion(..) |
                 hir::ItemTrait(..) |
                 hir::ItemImpl(..) |
-                hir::ItemDefaultImpl(..) => None,
+                hir::ItemAutoImpl(..) => None,
 
                 hir::ItemMod(ref m) => search_mod(this, m, idx, names),
             };
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 0cb920a111dd9..e871c0dbdab13 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -409,7 +409,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
                     //HirItem::ItemTrait(..) => ("ItemTrait", LABELS_TRAIT),
 
                     // `impl Trait for .. {}`
-                    HirItem::ItemDefaultImpl(..) => ("ItemDefaultImpl", LABELS_IMPL),
+                    HirItem::ItemAutoImpl(..) => ("ItemAutoImpl", LABELS_IMPL),
 
                     // An implementation, eg `impl<A> Trait for Foo { .. }`
                     HirItem::ItemImpl(..) => ("ItemImpl", LABELS_IMPL),
diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs
index 027ed84faf0fd..d14a6943fc112 100644
--- a/src/librustc_lint/bad_style.rs
+++ b/src/librustc_lint/bad_style.rs
@@ -23,7 +23,7 @@ use rustc::hir::intravisit::FnKind;
 
 #[derive(PartialEq)]
 pub enum MethodLateContext {
-    TraitDefaultImpl,
+    TraitAutoImpl,
     TraitImpl,
     PlainImpl,
 }
@@ -32,7 +32,7 @@ pub fn method_context(cx: &LateContext, id: ast::NodeId) -> MethodLateContext {
     let def_id = cx.tcx.hir.local_def_id(id);
     let item = cx.tcx.associated_item(def_id);
     match item.container {
-        ty::TraitContainer(..) => MethodLateContext::TraitDefaultImpl,
+        ty::TraitContainer(..) => MethodLateContext::TraitAutoImpl,
         ty::ImplContainer(cid) => {
             match cx.tcx.impl_trait_ref(cid) {
                 Some(_) => MethodLateContext::TraitImpl,
@@ -245,7 +245,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
                     MethodLateContext::PlainImpl => {
                         self.check_snake_case(cx, "method", &name.as_str(), Some(span))
                     }
-                    MethodLateContext::TraitDefaultImpl => {
+                    MethodLateContext::TraitAutoImpl => {
                         self.check_snake_case(cx, "trait method", &name.as_str(), Some(span))
                     }
                     _ => (),
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 70cac419648d5..cd18ca10af04d 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -55,6 +55,31 @@ use bad_style::{MethodLateContext, method_context};
 // hardwired lints from librustc
 pub use lint::builtin::*;
 
+declare_lint! {
+    pub AUTO_IMPL,
+    Deny,
+    "The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`"
+}
+
+#[derive(Copy, Clone)]
+pub struct AutoImpl;
+
+impl LintPass for AutoImpl {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(AUTO_IMPL)
+    }
+}
+
+impl EarlyLintPass for AutoImpl {
+    fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
+        let msg = "The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`";
+        match item.node {
+            ast::ItemKind::AutoImpl(..) => cx.span_lint(AUTO_IMPL, item.span, msg),
+            _ => ()
+        }
+     }
+}
+
 declare_lint! {
     WHILE_TRUE,
     Warn,
@@ -228,7 +253,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
 
     fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
         match it.node {
-            hir::ItemTrait(hir::Unsafety::Unsafe, ..) => {
+            hir::ItemTrait(_, hir::Unsafety::Unsafe, ..) => {
                 self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
             }
 
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 42fcf377d6539..d59d09a8a0670 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -109,6 +109,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
                        AnonymousParameters,
                        IllegalFloatLiteralPattern,
                        UnusedDocComment,
+                       AutoImpl,
                        );
 
     add_early_builtin_with_new!(sess,
@@ -181,6 +182,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
     // - Eventually, remove lint
     store.register_future_incompatible(sess,
                                        vec![
+        FutureIncompatibleInfo {
+            id: LintId::of(AUTO_IMPL),
+            reference: "issue #13231 <https://github.com/rust-lang/rust/issues/13231>",
+        },
         FutureIncompatibleInfo {
             id: LintId::of(PRIVATE_IN_PUBLIC),
             reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index fbe63e0ab4a8a..97c00aede90cf 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -144,7 +144,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
     is_const_fn => { cdata.is_const_fn(def_id.index) }
     is_foreign_item => { cdata.is_foreign_item(def_id.index) }
-    is_default_impl => { cdata.is_default_impl(def_id.index) }
+    is_auto_impl => { cdata.is_auto_impl(def_id.index) }
     describe_def => { cdata.get_def(def_id.index) }
     def_span => { cdata.get_span(def_id.index, &tcx.sess) }
     lookup_stability => {
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index b45196191249d..fa9b166ca942e 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -459,7 +459,7 @@ impl<'tcx> EntryKind<'tcx> {
 
             EntryKind::ForeignMod |
             EntryKind::Impl(_) |
-            EntryKind::DefaultImpl(_) |
+            EntryKind::AutoImpl(_) |
             EntryKind::Field |
             EntryKind::Generator(_) |
             EntryKind::Closure(_) => return None,
@@ -529,7 +529,7 @@ impl<'a, 'tcx> CrateMetadata {
         ty::TraitDef::new(self.local_def_id(item_id),
                           data.unsafety,
                           data.paren_sugar,
-                          data.has_default_impl,
+                          data.has_auto_impl,
                           self.def_path_table.def_path_hash(item_id))
     }
 
@@ -735,7 +735,7 @@ impl<'a, 'tcx> CrateMetadata {
                         continue;
                     }
                     EntryKind::Impl(_) |
-                    EntryKind::DefaultImpl(_) => continue,
+                    EntryKind::AutoImpl(_) => continue,
 
                     _ => {}
                 }
@@ -1082,9 +1082,9 @@ impl<'a, 'tcx> CrateMetadata {
         self.dllimport_foreign_items.contains(&id)
     }
 
-    pub fn is_default_impl(&self, impl_id: DefIndex) -> bool {
+    pub fn is_auto_impl(&self, impl_id: DefIndex) -> bool {
         match self.entry(impl_id).kind {
-            EntryKind::DefaultImpl(_) => true,
+            EntryKind::AutoImpl(_) => true,
             _ => false,
         }
     }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 725d6d8fad0e0..5f2b8efa5387f 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -919,7 +919,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
                     ctor_sig: None,
                 }), repr_options)
             }
-            hir::ItemDefaultImpl(..) => {
+            hir::ItemAutoImpl(..) => {
                 let data = ImplData {
                     polarity: hir::ImplPolarity::Positive,
                     defaultness: hir::Defaultness::Final,
@@ -928,7 +928,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
                     trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)),
                 };
 
-                EntryKind::DefaultImpl(self.lazy(&data))
+                EntryKind::AutoImpl(self.lazy(&data))
             }
             hir::ItemImpl(_, polarity, defaultness, ..) => {
                 let trait_ref = tcx.impl_trait_ref(def_id);
@@ -970,7 +970,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
                 let data = TraitData {
                     unsafety: trait_def.unsafety,
                     paren_sugar: trait_def.paren_sugar,
-                    has_default_impl: tcx.trait_has_default_impl(def_id),
+                    has_auto_impl: tcx.trait_is_auto(def_id),
                     super_predicates: self.lazy(&tcx.super_predicates_of(def_id)),
                 };
 
@@ -1517,7 +1517,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
             hir::ItemGlobalAsm(..) |
             hir::ItemExternCrate(..) |
             hir::ItemUse(..) |
-            hir::ItemDefaultImpl(..) |
+            hir::ItemAutoImpl(..) |
             hir::ItemTy(..) => {
                 // no sub-item recording needed in these cases
             }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index d85fdeb377cd3..3efe74bfecc92 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -303,7 +303,7 @@ pub enum EntryKind<'tcx> {
     Generator(Lazy<GeneratorData<'tcx>>),
     Trait(Lazy<TraitData<'tcx>>),
     Impl(Lazy<ImplData<'tcx>>),
-    DefaultImpl(Lazy<ImplData<'tcx>>),
+    AutoImpl(Lazy<ImplData<'tcx>>),
     Method(Lazy<MethodData<'tcx>>),
     AssociatedType(AssociatedContainer),
     AssociatedConst(AssociatedContainer, u8),
@@ -359,7 +359,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for EntryKind<'gcx> {
             EntryKind::Trait(ref trait_data) => {
                 trait_data.hash_stable(hcx, hasher);
             }
-            EntryKind::DefaultImpl(ref impl_data) |
+            EntryKind::AutoImpl(ref impl_data) |
             EntryKind::Impl(ref impl_data) => {
                 impl_data.hash_stable(hcx, hasher);
             }
@@ -426,14 +426,14 @@ impl_stable_hash_for!(struct VariantData<'tcx> {
 pub struct TraitData<'tcx> {
     pub unsafety: hir::Unsafety,
     pub paren_sugar: bool,
-    pub has_default_impl: bool,
+    pub has_auto_impl: bool,
     pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
 }
 
 impl_stable_hash_for!(struct TraitData<'tcx> {
     unsafety,
     paren_sugar,
-    has_default_impl,
+    has_auto_impl,
     super_predicates
 });
 
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index e44f3f3982491..f2e4fd7dbe0e3 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -213,7 +213,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                                         item.span,
                                         Some("place qualifiers on individual impl items instead"));
             }
-            ItemKind::DefaultImpl(..) => {
+            ItemKind::AutoImpl(..) => {
                 self.invalid_visibility(&item.vis, item.span, None);
             }
             ItemKind::ForeignMod(..) => {
@@ -229,7 +229,22 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     }
                 }
             }
-            ItemKind::Trait(.., ref bounds, ref trait_items) => {
+            ItemKind::Trait(is_auto, _, ref generics, ref bounds, ref trait_items) => {
+                if is_auto == IsAuto::Yes {
+                    // Auto traits cannot have generics, super traits nor contain items.
+                    if !generics.ty_params.is_empty() {
+                        self.err_handler().span_err(item.span,
+                                                    "auto traits cannot have generics");
+                    }
+                    if !bounds.is_empty() {
+                        self.err_handler().span_err(item.span,
+                                                    "auto traits cannot have super traits");
+                    }
+                    if !trait_items.is_empty() {
+                        self.err_handler().span_err(item.span,
+                                                    "auto traits cannot contain items");
+                    }
+                }
                 self.no_questions_in_bounds(bounds, "supertraits", true);
                 for trait_item in trait_items {
                     if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 3beba03ee1401..11eb8ac5f367f 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -147,7 +147,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
                 let def_id = self.tcx.hir.local_def_id(item.id);
                 cmp::min(self.item_ty_level(def_id), self.impl_trait_level(def_id))
             }
-            hir::ItemDefaultImpl(..) => {
+            hir::ItemAutoImpl(..) => {
                 let def_id = self.tcx.hir.local_def_id(item.id);
                 self.impl_trait_level(def_id)
             }
@@ -213,7 +213,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
             }
             hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) |
             hir::ItemGlobalAsm(..) | hir::ItemTy(..) | hir::ItemMod(..) |
-            hir::ItemFn(..) | hir::ItemExternCrate(..) | hir::ItemDefaultImpl(..) => {}
+            hir::ItemFn(..) | hir::ItemExternCrate(..) | hir::ItemAutoImpl(..) => {}
         }
 
         // Mark all items in interfaces of reachable items as reachable
@@ -225,7 +225,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
             // Reexports are handled in visit_mod
             hir::ItemUse(..) => {}
             // The interface is empty
-            hir::ItemDefaultImpl(..) => {}
+            hir::ItemAutoImpl(..) => {}
             // The interface is empty
             hir::ItemGlobalAsm(..) => {}
             // Visit everything
@@ -1504,7 +1504,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
                 }
             }
             // The interface is empty
-            hir::ItemDefaultImpl(..) => {}
+            hir::ItemAutoImpl(..) => {}
             // An inherent impl is public when its type is public
             // Subitems of inherent impls have their own publicity
             hir::ItemImpl(.., None, _, ref impl_item_refs) => {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 880b370c7f66b..ef556019699a0 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -376,7 +376,7 @@ impl<'a> Resolver<'a> {
                 self.insert_field_names(item_def_id, field_names);
             }
 
-            ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => {}
+            ItemKind::AutoImpl(..) | ItemKind::Impl(..) => {}
 
             ItemKind::Trait(..) => {
                 let def_id = self.definitions.local_def_id(item.id);
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 3b27890013a22..73b2c64122f07 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1841,7 +1841,7 @@ impl<'a> Resolver<'a> {
                                              |this| visit::walk_item(this, item));
             }
 
-            ItemKind::DefaultImpl(_, ref trait_ref) => {
+            ItemKind::AutoImpl(_, ref trait_ref) => {
                 self.with_optional_trait_ref(Some(trait_ref), |this, _| {
                     // Resolve type arguments in trait path
                     visit::walk_trait_ref(this, trait_ref);
@@ -1854,7 +1854,7 @@ impl<'a> Resolver<'a> {
                                             item.id,
                                             impl_items),
 
-            ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => {
+            ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
                     let local_def_id = this.definitions.local_def_id(item.id);
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index dcce714e5423d..41288c88ede90 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1232,7 +1232,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
                  ref impl_items) => {
                 self.process_impl(item, ty_params, trait_ref, &typ, impl_items)
             }
-            Trait(_, ref generics, ref trait_refs, ref methods) =>
+            Trait(_, _, ref generics, ref trait_refs, ref methods) =>
                 self.process_trait(item, generics, trait_refs, methods),
             Mod(ref m) => {
                 self.process_mod(item);
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index b0844d1b82404..80c1b0ebeb0b2 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -477,8 +477,13 @@ impl Sig for ast::Item {
                 sig.text.push_str(" {}");
                 Ok(sig)
             }
-            ast::ItemKind::Trait(unsafety, ref generics, ref bounds, _) => {
+            ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, _) => {
                 let mut text = String::new();
+
+                if is_auto == ast::IsAuto::Yes {
+                    text.push_str("auto ");
+                }
+
                 if unsafety == ast::Unsafety::Unsafe {
                     text.push_str("unsafe ");
                 }
@@ -499,7 +504,7 @@ impl Sig for ast::Item {
 
                 Ok(sig)
             }
-            ast::ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
+            ast::ItemKind::AutoImpl(unsafety, ref trait_ref) => {
                 let mut text = String::new();
                 if unsafety == ast::Unsafety::Unsafe {
                     text.push_str("unsafe ");
diff --git a/src/librustc_trans_utils/collector.rs b/src/librustc_trans_utils/collector.rs
index cf9b80e5ed404..c45ab65e9d850 100644
--- a/src/librustc_trans_utils/collector.rs
+++ b/src/librustc_trans_utils/collector.rs
@@ -883,7 +883,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
             hir::ItemUse(..)         |
             hir::ItemForeignMod(..)  |
             hir::ItemTy(..)          |
-            hir::ItemDefaultImpl(..) |
+            hir::ItemAutoImpl(..) |
             hir::ItemTrait(..)       |
             hir::ItemMod(..)         => {
                 // Nothing to do, just keep recursing...
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index ddbdd20430589..483af08cabfce 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -114,7 +114,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
                 // FIXME(#27579) what amount of WF checking do we need for neg impls?
 
                 let trait_ref = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)).unwrap();
-                if !tcx.trait_has_default_impl(trait_ref.def_id) {
+                if !tcx.trait_is_auto(trait_ref.def_id) {
                     error_192(tcx, item.span);
                 }
             }
@@ -318,7 +318,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
     fn check_trait(&mut self, item: &hir::Item) {
         let trait_def_id = self.tcx.hir.local_def_id(item.id);
 
-        if self.tcx.trait_has_default_impl(trait_def_id) {
+        if self.tcx.trait_is_auto(trait_def_id) {
             self.check_auto_trait(trait_def_id, item.span);
         }
 
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 6109fc57b0dfc..90a0952af0425 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -132,7 +132,7 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
 
     unsafety::check(tcx);
     orphan::check(tcx);
-    overlap::check_default_impls(tcx);
+    overlap::check_auto_impls(tcx);
 
     // these queries are executed for side-effects (error reporting):
     tcx.crate_inherent_impls(LOCAL_CRATE);
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index a5edc95b79b08..9f18397362189 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -100,11 +100,11 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
                 // This final impl is legal according to the orpan
                 // rules, but it invalidates the reasoning from
                 // `two_foos` above.
-                debug!("trait_ref={:?} trait_def_id={:?} trait_has_default_impl={}",
+                debug!("trait_ref={:?} trait_def_id={:?} trait_is_auto={}",
                        trait_ref,
                        trait_def_id,
-                       self.tcx.trait_has_default_impl(trait_def_id));
-                if self.tcx.trait_has_default_impl(trait_def_id) &&
+                       self.tcx.trait_is_auto(trait_def_id));
+                if self.tcx.trait_is_auto(trait_def_id) &&
                    !trait_def_id.is_local() {
                     let self_ty = trait_ref.self_ty();
                     let opt_self_def_id = match self_ty.sty {
@@ -142,7 +142,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
                     }
                 }
             }
-            hir::ItemDefaultImpl(_, ref item_trait_ref) => {
+            hir::ItemAutoImpl(_, ref item_trait_ref) => {
                 // "Trait" impl
                 debug!("coherence2::orphan check: default trait impl {}",
                        self.tcx.hir.node_to_string(item.id));
diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
index 59ebae16d08ca..5cc6eaa5602fb 100644
--- a/src/librustc_typeck/coherence/overlap.rs
+++ b/src/librustc_typeck/coherence/overlap.rs
@@ -18,7 +18,7 @@ use syntax::ast;
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 
-pub fn check_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+pub fn check_auto_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut overlap = OverlapChecker { tcx };
 
     // this secondary walk specifically checks for some other cases,
@@ -74,19 +74,19 @@ struct OverlapChecker<'cx, 'tcx: 'cx> {
 impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> {
     fn visit_item(&mut self, item: &'v hir::Item) {
         match item.node {
-            hir::ItemDefaultImpl(..) => {
-                // look for another default impl; note that due to the
+            hir::ItemAutoImpl(..) => {
+                // look for another auto impl; note that due to the
                 // general orphan/coherence rules, it must always be
                 // in this crate.
                 let impl_def_id = self.tcx.hir.local_def_id(item.id);
                 let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
 
-                let prev_id = self.tcx.hir.trait_default_impl(trait_ref.def_id).unwrap();
+                let prev_id = self.tcx.hir.trait_auto_impl(trait_ref.def_id).unwrap();
                 if prev_id != item.id {
                     let mut err = struct_span_err!(self.tcx.sess,
                                                    self.tcx.span_of_impl(impl_def_id).unwrap(),
                                                    E0521,
-                                                   "redundant default implementations of trait \
+                                                   "redundant auto implementations of trait \
                                                     `{}`:",
                                                    trait_ref);
                     err.span_note(self.tcx
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index 4672975d056b8..280fb04e04001 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -84,7 +84,7 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
 impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> {
     fn visit_item(&mut self, item: &'v hir::Item) {
         match item.node {
-            hir::ItemDefaultImpl(unsafety, _) => {
+            hir::ItemAutoImpl(unsafety, _) => {
                 self.check_unsafety_coherence(item, None, unsafety, hir::ImplPolarity::Positive);
             }
             hir::ItemImpl(unsafety, polarity, _, ref generics, ..) => {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 75e864d07a6c2..814470974285f 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -73,7 +73,7 @@ pub fn provide(providers: &mut Providers) {
         impl_trait_ref,
         impl_polarity,
         is_foreign_item,
-        is_default_impl,
+        is_auto_impl,
         ..*providers
     };
 }
@@ -273,7 +273,7 @@ fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 ItemEnum(_, ref generics) |
                 ItemStruct(_, ref generics) |
                 ItemUnion(_, ref generics) => generics,
-                ItemTrait(_, ref generics, ..) => {
+                ItemTrait(_, _, ref generics, ..) => {
                     // Implied `Self: Trait` and supertrait bounds.
                     if param_id == item_node_id {
                         result.predicates.push(ty::TraitRef {
@@ -425,7 +425,7 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
             tcx.predicates_of(def_id);
             convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
         },
-        hir::ItemDefaultImpl(..) => {
+        hir::ItemAutoImpl(..) => {
             tcx.impl_trait_ref(def_id);
         }
         hir::ItemImpl(..) => {
@@ -670,7 +670,7 @@ fn super_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     };
 
     let (generics, bounds) = match item.node {
-        hir::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
+        hir::ItemTrait(.., ref generics, ref supertraits, _) => (generics, supertraits),
         _ => span_bug!(item.span,
                        "super_predicates invoked on non-trait"),
     };
@@ -713,7 +713,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let item = tcx.hir.expect_item(node_id);
 
     let unsafety = match item.node {
-        hir::ItemTrait(unsafety, ..) => unsafety,
+        hir::ItemTrait(_, unsafety, ..) => unsafety,
         _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
     };
 
@@ -730,11 +730,14 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 
     let def_path_hash = tcx.def_path_hash(def_id);
-    let has_default_impl = tcx.hir.trait_is_auto(def_id);
+    let is_auto = match item.node {
+        hir::ItemTrait(hir::IsAuto::Yes, ..) => true,
+        _ => tcx.hir.trait_is_auto(def_id),
+    };
     let def = ty::TraitDef::new(def_id,
                                 unsafety,
                                 paren_sugar,
-                                has_default_impl,
+                                is_auto,
                                 def_path_hash);
     tcx.alloc_trait_def(def)
 }
@@ -888,7 +891,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     generics
                 }
 
-                ItemTrait(_, ref generics, ..) => {
+                ItemTrait(_, _, ref generics, ..) => {
                     // Add in the self type parameter.
                     //
                     // Something of a hack: use the node id for the trait, also as
@@ -1074,7 +1077,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     let substs = Substs::identity_for_item(tcx, def_id);
                     tcx.mk_adt(def, substs)
                 }
-                ItemDefaultImpl(..) |
+                ItemAutoImpl(..) |
                 ItemTrait(..) |
                 ItemMod(..) |
                 ItemForeignMod(..) |
@@ -1223,7 +1226,7 @@ fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
     match tcx.hir.expect_item(node_id).node {
-        hir::ItemDefaultImpl(_, ref ast_trait_ref) => {
+        hir::ItemAutoImpl(_, ref ast_trait_ref) => {
             Some(AstConv::instantiate_mono_trait_ref(&icx,
                                                      ast_trait_ref,
                                                      tcx.mk_self_type()))
@@ -1350,7 +1353,7 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     generics
                 }
 
-                ItemTrait(_, ref generics, .., ref items) => {
+                ItemTrait(_, _, ref generics, .., ref items) => {
                     is_trait = Some((ty::TraitRef {
                         def_id,
                         substs: Substs::identity_for_item(tcx, def_id)
@@ -1665,13 +1668,13 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 }
 
-fn is_default_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+fn is_auto_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              def_id: DefId)
                              -> bool {
     match tcx.hir.get_if_local(def_id) {
-        Some(hir_map::NodeItem(&hir::Item { node: hir::ItemDefaultImpl(..), .. }))
+        Some(hir_map::NodeItem(&hir::Item { node: hir::ItemAutoImpl(..), .. }))
              => true,
         Some(_) => false,
-        _ => bug!("is_default_impl applied to non-local def-id {:?}", def_id)
+        _ => bug!("is_auto_impl applied to non-local def-id {:?}", def_id)
     }
 }
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 594cd0878cbfb..013eb9c8ed2da 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -1854,7 +1854,7 @@ unsafe impl !Clone for Foo { }
 
 This will compile:
 
-```
+```ignore (ignore auto_trait future compatibility warning)
 #![feature(optin_builtin_traits)]
 
 struct Foo;
@@ -4669,7 +4669,7 @@ register_diagnostics! {
 //  E0372, // coherence not object safe
     E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
            // between structures with the same definition
-    E0521, // redundant default implementations of trait
+    E0521, // redundant auto implementations of trait
     E0533, // `{}` does not name a unit variant, unit struct or a constant
 //  E0563, // cannot determine a type for this `impl Trait`: {} // removed in 6383de15
     E0564, // only named lifetimes are allowed in `impl Trait`,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 3a4dcc3217388..9fb9437e1bc9a 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -292,10 +292,10 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
         }
     }
 
-    // If this is a defaulted impl, then bail out early here
-    if tcx.is_default_impl(did) {
+    // If this is an auto impl, then bail out early here
+    if tcx.is_auto_impl(did) {
         return ret.push(clean::Item {
-            inner: clean::DefaultImplItem(clean::DefaultImpl {
+            inner: clean::AutoImplItem(clean::AutoImpl {
                 // FIXME: this should be decoded
                 unsafety: hir::Unsafety::Normal,
                 trait_: match associated_trait.as_ref().unwrap().clean(cx) {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index f8fea643d5e14..4b60536e1d176 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -425,7 +425,7 @@ pub enum ItemEnum {
     PrimitiveItem(PrimitiveType),
     AssociatedConstItem(Type, Option<String>),
     AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
-    DefaultImplItem(DefaultImpl),
+    AutoImplItem(AutoImpl),
     /// An item that has been stripped by a rustdoc pass
     StrippedItem(Box<ItemEnum>),
 }
@@ -2733,12 +2733,12 @@ fn build_deref_target_impls(cx: &DocContext,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct DefaultImpl {
+pub struct AutoImpl {
     pub unsafety: hir::Unsafety,
     pub trait_: Type,
 }
 
-impl Clean<Item> for doctree::DefaultImpl {
+impl Clean<Item> for doctree::AutoImpl {
     fn clean(&self, cx: &DocContext) -> Item {
         Item {
             name: None,
@@ -2748,7 +2748,7 @@ impl Clean<Item> for doctree::DefaultImpl {
             visibility: Some(Public),
             stability: None,
             deprecation: None,
-            inner: DefaultImplItem(DefaultImpl {
+            inner: AutoImplItem(AutoImpl {
                 unsafety: self.unsafety,
                 trait_: self.trait_.clean(cx),
             }),
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 71594825cdb01..c21bfd8842f72 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -44,7 +44,7 @@ pub struct Module {
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub impls: Vec<Impl>,
-    pub def_traits: Vec<DefaultImpl>,
+    pub def_traits: Vec<AutoImpl>,
     pub foreigns: Vec<hir::ForeignMod>,
     pub macros: Vec<Macro>,
     pub is_crate: bool,
@@ -227,7 +227,7 @@ pub struct Impl {
     pub id: ast::NodeId,
 }
 
-pub struct DefaultImpl {
+pub struct AutoImpl {
     pub unsafety: hir::Unsafety,
     pub trait_: hir::TraitRef,
     pub id: ast::NodeId,
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index c9c5f01f0aea1..c214c15ed4b2b 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -82,7 +82,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
             clean::PrimitiveItem(..)       => ItemType::Primitive,
             clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
             clean::AssociatedTypeItem(..)  => ItemType::AssociatedType,
-            clean::DefaultImplItem(..)     => ItemType::Impl,
+            clean::AutoImplItem(..)        => ItemType::Impl,
             clean::ForeignTypeItem         => ItemType::ForeignType,
             clean::StrippedItem(..)        => unreachable!(),
         }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index edd01a66075b0..7e1742c6e1085 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1929,7 +1929,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
     document(w, cx, item)?;
 
     let mut indices = (0..items.len()).filter(|i| {
-        if let clean::DefaultImplItem(..) = items[*i].inner {
+        if let clean::AutoImplItem(..) = items[*i].inner {
             return false;
         }
         !items[*i].is_stripped()
@@ -3744,7 +3744,7 @@ fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item,
                    ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
                    ItemType::AssociatedType, ItemType::AssociatedConst, ItemType::ForeignType] {
         if items.iter().any(|it| {
-            if let clean::DefaultImplItem(..) = it.inner {
+            if let clean::AutoImplItem(..) = it.inner {
                 false
             } else {
                 !it.is_stripped() && it.type_() == myty
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 959543404d8d2..77d97c84c99bf 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -116,7 +116,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
             // handled in the `strip-priv-imports` pass
             clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
 
-            clean::DefaultImplItem(..) | clean::ImplItem(..) => {}
+            clean::AutoImplItem(..) | clean::ImplItem(..) => {}
 
             // tymethods/macros have no control over privacy
             clean::MacroItem(..) | clean::TyMethodItem(..) => {}
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 327a330c2a2e5..b55076a01afe0 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -481,7 +481,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 };
                 om.constants.push(s);
             },
-            hir::ItemTrait(unsafety, ref gen, ref b, ref item_ids) => {
+            hir::ItemTrait(_, unsafety, ref gen, ref b, ref item_ids) => {
                 let items = item_ids.iter()
                                     .map(|ti| self.cx.tcx.hir.trait_item(ti.id).clone())
                                     .collect();
@@ -532,10 +532,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     om.impls.push(i);
                 }
             },
-            hir::ItemDefaultImpl(unsafety, ref trait_ref) => {
+            hir::ItemAutoImpl(unsafety, ref trait_ref) => {
                 // See comment above about ItemImpl.
                 if !self.inlining {
-                    let i = DefaultImpl {
+                    let i = AutoImpl {
                         unsafety,
                         trait_: trait_ref.clone(),
                         id: item.id,
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 97b09b7e2ad99..385076e50ddea 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -188,6 +188,8 @@ pub struct AssertUnwindSafe<T>(
 // * Types like Mutex/RwLock which are explicilty poisoned are unwind safe
 // * Our custom AssertUnwindSafe wrapper is indeed unwind safe
 #[stable(feature = "catch_unwind", since = "1.9.0")]
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 impl UnwindSafe for .. {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {}
@@ -221,6 +223,8 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
 // only thing which doesn't implement it (which then transitively applies to
 // everything else).
 #[stable(feature = "catch_unwind", since = "1.9.0")]
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 impl RefUnwindSafe for .. {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index be0af8052eb13..99dff4edaade7 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1581,6 +1581,13 @@ impl FnDecl {
     }
 }
 
+/// Is the trait definition an auto trait?
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum IsAuto {
+    Yes,
+    No
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Unsafety {
     Unsafe,
@@ -1942,12 +1949,12 @@ pub enum ItemKind {
     Union(VariantData, Generics),
     /// A Trait declaration (`trait` or `pub trait`).
     ///
-    /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
-    Trait(Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
+    /// E.g. `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`
+    Trait(IsAuto, Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
     /// Auto trait implementation.
     ///
     /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
-    DefaultImpl(Unsafety, TraitRef),
+    AutoImpl(Unsafety, TraitRef),
     /// An implementation.
     ///
     /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
@@ -1986,7 +1993,7 @@ impl ItemKind {
             ItemKind::Mac(..) |
             ItemKind::MacroDef(..) |
             ItemKind::Impl(..) |
-            ItemKind::DefaultImpl(..) => "item"
+            ItemKind::AutoImpl(..) => "item"
         }
     }
 }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 30451ec757a9f..e354d56f5afc2 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1357,10 +1357,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 }
             }
 
-            ast::ItemKind::DefaultImpl(..) => {
+            ast::ItemKind::AutoImpl(..) => {
                 gate_feature_post!(&self, optin_builtin_traits,
                                    i.span,
-                                   "default trait implementations are experimental \
+                                   "auto trait implementations are experimental \
                                     and possibly buggy");
             }
 
@@ -1389,6 +1389,12 @@ 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::MacroDef(ast::MacroDef { legacy: false, .. }) => {
                 let msg = "`macro` is experimental";
                 gate_feature_post!(&self, decl_macro, i.span, msg);
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index fea49424dc8d2..cc63bffec48a1 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -908,8 +908,8 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
             let generics = folder.fold_generics(generics);
             ItemKind::Union(folder.fold_variant_data(struct_def), generics)
         }
-        ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
-            ItemKind::DefaultImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
+        ItemKind::AutoImpl(unsafety, ref trait_ref) => {
+            ItemKind::AutoImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
         }
         ItemKind::Impl(unsafety,
                        polarity,
@@ -926,7 +926,8 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
             folder.fold_ty(ty),
             impl_items.move_flat_map(|item| folder.fold_impl_item(item)),
         ),
-        ItemKind::Trait(unsafety, generics, bounds, items) => ItemKind::Trait(
+        ItemKind::Trait(is_auto, unsafety, generics, bounds, items) => ItemKind::Trait(
+            is_auto,
             unsafety,
             folder.fold_generics(generics),
             folder.fold_bounds(bounds),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index a3a265450ab0e..5176379ee2f88 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -21,7 +21,7 @@ use ast::EnumDef;
 use ast::{Expr, ExprKind, RangeLimits};
 use ast::{Field, FnDecl};
 use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
-use ast::{Ident, ImplItem, Item, ItemKind};
+use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
 use ast::{Lifetime, LifetimeDef, Lit, LitKind, UintTy};
 use ast::Local;
 use ast::MacStmtStyle;
@@ -3873,6 +3873,16 @@ impl<'a> Parser<'a> {
         self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
     }
 
+    fn eat_auto_trait(&mut self) -> bool {
+        if self.token.is_keyword(keywords::Auto)
+            && self.look_ahead(1, |t| t.is_keyword(keywords::Trait))
+        {
+            self.eat_keyword(keywords::Auto) && self.eat_keyword(keywords::Trait)
+        } else {
+            false
+        }
+    }
+
     fn is_defaultness(&self) -> bool {
         // `pub` is included for better error messages
         self.token.is_keyword(keywords::Default) &&
@@ -5051,7 +5061,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse trait Foo { ... }
-    fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
+    fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
         let ident = self.parse_ident()?;
         let mut tps = self.parse_generics()?;
 
@@ -5078,7 +5088,7 @@ impl<'a> Parser<'a> {
                 }
             }
         }
-        Ok((ident, ItemKind::Trait(unsafety, tps, bounds, trait_items), None))
+        Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None))
     }
 
     /// Parses items implementations variants
@@ -5133,19 +5143,19 @@ impl<'a> Parser<'a> {
 
         if opt_trait.is_some() && self.eat(&token::DotDot) {
             if generics.is_parameterized() {
-                self.span_err(impl_span, "default trait implementations are not \
+                self.span_err(impl_span, "auto trait implementations are not \
                                           allowed to have generics");
             }
 
             if let ast::Defaultness::Default = defaultness {
                 self.span_err(impl_span, "`default impl` is not allowed for \
-                                         default trait implementations");
+                                         auto trait implementations");
             }
 
             self.expect(&token::OpenDelim(token::Brace))?;
             self.expect(&token::CloseDelim(token::Brace))?;
             Ok((keywords::Invalid.ident(),
-             ItemKind::DefaultImpl(unsafety, opt_trait.unwrap()), None))
+             ItemKind::AutoImpl(unsafety, opt_trait.unwrap()), None))
         } else {
             if opt_trait.is_some() {
                 ty = self.parse_ty()?;
@@ -5988,13 +5998,19 @@ impl<'a> Parser<'a> {
             return Ok(Some(item));
         }
         if self.check_keyword(keywords::Unsafe) &&
-            self.look_ahead(1, |t| t.is_keyword(keywords::Trait))
+            (self.look_ahead(1, |t| t.is_keyword(keywords::Trait)) ||
+            self.look_ahead(1, |t| t.is_keyword(keywords::Auto)))
         {
             // UNSAFE TRAIT ITEM
             self.expect_keyword(keywords::Unsafe)?;
-            self.expect_keyword(keywords::Trait)?;
+            let is_auto = if self.eat_keyword(keywords::Trait) {
+                IsAuto::No
+            } else {
+                self.eat_auto_trait();
+                IsAuto::Yes
+            };
             let (ident, item_, extra_attrs) =
-                self.parse_item_trait(ast::Unsafety::Unsafe)?;
+                self.parse_item_trait(is_auto, ast::Unsafety::Unsafe)?;
             let prev_span = self.prev_span;
             let item = self.mk_item(lo.to(prev_span),
                                     ident,
@@ -6097,10 +6113,19 @@ impl<'a> Parser<'a> {
                                     maybe_append(attrs, extra_attrs));
             return Ok(Some(item));
         }
-        if self.eat_keyword(keywords::Trait) {
+        if self.check_keyword(keywords::Trait)
+            || (self.check_keyword(keywords::Auto)
+                && self.look_ahead(1, |t| t.is_keyword(keywords::Trait)))
+        {
+            let is_auto = if self.eat_keyword(keywords::Trait) {
+                IsAuto::No
+            } else {
+                self.eat_auto_trait();
+                IsAuto::Yes
+            };
             // TRAIT ITEM
             let (ident, item_, extra_attrs) =
-                self.parse_item_trait(ast::Unsafety::Normal)?;
+                self.parse_item_trait(is_auto, ast::Unsafety::Normal)?;
             let prev_span = self.prev_span;
             let item = self.mk_item(lo.to(prev_span),
                                     ident,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 8a970fd409895..227db93cf656e 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1287,7 +1287,7 @@ impl<'a> State<'a> {
                 self.head(&visibility_qualified(&item.vis, "union"))?;
                 self.print_struct(struct_def, generics, item.ident, item.span, true)?;
             }
-            ast::ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
+            ast::ItemKind::AutoImpl(unsafety, ref trait_ref) => {
                 self.head("")?;
                 self.print_visibility(&item.vis)?;
                 self.print_unsafety(unsafety)?;
@@ -1338,10 +1338,11 @@ impl<'a> State<'a> {
                 }
                 self.bclose(item.span)?;
             }
-            ast::ItemKind::Trait(unsafety, ref generics, ref bounds, ref trait_items) => {
+            ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
                 self.head("")?;
                 self.print_visibility(&item.vis)?;
                 self.print_unsafety(unsafety)?;
+                self.print_is_auto(is_auto)?;
                 self.word_nbsp("trait")?;
                 self.print_ident(item.ident)?;
                 self.print_generics(generics)?;
@@ -3123,6 +3124,13 @@ impl<'a> State<'a> {
             ast::Unsafety::Unsafe => self.word_nbsp("unsafe"),
         }
     }
+
+    pub fn print_is_auto(&mut self, s: ast::IsAuto) -> io::Result<()> {
+        match s {
+            ast::IsAuto::Yes => self.word_nbsp("auto"),
+            ast::IsAuto::No => Ok(()),
+        }
+    }
 }
 
 fn repeat(s: &str, n: usize) -> String { iter::repeat(s).take(n).collect() }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 96e47a6cc0ff6..c2e90f0bb13a3 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -281,7 +281,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_generics(type_parameters);
             visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
         }
-        ItemKind::DefaultImpl(_, ref trait_ref) => {
+        ItemKind::AutoImpl(_, ref trait_ref) => {
             visitor.visit_trait_ref(trait_ref)
         }
         ItemKind::Impl(_, _, _,
@@ -300,7 +300,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_variant_data(struct_definition, item.ident,
                                      generics, item.id, item.span);
         }
-        ItemKind::Trait(_, ref generics, ref bounds, ref methods) => {
+        ItemKind::Trait(.., ref generics, ref bounds, ref methods) => {
             visitor.visit_generics(generics);
             walk_list!(visitor, visit_ty_param_bound, bounds);
             walk_list!(visitor, visit_trait_item, methods);
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 872fc031cfb1a..26e6f27e20f40 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -309,11 +309,12 @@ declare_keywords! {
     (54, Yield,          "yield")
 
     // Weak keywords, have special meaning only in specific contexts.
-    (55, Catch,          "catch")
-    (56, Default,        "default")
-    (57, Dyn,            "dyn")
-    (58, StaticLifetime, "'static")
-    (59, Union,          "union")
+    (55, Auto,           "auto")
+    (56, Catch,          "catch")
+    (57, Default,        "default")
+    (58, Dyn,            "dyn")
+    (59, StaticLifetime, "'static")
+    (60, Union,          "union")
 }
 
 // If an interner exists in TLS, return it. Otherwise, prepare a fresh one.
diff --git a/src/rtstartup/rsbegin.rs b/src/rtstartup/rsbegin.rs
index 8733c7436d5bd..d33b52486296f 100644
--- a/src/rtstartup/rsbegin.rs
+++ b/src/rtstartup/rsbegin.rs
@@ -14,7 +14,7 @@
 // When an executable or dylib image is linked, all user code and libraries are
 // "sandwiched" between these two object files, so code or data from rsbegin.o
 // become first in the respective sections of the image, whereas code and data
-// from rsend.o become the last ones.  This effect can be used to place symbols
+// from rsend.o become the last ones. This effect can be used to place symbols
 // at the beginning or at the end of a section, as well as to insert any required
 // headers or footers.
 //
@@ -31,11 +31,15 @@
 trait Sized {}
 #[lang = "sync"]
 trait Sync {}
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 impl Sync for .. {}
 #[lang = "copy"]
 trait Copy {}
 #[lang = "freeze"]
 trait Freeze {}
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 impl Freeze for .. {}
 
 #[lang = "drop_in_place"]
diff --git a/src/rtstartup/rsend.rs b/src/rtstartup/rsend.rs
index a6aed3540ddbb..410366d0d7ff5 100644
--- a/src/rtstartup/rsend.rs
+++ b/src/rtstartup/rsend.rs
@@ -23,6 +23,8 @@ impl<T> Sync for T {}
 trait Copy {}
 #[lang = "freeze"]
 trait Freeze {}
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 impl Freeze for .. {}
 
 #[lang = "drop_in_place"]
diff --git a/src/test/compile-fail/auto-impl-future-compat.rs b/src/test/compile-fail/auto-impl-future-compat.rs
new file mode 100644
index 0000000000000..5c32a75639880
--- /dev/null
+++ b/src/test/compile-fail/auto-impl-future-compat.rs
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(optin_builtin_traits)]
+
+trait Foo {}
+impl Foo for .. {}
+//~^ ERROR The form `impl Foo for .. {}` will be removed, please use `auto trait Foo {}`
+//~^^ WARN this was previously accepted by the compiler
diff --git a/src/test/compile-fail/auto-trait-validation.rs b/src/test/compile-fail/auto-trait-validation.rs
new file mode 100644
index 0000000000000..b28b776d9c2a6
--- /dev/null
+++ b/src/test/compile-fail/auto-trait-validation.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(optin_builtin_traits)]
+
+auto trait Generic<T> {}
+//~^ ERROR auto traits cannot have generics
+//~^^ traits with auto impls (`e.g. impl Trait for ..`) can not have type parameters
+auto trait Bound : Copy {}
+//~^ ERROR auto traits cannot have super traits
+//~^^ traits with auto impls (`e.g. impl Trait for ..`) cannot have predicates
+auto trait MyTrait { fn foo() {} }
+//~^ ERROR auto traits cannot contain items
+//~^^ traits with default impls (`e.g. impl Trait for ..`) must have no methods or associated items
+fn main() {}
diff --git a/src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs b/src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs
index 2e425ac96c55f..1e1c55de87e17 100644
--- a/src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs
+++ b/src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs
@@ -12,6 +12,7 @@
 #![crate_type = "rlib"]
 
 pub trait DefaultedTrait { }
+#[allow(auto_impl)]
 impl DefaultedTrait for .. { }
 
 pub struct Something<T> { t: T }
diff --git a/src/test/compile-fail/coherence-default-trait-impl.rs b/src/test/compile-fail/coherence-default-trait-impl.rs
index e6bf068156c2b..9c26b8b05f259 100644
--- a/src/test/compile-fail/coherence-default-trait-impl.rs
+++ b/src/test/compile-fail/coherence-default-trait-impl.rs
@@ -12,18 +12,22 @@
 
 trait MyTrait { fn foo() {} }
 
+#[allow(auto_impl)]
 impl MyTrait for .. {}
-//~^ ERROR redundant default implementations of trait `MyTrait`
+//~^ ERROR redundant auto implementations of trait `MyTrait`
 
+#[allow(auto_impl)]
 impl MyTrait for .. {}
 
 trait MySafeTrait {}
 
+#[allow(auto_impl)]
 unsafe impl MySafeTrait for .. {}
 //~^ ERROR implementing the trait `MySafeTrait` is not unsafe
 
 unsafe trait MyUnsafeTrait {}
 
+#[allow(auto_impl)]
 impl MyUnsafeTrait for .. {}
 //~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
 
diff --git a/src/test/compile-fail/feature-gate-optin-builtin-traits.rs b/src/test/compile-fail/feature-gate-optin-builtin-traits.rs
index 59d7473a741d6..4c5502cec18a8 100644
--- a/src/test/compile-fail/feature-gate-optin-builtin-traits.rs
+++ b/src/test/compile-fail/feature-gate-optin-builtin-traits.rs
@@ -17,8 +17,12 @@ trait DummyTrait {
     fn dummy(&self) {}
 }
 
+auto trait AutoDummyTrait {}
+//~^ ERROR auto traits are experimental and possibly buggy
+
+#[allow(auto_impl)]
 impl DummyTrait for .. {}
-//~^ ERROR default trait implementations are experimental and possibly buggy
+//~^ ERROR auto trait implementations are experimental and possibly buggy
 
 impl !DummyTrait for DummyStruct {}
 //~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now
diff --git a/src/test/compile-fail/issue-23080-2.rs b/src/test/compile-fail/issue-23080-2.rs
index 9d20c17674bc3..bf44cd53f67dc 100644
--- a/src/test/compile-fail/issue-23080-2.rs
+++ b/src/test/compile-fail/issue-23080-2.rs
@@ -17,6 +17,7 @@ unsafe trait Trait {
     type Output;
 }
 
+#[allow(auto_impl)]
 unsafe impl Trait for .. {}
 
 fn call_method<T: Trait>(x: T) {}
diff --git a/src/test/compile-fail/issue-23080.rs b/src/test/compile-fail/issue-23080.rs
index 2e8cba87be515..1fb63391d5608 100644
--- a/src/test/compile-fail/issue-23080.rs
+++ b/src/test/compile-fail/issue-23080.rs
@@ -19,6 +19,7 @@ unsafe trait Trait {
     }
 }
 
+#[allow(auto_impl)]
 unsafe impl Trait for .. {}
 
 fn call_method<T: Trait>(x: T) {
diff --git a/src/test/compile-fail/phantom-oibit.rs b/src/test/compile-fail/phantom-oibit.rs
index c84927ea26639..1c1cb396a54f2 100644
--- a/src/test/compile-fail/phantom-oibit.rs
+++ b/src/test/compile-fail/phantom-oibit.rs
@@ -18,6 +18,7 @@ use std::marker::{PhantomData};
 
 unsafe trait Zen {}
 
+#[allow(auto_impl)]
 unsafe impl Zen for .. {}
 
 unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}
diff --git a/src/test/compile-fail/privacy-sanity.rs b/src/test/compile-fail/privacy-sanity.rs
index 933ec3837dfc7..34082adb8f9a5 100644
--- a/src/test/compile-fail/privacy-sanity.rs
+++ b/src/test/compile-fail/privacy-sanity.rs
@@ -21,6 +21,7 @@ pub struct S {
 }
 struct Ts(pub u8);
 
+#[allow(auto_impl)]
 pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
 pub impl Tr for S {  //~ ERROR unnecessary visibility qualifier
     pub fn f() {} //~ ERROR unnecessary visibility qualifier
@@ -49,6 +50,7 @@ const MAIN: u8 = {
     }
     struct Ts(pub u8);
 
+    #[allow(auto_impl)]
     pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
     pub impl Tr for S {  //~ ERROR unnecessary visibility qualifier
         pub fn f() {} //~ ERROR unnecessary visibility qualifier
@@ -80,6 +82,7 @@ fn main() {
     }
     struct Ts(pub u8);
 
+    #[allow(auto_impl)]
     pub impl MarkerTr for .. {} //~ ERROR unnecessary visibility qualifier
     pub impl Tr for S {  //~ ERROR unnecessary visibility qualifier
         pub fn f() {} //~ ERROR unnecessary visibility qualifier
diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs
index c1746d765dd9f..cad43ffeacec9 100644
--- a/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs
+++ b/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs
@@ -13,7 +13,8 @@
 
 trait Foo {}
 
+#[allow(auto_impl)]
 default impl Foo for .. {}
-//~^ ERROR `default impl` is not allowed for default trait implementations
+//~^ ERROR `default impl` is not allowed for auto trait implementations
 
 fn main() {}
diff --git a/src/test/compile-fail/specialization/specialization-polarity.rs b/src/test/compile-fail/specialization/specialization-polarity.rs
index 27a3e31491b82..c97cb3f6bb70b 100644
--- a/src/test/compile-fail/specialization/specialization-polarity.rs
+++ b/src/test/compile-fail/specialization/specialization-polarity.rs
@@ -15,6 +15,7 @@
 
 trait Foo {}
 
+#[allow(auto_impl)]
 impl Foo for .. {}
 
 impl<T> Foo for T {}
@@ -22,6 +23,7 @@ impl !Foo for u8 {} //~ ERROR E0119
 
 trait Bar {}
 
+#[allow(auto_impl)]
 impl Bar for .. {}
 
 impl<T> !Bar for T {}
diff --git a/src/test/compile-fail/syntaxt-default-trait-impls.rs b/src/test/compile-fail/syntaxt-default-trait-impls.rs
index 7d6a1c9c1544c..45303cbf70025 100644
--- a/src/test/compile-fail/syntaxt-default-trait-impls.rs
+++ b/src/test/compile-fail/syntaxt-default-trait-impls.rs
@@ -10,9 +10,10 @@
 
 #![feature(optin_builtin_traits)]
 
-trait MyDefaultImpl {}
+trait MyAutoImpl {}
 
-impl<T> MyDefaultImpl for .. {}
-//~^ ERROR default trait implementations are not allowed to have generics
+#[allow(auto_impl)]
+impl<T> MyAutoImpl for .. {}
+//~^ ERROR auto trait implementations are not allowed to have generics
 
 fn main() {}
diff --git a/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs b/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs
index fe0e583b20a38..6c7928f13f894 100644
--- a/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs
+++ b/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs
@@ -15,6 +15,7 @@
 #![feature(optin_builtin_traits)]
 
 trait Magic: Copy {} //~ ERROR E0568
+#[allow(auto_impl)]
 impl Magic for .. {}
 
 fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
diff --git a/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs b/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs
index f6678ac7c2d8c..173582ed22fdc 100644
--- a/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs
+++ b/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs
@@ -11,6 +11,7 @@
 #![feature(optin_builtin_traits)]
 
 trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
+#[allow(auto_impl)]
 impl Magic for .. {}
 impl<T:Magic> Magic for T {}
 
diff --git a/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs b/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs
index 9497dfb39d7d0..6802f72504b7d 100644
--- a/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs
+++ b/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs
@@ -35,6 +35,7 @@
 #![feature(optin_builtin_traits)]
 
 trait Magic: Copy {} //~ ERROR E0568
+#[allow(auto_impl)]
 impl Magic for .. {}
 impl<T:Magic> Magic for T {}
 
diff --git a/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs b/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs
index 5a852c54869a5..3c409d1b371eb 100644
--- a/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs
+++ b/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs
@@ -11,4 +11,5 @@
 #![feature(optin_builtin_traits)]
 
 trait Magic<T> {} //~ ERROR E0567
+#[allow(auto_impl)]
 impl Magic<isize> for .. {}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs b/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs
index 8a46d6c76c30f..a837d8c9ca74e 100644
--- a/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs
+++ b/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs
@@ -12,6 +12,7 @@
 
 trait MyTrait {}
 
+#[allow(auto_impl)]
 impl MyTrait for .. {}
 
 struct MyS;
diff --git a/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs b/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs
index 3d7746b369cc0..bed184eb4ccca 100644
--- a/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs
+++ b/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs
@@ -12,6 +12,7 @@
 
 trait MyTrait {}
 
+#[allow(auto_impl)]
 impl MyTrait for .. {}
 impl<T> !MyTrait for *mut T {}
 
diff --git a/src/test/compile-fail/typeck-default-trait-impl-negation.rs b/src/test/compile-fail/typeck-default-trait-impl-negation.rs
index 8c2658b89a506..f3a6d8a342e22 100644
--- a/src/test/compile-fail/typeck-default-trait-impl-negation.rs
+++ b/src/test/compile-fail/typeck-default-trait-impl-negation.rs
@@ -12,10 +12,12 @@
 
 trait MyTrait {}
 
+#[allow(auto_impl)]
 impl MyTrait for .. {}
 
 unsafe trait MyUnsafeTrait {}
 
+#[allow(auto_impl)]
 unsafe impl MyUnsafeTrait for .. {}
 
 struct ThisImplsTrait;
diff --git a/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs b/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs
index 4d71517e06058..da3e926d6fc1f 100644
--- a/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs
+++ b/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs
@@ -10,6 +10,7 @@
 
 #![feature(optin_builtin_traits)]
 
+#[allow(auto_impl)]
 impl Copy for .. {} //~ ERROR E0318
      //~^ NOTE `Copy` trait not defined in this crate
 fn main() {}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-precedence.rs b/src/test/compile-fail/typeck-default-trait-impl-precedence.rs
index 66c7a1c75ffe4..bdd6487b86d74 100644
--- a/src/test/compile-fail/typeck-default-trait-impl-precedence.rs
+++ b/src/test/compile-fail/typeck-default-trait-impl-precedence.rs
@@ -16,6 +16,7 @@
 #![feature(optin_builtin_traits)]
 
 trait Defaulted { }
+#[allow(auto_impl)]
 impl Defaulted for .. { }
 impl<'a,T:Signed> Defaulted for &'a T { }
 impl<'a,T:Signed> Defaulted for &'a mut T { }
diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs
index 44950ee8a601f..108363a464519 100644
--- a/src/test/incremental/hashes/trait_defs.rs
+++ b/src/test/incremental/hashes/trait_defs.rs
@@ -249,7 +249,7 @@ trait TraitChangeMethodParametersOrder {
 
 // Add default implementation to method -------------------------------------------
 #[cfg(cfail1)]
-trait TraitAddMethodDefaultImplementation {
+trait TraitAddMethodAutoImplementation {
     fn method();
 }
 
@@ -258,7 +258,7 @@ trait TraitAddMethodDefaultImplementation {
 #[rustc_clean(label="Hir", cfg="cfail3")]
 #[rustc_metadata_clean(cfg="cfail2")]
 #[rustc_metadata_clean(cfg="cfail3")]
-trait TraitAddMethodDefaultImplementation {
+trait TraitAddMethodAutoImplementation {
     #[rustc_dirty(label="Hir", cfg="cfail2")]
     #[rustc_clean(label="Hir", cfg="cfail3")]
     #[rustc_metadata_dirty(cfg="cfail2")]
diff --git a/src/test/pretty/default-trait-impl.rs b/src/test/pretty/auto-trait.rs
similarity index 90%
rename from src/test/pretty/default-trait-impl.rs
rename to src/test/pretty/auto-trait.rs
index a5246b9300c91..842af49e8a7f9 100644
--- a/src/test/pretty/default-trait-impl.rs
+++ b/src/test/pretty/auto-trait.rs
@@ -12,8 +12,8 @@
 
 // pp-exact
 
-trait MyTrait { }
+auto trait MyTrait { }
 
-impl MyTrait for .. { }
+unsafe auto trait UnsafeMyTrait { }
 
 pub fn main() { }
diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs
index 8ab8f4715755d..185476fb704f7 100644
--- a/src/test/run-make/simd-ffi/simd.rs
+++ b/src/test/run-make/simd-ffi/simd.rs
@@ -81,4 +81,5 @@ pub mod marker {
 
 #[lang = "freeze"]
 trait Freeze {}
+#[allow(auto_impl)]
 impl Freeze for .. {}
diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs
index af24c3b460b2e..a0feb72702834 100644
--- a/src/test/run-make/target-specs/foo.rs
+++ b/src/test/run-make/target-specs/foo.rs
@@ -19,6 +19,7 @@ trait Sized { }
 
 #[lang = "freeze"]
 trait Freeze {}
+#[allow(auto_impl)]
 impl Freeze for .. {}
 
 #[lang="start"]
diff --git a/src/test/run-pass/auto-is-contextual.rs b/src/test/run-pass/auto-is-contextual.rs
new file mode 100644
index 0000000000000..ad433cc26a790
--- /dev/null
+++ b/src/test/run-pass/auto-is-contextual.rs
@@ -0,0 +1,24 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! auto {
+    () => (struct S;)
+}
+
+auto!();
+
+fn auto() {}
+
+fn main() {
+    auto();
+    let auto = 10;
+    auto;
+    auto as u8;
+}
diff --git a/src/test/run-pass/auto-traits.rs b/src/test/run-pass/auto-traits.rs
new file mode 100644
index 0000000000000..752f5a11375ad
--- /dev/null
+++ b/src/test/run-pass/auto-traits.rs
@@ -0,0 +1,36 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(optin_builtin_traits)]
+
+auto trait Auto {}
+// Redundant but accepted until we remove it.
+#[allow(auto_impl)]
+impl Auto for .. {}
+
+unsafe auto trait AutoUnsafe {}
+
+impl !Auto for bool {}
+impl !AutoUnsafe for bool {}
+
+struct AutoBool(bool);
+
+impl Auto for AutoBool {}
+unsafe impl AutoUnsafe for AutoBool {}
+
+fn take_auto<T: Auto>(_: T) {}
+fn take_auto_unsafe<T: AutoUnsafe>(_: T) {}
+
+fn main() {
+    take_auto(0);
+    take_auto(AutoBool(true));
+    take_auto_unsafe(0);
+    take_auto_unsafe(AutoBool(true));
+}
diff --git a/src/test/run-pass/issue-29516.rs b/src/test/run-pass/issue-29516.rs
index b586abc29e243..5fa0a002a10db 100644
--- a/src/test/run-pass/issue-29516.rs
+++ b/src/test/run-pass/issue-29516.rs
@@ -11,6 +11,7 @@
 #![feature(optin_builtin_traits)]
 
 trait NotSame {}
+#[allow(auto_impl)]
 impl NotSame for .. {}
 impl<A> !NotSame for (A, A) {}
 
diff --git a/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs b/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs
index 52bd386ba595b..4fd55bd482cd9 100644
--- a/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs
+++ b/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs
@@ -16,6 +16,7 @@ pub mod bar {
 
     pub trait Bar {}
 
+    #[allow(auto_impl)]
     impl Bar for .. {}
 
     pub trait Foo {
diff --git a/src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs b/src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs
index 6e8f80c8f5f9f..d886778278dfd 100644
--- a/src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs
+++ b/src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs
@@ -12,4 +12,5 @@
 
 pub trait AnOibit {}
 
+#[allow(auto_impl)]
 impl AnOibit for .. {}
diff --git a/src/test/rustdoc/impl-parts.rs b/src/test/rustdoc/impl-parts.rs
index 48ef4b6be66de..f74f66ce72905 100644
--- a/src/test/rustdoc/impl-parts.rs
+++ b/src/test/rustdoc/impl-parts.rs
@@ -12,6 +12,7 @@
 
 pub trait AnOibit {}
 
+#[allow(auto_impl)]
 impl AnOibit for .. {}
 
 pub struct Foo<T> { field: T }
diff --git a/src/tools/toolstate.toml b/src/tools/toolstate.toml
index f1684f4c5acbe..9dd420c14586d 100644
--- a/src/tools/toolstate.toml
+++ b/src/tools/toolstate.toml
@@ -29,7 +29,7 @@ miri = "Broken"
 clippy = "Broken"
 
 # ping @nrc
-rls = "Testing"
+rls = "Broken"
 
 # ping @nrc
-rustfmt = "Testing"
+rustfmt = "Broken"