++, this is what I’ve suggested elsewhere and I think it side-steps all the annoying problems; I do think you want fn <T as Trait<A>>::method::<B> though… right? (never mind, I worked out a contrived example demonstrating you’re right).
trait Foo<T> {
const K: T;
}
fn foo<T: Default>() {}
impl<T> Foo<T> for fn foo<T> where T: Default {
const K = T::default(); // yeah it's not const just humor me
}
const FOO_I32: i32 = fn foo<i32>::K; // once the parser hits a `fn` token
// it's no longer in expr mode
I think I also suggested at some point that within a function’s scope (including paramteres and return type), it should be allowed to abbreviate as fn or similar (I imagine that some might want fn to be like self and refer to the unique value of the function’s associated ZST, but writing something like fn.type would be ok, too).
I agree that we should have some mechanism like this, but I’m opposed to the keyword typeof; I’m a bigger fan of val.type or val::type, since it avoids introducing a new keyword, and because Rust seems to me much more comfortable with method chaining than C++ is. See also Java, Scala, and Kotlin’s respective T.class, x.type, and x::class. Certainly, I think that C++ spelling it decltype(x) was a mistake.
I also really hate multi-word keywords, but that’s just me.
In fact, there’s talk floated about of making Bar's ctor be a function as well, by allowing f { .. } syntax for function calls. Not sure where all that went though. I think it’s a nice feature that a tuple struct exposes its constructor as a bona-fide function, and changing this would produce a lot of churn anyways. Plus, types and values (which include functions) live in separate namespaces, and attempting to unify those is very much a “this kills the crab” scenario.
Also, something I’d really like is fn foo::return as sugar for <fn foo as FnOnce<..>>::Output (well, we can completely side-step the trait system, the desugaring is just for illustration) and maybe its friends like fn foo::yield.