diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-02-13 19:52:55 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-02-18 15:23:34 -0500 |
| commit | 2939e483fd8a32d330c837725513b493fd457dc3 (patch) | |
| tree | 2ef40b4ce7711ff68e3c140ea65bfc4dd1a984a6 /src/test | |
| parent | 5511add74205d8547f98959b01e5053be2395723 (diff) | |
| download | rust-2939e483fd8a32d330c837725513b493fd457dc3.tar.gz rust-2939e483fd8a32d330c837725513b493fd457dc3.zip | |
Extend the implicator so it produces general obligations and also so
that it produces "outlives" relations for associated types. Add several tests relating to #22246.
Diffstat (limited to 'src/test')
5 files changed, 307 insertions, 0 deletions
diff --git a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs new file mode 100644 index 00000000000..fa26c9c54c8 --- /dev/null +++ b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.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 are imposing the requirement that every associated +// type of a bound that appears in the where clause on a struct must +// outlive the location in which the type appears, even when the +// associted type is in a supertype. Issue #22246. + +#![allow(dead_code)] + +use std::mem::transmute; +use std::ops::Deref; + +/////////////////////////////////////////////////////////////////////////// + +pub trait TheTrait { + type TheAssocType; + + fn dummy(&self) { } +} + +pub trait TheSubTrait : TheTrait { +} + +pub struct TheType<'b> { + m: [fn(&'b()); 0] +} + +impl<'b> TheTrait for TheType<'b> { + type TheAssocType = &'b (); +} + +impl<'b> TheSubTrait for TheType<'b> { +} + +/////////////////////////////////////////////////////////////////////////// + +pub struct WithAssoc<T:TheSubTrait> { + m: [T; 0] +} + +fn with_assoc<'a,'b>() { + // For this type to be valid, the rules require that all + // associated types of traits that appear in `WithAssoc` must + // outlive 'a. In this case, that means TheType<'b>::TheAssocType, + // which is &'b (), must outlive 'a. + + let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR cannot infer +} + +fn main() { +} diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs new file mode 100644 index 00000000000..5e02aae672d --- /dev/null +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs @@ -0,0 +1,69 @@ +// 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 structs with higher-ranked where clauses don't generate +// "outlives" requirements. Issue #22246. + +#![allow(dead_code)] + +/////////////////////////////////////////////////////////////////////////// + +pub trait TheTrait<'b> { + type TheAssocType; + + fn dummy(&'b self) { } +} + +pub struct TheType<'b> { + m: [fn(&'b()); 0] +} + +impl<'a,'b> TheTrait<'a> for TheType<'b> { + type TheAssocType = &'b (); +} + +/////////////////////////////////////////////////////////////////////////// + +pub struct WithHrAssoc<T> + where for<'a> T : TheTrait<'a> +{ + m: [T; 0] +} + +fn with_assoc<'a,'b>() { + // We get no error here because the where clause has a higher-ranked assoc type, + // which could not be projected from. + + let _: &'a WithHrAssoc<TheType<'b>> = loop { }; +} + +/////////////////////////////////////////////////////////////////////////// + +pub trait TheSubTrait : for<'a> TheTrait<'a> { +} + +impl<'b> TheSubTrait for TheType<'b> { } + +pub struct WithHrAssocSub<T> + where T : TheSubTrait +{ + m: [T; 0] +} + +fn with_assoc_sub<'a,'b>() { + // Same here, because although the where clause is not HR, it + // extends a trait in a HR way. + + let _: &'a WithHrAssocSub<TheType<'b>> = loop { }; +} + +#[rustc_error] +fn main() { //~ ERROR compilation successful +} diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs new file mode 100644 index 00000000000..6ee65fbdf91 --- /dev/null +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs @@ -0,0 +1,53 @@ +// 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 are imposing the requirement that every associated +// type of a bound that appears in the where clause on a struct must +// outlive the location in which the type appears, even when the +// constraint is in a where clause not a bound. Issue #22246. + +#![allow(dead_code)] + +use std::mem::transmute; +use std::ops::Deref; + +/////////////////////////////////////////////////////////////////////////// + +pub trait TheTrait { + type TheAssocType; + + fn dummy(&self) { } +} + +pub struct TheType<'b> { + m: [fn(&'b()); 0] +} + +impl<'b> TheTrait for TheType<'b> { + type TheAssocType = &'b (); +} + +/////////////////////////////////////////////////////////////////////////// + +pub struct WithAssoc<T> where T : TheTrait { + m: [T; 0] +} + +fn with_assoc<'a,'b>() { + // For this type to be valid, the rules require that all + // associated types of traits that appear in `WithAssoc` must + // outlive 'a. In this case, that means TheType<'b>::TheAssocType, + // which is &'b (), must outlive 'a. + + let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR cannot infer +} + +fn main() { +} diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs new file mode 100644 index 00000000000..49a0726fa3b --- /dev/null +++ b/src/test/compile-fail/regions-assoc-type-outlives-container.rs @@ -0,0 +1,91 @@ +// 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 are imposing the requirement that every associated +// type of a bound that appears in the where clause on a struct must +// outlive the location in which the type appears. Issue #22246. + +#![allow(dead_code)] + +use std::mem::transmute; +use std::ops::Deref; + +/////////////////////////////////////////////////////////////////////////// + +pub trait TheTrait { + type TheAssocType; + + fn dummy(&self) { } +} + +pub struct TheType<'b> { + m: [fn(&'b()); 0] +} + +impl<'b> TheTrait for TheType<'b> { + type TheAssocType = &'b (); +} + +/////////////////////////////////////////////////////////////////////////// + +pub struct WithAssoc<T:TheTrait> { + m: [T; 0] +} + +pub struct WithoutAssoc<T> { + m: [T; 0] +} + +fn with_assoc<'a,'b>() { + // For this type to be valid, the rules require that all + // associated types of traits that appear in `WithAssoc` must + // outlive 'a. In this case, that means TheType<'b>::TheAssocType, + // which is &'b (), must outlive 'a. + + let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR cannot infer +} + +fn with_assoc1<'a,'b>() where 'b : 'a { + // For this type to be valid, the rules require that all + // associated types of traits that appear in `WithAssoc` must + // outlive 'a. In this case, that means TheType<'b>::TheAssocType, + // which is &'b (), must outlive 'a, so 'b : 'a must hold, and + // that is in the where clauses, so we're fine. + + let _: &'a WithAssoc<TheType<'b>> = loop { }; +} + +fn without_assoc<'a,'b>() { + // Here there are no associated types and the `'b` appearing in + // `TheType<'b>` is purely covariant, so there is no requirement + // that `'b:'a` holds. + + let _: &'a WithoutAssoc<TheType<'b>> = loop { }; +} + +fn call_with_assoc<'a,'b>() { + // As `with_assoc`, but just checking that we impose the same rule + // on the value supplied for the type argument, even when there is + // no data. + + call::<&'a WithAssoc<TheType<'b>>>(); + //~^ ERROR cannot infer +} + +fn call_without_assoc<'a,'b>() { + // As `without_assoc`, but in a distinct scenario. + + call::<&'a WithoutAssoc<TheType<'b>>>(); +} + +fn call<T>() { } + +fn main() { +} diff --git a/src/test/run-pass/regions-issue-22246.rs b/src/test/run-pass/regions-issue-22246.rs new file mode 100644 index 00000000000..f5c34d6b34e --- /dev/null +++ b/src/test/run-pass/regions-issue-22246.rs @@ -0,0 +1,35 @@ +// 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. + +// Regression test for issue #22246 -- we should be able to deduce +// that `&'a B::Owned` implies that `B::Owned : 'a`. + +#![allow(dead_code)] + +use std::ops::Deref; + +pub trait ToOwned { + type Owned: Borrow<Self>; + fn to_owned(&self) -> Self::Owned; +} + +pub trait Borrow<Borrowed> { + fn borrow(&self) -> &Borrowed; +} + +pub struct Foo<B:ToOwned> { + owned: B::Owned +} + +fn foo<B:ToOwned>(this: &Foo<B>) -> &B { + this.owned.borrow() +} + +fn main() { } |
