Introduce the new phantomdata/phantomfn markers and integrate them
into variance inference; fix various bugs in variance inference so that it considers the correct set of constraints; modify infer to consider the results of variance inference for type arguments.
This commit is contained in:
parent
dfc5c0f1e8
commit
2594d56e32
38 changed files with 1521 additions and 502 deletions
31
src/test/compile-fail/variance-contravariant-arg-object.rs
Normal file
31
src/test/compile-fail/variance-contravariant-arg-object.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Get<T> : 'static {
|
||||
fn get(&self, t: T);
|
||||
}
|
||||
|
||||
fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
|
||||
-> Box<Get<&'min i32>>
|
||||
where 'max : 'min
|
||||
{
|
||||
v //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
|
||||
-> Box<Get<&'max i32>>
|
||||
where 'max : 'min
|
||||
{
|
||||
v
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Get<T> {
|
||||
fn get(&self, t: T);
|
||||
}
|
||||
|
||||
fn get_min_from_max<'min, 'max, G>()
|
||||
where 'max : 'min, G : Get<&'max i32>
|
||||
{
|
||||
impls_get::<G,&'min i32>() //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn get_max_from_min<'min, 'max, G>()
|
||||
where 'max : 'min, G : Get<&'min i32>
|
||||
{
|
||||
impls_get::<G,&'max i32>()
|
||||
}
|
||||
|
||||
fn impls_get<G,T>() where G : Get<T> { }
|
||||
|
||||
fn main() { }
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Get {
|
||||
fn get(&self);
|
||||
}
|
||||
|
||||
fn get_min_from_max<'min, 'max, G>()
|
||||
where 'max : 'min, G : 'max, &'max G : Get
|
||||
{
|
||||
impls_get::<&'min G>(); //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn get_max_from_min<'min, 'max, G>()
|
||||
where 'max : 'min, G : 'max, &'min G : Get
|
||||
{
|
||||
impls_get::<&'max G>();
|
||||
}
|
||||
|
||||
fn impls_get<G>() where G : Get { }
|
||||
|
||||
fn main() { }
|
||||
31
src/test/compile-fail/variance-covariant-arg-object.rs
Normal file
31
src/test/compile-fail/variance-covariant-arg-object.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Get<T> : 'static {
|
||||
fn get(&self) -> T;
|
||||
}
|
||||
|
||||
fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
|
||||
-> Box<Get<&'min i32>>
|
||||
where 'max : 'min
|
||||
{
|
||||
v
|
||||
}
|
||||
|
||||
fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
|
||||
-> Box<Get<&'max i32>>
|
||||
where 'max : 'min
|
||||
{
|
||||
v //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
31
src/test/compile-fail/variance-covariant-arg-trait-match.rs
Normal file
31
src/test/compile-fail/variance-covariant-arg-trait-match.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Get<T> {
|
||||
fn get(&self) -> T;
|
||||
}
|
||||
|
||||
fn get_min_from_max<'min, 'max, G>()
|
||||
where 'max : 'min, G : Get<&'max i32>
|
||||
{
|
||||
impls_get::<G,&'min i32>()
|
||||
}
|
||||
|
||||
fn get_max_from_min<'min, 'max, G>()
|
||||
where 'max : 'min, G : Get<&'min i32>
|
||||
{
|
||||
impls_get::<G,&'max i32>() //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn impls_get<G,T>() where G : Get<T> { }
|
||||
|
||||
fn main() { }
|
||||
31
src/test/compile-fail/variance-covariant-self-trait-match.rs
Normal file
31
src/test/compile-fail/variance-covariant-self-trait-match.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Get {
|
||||
fn get() -> Self;
|
||||
}
|
||||
|
||||
fn get_min_from_max<'min, 'max, G>()
|
||||
where 'max : 'min, G : 'max, &'max G : Get
|
||||
{
|
||||
impls_get::<&'min G>();
|
||||
}
|
||||
|
||||
fn get_max_from_min<'min, 'max, G>()
|
||||
where 'max : 'min, G : 'max, &'min G : Get
|
||||
{
|
||||
impls_get::<&'max G>(); //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn impls_get<G>() where G : Get { }
|
||||
|
||||
fn main() { }
|
||||
31
src/test/compile-fail/variance-invariant-arg-object.rs
Normal file
31
src/test/compile-fail/variance-invariant-arg-object.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Get<T> : 'static {
|
||||
fn get(&self, t: T) -> T;
|
||||
}
|
||||
|
||||
fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
|
||||
-> Box<Get<&'min i32>>
|
||||
where 'max : 'min
|
||||
{
|
||||
v //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
|
||||
-> Box<Get<&'max i32>>
|
||||
where 'max : 'min
|
||||
{
|
||||
v //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
31
src/test/compile-fail/variance-invariant-arg-trait-match.rs
Normal file
31
src/test/compile-fail/variance-invariant-arg-trait-match.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Get<T> {
|
||||
fn get(&self, t: T) -> T;
|
||||
}
|
||||
|
||||
fn get_min_from_max<'min, 'max, G>()
|
||||
where 'max : 'min, G : Get<&'max i32>
|
||||
{
|
||||
impls_get::<G,&'min i32>() //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn get_max_from_min<'min, 'max, G>()
|
||||
where 'max : 'min, G : Get<&'min i32>
|
||||
{
|
||||
impls_get::<G,&'max i32>() //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn impls_get<G,T>() where G : Get<T> { }
|
||||
|
||||
fn main() { }
|
||||
31
src/test/compile-fail/variance-invariant-self-trait-match.rs
Normal file
31
src/test/compile-fail/variance-invariant-self-trait-match.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Get {
|
||||
fn get(&self) -> Self;
|
||||
}
|
||||
|
||||
fn get_min_from_max<'min, 'max, G>()
|
||||
where 'max : 'min, &'max G : Get
|
||||
{
|
||||
impls_get::<&'min G>(); //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn get_max_from_min<'min, 'max, G>()
|
||||
where 'max : 'min, &'min G : Get
|
||||
{
|
||||
impls_get::<&'max G>(); //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn impls_get<G>() where G : Get { }
|
||||
|
||||
fn main() { }
|
||||
25
src/test/compile-fail/variance-regions-unused-direct.rs
Normal file
25
src/test/compile-fail/variance-regions-unused-direct.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// 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.
|
||||
|
||||
// Test that disallow lifetime parameters that are unused.
|
||||
|
||||
use std::marker;
|
||||
|
||||
struct Bivariant<'a>; //~ ERROR parameter `'a` is never used
|
||||
|
||||
struct Struct<'a, 'd> { //~ ERROR parameter `'d` is never used
|
||||
field: &'a [i32]
|
||||
}
|
||||
|
||||
trait Trait<'a, 'd> { //~ ERROR parameter `'d` is never used
|
||||
fn method(&'a self);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
21
src/test/compile-fail/variance-regions-unused-indirect.rs
Normal file
21
src/test/compile-fail/variance-regions-unused-indirect.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// 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.
|
||||
|
||||
// Test that disallow lifetime parameters that are unused.
|
||||
|
||||
enum Foo<'a> { //~ ERROR parameter `'a` is never used
|
||||
Foo1(Bar<'a>)
|
||||
}
|
||||
|
||||
enum Bar<'a> { //~ ERROR parameter `'a` is never used
|
||||
Bar1(Foo<'a>)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
64
src/test/compile-fail/variance-trait-bounds.rs
Normal file
64
src/test/compile-fail/variance-trait-bounds.rs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
// 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.
|
||||
|
||||
#![deny(bivariance)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
// Check that bounds on type parameters (other than `Self`) do not
|
||||
// influence variance.
|
||||
|
||||
#[rustc_variance]
|
||||
trait Getter<T> { //~ ERROR types=[[+];[-];[]]
|
||||
fn get(&self) -> T;
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait Setter<T> { //~ ERROR types=[[-];[-];[]]
|
||||
fn get(&self, T);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[[+, +];[];[]]
|
||||
t: T, u: U
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[*, +];[];[]]
|
||||
//~^ ERROR parameter `U` is never used
|
||||
Foo(T)
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[[-, +];[-];[]]
|
||||
fn getter(&self, u: U) -> T;
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[+];[-];[]]
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait TestTrait3<U> { //~ ERROR types=[[-];[-];[]]
|
||||
fn getter<T:Getter<U>>(&self);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[[*, +];[];[]]
|
||||
//~^ ERROR parameter `U` is never used
|
||||
t: T
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR types=[[*, +];[];[]]
|
||||
//~^ ERROR parameter `U` is never used
|
||||
t: T
|
||||
}
|
||||
|
||||
pub fn main() { }
|
||||
74
src/test/compile-fail/variance-types-bounds.rs
Normal file
74
src/test/compile-fail/variance-types-bounds.rs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
// 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.
|
||||
|
||||
// Test that we correctly infer variance for type parameters in
|
||||
// various types and traits.
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestImm<A, B> { //~ ERROR types=[[+, +];[];[]]
|
||||
x: A,
|
||||
y: B,
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestMut<A, B:'static> { //~ ERROR types=[[+, o];[];[]]
|
||||
x: A,
|
||||
y: &'static mut B,
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[[+, o];[];[]]
|
||||
m: TestMut<A, B>
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[[o, o];[];[]]
|
||||
n: TestMut<A, B>,
|
||||
m: TestMut<B, A>
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait Getter<A> { //~ ERROR types=[[+];[-];[]]
|
||||
fn get(&self) -> A;
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait Setter<A> { //~ ERROR types=[[-];[o];[]]
|
||||
fn set(&mut self, a: A);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait GetterSetter<A> { //~ ERROR types=[[o];[o];[]]
|
||||
fn get(&self) -> A;
|
||||
fn set(&mut self, a: A);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait GetterInTypeBound<A> { //~ ERROR types=[[-];[-];[]]
|
||||
// Here, the use of `A` in the method bound *does* affect
|
||||
// variance. Think of it as if the method requested a dictionary
|
||||
// for `T:Getter<A>`. Since this dictionary is an input, it is
|
||||
// contravariant, and the Getter is covariant w/r/t A, yielding an
|
||||
// overall contravariant result.
|
||||
fn do_it<T:Getter<A>>(&self);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait SetterInTypeBound<A> { //~ ERROR types=[[+];[-];[]]
|
||||
fn do_it<T:Setter<A>>(&self);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestObject<A, R> { //~ ERROR types=[[-, +];[];[]]
|
||||
n: Box<Setter<A>+Send>,
|
||||
m: Box<Getter<R>+Send>,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
51
src/test/compile-fail/variance-types.rs
Normal file
51
src/test/compile-fail/variance-types.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
// 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.
|
||||
|
||||
#![deny(bivariance)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
// Check that a type parameter which is only used in a trait bound is
|
||||
// not considered bivariant.
|
||||
|
||||
#[rustc_variance]
|
||||
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[o, o];[];[]], regions=[[-];[];[]]
|
||||
t: &'a mut (A,B)
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct InvariantCell<A> { //~ ERROR types=[[o];[];[]]
|
||||
t: Cell<A>
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct InvariantIndirect<A> { //~ ERROR types=[[o];[];[]]
|
||||
t: InvariantCell<A>
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct Covariant<A> { //~ ERROR types=[[+];[];[]]
|
||||
t: A, u: fn() -> A
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct Contravariant<A> { //~ ERROR types=[[-];[];[]]
|
||||
t: fn(A)
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
enum Enum<A,B,C> { //~ ERROR types=[[+, -, o];[];[]]
|
||||
Foo(Covariant<A>),
|
||||
Bar(Contravariant<B>),
|
||||
Zed(Covariant<C>,Contravariant<C>)
|
||||
}
|
||||
|
||||
pub fn main() { }
|
||||
17
src/test/compile-fail/variance-unused-region-param.rs
Normal file
17
src/test/compile-fail/variance-unused-region-param.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// 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.
|
||||
|
||||
// Test that we report an error for unused type parameters in types.
|
||||
|
||||
struct SomeStruct<'a> { x: u32 } //~ ERROR parameter `'a` is never used
|
||||
enum SomeEnum<'a> { Nothing } //~ ERROR parameter `'a` is never used
|
||||
trait SomeTrait<'a> { fn foo(&self); } //~ ERROR parameter `'a` is never used
|
||||
|
||||
fn main() {}
|
||||
36
src/test/compile-fail/variance-unused-type-param.rs
Normal file
36
src/test/compile-fail/variance-unused-type-param.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
// Test that we report an error for unused type parameters in types and traits,
|
||||
// and that we offer a helpful suggestion.
|
||||
|
||||
struct SomeStruct<A> { x: u32 }
|
||||
//~^ ERROR parameter `A` is never used
|
||||
//~| HELP PhantomData
|
||||
|
||||
enum SomeEnum<A> { Nothing }
|
||||
//~^ ERROR parameter `A` is never used
|
||||
//~| HELP PhantomData
|
||||
|
||||
trait SomeTrait<A> { fn foo(&self); }
|
||||
//~^ ERROR parameter `A` is never used
|
||||
//~| HELP PhantomFn
|
||||
|
||||
// Here T might *appear* used, but in fact it isn't.
|
||||
enum ListCell<T> {
|
||||
//~^ ERROR parameter `T` is never used
|
||||
//~| HELP PhantomData
|
||||
Cons(Box<ListCell<T>>),
|
||||
Nil
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
24
src/test/compile-fail/variance-use-contravariant-struct-1.rs
Normal file
24
src/test/compile-fail/variance-use-contravariant-struct-1.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// 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 various uses of structs with distint variances to make sure
|
||||
// they permit lifetimes to be approximated as expected.
|
||||
|
||||
struct SomeStruct<T>(fn(T));
|
||||
|
||||
fn foo<'min,'max>(v: SomeStruct<&'max ()>)
|
||||
-> SomeStruct<&'min ()>
|
||||
where 'max : 'min
|
||||
{
|
||||
v //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { }
|
||||
26
src/test/compile-fail/variance-use-contravariant-struct-2.rs
Normal file
26
src/test/compile-fail/variance-use-contravariant-struct-2.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// 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 various uses of structs with distint variances to make sure
|
||||
// they permit lifetimes to be approximated as expected.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct SomeStruct<T>(fn(T));
|
||||
|
||||
fn bar<'min,'max>(v: SomeStruct<&'min ()>)
|
||||
-> SomeStruct<&'max ()>
|
||||
where 'max : 'min
|
||||
{
|
||||
v
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { } //~ ERROR compilation successful
|
||||
23
src/test/compile-fail/variance-use-covariant-struct-1.rs
Normal file
23
src/test/compile-fail/variance-use-covariant-struct-1.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// 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 a covariant struct does not permit the lifetime of a
|
||||
// reference to be enlarged.
|
||||
|
||||
struct SomeStruct<T>(T);
|
||||
|
||||
fn foo<'min,'max>(v: SomeStruct<&'min ()>)
|
||||
-> SomeStruct<&'max ()>
|
||||
where 'max : 'min
|
||||
{
|
||||
v //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
25
src/test/compile-fail/variance-use-covariant-struct-2.rs
Normal file
25
src/test/compile-fail/variance-use-covariant-struct-2.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// 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 a covariant struct permits the lifetime of a reference to
|
||||
// be shortened.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct SomeStruct<T>(T);
|
||||
|
||||
fn foo<'min,'max>(v: SomeStruct<&'max ()>)
|
||||
-> SomeStruct<&'min ()>
|
||||
where 'max : 'min
|
||||
{
|
||||
v
|
||||
}
|
||||
|
||||
#[rustc_error] fn main() { } //~ ERROR compilation successful
|
||||
31
src/test/compile-fail/variance-use-invariant-struct-1.rs
Normal file
31
src/test/compile-fail/variance-use-invariant-struct-1.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// 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 various uses of structs with distint variances to make sure
|
||||
// they permit lifetimes to be approximated as expected.
|
||||
|
||||
struct SomeStruct<T>(*mut T);
|
||||
|
||||
fn foo<'min,'max>(v: SomeStruct<&'max ()>)
|
||||
-> SomeStruct<&'min ()>
|
||||
where 'max : 'min
|
||||
{
|
||||
v //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn bar<'min,'max>(v: SomeStruct<&'min ()>)
|
||||
-> SomeStruct<&'max ()>
|
||||
where 'max : 'min
|
||||
{
|
||||
v //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { }
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// 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.
|
||||
|
||||
// Elaborated version of the opening example from RFC 738. This failed
|
||||
// to compile before variance because invariance of `Option` prevented
|
||||
// us from approximating the lifetimes of `field1` and `field2` to a
|
||||
// common intersection.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct List<'l> {
|
||||
field1: &'l i32,
|
||||
field2: Option<&'l i32>,
|
||||
}
|
||||
|
||||
fn foo(field1: &i32, field2: Option<&i32>) -> i32 {
|
||||
let list = List { field1: field1, field2: field2 };
|
||||
*list.field1 + list.field2.cloned().unwrap_or(0)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = 22;
|
||||
let y = Some(3);
|
||||
let z = None;
|
||||
assert_eq!(foo(&x, y.as_ref()), 25);
|
||||
assert_eq!(foo(&x, z.as_ref()), 22);
|
||||
}
|
||||
49
src/test/run-pass/variance-trait-matching.rs
Normal file
49
src/test/run-pass/variance-trait-matching.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
// Get<T> is covariant in T
|
||||
trait Get<T> {
|
||||
fn get(&self) -> T;
|
||||
}
|
||||
|
||||
struct Cloner<T:Clone> {
|
||||
t: T
|
||||
}
|
||||
|
||||
impl<T:Clone> Get<T> for Cloner<T> {
|
||||
fn get(&self) -> T {
|
||||
self.t.clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn get<'a, G>(get: &G) -> i32
|
||||
where G : Get<&'a i32>
|
||||
{
|
||||
// This call only type checks if we can use `G : Get<&'a i32>` as
|
||||
// evidence that `G : Get<&'b i32>` where `'a : 'b`.
|
||||
pick(get, &22)
|
||||
}
|
||||
|
||||
fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32
|
||||
where G : Get<&'b i32>
|
||||
{
|
||||
let v = *get.get();
|
||||
if v % 2 != 0 { v } else { *if_odd }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Cloner { t: &23 };
|
||||
let y = get(&x);
|
||||
assert_eq!(y, 23);
|
||||
}
|
||||
|
||||
|
||||
28
src/test/run-pass/variance-vec-covariant.rs
Normal file
28
src/test/run-pass/variance-vec-covariant.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// 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 vec is now covariant in its argument type.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn foo<'a,'b>(v1: Vec<&'a i32>, v2: Vec<&'b i32>) -> i32 {
|
||||
bar(v1, v2).cloned().unwrap_or(0) // only type checks if we can intersect 'a and 'b
|
||||
}
|
||||
|
||||
fn bar<'c>(v1: Vec<&'c i32>, v2: Vec<&'c i32>) -> Option<&'c i32> {
|
||||
v1.get(0).cloned().or_else(|| v2.get(0).cloned())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = 22;
|
||||
let y = 44;
|
||||
assert_eq!(foo(vec![&x], vec![&y]), 22);
|
||||
assert_eq!(foo(vec![&y], vec![&x]), 44);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue