Why can't the compiler parse "a like u32 <b" or the like?

The following code looks trivial and unambiguous ( Playground ):

let a: u16 = 5; let b: u32 = 10; let c = a as u32 < b; 

However, the compiler (as of 2017-05-30) fails with a syntax error:

 error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `;` --> src/main.rs:6:25 | 6 | let c = a as u32 < b; | 

What is wrong with the compiler?

+7
syntax-error rust
source share
1 answer

Note. . Recent Rust compilers now provide a more useful error message ( # 42578 ):

 error: `<` is interpreted as a start of generic arguments for `u32`, not a comparison --> src/main.rs:6:22 | 6 | let c = a as u32 < b; | -------- ^ -- interpreted as generic arguments | | | | | not interpreted as comparison | help: try comparing the casted value: `(a as u32)` 

This is a known issue with the compiler ( # 22644 ). Simply put, since the type ( u32 ) was followed by < , the compiler tried to parse < as the beginning of the list of type parameters. Consequently, the compiler expected something like u32 < b > , which would be syntactically valid, although this does not make sense. Nonetheless, an example that makes a perfectly valid Rust is foo as Rc < fmt::Debug > , and if the syntax is too eager to make < a less-than statement, then this one will fail just the same.

Of course, there are technically ways to get around this: C ++ and C # had the same ambiguity from the very beginning, they just have some mechanisms that eliminate the ambiguity of these cases (for example, look ahead for an arbitrary number of tokens), although it makes the parser more complicated. Enabling these mechanisms in Rust can violate syntax changes (or probably only the rustc syntax core).

Since there is currently no active discussion to solve this problem, a fairly simple and long-term solution is to wrap the drill around parentheses:

 let c = (a as u32) < b; 
+12
source share

All Articles