about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-02-09 16:49:27 +1300
committerNick Cameron <ncameron@mozilla.com>2015-02-10 16:54:23 +1300
commitf9c577e5141dda6413efcfd036389d7d2480e528 (patch)
tree3dfa9344f8fee97ad3ad267a7312502d0cb8c8be
parent8122ce81d0909bed39c6df3e47bc751851bded84 (diff)
Tests
-rw-r--r--src/libsyntax/print/pprust.rs14
-rw-r--r--src/test/compile-fail/where-for-self-2.rs33
-rw-r--r--src/test/compile-fail/where-for-self.rs29
-rw-r--r--src/test/run-pass/where-for-self.rs59
4 files changed, 131 insertions, 4 deletions
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 0da15859ea2..583095e1574 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1025,11 +1025,11 @@ impl<'a> State<'a> {
         self.print_path(&t.path, false)
     }
 
-    fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> IoResult<()> {
-        if !t.bound_lifetimes.is_empty() {
+    fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> IoResult<()> {
+        if !lifetimes.is_empty() {
             try!(word(&mut self.s, "for<"));
             let mut comma = false;
-            for lifetime_def in &t.bound_lifetimes {
+            for lifetime_def in lifetimes {
                 if comma {
                     try!(self.word_space(","))
                 }
@@ -1038,7 +1038,11 @@ impl<'a> State<'a> {
             }
             try!(word(&mut self.s, ">"));
         }
+        Ok(())
+    }
 
+    fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> IoResult<()> {
+        try!(self.print_formal_lifetime_list(&t.bound_lifetimes));
         self.print_trait_ref(&t.trait_ref)
     }
 
@@ -2517,9 +2521,11 @@ impl<'a> State<'a> {
             }
 
             match predicate {
-                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounded_ty,
+                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bound_lifetimes,
+                                                                              ref bounded_ty,
                                                                               ref bounds,
                                                                               ..}) => {
+                    try!(self.print_formal_lifetime_list(bound_lifetimes));
                     try!(self.print_type(&**bounded_ty));
                     try!(self.print_bounds(":", bounds));
                 }
diff --git a/src/test/compile-fail/where-for-self-2.rs b/src/test/compile-fail/where-for-self-2.rs
new file mode 100644
index 00000000000..cd5240198b3
--- /dev/null
+++ b/src/test/compile-fail/where-for-self-2.rs
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+// Test that we can quantify lifetimes outside a constraint (i.e., including
+// the self type) in a where clause. Specifically, test that implementing for a
+// specific lifetime is not enough to satisify the `for<'a> ...` constraint, which
+// should require *all* lifetimes.
+
+static X: &'static u32 = &42;
+
+trait Bar {
+    fn bar(&self);
+}
+
+impl Bar for &'static u32 {
+    fn bar(&self) {}
+}
+
+fn foo<T>(x: &T)
+    where for<'a> &'a T: Bar
+{}
+
+fn main() {
+    foo(&X);
+    //~^ error: `for<'a> Bar` is not implemented
+}
diff --git a/src/test/compile-fail/where-for-self.rs b/src/test/compile-fail/where-for-self.rs
new file mode 100644
index 00000000000..8f447face4e
--- /dev/null
+++ b/src/test/compile-fail/where-for-self.rs
@@ -0,0 +1,29 @@
+// Copyright 2015 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.
+
+// Test that we can quantify lifetimes outside a constraint (i.e., including
+// the self type) in a where clause. Specifically, test that we cannot nest
+// quantification in constraints (to be clear, there is no reason this should not
+// we're testing we don't crash or do something stupid).
+
+trait Bar<'a> {
+    fn bar(&self);
+}
+
+impl<'a, 'b> Bar<'b> for &'a u32 {
+    fn bar(&self) {}
+}
+
+fn foo<T>(x: &T)
+    where for<'a> &'a T: for<'b> Bar<'b>
+    //~^ error: nested quantification of lifetimes
+{}
+
+fn main() {}
diff --git a/src/test/run-pass/where-for-self.rs b/src/test/run-pass/where-for-self.rs
new file mode 100644
index 00000000000..5d426793c2e
--- /dev/null
+++ b/src/test/run-pass/where-for-self.rs
@@ -0,0 +1,59 @@
+// Copyright 2015 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.
+
+// Test that we can quantify lifetimes outside a constraint (i.e., including
+// the self type) in a where clause.
+
+static mut COUNT: u32 = 1;
+
+trait Bar<'a> {
+    fn bar(&self);
+}
+
+trait Baz<'a> {
+    fn baz(&self);
+}
+
+impl<'a, 'b> Bar<'b> for &'a u32 {
+    fn bar(&self) {
+        unsafe { COUNT *= 2; }
+    }
+}
+
+impl<'a, 'b> Baz<'b> for &'a u32 {
+    fn baz(&self) {
+        unsafe { COUNT *= 3; }
+    }
+}
+
+// Test we can use the syntax for HRL including the self type.
+fn foo1<T>(x: &T)
+    where for<'a, 'b> &'a T: Bar<'b>
+{
+    x.bar()
+}
+
+// Test we can quantify multiple bounds (i.e., the precedence is sensible).
+fn foo2<T>(x: &T)
+    where for<'a, 'b> &'a T: Bar<'b> + Baz<'b>
+{
+    x.baz();
+    x.bar()
+}
+
+fn main() {
+    let x = 42u32;
+    foo1(&x);
+    foo2(&x);
+    unsafe {
+        assert!(COUNT == 12);
+    }
+}
+