-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add more extensive tests for impl Trait.
- Loading branch information
Showing
7 changed files
with
291 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |