From f46f388cb20962cdf08747132c17448cf9602b5e Mon Sep 17 00:00:00 2001
From: "leonardo.yvens" <leoyvens@gmail.com>
Date: Sat, 4 Nov 2017 19:44:19 -0200
Subject: [PATCH 1/2] Fix checking of auto trait bounds in trait objects.

Any auto trait is allowed in trait object bounds.
Fix duplicate check of type and lifetime parameter count.
---
 src/librustc_typeck/astconv.rs       | 27 +++++----------------------
 src/librustc_typeck/diagnostics.rs   |  6 +++---
 src/test/compile-fail/E0225.rs       |  4 ++--
 src/test/compile-fail/bad-sized.rs   |  2 +-
 src/test/compile-fail/issue-22560.rs |  2 +-
 src/test/compile-fail/issue-32963.rs |  2 +-
 src/test/run-pass/auto-traits.rs     |  3 +++
 7 files changed, 16 insertions(+), 30 deletions(-)

diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index c7f7e62fd61ef..77ead1d503306 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -572,8 +572,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
             let b = &trait_bounds[0];
             let span = b.trait_ref.path.span;
             struct_span_err!(self.tcx().sess, span, E0225,
-                "only Send/Sync traits can be used as additional traits in a trait object")
-                .span_label(span, "non-Send/Sync additional trait")
+                "only auto traits can be used as additional traits in a trait object")
+                .span_label(span, "non-auto additional trait")
                 .emit();
         }
 
@@ -1311,27 +1311,10 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
     -> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
 {
     let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
+        // Checks whether `trait_did` is an auto trait and adds it to `auto_traits` if so.
         match bound.trait_ref.path.def {
-            Def::Trait(trait_did) => {
-                // Checks whether `trait_did` refers to one of the builtin
-                // traits, like `Send`, and adds it to `auto_traits` if so.
-                if Some(trait_did) == tcx.lang_items().send_trait() ||
-                    Some(trait_did) == tcx.lang_items().sync_trait() {
-                    let segments = &bound.trait_ref.path.segments;
-                    segments[segments.len() - 1].with_parameters(|parameters| {
-                        if !parameters.types.is_empty() {
-                            check_type_argument_count(tcx, bound.trait_ref.path.span,
-                                                      parameters.types.len(), &[]);
-                        }
-                        if !parameters.lifetimes.is_empty() {
-                            report_lifetime_number_error(tcx, bound.trait_ref.path.span,
-                                                         parameters.lifetimes.len(), 0);
-                        }
-                    });
-                    true
-                } else {
-                    false
-                }
+            Def::Trait(trait_did) if tcx.trait_is_auto(trait_did) => {
+                true
             }
             _ => false
         }
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 075367cbbb7cd..76ac372b29f14 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -2455,9 +2455,9 @@ fn main() {
 }
 ```
 
-Send and Sync are an exception to this rule: it's possible to have bounds of
-one non-builtin trait, plus either or both of Send and Sync. For example, the
-following compiles correctly:
+Auto traits such as Send and Sync are an exception to this rule:
+It's possible to have bounds of one non-builtin trait, plus any number of
+auto traits. For example, the following compiles correctly:
 
 ```
 fn main() {
diff --git a/src/test/compile-fail/E0225.rs b/src/test/compile-fail/E0225.rs
index 8c79c15e3de5b..c2f610ecd2816 100644
--- a/src/test/compile-fail/E0225.rs
+++ b/src/test/compile-fail/E0225.rs
@@ -10,6 +10,6 @@
 
 fn main() {
     let _: Box<std::io::Read + std::io::Write>;
-    //~^ ERROR only Send/Sync traits can be used as additional traits in a trait object [E0225]
-    //~| NOTE non-Send/Sync additional trait
+    //~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
+    //~| NOTE non-auto additional trait
 }
diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs
index a2e2e5caafe6d..df3da5096bf53 100644
--- a/src/test/compile-fail/bad-sized.rs
+++ b/src/test/compile-fail/bad-sized.rs
@@ -12,7 +12,7 @@ trait Trait {}
 
 pub fn main() {
     let x: Vec<Trait + Sized> = Vec::new();
-    //~^ ERROR only Send/Sync traits can be used as additional traits in a trait object
+    //~^ ERROR only auto traits can be used as additional traits in a trait object
     //~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
     //~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
 }
diff --git a/src/test/compile-fail/issue-22560.rs b/src/test/compile-fail/issue-22560.rs
index eb5c6076440e9..914a3bd79d460 100644
--- a/src/test/compile-fail/issue-22560.rs
+++ b/src/test/compile-fail/issue-22560.rs
@@ -23,6 +23,6 @@ type Test = Add +
             //~| NOTE missing reference to `RHS`
             //~| NOTE because of the default `Self` reference, type parameters must be specified on object types
             //~| ERROR E0225
-            //~| NOTE non-Send/Sync additional trait
+            //~| NOTE non-auto additional trait
 
 fn main() { }
diff --git a/src/test/compile-fail/issue-32963.rs b/src/test/compile-fail/issue-32963.rs
index f146cfbe68b96..e97e5a86a9d7d 100644
--- a/src/test/compile-fail/issue-32963.rs
+++ b/src/test/compile-fail/issue-32963.rs
@@ -16,6 +16,6 @@ fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
 
 fn main() {
     size_of_copy::<Misc+Copy>();
-    //~^ ERROR only Send/Sync traits can be used as additional traits in a trait object
+    //~^ ERROR only auto traits can be used as additional traits in a trait object
     //~| ERROR the trait bound `Misc: std::marker::Copy` is not satisfied
 }
diff --git a/src/test/run-pass/auto-traits.rs b/src/test/run-pass/auto-traits.rs
index 752f5a11375ad..e42aca9ccbd13 100644
--- a/src/test/run-pass/auto-traits.rs
+++ b/src/test/run-pass/auto-traits.rs
@@ -33,4 +33,7 @@ fn main() {
     take_auto(AutoBool(true));
     take_auto_unsafe(0);
     take_auto_unsafe(AutoBool(true));
+
+    /// Auto traits are allowed in trait object bounds.
+    let _: &(Send + Auto) = &0;
 }

From 7995f879d0c520d162d965db0ebbe403bfa2bfda Mon Sep 17 00:00:00 2001
From: "leonardo.yvens" <leoyvens@gmail.com>
Date: Tue, 7 Nov 2017 10:39:17 -0200
Subject: [PATCH 2/2] Remove `send` lang item.

It's completely unused.
---
 src/libcore/marker.rs             | 2 +-
 src/librustc/middle/lang_items.rs | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index e47b99ed552d3..0a8127f4ce4fe 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -39,7 +39,7 @@ use hash::Hasher;
 /// [arc]: ../../std/sync/struct.Arc.html
 /// [ub]: ../../reference/behavior-considered-undefined.html
 #[stable(feature = "rust1", since = "1.0.0")]
-#[lang = "send"]
+#[cfg_attr(stage0, lang = "send")]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
 pub unsafe trait Send {
     // empty.
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 679c4f17a6c03..568c1952b1e6d 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -228,7 +228,6 @@ language_item_table! {
     F32ImplItem,                     "f32",                     f32_impl;
     F64ImplItem,                     "f64",                     f64_impl;
 
-    SendTraitLangItem,               "send",                    send_trait;
     SizedTraitLangItem,              "sized",                   sized_trait;
     UnsizeTraitLangItem,             "unsize",                  unsize_trait;
     CopyTraitLangItem,               "copy",                    copy_trait;