Note that the ambiguity with type ascriptions only exists if the expression being ascribed consists of a single identifier (referring to a variable or constant), as an argument name is always a single identifier. Cases like
func(foo: ...)
But there is rarely a need to write a type ascription of a variable/constant, or a reason why one would do so by mistake. Since type ascription is not stable, the parser could be changed to carve out the special case of āidentifier followed by colon in argument positionā for keyword arguments, and parse as type ascription in all other cases.
Type ascription can do two things: affect type inference of the value on the left, and perform implicit coercions. For the former, since the type in question is the variableās type, it would make much more sense to just put it on the variable declaration. The latter will usually happen automatically. There are exceptions, like if @ubsanās example is changed to use a variable:
fn print<T: std::fmt::Debug>(t: T) { println!("{:?}", t); }
fn main() {
let r: &i32 = &0;
print(r: *const i32);
}
ā¦but I donāt think theyāre common at all. (By the way, current nightly doesnāt like this example with #![feature(type_ascription)] - it errors with a type mismatch - but based on the RFC I think it should be allowed.) If you encountered such an ambiguity, you could fix it just by surrounding the whole thing in parentheses ā print((r: *const i32)) ā or alternately by changing : to as (though that might produce a warning).
Also, there arenāt that many implicit coercions, and with the raw pointer ones, the parser could have a special diagnostic: *mut and *const cannot be the start of an expression, so the fragment func(identifier: *mut or func(identifier: *const could produce an error explicitly stating that parentheses are required. (Or it could just automatically disambiguate as an ascription, though thatās probably more confusion than itās worth.) Similarly, the current parser error that tends to crop up if you write a generic type where itās expecting a value:
error: chained comparison operators require parentheses
--> <anon>:6:18
|
6 | foo(&Iterator<i32>);
| ^^^^^^
|
= help: use `::<...>` instead of `<...>` if you meant to specify type arguments
could be changed to note cases where a type ascription might have been intended instead of a keyword argument.