-
Notifications
You must be signed in to change notification settings - Fork 847
Description
Using a made-up directive (or a typo) will not yield a syntax warning. I think it should. Though some typos are caught.
Repro steps
Useful FS1169, but incorrect:
#iff FALSE
something illegal
#endif
gives:
FS1169: #if directive should be immediately followed by an identifier
Though, from a syntax standpoint, the directive keyword here is iff, not if, so it should be recognized as an invalid directive, rather than a misuse of the #if .
Error, but unexpected
#foo 12
gives:
FS0010: Unexpected integer literal in implementation file. Expected incomplete structured construct at or before this point or other token.
Probably not the text you'd expect, and certainly not where you might expect it, as it is #foo that's illegal, 12 is irrelevant:
No error at all, but totally illegal
#foo "test"
Warning, but unexpected
module X =
#foo "test"
()
gives this warning:
FS0236: Directives inside modules are ignored
But it is illegal syntax and should give an error.
Expected behavior
All scenarios above should give an error on the the start of the false, non-existent directive.
Actual behavior
Errors, warnings, or even no errors where it is clearly illegal syntax
Known workarounds
Use your brains, don't rely on the compiler to check for valid syntax ;).
Related information
Seen on current and previous versions of F#, so this is not a new bug.
In theory, failing capturing these syntax errors could be exploited by a preprocessor to do something useful with these directives. That means that fixing this is potentially backward-incompatible if users have indeed exploited this bug. Still, I would suggest to fix it, or turn it into a proper feature (for instance with a hook to do that preprocessing in a neat way).
Do note, however, that the F# 4.0 spec, section 12.4, shows in the syntax that there must be a space between the directive and the string or strings (and it contains a typo, suggesting there is a space between # and the identifier). Also, the specification only lists what are valid directive, suggesting anything else should be invalid (i.e., #iff, #foo from the examples above).
