2015-03-31 23:58:01 +00:00
|
|
|
#![allow(dead_code)]
|
|
|
|
|
|
|
|
// Get<T> is covariant in T
|
|
|
|
trait Get<T> {
|
|
|
|
fn get(&self) -> T;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Cloner<T:Clone> {
|
|
|
|
t: T
|
2014-06-26 01:18:13 +00:00
|
|
|
}
|
|
|
|
|
2015-03-31 23:58:01 +00:00
|
|
|
impl<T:Clone> Get<T> for Cloner<T> {
|
|
|
|
fn get(&self) -> T {
|
|
|
|
self.t.clone()
|
2014-06-26 01:18:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-31 23:58:01 +00:00
|
|
|
fn get<'a, G>(get: &G) -> i32
|
|
|
|
where G : Get<&'a i32>
|
|
|
|
{
|
|
|
|
// This fails to type-check because, without variance, we can't
|
|
|
|
// use `G : Get<&'a i32>` as evidence that `G : Get<&'b i32>`,
|
|
|
|
// even if `'a : 'b`.
|
2018-12-25 15:56:47 +00:00
|
|
|
pick(get, &22) //~ ERROR explicit lifetime required in the type of `get` [E0621]
|
2014-06-26 01:18:13 +00:00
|
|
|
}
|
|
|
|
|
2015-03-31 23:58:01 +00:00
|
|
|
fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32
|
|
|
|
where G : Get<&'b i32>
|
|
|
|
{
|
|
|
|
let v = *get.get();
|
|
|
|
if v % 2 != 0 { v } else { *if_odd }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let x = Cloner { t: &23 };
|
|
|
|
let y = get(&x);
|
|
|
|
assert_eq!(y, 23);
|
|
|
|
}
|