Skip to content

Commit 23f0494

Browse files
committed
test: add more extensive tests for impl Trait.
1 parent 08bf9f6 commit 23f0494

File tree

7 files changed

+291
-0
lines changed

7 files changed

+291
-0
lines changed

Diff for: src/test/compile-fail/impl-trait/disallowed-2.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(conservative_impl_trait)]
12+
13+
fn main() {
14+
let _: impl Fn() = || {};
15+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
16+
let _ = || -> impl Fn() { || {} };
17+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
18+
}

Diff for: src/test/compile-fail/impl-trait/disallowed.rs

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(conservative_impl_trait)]
12+
13+
fn arguments(_: impl Fn(),
14+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
15+
_: Vec<impl Clone>) {}
16+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
17+
18+
type Factory<R> = impl Fn() -> R;
19+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
20+
21+
type GlobalFactory<R> = fn() -> impl FnOnce() -> R;
22+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
23+
24+
trait LazyToString {
25+
fn lazy_to_string<'a>(&'a self) -> impl Fn() -> String;
26+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
27+
}
28+
29+
// Note that the following impl doesn't error, because the trait is invalid.
30+
impl LazyToString for String {
31+
fn lazy_to_string<'a>(&'a self) -> impl Fn() -> String {
32+
|| self.clone()
33+
}
34+
}
35+
36+
#[derive(Copy, Clone)]
37+
struct Lazy<T>(T);
38+
39+
impl std::ops::Add<Lazy<i32>> for Lazy<i32> {
40+
type Output = impl Fn() -> Lazy<i32>;
41+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
42+
43+
fn add(self, other: Lazy<i32>) -> Self::Output {
44+
move || Lazy(self.0 + other.0)
45+
}
46+
}
47+
48+
impl<F> std::ops::Add<F>
49+
for impl Fn() -> Lazy<i32>
50+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
51+
where F: Fn() -> impl FnOnce() -> i32
52+
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
53+
{
54+
type Output = Self;
55+
56+
fn add(self, other: F) -> Self::Output {
57+
move || Lazy(self().0 + other()())
58+
}
59+
}
60+
61+
fn main() {}

Diff for: src/test/compile-fail/impl-trait/equality.rs

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(conservative_impl_trait, specialization)]
12+
13+
trait Foo: Copy + ToString {}
14+
15+
impl<T: Copy + ToString> Foo for T {}
16+
17+
fn hide<T: Foo>(x: T) -> impl Foo {
18+
x
19+
}
20+
21+
fn two(x: bool) -> impl Foo {
22+
if x {
23+
return 1_i32;
24+
}
25+
0_u32
26+
//~^ ERROR mismatched types
27+
//~| expected i32, found u32
28+
}
29+
30+
fn sum_to(n: u32) -> impl Foo {
31+
if n == 0 {
32+
0
33+
} else {
34+
n + sum_to(n - 1)
35+
//~^ ERROR the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
36+
}
37+
}
38+
39+
trait Leak: Sized {
40+
type T;
41+
fn leak(self) -> Self::T;
42+
}
43+
impl<T> Leak for T {
44+
default type T = ();
45+
default fn leak(self) -> Self::T { panic!() }
46+
}
47+
impl Leak for i32 {
48+
type T = i32;
49+
fn leak(self) -> i32 { self }
50+
}
51+
52+
trait CheckIfSend: Sized {
53+
type T: Default;
54+
fn check(self) -> Self::T { Default::default() }
55+
}
56+
impl<T> CheckIfSend for T {
57+
default type T = ();
58+
}
59+
impl<T: Send> CheckIfSend for T {
60+
type T = bool;
61+
}
62+
63+
fn main() {
64+
let _: u32 = hide(0_u32);
65+
//~^ ERROR mismatched types
66+
//~| expected type `u32`
67+
//~| found type `impl Foo`
68+
//~| expected u32, found anonymized type
69+
70+
let _: i32 = Leak::leak(hide(0_i32));
71+
//~^ ERROR mismatched types
72+
//~| expected type `i32`
73+
//~| found type `<impl Foo as Leak>::T`
74+
//~| expected i32, found associated type
75+
76+
let _: bool = CheckIfSend::check(hide(0_i32));
77+
//~^ ERROR mismatched types
78+
//~| expected type `bool`
79+
//~| found type `<impl Foo as CheckIfSend>::T`
80+
//~| expected bool, found associated type
81+
82+
let mut x = (hide(0_u32), hide(0_i32));
83+
x = (x.1,
84+
//~^ ERROR mismatched types
85+
//~| expected u32, found i32
86+
x.0);
87+
//~^ ERROR mismatched types
88+
//~| expected i32, found u32
89+
}

Diff for: src/test/compile-fail/impl-trait/feature-gate.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn foo() -> impl Fn() { || {} }
12+
//~^ ERROR `impl Trait` is experimental
13+
14+
fn main() {}

Diff for: src/test/compile-fail/impl-trait/lifetimes.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(conservative_impl_trait)]
12+
13+
// Helper creating a fake borrow, captured by the impl Trait.
14+
fn borrow<'a, T>(_: &'a mut T) -> impl Copy { () }
15+
16+
fn stack() -> impl Copy {
17+
//~^ ERROR only named lifetimes are allowed in `impl Trait`
18+
let x = 0;
19+
&x
20+
}
21+
22+
fn late_bound(x: &i32) -> impl Copy {
23+
//~^ ERROR only named lifetimes are allowed in `impl Trait`
24+
x
25+
}
26+
27+
// FIXME(#34511) Should work but doesn't at the moment,
28+
// region-checking needs an overhault to support this.
29+
fn early_bound<'a>(x: &'a i32) -> impl Copy {
30+
//~^ ERROR only named lifetimes are allowed in `impl Trait`
31+
x
32+
}
33+
34+
fn ambiguous<'a, 'b>(x: &'a [u32], y: &'b [u32]) -> impl Iterator<Item=u32> {
35+
//~^ ERROR only named lifetimes are allowed in `impl Trait`
36+
if x.len() < y.len() {
37+
x.iter().cloned()
38+
} else {
39+
y.iter().cloned()
40+
}
41+
}
42+
43+
fn main() {}

Diff for: src/test/compile-fail/impl-trait/loan-extend.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(conservative_impl_trait)]
12+
13+
// Helper creating a fake borrow, captured by the impl Trait.
14+
fn borrow<'a, T>(_: &'a mut T) -> impl Copy { () }
15+
16+
fn main() {
17+
//~^ NOTE reference must be valid for the block
18+
let long;
19+
let mut short = 0;
20+
//~^ NOTE but borrowed value is only valid for the block suffix following statement 1
21+
long = borrow(&mut short);
22+
//~^ ERROR `short` does not live long enough
23+
}

Diff for: src/test/run-pass/impl-trait/equality.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(conservative_impl_trait, specialization)]
12+
13+
trait Foo: std::fmt::Debug + Eq {}
14+
15+
impl<T: std::fmt::Debug + Eq> Foo for T {}
16+
17+
fn hide<T: Foo>(x: T) -> impl Foo {
18+
x
19+
}
20+
21+
trait Leak<T>: Sized {
22+
fn leak(self) -> T;
23+
}
24+
impl<T, U> Leak<T> for U {
25+
default fn leak(self) -> T { panic!("type mismatch") }
26+
}
27+
impl<T> Leak<T> for T {
28+
fn leak(self) -> T { self }
29+
}
30+
31+
fn lucky_seven() -> impl Fn(usize) -> u8 {
32+
let a = [1, 2, 3, 4, 5, 6, 7];
33+
move |i| a[i]
34+
}
35+
36+
fn main() {
37+
assert_eq!(hide(42), hide(42));
38+
39+
assert_eq!(std::mem::size_of_val(&hide([0_u8; 5])), 5);
40+
assert_eq!(std::mem::size_of_val(&lucky_seven()), 7);
41+
42+
assert_eq!(Leak::<i32>::leak(hide(5_i32)), 5_i32);
43+
}

0 commit comments

Comments
 (0)