mirror of https://github.com/rust-lang/rust
93 lines
2.6 KiB
Rust
93 lines
2.6 KiB
Rust
//@ run-pass
|
|
|
|
// Tests that the return type of trait methods is correctly normalized when
|
|
// checking that a method in an impl matches the trait definition when the
|
|
// return type involves a defaulted associated type.
|
|
// ie. the trait has a method with return type `-> Self::R`, and `type R = ()`,
|
|
// but the impl leaves out the return type (resulting in `()`).
|
|
// Note that specialization is not involved in this test; no items in
|
|
// implementations may be overridden. If they were, the normalization wouldn't
|
|
// happen.
|
|
|
|
#![feature(associated_type_defaults)]
|
|
|
|
macro_rules! overload {
|
|
($a:expr, $b:expr) => {
|
|
overload::overload2($a, $b)
|
|
};
|
|
($a:expr, $b:expr, $c:expr) => {
|
|
overload::overload3($a, $b, $c)
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let () = overload!(42, true);
|
|
|
|
let r: f32 = overload!("Hello world", 13.0);
|
|
assert_eq!(r, 13.0);
|
|
|
|
let () = overload!(42, true, 42.5);
|
|
|
|
let r: i32 = overload!("Hello world", 13.0, 42);
|
|
assert_eq!(r, 42);
|
|
}
|
|
|
|
mod overload {
|
|
/// This trait has an assoc. type defaulting to `()`, and a required method returning a value
|
|
/// of that assoc. type.
|
|
pub trait Overload {
|
|
// type R;
|
|
type R = ();
|
|
fn overload(self) -> Self::R;
|
|
}
|
|
|
|
// overloads for 2 args
|
|
impl Overload for (i32, bool) {
|
|
// type R = ();
|
|
|
|
/// This function has no return type specified, and so defaults to `()`.
|
|
///
|
|
/// This should work, but didn't, until RFC 2532 was implemented.
|
|
fn overload(self) /*-> Self::R*/ {
|
|
let (a, b) = self; // destructure args
|
|
println!("i32 and bool {:?}", (a, b));
|
|
}
|
|
}
|
|
impl<'a> Overload for (&'a str, f32) {
|
|
type R = f32;
|
|
fn overload(self) -> Self::R {
|
|
let (a, b) = self; // destructure args
|
|
println!("&str and f32 {:?}", (a, b));
|
|
b
|
|
}
|
|
}
|
|
|
|
// overloads for 3 args
|
|
impl Overload for (i32, bool, f32) {
|
|
// type R = ();
|
|
fn overload(self) /*-> Self::R*/ {
|
|
let (a, b, c) = self; // destructure args
|
|
println!("i32 and bool and f32 {:?}", (a, b, c));
|
|
}
|
|
}
|
|
impl<'a> Overload for (&'a str, f32, i32) {
|
|
type R = i32;
|
|
fn overload(self) -> Self::R {
|
|
let (a, b, c) = self; // destructure args
|
|
println!("&str and f32 and i32: {:?}", (a, b, c));
|
|
c
|
|
}
|
|
}
|
|
|
|
// overloads for more args
|
|
// ...
|
|
|
|
pub fn overload2<R, A, B>(a: A, b: B) -> R where (A, B): Overload<R = R> {
|
|
(a, b).overload()
|
|
}
|
|
|
|
pub fn overload3<R, A, B, C>(a: A, b: B, c: C) -> R where (A, B, C): Overload<R = R> {
|
|
(a, b, c).overload()
|
|
}
|
|
}
|