Patch tests and create new tests related to projection from a HRTB.

This commit is contained in:
Niko Matsakis 2014-12-26 15:37:56 -05:00
parent 3657ae13f5
commit 7836c72eba
21 changed files with 399 additions and 40 deletions

View File

@ -25,6 +25,7 @@ impl Foo for int {
fn boo(&self) -> uint { 42 }
}
fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {} //~ERROR equality constraints are not allowed in this
fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
//~^ ERROR associated type bindings are not allowed here
pub fn main() {}

View File

@ -43,6 +43,6 @@ pub fn baz(x: &Foo<A=Bar>) {
pub fn main() {
let a = 42i;
foo1(a); //~ERROR the trait `Foo` is not implemented for the type `int`
baz(&a); //~ERROR the trait `Foo` is not implemented for the type `int`
foo1(a); //~ERROR expected uint, found struct Bar
baz(&a); //~ERROR expected uint, found struct Bar
}

View File

@ -0,0 +1,72 @@
// 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.
// Check testing of equality constraints in a higher-ranked context.
#![feature(associated_types)]
pub trait TheTrait<T> {
type A;
fn get(&self, t: T) -> Self::A;
}
struct IntStruct {
x: int
}
impl<'a> TheTrait<&'a int> for IntStruct {
type A = &'a int;
fn get(&self, t: &'a int) -> &'a int {
t
}
}
struct UintStruct {
x: int
}
impl<'a> TheTrait<&'a int> for UintStruct {
type A = &'a uint;
fn get(&self, t: &'a int) -> &'a uint {
panic!()
}
}
fn foo<T>()
where T : for<'x> TheTrait<&'x int, A = &'x int>
{
// ok for IntStruct, but not UintStruct
}
fn bar<T>()
where T : for<'x> TheTrait<&'x int, A = &'x uint>
{
// ok for UintStruct, but not IntStruct
}
fn baz<T>()
where T : for<'x,'y> TheTrait<&'x int, A = &'y int>
{
// not ok for either struct, due to the use of two lifetimes
}
pub fn main() {
foo::<IntStruct>();
foo::<UintStruct>(); //~ ERROR type mismatch
bar::<IntStruct>(); //~ ERROR type mismatch
bar::<UintStruct>();
baz::<IntStruct>(); //~ ERROR type mismatch
baz::<UintStruct>(); //~ ERROR type mismatch
}

View File

@ -18,16 +18,6 @@ trait Get {
fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
//~^ ERROR ambiguous associated type
trait Other {
fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
//~^ ERROR no suitable bound on `Self`
}
impl<T:Get> Other for T {
fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
//~^ ERROR currently unsupported
}
trait Grab {
type Value;
fn grab(&self) -> Grab::Value;

View File

@ -0,0 +1,44 @@
// 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.
// Check that the user gets an errror if they omit a binding from an
// object type.
#![feature(associated_types)]
pub trait Foo {
type A;
type B;
fn boo(&self) -> <Self as Foo>::A;
}
struct Bar;
impl Foo for int {
type A = uint;
type B = char;
fn boo(&self) -> uint {
42
}
}
pub fn main() {
let a = &42i as &Foo<A=uint, B=char>;
let b = &42i as &Foo<A=uint>;
//~^ ERROR the value of the associated type `B` (from the trait `Foo`) must be specified
let c = &42i as &Foo<B=char>;
//~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified
let d = &42i as &Foo;
//~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified
//~| ERROR the value of the associated type `B` (from the trait `Foo`) must be specified
}

View File

@ -21,7 +21,7 @@ struct Struct {
impl Struct {
fn uhoh<T>(foo: <T as Get>::Value) {}
//~^ ERROR no suitable bound on `T`
//~^ ERROR the trait `Get` is not implemented for the type `T`
}
fn main() {

View File

@ -0,0 +1,21 @@
#![feature(associated_types)]
// Check that we get an error when you use `<Self as Get>::Value` in
// the trait definition but `Self` does not, in fact, implement `Get`.
trait Get {
type Value;
}
trait Other {
fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
//~^ ERROR the trait `Get` is not implemented for the type `Self`
}
impl<T:Get> Other for T {
fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
//~^ ERROR the trait `Get` is not implemented for the type `(T, U)`
//~| ERROR the trait `Get` is not implemented for the type `(T, U)`
}
fn main() { }

View File

@ -0,0 +1,28 @@
// 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 you can't use a higher-ranked trait bound inside of a qualified
// path (just won't parse).
#![feature(associated_types)]
pub trait Foo<T> {
type A;
fn get(&self, t: T) -> Self::A;
}
fn foo2<I>(x: <I as for<'x> Foo<&'x int>>::A)
//~^ ERROR expected identifier, found keyword `for`
//~| ERROR expected one of `::` or `>`
{
}
pub fn main() {}

View File

@ -0,0 +1,37 @@
// 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.
// Check projection of an associated type out of a higher-ranked
// trait-bound in the context of a function body.
#![feature(associated_types)]
pub trait Foo<T> {
type A;
fn get(&self, t: T) -> Self::A;
}
fn foo<'a, I : for<'x> Foo<&'x int>>(
x: <I as Foo<&'a int>>::A)
{
let y: I::A = x;
}
fn bar<'a, 'b, I : for<'x> Foo<&'x int>>(
x: <I as Foo<&'a int>>::A,
y: <I as Foo<&'b int>>::A,
cond: bool)
{ //~ ERROR cannot infer
// x and y here have two distinct lifetimes:
let z: I::A = if cond { x } else { y };
}
pub fn main() {}

View File

@ -0,0 +1,47 @@
// 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.
// Check projection of an associated type out of a higher-ranked trait-bound
// in the context of a function signature.
#![feature(associated_types)]
pub trait Foo<T> {
type A;
fn get(&self, t: T) -> Self::A;
}
fn foo2<I : for<'x> Foo<&'x int>>(
x: I::A)
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
{
// This case is illegal because we have to instantiate `'x`, and
// we don't know what region to instantiate it with.
//
// This could perhaps be made equivalent to the examples below,
// specifically for fn signatures.
}
fn foo3<I : for<'x> Foo<&'x int>>(
x: <I as Foo<&int>>::A)
{
// OK, in this case we spelled out the precise regions involved, though we left one of
// them anonymous.
}
fn foo4<'a, I : for<'x> Foo<&'x int>>(
x: <I as Foo<&'a int>>::A)
{
// OK, in this case we spelled out the precise regions involved.
}
pub fn main() {}

View File

@ -0,0 +1,36 @@
// 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.
// Check projection of an associated type out of a higher-ranked trait-bound
// in the context of a struct definition.
#![feature(associated_types)]
pub trait Foo<T> {
type A;
fn get(&self, t: T) -> Self::A;
}
struct SomeStruct<I : for<'x> Foo<&'x int>> {
field: I::A
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
}
struct AnotherStruct<I : for<'x> Foo<&'x int>> {
field: <I as Foo<&int>>::A
//~^ ERROR missing lifetime specifier
}
struct YetAnotherStruct<'a, I : for<'x> Foo<&'x int>> {
field: <I as Foo<&'a int>>::A
}
pub fn main() {}

View File

@ -0,0 +1,35 @@
// 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.
// Check projection of an associated type out of a higher-ranked trait-bound
// in the context of a method definition in a trait.
#![feature(associated_types)]
pub trait Foo<T> {
type A;
fn get(&self, t: T) -> Self::A;
}
trait SomeTrait<I : for<'x> Foo<&'x int>> {
fn some_method(&self, arg: I::A);
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
}
trait AnotherTrait<I : for<'x> Foo<&'x int>> {
fn some_method(&self, arg: <I as Foo<&int>>::A);
}
trait YetAnotherTrait<I : for<'x> Foo<&'x int>> {
fn some_method<'a>(&self, arg: <I as Foo<&'a int>>::A);
}
pub fn main() {}

View File

@ -41,14 +41,14 @@ enum Boo {
Quux(Bar<uint>),
}
struct Badness<T> {
struct Badness<U> {
//~^ ERROR not implemented
b: Foo<T>,
b: Foo<U>,
}
enum MoreBadness<T> {
enum MoreBadness<V> {
//~^ ERROR not implemented
EvenMoreBadness(Bar<T>),
EvenMoreBadness(Bar<V>),
}
trait PolyTrait<T> {

View File

@ -0,0 +1,20 @@
// 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 sized-ness checking in substitution in impls.
// impl - struct
struct S5<Y>;
impl<Sized? X> S5<X> { //~ ERROR not implemented
}
fn main() { }

View File

@ -0,0 +1,22 @@
// 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 sized-ness checking in substitution in impls.
// impl - struct
trait T3<Sized? Z> {
}
struct S5<Y>;
impl<Sized? X> T3<X> for S5<X> { //~ ERROR not implemented
}
fn main() { }

View File

@ -0,0 +1,21 @@
// 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 sized-ness checking in substitution in impls.
// impl - unbounded
trait T2<Z> {
}
struct S4<Sized? Y>;
impl<Sized? X> T2<X> for S4<X> {
//~^ ERROR `core::kinds::Sized` is not implemented for the type `X`
}
fn main() { }

View File

@ -13,7 +13,7 @@
trait T {}
fn f<Sized? Y: T>() {
//~^ERROR incompatible bounds on type parameter `Y`, bound `T` does not allow unsized type
//~^ERROR incompatible bounds on `Y`, bound `T` does not allow unsized type
}
pub fn main() {

View File

@ -21,23 +21,4 @@ impl<Sized? X: T> T1<X> for S3<X> {
//~^ ERROR `core::kinds::Sized` is not implemented for the type `X`
}
// impl - unbounded
trait T2<Z> {
}
struct S4<Sized? Y>;
impl<Sized? X> T2<X> for S4<X> {
//~^ ERROR `core::kinds::Sized` is not implemented for the type `X`
}
// impl - struct
trait T3<Sized? Z> {
}
struct S5<Y>;
impl<Sized? X> T3<X> for S5<X> { //~ ERROR not implemented
}
impl<Sized? X> S5<X> { //~ ERROR not implemented
}
fn main() { }

View File

@ -8,13 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-pretty -- currently pretty prints as `Hash<<Self as Hasher...` which fails to parse
#![feature(associated_types)]
pub trait Hasher {
type State;
fn hash<T: Hash<
<Self as Hasher>::State //~ ERROR no suitable bound on `Self`
<Self as Hasher>::State
>>(&self, value: &T) -> u64;
}

View File

@ -17,6 +17,8 @@ trait Foo {
type A;
}
fn bar(x: &Foo) {} //~ERROR missing type for associated type `A`
fn bar(x: &Foo) {}
// FIXME(#19482) -- `Foo` should specify `A`, but this is not
// currently enforced except at object creation
pub fn main() {}