Currently the type ascription feature uses the : syntax. It’s on nightly for quite a long time, but it doesn’t look it’s going to be stabilized soon. I guess that one of the problems with the : syntax is its interoperation with struct literals, which also use the same symbol. So I’d like to propose to change the colon symbol to type to avoid this amiguity. I’ve tried to search whether it was discussed before, but I haven’t found anything. So if somebody has some links to previous discussion on this syntax, I’d be happy to see them.
Motivation
- Less ambiguity with the struct literal syntax
- More compatibility with various “anonymous structs” / struct shorthand syntax / keyword arguments proposals (by freeing the
:).
- Ability to use type ascriptions in patterns in an unambiguous way (I hope).
Examples
Type ascription of simple expression:
let foo = (0..10).collect() type Vec<_>;
Struct literals:
Struct { foo: foo type T } // simply annotating expression
Struct { foo type T } // shorthand syntax
Struct { foo type T: foo } // perhaps we should also allow this, for consistency?
Interaction with -> T-like functions (imho it reads pretty well):
let x = line.parse()? type i32;
let x = height.into() type f64;
Patterns:
match "aaa".parse() {
Ok(a type T) => { ... }
Err(Error { inner: e type E }) => { ... }
}
Detailed design
For expressions, use the same grammar as the as-conversion.
For patterns, not sure about the precise rules yet.
Drawbacks
- Longer syntax (one may say it’s less perl-y though)
- Perhaps it’s less discoverable? (although more searchable)
- If we allow
type in all patterns, there will be multiple ways to write an annotated let statement:
let a: T = foo();
let a = foo() type T;
let a type T = foo();
// Also
let b type Result<T, _>: Result<_, E> = foo();
(I guess that allowing current type ascription syntax – : – in patterns whould just change the let statement grammar to let <pat> [ = <expr>])
- Probably, this also introduces ambiguity in grammar, which I just haven’t thought about yet.