Pre-Pre-RFC: async methods & bounding async fns

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? :smile:)

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!

5 Likes