From f9c577e5141dda6413efcfd036389d7d2480e528 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Mon, 9 Feb 2015 16:49:27 +1300 Subject: [PATCH] Tests --- src/libsyntax/print/pprust.rs | 14 ++++-- src/test/compile-fail/where-for-self-2.rs | 33 +++++++++++++ src/test/compile-fail/where-for-self.rs | 29 +++++++++++ src/test/run-pass/where-for-self.rs | 59 +++++++++++++++++++++++ 4 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 src/test/compile-fail/where-for-self-2.rs create mode 100644 src/test/compile-fail/where-for-self.rs create mode 100644 src/test/run-pass/where-for-self.rs 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 or the MIT license +// , 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(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 or the MIT license +// , 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(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 or the MIT license +// , 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(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(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); + } +} +