diff options
Diffstat (limited to 'src/test/ui/associated-types/issue-54182-1.rs')
-rw-r--r-- | src/test/ui/associated-types/issue-54182-1.rs | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/test/ui/associated-types/issue-54182-1.rs b/src/test/ui/associated-types/issue-54182-1.rs new file mode 100644 index 000000000..1a1e98cba --- /dev/null +++ b/src/test/ui/associated-types/issue-54182-1.rs @@ -0,0 +1,92 @@ +// 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() + } +} |