Illegal prefix operators sometimes compile fine, but give confusing errors when applied
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 11h
- Merged PRs (30d)
- 131
Description
When trying to experimentally determine what operators can be overloaded as prefix operators (the [docs are sorely lacking and even misinforming, as this SO question shows](http://stackoverflow.com/questions/2304120/f-what-are-the-valid-prefix-operators)), I stumbled upon the following weird behavior:
```
let (?%) x = x + 1
let test = ?% 2
```
Two things to note:
1. In Visual Studio it shows as a warning (orange curly)
2. When compiled, or when hovering over it, it throws the error _"FS0010: Unexpected infix operator in binding"_ (which itself can be resolved by using parentheses around the operator)
According to the docs and the spec, at least what I make of it, a prefix operator must start with a `!`, a `~`, a `+` or a `-`. The above shows that a prefix operator can also start with a `?`, but this seems a bug (I mean, I think it should be disallowed), because:
```
let (?!) x = x + 1
```
will fail to compile, throwing the (expected) error _"FS1208: Invalid operator definition. Prefix operator definitions must use a valid prefix operator name."_.
I fully realize that I may not understand the docs or the spec well enough to know what prefix operators are illegal or not, but I think the above shows that there is at least some ambiguity to how the compiler treats the rules, and it shows that the docs seem incomplete.
To illustrate the latter, [MSDN F# operator precedence](https://msdn.microsoft.com/en-us/library/dd233228.aspx#Anchor_1) shows `+op` and `-op` as valid, but:
```
let (+^) a = a // compiles
let test = +^ 2 // throws FS1208: Invalid prefix operator
```
Again, this can be resolved by using parentheses, but here we see a _different_ error in a similar situation, besides, this situation uses an example from the docs (and it seems to me this is allowed by the spec as well), but fails to compile, unless you use parentheses (though I fail to see ambiguity issues here, nor precedence rule issues).
Finally, the last (different, again) error I noticed is with:
```
let (+.) a = a // compiles
let test = +. 2 // throws FS0001: The type 'int' does not support the operator '~+.'
// and throws FS0043: The type 'int' does not support the operator '~+.'
```
again solvable by using parentheses which, I think, are again not needed.
Contributor guide
Assessment
This issue has not been assessed yet.