New tests --- projection outlives relation
This commit is contained in:
parent
d159977502
commit
788a802dad
15 changed files with 405 additions and 23 deletions
38
src/test/compile-fail/associated-types-outlives.rs
Normal file
38
src/test/compile-fail/associated-types-outlives.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
// 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 #24622. The older associated types code
|
||||
// was erroneously assuming that all projections outlived the current
|
||||
// fn body, causing this (invalid) code to be accepted.
|
||||
|
||||
pub trait Foo<'a> {
|
||||
type Bar;
|
||||
}
|
||||
|
||||
impl<'a, T:'a> Foo<'a> for T {
|
||||
type Bar = &'a T;
|
||||
}
|
||||
|
||||
fn denormalise<'a, T>(t: &'a T) -> <T as Foo<'a>>::Bar {
|
||||
t
|
||||
}
|
||||
|
||||
pub fn free_and_use<T: for<'a> Foo<'a>,
|
||||
F: for<'a> FnOnce(<T as Foo<'a>>::Bar)>(x: T, f: F) {
|
||||
let y;
|
||||
'body: loop { // lifetime annotations added for clarity
|
||||
's: loop { y = denormalise(&x); break }
|
||||
drop(x); //~ ERROR cannot move out of `x` because it is borrowed
|
||||
return f(y);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
}
|
|
@ -72,13 +72,12 @@ fn meh1<'a, T: Iter>(v: &'a T) -> Box<X+'a>
|
|||
where T::Item : Clone
|
||||
{
|
||||
// This case is kind of interesting. It's the same as `ok3` but
|
||||
// without the explicit declaration. In principle, it seems like
|
||||
// we ought to be able to infer that `T::Item : 'a` because we
|
||||
// invoked `v.as_self()` which yielded a value of type `&'a
|
||||
// T::Item`. But we're not that smart at present.
|
||||
// without the explicit declaration. This is valid because `T: 'a
|
||||
// => T::Item: 'a`, and the former we can deduce from our argument
|
||||
// of type `&'a T`.
|
||||
|
||||
let item = Clone::clone(v.as_item());
|
||||
Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live
|
||||
Box::new(item)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
// Illustrates the "projection gap": in this test, even though we know
|
||||
// that `T::Foo: 'x`, that does not tell us that `T: 'x`, because
|
||||
// there might be other ways for the caller of `func` to show that
|
||||
// `T::Foo: 'x` holds (e.g., where-clause).
|
||||
|
||||
trait Trait1<'x> {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
// calling this fn should trigger a check that the type argument
|
||||
// supplied is well-formed.
|
||||
fn wf<T>() { }
|
||||
|
||||
fn func<'x, T:Trait1<'x>>(t: &'x T::Foo)
|
||||
{
|
||||
wf::<&'x T>();
|
||||
//~^ ERROR the parameter type `T` may not live long enough
|
||||
}
|
||||
|
||||
fn caller2<'x, T:Trait1<'x>>(t: &'x T)
|
||||
{
|
||||
wf::<&'x T::Foo>(); // OK
|
||||
}
|
||||
|
||||
fn caller3<'x, T:Trait1<'x>>(t: &'x T::Foo)
|
||||
{
|
||||
wf::<&'x T::Foo>(); // OK
|
||||
}
|
||||
|
||||
fn main() { }
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
// Along with the other tests in this series, illustrates the
|
||||
// "projection gap": in this test, we know that `T: 'x`, and that is
|
||||
// enough to conclude that `T::Foo: 'x`.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
trait Trait1<'x> {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
// calling this fn should trigger a check that the type argument
|
||||
// supplied is well-formed.
|
||||
fn wf<T>() { }
|
||||
|
||||
fn func<'x, T:Trait1<'x>>(t: &'x T)
|
||||
{
|
||||
wf::<&'x T::Foo>();
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { } //~ ERROR compilation successful
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
// Along with the other tests in this series, illustrates the
|
||||
// "projection gap": in this test, we know that `T::Foo: 'x`, and that
|
||||
// is (naturally) enough to conclude that `T::Foo: 'x`.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
trait Trait1<'x> {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
// calling this fn should trigger a check that the type argument
|
||||
// supplied is well-formed.
|
||||
fn wf<T>() { }
|
||||
|
||||
fn func<'x, T:Trait1<'x>>(t: &'x T::Foo)
|
||||
{
|
||||
wf::<&'x T::Foo>();
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { } //~ ERROR compilation successful
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
// Along with the other tests in this series, illustrates the
|
||||
// "projection gap": in this test, we know that `T: 'x`, and that
|
||||
// is (naturally) enough to conclude that `T: 'x`.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
trait Trait1<'x> {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
// calling this fn should trigger a check that the type argument
|
||||
// supplied is well-formed.
|
||||
fn wf<T>() { }
|
||||
|
||||
fn func<'x, T:Trait1<'x>>(t: &'x T)
|
||||
{
|
||||
wf::<&'x T>();
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { } //~ ERROR compilation successful
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
// The "projection gap" is particularly "fun" around higher-ranked
|
||||
// projections. This is because the current code is hard-coded to say
|
||||
// that a projection that contains escaping regions, like `<T as
|
||||
// Trait2<'y, 'z>>::Foo` where `'z` is bound, can only be found to
|
||||
// outlive a region if all components that appear free (`'y`, where)
|
||||
// outlive that region. However, we DON'T add those components to the
|
||||
// implied bounds set, but rather we treat projections with escaping
|
||||
// regions as opaque entities, just like projections without escaping
|
||||
// regions.
|
||||
|
||||
trait Trait1<T> { }
|
||||
|
||||
trait Trait2<'a, 'b> {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
fn wf<T>() { }
|
||||
|
||||
// As a side-effect of the conservative process above, this argument
|
||||
// is not automatically considered well-formed, since for it to be WF,
|
||||
// we would need to know that `'y: 'x`, but we do not infer that.
|
||||
fn callee<'x, 'y, T>(
|
||||
t: &'x for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
|
||||
{
|
||||
wf::<&'x &'y i32>();
|
||||
//~^ ERROR reference has a longer lifetime than the data it references
|
||||
}
|
||||
|
||||
fn main() { }
|
56
src/test/compile-fail/regions-outlives-nominal-type-enum.rs
Normal file
56
src/test/compile-fail/regions-outlives-nominal-type-enum.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Copyright 2014 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 a nominal type (like `Foo<'a>`) outlives `'b` if its
|
||||
// arguments (like `'a`) outlive `'b`.
|
||||
//
|
||||
// Rule OutlivesNominalType from RFC 1214.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod variant_enum_region {
|
||||
enum Foo<'a> {
|
||||
V { x: &'a i32 }
|
||||
}
|
||||
struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
|
||||
f: &'a Foo<'b>
|
||||
}
|
||||
}
|
||||
|
||||
mod rev_variant_enum_region {
|
||||
enum Foo<'a> {
|
||||
V { x: fn(&'a i32) }
|
||||
}
|
||||
struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
|
||||
f: &'a Foo<'b>
|
||||
}
|
||||
}
|
||||
|
||||
mod variant_enum_type {
|
||||
enum Foo<T> {
|
||||
V { x: T }
|
||||
}
|
||||
struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
|
||||
f: &'a Foo<&'b i32>
|
||||
}
|
||||
}
|
||||
|
||||
mod rev_variant_enum_type {
|
||||
enum Foo<T> {
|
||||
V { x: fn(T) }
|
||||
}
|
||||
struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
|
||||
f: &'a Foo<&'b i32>
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { }
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright 2014 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 a nominal type (like `Foo<'a>`) outlives `'b` if its
|
||||
// arguments (like `'a`) outlive `'b`.
|
||||
//
|
||||
// Rule OutlivesNominalType from RFC 1214.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod variant_struct_region {
|
||||
struct Foo<'a> {
|
||||
x: &'a i32,
|
||||
}
|
||||
struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
|
||||
f: &'a Foo<'b>
|
||||
}
|
||||
}
|
||||
|
||||
mod rev_variant_struct_region {
|
||||
struct Foo<'a> {
|
||||
x: fn(&'a i32),
|
||||
}
|
||||
struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
|
||||
f: &'a Foo<'b>
|
||||
}
|
||||
}
|
||||
|
||||
mod variant_struct_type {
|
||||
struct Foo<T> {
|
||||
x: T
|
||||
}
|
||||
struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
|
||||
f: &'a Foo<&'b i32>
|
||||
}
|
||||
}
|
||||
|
||||
mod rev_variant_struct_type {
|
||||
struct Foo<T> {
|
||||
x: fn(T)
|
||||
}
|
||||
struct Bar<'a,'b> { //~ ERROR reference has a longer lifetime
|
||||
f: &'a Foo<&'b i32>
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { }
|
|
@ -37,10 +37,10 @@ pub struct WithHrAssoc<T>
|
|||
}
|
||||
|
||||
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.
|
||||
// We get an error because beacuse 'b:'a does not hold:
|
||||
|
||||
let _: &'a WithHrAssoc<TheType<'b>> = loop { };
|
||||
//~^ ERROR reference has a longer lifetime
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -57,12 +57,13 @@ pub struct WithHrAssocSub<T>
|
|||
}
|
||||
|
||||
fn with_assoc_sub<'a,'b>() {
|
||||
// Same here, because although the where clause is not HR, it
|
||||
// extends a trait in a HR way.
|
||||
// The error here is just because `'b:'a` must hold for the type
|
||||
// below to be well-formed, it is not related to the HR relation.
|
||||
|
||||
let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
|
||||
//~^ ERROR reference has a longer lifetime
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { //~ ERROR compilation successful
|
||||
fn main() {
|
||||
}
|
|
@ -59,11 +59,10 @@ fn with_assoc1<'a,'b>() where 'b : 'a {
|
|||
}
|
||||
|
||||
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.
|
||||
// Here there are no associated types but there is a requirement
|
||||
// that `'b:'a` holds because the `'b` appears in `TheType<'b>`.
|
||||
|
||||
let _: &'a WithoutAssoc<TheType<'b>> = loop { };
|
||||
let _: &'a WithoutAssoc<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
|
||||
}
|
||||
|
||||
fn call_with_assoc<'a,'b>() {
|
||||
|
@ -72,13 +71,13 @@ fn call_with_assoc<'a,'b>() {
|
|||
// no data.
|
||||
|
||||
call::<&'a WithAssoc<TheType<'b>>>();
|
||||
//~^ ERROR cannot infer
|
||||
//~^ ERROR reference has a longer lifetime
|
||||
}
|
||||
|
||||
fn call_without_assoc<'a,'b>() {
|
||||
// As `without_assoc`, but in a distinct scenario.
|
||||
|
||||
call::<&'a WithoutAssoc<TheType<'b>>>();
|
||||
call::<&'a WithoutAssoc<TheType<'b>>>(); //~ ERROR reference has a longer lifetime
|
||||
}
|
||||
|
||||
fn call<T>() { }
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2014 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 `<F as Foo<'a>>::Type: 'b`, where `trait Foo<'a> { Type:
|
||||
// 'a; }`, does not require that `F: 'b`.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait SomeTrait<'a> {
|
||||
type Type: 'a;
|
||||
}
|
||||
|
||||
impl<'a: 'c, 'c, T> SomeTrait<'a> for &'c T where T: SomeTrait<'a> {
|
||||
type Type = <T as SomeTrait<'a>>::Type;
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// |
|
||||
// Note that this type must outlive 'a, due to the trait
|
||||
// definition. If we fall back to OutlivesProjectionComponents
|
||||
// here, then we would require that `T:'a`, which is too strong.
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { } //~ ERROR compilation successful
|
23
src/test/compile-fail/regions-outlives-scalar.rs
Normal file
23
src/test/compile-fail/regions-outlives-scalar.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2014 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 scalar values outlive all regions.
|
||||
// Rule OutlivesScalar from RFC 1214.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct Foo<'a> {
|
||||
x: &'a i32,
|
||||
y: &'static i32
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { } //~ ERROR compilation successful
|
|
@ -9,10 +9,11 @@
|
|||
// except according to those terms.
|
||||
|
||||
// A variant of traits-issue-23003 in which an infinite series of
|
||||
// types are required. This currently creates an overflow. This test
|
||||
// is included to ensure that some controlled failure, at least,
|
||||
// results -- but it might be that we should adjust the rules somewhat
|
||||
// to make this legal. -nmatsakis
|
||||
// types are required. This test now just compiles fine, since the
|
||||
// relevant rules that triggered the overflow were removed.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
@ -32,7 +33,7 @@ impl<B> Async for Complete<B> {
|
|||
type Cancel = Receipt<Complete<Option<B>>>;
|
||||
}
|
||||
|
||||
fn foo(r: Receipt<Complete<()>>) { }
|
||||
//~^ ERROR overflow
|
||||
fn foo(_: Receipt<Complete<()>>) { }
|
||||
|
||||
fn main() { }
|
||||
#[rustc_error]
|
||||
fn main() { } //~ ERROR compilation successful
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue