2 ms·
I'm thinking of the need to have blocks wrapping expressions in types [1]: const X: usize = 7; let x: RectangularArray<i32, 2, 4>; let y: RectangularA
by twic 6y ago
I'm thinking of the need to have blocks wrapping expressions in types [1]:
const X: usize = 7;
let x: RectangularArray<i32, 2, 4>;
let y: RectangularArray<i32, X, {2 * 2}>;
Simple cases are fine, but i suspect a lot of real-world use of const generics are going to require blocks.
AIUI, this is only because <> was chosen as the container for type arguments, and > is also a legal operator in expressions. So, for example, if Rust had used Scala-esque [] for type arguments, this would not be a problem.
[1] https://rust-lang.github.io/rfcs/2000-const-generics.html#applying-a-const-as-a-parameter https://rust-lang.github.io/rfcs/2000-const-generics.html#ap...
- Uther 6y agoWhile I would prefer brackets, that would not be enought to solve all the problems since, there would be conflict with array syntax too.
- twic 6y agoBut the square brackets used in array access nest, so the parsing is never ambiguous. The reason > needs braces is that without them, if you're parsing and so far you've seen these characters: let y: RectangularArray<i32, X, 2> You don't know if that final > is ending the argument list, or is a greater-than operator, with the rest of an expression coming after it. But if it was square brackets, then a closing square bracket on its own can only ever be the end of the list: let y: RectangularArray[i32, X, 2] Because if it was closing an array access, there would have to have been an opening square bracket: let y: RectangularArray[i32, X, a[1]
- twic 6y agoIn case anyone ever stumbles across this thread, a couple of posts about this: https://keleshev.com/parsing-ambiguity-type-argument-v-less-than https://keleshev.com/parsing-ambiguity-type-argument-v-less-... https://soc.me/languages/stop-using-for-generics https://soc.me/languages/stop-using-for-generics
- masklinn 6y agoThat's what I originally thought about, but the thing is `]` in and of itself is not an operator while `>` is, so foo<bar, qux>corge> "is" valid syntax while foo[bar, qux]corge] is not. The former requires some sort of disambiguation, while the latter is not. Put an other way, in terms of syntax `[]` always parses the same way (with `[` is infix and `]` terminates it), there can be ambiguity between indexing and generics but it doesn't really matter for the original parsing. For `<>` however, the parsing itself can be ambiguous as `>` could either be the terminator of an earlier `<` or it could be the infix `>` operator. That is where the issue lies, you can't know how to build the AST without either explicit disambiguation, or infinite lookaheads.