test: add more extensive tests for impl Trait.
This commit is contained in:
parent
08bf9f69b9
commit
23f0494114
18
src/test/compile-fail/impl-trait/disallowed-2.rs
Normal file
18
src/test/compile-fail/impl-trait/disallowed-2.rs
Normal 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
|
||||
}
|
61
src/test/compile-fail/impl-trait/disallowed.rs
Normal file
61
src/test/compile-fail/impl-trait/disallowed.rs
Normal 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() {}
|
89
src/test/compile-fail/impl-trait/equality.rs
Normal file
89
src/test/compile-fail/impl-trait/equality.rs
Normal 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
|
||||
}
|
14
src/test/compile-fail/impl-trait/feature-gate.rs
Normal file
14
src/test/compile-fail/impl-trait/feature-gate.rs
Normal 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() {}
|
43
src/test/compile-fail/impl-trait/lifetimes.rs
Normal file
43
src/test/compile-fail/impl-trait/lifetimes.rs
Normal 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() {}
|
23
src/test/compile-fail/impl-trait/loan-extend.rs
Normal file
23
src/test/compile-fail/impl-trait/loan-extend.rs
Normal 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
|
||||
}
|
43
src/test/run-pass/impl-trait/equality.rs
Normal file
43
src/test/run-pass/impl-trait/equality.rs
Normal 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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user