about summary refs log tree commit diff
diff options
context:
space:
mode:
authorleonardo.yvens <leoyvens@gmail.com>2017-11-04 19:44:19 -0200
committerleonardo.yvens <leoyvens@gmail.com>2017-11-04 22:00:25 -0200
commitf46f388cb20962cdf08747132c17448cf9602b5e (patch)
tree215cbd342f2587cbd198675a91305f61dc5a9cb0
parentd762b1d6c67db12e117186d94d70e46cddb22965 (diff)
downloadrust-f46f388cb20962cdf08747132c17448cf9602b5e.tar.gz
rust-f46f388cb20962cdf08747132c17448cf9602b5e.zip
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.
-rw-r--r--src/librustc_typeck/astconv.rs27
-rw-r--r--src/librustc_typeck/diagnostics.rs6
-rw-r--r--src/test/compile-fail/E0225.rs4
-rw-r--r--src/test/compile-fail/bad-sized.rs2
-rw-r--r--src/test/compile-fail/issue-22560.rs2
-rw-r--r--src/test/compile-fail/issue-32963.rs2
-rw-r--r--src/test/run-pass/auto-traits.rs3
7 files changed, 16 insertions, 30 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index c7f7e62fd61..77ead1d5033 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 075367cbbb7..76ac372b29f 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 8c79c15e3de..c2f610ecd28 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 a2e2e5caafe..df3da5096bf 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 eb5c6076440..914a3bd79d4 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 f146cfbe68b..e97e5a86a9d 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 752f5a11375..e42aca9ccbd 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;
 }