Skip to content

Invalid directives are not a syntax error, unless in specific places #3487

@abelbraaksma

Description

@abelbraaksma

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:

image

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugImpact-Low(Internal MS Team use only) Describes an issue with limited impact on existing code.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions