1 // run-pass
2 
3 use std::borrow::{Cow, ToOwned};
4 use std::default::Default;
5 use std::iter::FromIterator;
6 use std::ops::Add;
7 use std::option::IntoIter as OptionIter;
8 
9 pub struct XorShiftRng;
10 use XorShiftRng as DummyRng;
11 impl Rng for XorShiftRng {}
12 pub trait Rng {}
13 pub trait Rand: Default + Sized {
rand<R: Rng>(_rng: &mut R) -> Self14     fn rand<R: Rng>(_rng: &mut R) -> Self { Default::default() }
15 }
16 impl Rand for i32 { }
17 
18 pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
into_cow(self) -> Cow<'a, B>19     fn into_cow(self) -> Cow<'a, B>;
20 }
21 
22 impl<'a> IntoCow<'a, str> for String {
into_cow(self) -> Cow<'a, str>23     fn into_cow(self) -> Cow<'a, str> {
24         Cow::Owned(self)
25     }
26 }
27 
28 #[derive(PartialEq, Eq)]
29 struct Newt<T>(T);
30 
id<T>(x: T) -> T31 fn id<T>(x: T) -> T { x }
eq<T: Eq>(a: T, b: T) -> bool32 fn eq<T: Eq>(a: T, b: T) -> bool { a == b }
u8_as_i8(x: u8) -> i833 fn u8_as_i8(x: u8) -> i8 { x as i8 }
odd(x: usize) -> bool34 fn odd(x: usize) -> bool { x % 2 == 1 }
dummy_rng() -> DummyRng35 fn dummy_rng() -> DummyRng { XorShiftRng }
36 
37 trait Size: Sized {
size() -> usize38     fn size() -> usize { std::mem::size_of::<Self>() }
39 }
40 impl<T> Size for T {}
41 
42 #[derive(PartialEq, Eq)]
43 struct BitVec;
44 
45 impl BitVec {
from_fn<F>(_: usize, _: F) -> BitVec where F: FnMut(usize) -> bool46     fn from_fn<F>(_: usize, _: F) -> BitVec where F: FnMut(usize) -> bool {
47         BitVec
48     }
49 }
50 
51 #[derive(PartialEq, Eq)]
52 struct Foo<T>(T);
53 
54 impl<T> Foo<T> {
map_in_place<U, F>(self, mut f: F) -> Foo<U> where F: FnMut(T) -> U55     fn map_in_place<U, F>(self, mut f: F) -> Foo<U> where F: FnMut(T) -> U {
56         Foo(f(self.0))
57     }
58 
59 }
60 
61 macro_rules! tests {
62     ($($expr:expr, $ty:ty, ($($test:expr),*);)+) => (pub fn main() {$({
63         const C: $ty = $expr;
64         static S: $ty = $expr;
65         assert!(eq(C($($test),*), $expr($($test),*)));
66         assert!(eq(S($($test),*), $expr($($test),*)));
67         assert!(eq(C($($test),*), S($($test),*)));
68     })+})
69 }
70 
71 tests! {
72     // Free function.
73     id, fn(i32) -> i32, (5);
74     id::<i32>, fn(i32) -> i32, (5);
75 
76     // Enum variant constructor.
77     Some, fn(i32) -> Option<i32>, (5);
78     Some::<i32>, fn(i32) -> Option<i32>, (5);
79 
80     // Tuple struct constructor.
81     Newt, fn(i32) -> Newt<i32>, (5);
82     Newt::<i32>, fn(i32) -> Newt<i32>, (5);
83 
84     // Inherent static methods.
85     Vec::new, fn() -> Vec<()>, ();
86     Vec::<()>::new, fn() -> Vec<()>, ();
87     <Vec<()>>::new, fn() -> Vec<()>, ();
88     Vec::with_capacity, fn(usize) -> Vec<()>, (5);
89     Vec::<()>::with_capacity, fn(usize) -> Vec<()>, (5);
90     <Vec<()>>::with_capacity, fn(usize) -> Vec<()>, (5);
91     BitVec::from_fn, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd);
92     BitVec::from_fn::<fn(usize) -> bool>, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd);
93 
94     // Inherent non-static method.
95     Foo::map_in_place, fn(Foo<u8>, fn(u8) -> i8) -> Foo<i8>, (Foo(b'f'), u8_as_i8);
96     Foo::map_in_place::<i8, fn(u8) -> i8>, fn(Foo<u8>, fn(u8) -> i8) -> Foo<i8>,
97         (Foo(b'f'), u8_as_i8);
98     Foo::<u8>::map_in_place, fn(Foo<u8>, fn(u8) -> i8) -> Foo<i8>
99         , (Foo(b'f'), u8_as_i8);
100     Foo::<u8>::map_in_place::<i8, fn(u8) -> i8>, fn(Foo<u8>, fn(u8) -> i8) -> Foo<i8>
101         , (Foo(b'f'), u8_as_i8);
102 
103     // Trait static methods.
104     bool::size, fn() -> usize, ();
105     <bool>::size, fn() -> usize, ();
106     <bool as Size>::size, fn() -> usize, ();
107 
108     Default::default, fn() -> i32, ();
109     i32::default, fn() -> i32, ();
110     <i32>::default, fn() -> i32, ();
111     <i32 as Default>::default, fn() -> i32, ();
112 
113     Rand::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
114     i32::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
115     <i32>::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
116     <i32 as Rand>::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
117     Rand::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
118     i32::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
119     <i32>::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
120     <i32 as Rand>::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
121 
122     // Trait non-static methods.
123     Clone::clone, fn(&i32) -> i32, (&5);
124     i32::clone, fn(&i32) -> i32, (&5);
125     <i32>::clone, fn(&i32) -> i32, (&5);
126     <i32 as Clone>::clone, fn(&i32) -> i32, (&5);
127 
128     FromIterator::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
129     Vec::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
130     <Vec<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
131     <Vec<_> as FromIterator<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>,
132         (Some(5).into_iter());
133     <Vec<i32> as FromIterator<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>,
134         (Some(5).into_iter());
135     FromIterator::from_iter::<OptionIter<i32>>, fn(OptionIter<i32>) -> Vec<i32>,
136         (Some(5).into_iter());
137     <Vec<i32> as FromIterator<_>>::from_iter::<OptionIter<i32>>, fn(OptionIter<i32>) -> Vec<i32>,
138         (Some(5).into_iter());
139 
140     Add::add, fn(i32, i32) -> i32, (5, 6);
141     i32::add, fn(i32, i32) -> i32, (5, 6);
142     <i32>::add, fn(i32, i32) -> i32, (5, 6);
143     <i32 as Add<_>>::add, fn(i32, i32) -> i32, (5, 6);
144     <i32 as Add<i32>>::add, fn(i32, i32) -> i32, (5, 6);
145 
146     String::into_cow, fn(String) -> Cow<'static, str>,
147         ("foo".to_string());
148     <String>::into_cow, fn(String) -> Cow<'static, str>,
149         ("foo".to_string());
150     <String as IntoCow<_>>::into_cow, fn(String) -> Cow<'static, str>,
151         ("foo".to_string());
152     <String as IntoCow<'static, _>>::into_cow, fn(String) -> Cow<'static, str>,
153         ("foo".to_string());
154 }
155