Here’s a code example: I hope I didn’t get anything wrong. I was obviously only able to check the currrently working stuff
Common: Setup code shared between all following code examples
struct MyStruct<T> { x: T }
trait MyTrait<T> { type Item; fn foo(&self) -> &T; }
impl<T> MyTrait<T> for MyStruct<T> { type Item = Box<T>; fn foo(&self) -> &T { &self.x } }
let my_struct = MyStruct { x: 42 };
Expression context: Referring to method without <.. as Trait>
let _ = <MyStruct<i32> as MyTrait<i32>>::foo(&my_struct); // Current
let _ = MyStruct<i32>::foo(&my_struct); // Proposed
let _ = my_struct.foo(); // Current: This already works for method calls
Type context: Referring to associated type without <.. as Trait>
let _ : <MyStruct<i32> as MyTrait<i32>>::Item = Box::new(123); // Current
let _ : MyStruct<i32>::Item = Box::new(123); // Proposed
Bad future
- We need
<.. as Trait>
to refer to a method or an associated type - We need
<typeof foo>
to refer to the type of a function
let _ : <<typeof <MyStruct<i32> as MyTrait<i32>>::foo> as FnOnce(&MyStruct<i32>) -> &i32>::Output = my_struct.foo();
Looks like C++ template programming ^^’
(See the scrollbar? Did you use it? )
output_of
let _ : output_of!(<MyStruct<i32> as MyTrait<i32>>::foo) = my_struct.foo();
let _ : output_of!(MyStruct<i32>::foo) = my_struct.foo(); // Without `<.. as Trait>`
Question: I wonder: What’s actually inside of output_of
?
- It’s not actually an expression because it’s incomplete
- Type also makes no sense because typeof and outputof are introduced to avoid making functions types
Edit: Answer by @withoutboats
Good future
let _ : MyStruct<i32>::foo::Output = my_struct.foo();
We can read from left to right, yay!