test: add more extensive tests for impl Trait.

This commit is contained in:
Eduard Burtescu 2016-08-11 00:04:43 +03:00
parent 08bf9f69b9
commit 23f0494114
7 changed files with 291 additions and 0 deletions

View File

@ -0,0 +1,18 @@
// Copyright 2016 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.
#![feature(conservative_impl_trait)]
fn main() {
let _: impl Fn() = || {};
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
let _ = || -> impl Fn() { || {} };
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}

View File

@ -0,0 +1,61 @@
// Copyright 2016 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.
#![feature(conservative_impl_trait)]
fn arguments(_: impl Fn(),
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
_: Vec<impl Clone>) {}
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
type Factory<R> = impl Fn() -> R;
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
type GlobalFactory<R> = fn() -> impl FnOnce() -> R;
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
trait LazyToString {
fn lazy_to_string<'a>(&'a self) -> impl Fn() -> String;
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}
// Note that the following impl doesn't error, because the trait is invalid.
impl LazyToString for String {
fn lazy_to_string<'a>(&'a self) -> impl Fn() -> String {
|| self.clone()
}
}
#[derive(Copy, Clone)]
struct Lazy<T>(T);
impl std::ops::Add<Lazy<i32>> for Lazy<i32> {
type Output = impl Fn() -> Lazy<i32>;
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
fn add(self, other: Lazy<i32>) -> Self::Output {
move || Lazy(self.0 + other.0)
}
}
impl<F> std::ops::Add<F>
for impl Fn() -> Lazy<i32>
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
where F: Fn() -> impl FnOnce() -> i32
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
{
type Output = Self;
fn add(self, other: F) -> Self::Output {
move || Lazy(self().0 + other()())
}
}
fn main() {}

View File

@ -0,0 +1,89 @@
// Copyright 2016 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.
#![feature(conservative_impl_trait, specialization)]
trait Foo: Copy + ToString {}
impl<T: Copy + ToString> Foo for T {}
fn hide<T: Foo>(x: T) -> impl Foo {
x
}
fn two(x: bool) -> impl Foo {
if x {
return 1_i32;
}
0_u32
//~^ ERROR mismatched types
//~| expected i32, found u32
}
fn sum_to(n: u32) -> impl Foo {
if n == 0 {
0
} else {
n + sum_to(n - 1)
//~^ ERROR the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
}
}
trait Leak: Sized {
type T;
fn leak(self) -> Self::T;
}
impl<T> Leak for T {
default type T = ();
default fn leak(self) -> Self::T { panic!() }
}
impl Leak for i32 {
type T = i32;
fn leak(self) -> i32 { self }
}
trait CheckIfSend: Sized {
type T: Default;
fn check(self) -> Self::T { Default::default() }
}
impl<T> CheckIfSend for T {
default type T = ();
}
impl<T: Send> CheckIfSend for T {
type T = bool;
}
fn main() {
let _: u32 = hide(0_u32);
//~^ ERROR mismatched types
//~| expected type `u32`
//~| found type `impl Foo`
//~| expected u32, found anonymized type
let _: i32 = Leak::leak(hide(0_i32));
//~^ ERROR mismatched types
//~| expected type `i32`
//~| found type `<impl Foo as Leak>::T`
//~| expected i32, found associated type
let _: bool = CheckIfSend::check(hide(0_i32));
//~^ ERROR mismatched types
//~| expected type `bool`
//~| found type `<impl Foo as CheckIfSend>::T`
//~| expected bool, found associated type
let mut x = (hide(0_u32), hide(0_i32));
x = (x.1,
//~^ ERROR mismatched types
//~| expected u32, found i32
x.0);
//~^ ERROR mismatched types
//~| expected i32, found u32
}

View File

@ -0,0 +1,14 @@
// Copyright 2016 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.
fn foo() -> impl Fn() { || {} }
//~^ ERROR `impl Trait` is experimental
fn main() {}

View File

@ -0,0 +1,43 @@
// Copyright 2016 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.
#![feature(conservative_impl_trait)]
// Helper creating a fake borrow, captured by the impl Trait.
fn borrow<'a, T>(_: &'a mut T) -> impl Copy { () }
fn stack() -> impl Copy {
//~^ ERROR only named lifetimes are allowed in `impl Trait`
let x = 0;
&x
}
fn late_bound(x: &i32) -> impl Copy {
//~^ ERROR only named lifetimes are allowed in `impl Trait`
x
}
// FIXME(#34511) Should work but doesn't at the moment,
// region-checking needs an overhault to support this.
fn early_bound<'a>(x: &'a i32) -> impl Copy {
//~^ ERROR only named lifetimes are allowed in `impl Trait`
x
}
fn ambiguous<'a, 'b>(x: &'a [u32], y: &'b [u32]) -> impl Iterator<Item=u32> {
//~^ ERROR only named lifetimes are allowed in `impl Trait`
if x.len() < y.len() {
x.iter().cloned()
} else {
y.iter().cloned()
}
}
fn main() {}

View File

@ -0,0 +1,23 @@
// Copyright 2016 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.
#![feature(conservative_impl_trait)]
// Helper creating a fake borrow, captured by the impl Trait.
fn borrow<'a, T>(_: &'a mut T) -> impl Copy { () }
fn main() {
//~^ NOTE reference must be valid for the block
let long;
let mut short = 0;
//~^ NOTE but borrowed value is only valid for the block suffix following statement 1
long = borrow(&mut short);
//~^ ERROR `short` does not live long enough
}

View File

@ -0,0 +1,43 @@
// Copyright 2016 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.
#![feature(conservative_impl_trait, specialization)]
trait Foo: std::fmt::Debug + Eq {}
impl<T: std::fmt::Debug + Eq> Foo for T {}
fn hide<T: Foo>(x: T) -> impl Foo {
x
}
trait Leak<T>: Sized {
fn leak(self) -> T;
}
impl<T, U> Leak<T> for U {
default fn leak(self) -> T { panic!("type mismatch") }
}
impl<T> Leak<T> for T {
fn leak(self) -> T { self }
}
fn lucky_seven() -> impl Fn(usize) -> u8 {
let a = [1, 2, 3, 4, 5, 6, 7];
move |i| a[i]
}
fn main() {
assert_eq!(hide(42), hide(42));
assert_eq!(std::mem::size_of_val(&hide([0_u8; 5])), 5);
assert_eq!(std::mem::size_of_val(&lucky_seven()), 7);
assert_eq!(Leak::<i32>::leak(hide(5_i32)), 5_i32);
}