about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJared Roesch <roeschinc@gmail.com>2016-08-16 22:48:09 -0700
committerJared Roesch <roeschinc@gmail.com>2016-09-02 11:58:02 -0700
commit352fac95ad5305bf8b0e482b8255b2b0057adf09 (patch)
tree500da3f0af1651d3ab4509f87c32f72b83c735d2 /src
parentf18c99072e6b9ec0075d913ea6454f0c5e75881c (diff)
downloadrust-352fac95ad5305bf8b0e482b8255b2b0057adf09.tar.gz
rust-352fac95ad5305bf8b0e482b8255b2b0057adf09.zip
Reject certain auto trait declarations
Fixes #29859
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ty/mod.rs10
-rw-r--r--src/librustc_typeck/check/wfcheck.rs53
-rw-r--r--src/librustc_typeck/diagnostics.rs2
-rw-r--r--src/test/compile-fail/issue-29859-2.rs15
-rw-r--r--src/test/compile-fail/issue-29859.rs6
5 files changed, 70 insertions, 16 deletions
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index e9c01f5bad6..414e7b71f7c 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -762,6 +762,16 @@ pub struct GenericPredicates<'tcx> {
 }
 
 impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
+    pub fn empty() -> GenericPredicates<'tcx> {
+        GenericPredicates {
+            predicates: VecPerParamSpace::empty(),
+        }
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.predicates.is_empty()
+    }
+
     pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
                        -> InstantiatedPredicates<'tcx> {
         let mut instantiated = InstantiatedPredicates::empty();
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 435442bd30a..0117dfa6730 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -251,6 +251,36 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
         });
     }
 
+    fn check_auto_trait(&mut self,
+                                   trait_def_id: DefId,
+                                   span: Span)
+    {
+        let predicates = self.tcx().lookup_predicates(trait_def_id);
+
+        // If we must exclude the Self : Trait predicate contained by all
+        // traits.
+        let no_refl_predicates : Vec<_> =
+            predicates.predicates.iter().filter(|predicate| {
+                match *predicate {
+                    &ty::Predicate::Trait(ref poly_trait_ref) =>
+                        poly_trait_ref.def_id() != trait_def_id,
+                    _ => true,
+            }
+            }).collect();
+
+        let trait_def = self.tcx().lookup_trait_def(trait_def_id);
+
+        // We use an if-else here, since the generics will also trigger
+        // an extraneous error message when we find predicates like
+        // `T : Sized` for a trait like: `trait Magic<T>`.
+        if !trait_def.generics.types.get_slice(ParamSpace::TypeSpace).is_empty() {
+            error_566(self.ccx, span);
+        } else if !no_refl_predicates.is_empty() {
+            error_565(self.ccx, span);
+        }
+
+    }
+
     fn check_trait(&mut self,
                    item: &hir::Item,
                    items: &[hir::TraitItem])
@@ -258,9 +288,18 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
         let trait_def_id = self.tcx().map.local_def_id(item.id);
 
         if self.tcx().trait_has_default_impl(trait_def_id) {
+            // We want to both ensure:
+            // 1) that there are no items contained within
+            // the trait defintion
+            //
+            // 2) that the definition doesn't violate the no-super trait rule
+            // for auto traits.
+
             if !items.is_empty() {
                 error_380(self.ccx, item.span);
             }
+
+            self.check_auto_trait(trait_def_id, item.span);
         }
 
         self.for_item(item).with_fcx(|fcx, this| {
@@ -272,6 +311,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
         });
     }
 
+
+
     fn check_item_fn(&mut self,
                      item: &hir::Item,
                      body: &hir::Block)
@@ -637,6 +678,18 @@ fn error_380(ccx: &CrateCtxt, span: Span) {
                Trait for ..`) must have no methods or associated items")
 }
 
+fn error_565(ccx: &CrateCtxt, span: Span) {
+    span_err!(ccx.tcx.sess, span, E0565,
+              "traits with default impls (`e.g. unsafe impl \
+               Trait for ..`) can not have predicates")
+}
+
+fn error_566(ccx: &CrateCtxt, span: Span) {
+    span_err!(ccx.tcx.sess, span, E0566,
+              "traits with default impls (`e.g. unsafe impl \
+               Trait for ..`) can not have type parameters")
+}
+
 fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::Name)
                        -> DiagnosticBuilder<'tcx> {
     let mut err = struct_span_err!(ccx.tcx.sess, span, E0392,
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 3f1374db369..7b7b4d2aa00 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -4072,4 +4072,6 @@ register_diagnostics! {
     E0563, // cannot determine a type for this `impl Trait`: {}
     E0564, // only named lifetimes are allowed in `impl Trait`,
            // but `{}` was found in the type `{}`
+    E0565, // auto-traits can not have predicates,
+    E0566, // auto traits can not have type parameters
 }
diff --git a/src/test/compile-fail/issue-29859-2.rs b/src/test/compile-fail/issue-29859-2.rs
index c0e50185f93..258aafb15ba 100644
--- a/src/test/compile-fail/issue-29859-2.rs
+++ b/src/test/compile-fail/issue-29859-2.rs
@@ -10,16 +10,5 @@
 
 #![feature(optin_builtin_traits)]
 
-trait Magic: Copy {}
-impl Magic for .. {}
-impl<T:Magic> Magic for T {}
-
-fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
-
-#[derive(Debug)]
-struct NoClone;
-
-fn main() {
-    let (a, b) = copy(NoClone); //~ ERROR E0277
-    println!("{:?} {:?}", a, b);
-}
+trait Magic<T> {} //~ E0566
+impl Magic<isize> for .. {}
diff --git a/src/test/compile-fail/issue-29859.rs b/src/test/compile-fail/issue-29859.rs
index c0e50185f93..3419e66af13 100644
--- a/src/test/compile-fail/issue-29859.rs
+++ b/src/test/compile-fail/issue-29859.rs
@@ -10,8 +10,8 @@
 
 #![feature(optin_builtin_traits)]
 
-trait Magic: Copy {}
-impl Magic for .. {}
+trait Magic: Copy {} //~ ERROR E0565
+impl Magic for .. {} 
 impl<T:Magic> Magic for T {}
 
 fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
@@ -20,6 +20,6 @@ fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
 struct NoClone;
 
 fn main() {
-    let (a, b) = copy(NoClone); //~ ERROR E0277
+    let (a, b) = copy(NoClone);
     println!("{:?} {:?}", a, b);
 }