From 19badc514976d64bf6c495e859a7e2a70230bf18 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:59:53 +0200 Subject: [PATCH 1/7] update for RFC FS-1146 (scoped nowarn) and for extended if grammar --- .../language-reference/compiler-directives.md | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/docs/fsharp/language-reference/compiler-directives.md b/docs/fsharp/language-reference/compiler-directives.md index b467d5339cf6d..958eb754a0545 100644 --- a/docs/fsharp/language-reference/compiler-directives.md +++ b/docs/fsharp/language-reference/compiler-directives.md @@ -19,39 +19,45 @@ The following table lists the preprocessor directives that are available in F#. |Directive|Description| |---------|-----------| -|`#if` *symbol*|Supports conditional compilation. Code in the section after the `#if` is included if the *symbol* is defined. The symbol can also be negated with `!`.| -|`#else`|Supports conditional compilation. Marks a section of code to include if the symbol used with the previous `#if` is not defined.| +|`#if` *if-expression*|Supports conditional compilation. Code in the section after the `#if` is included if the *if-eyxpression* evaluates to `defined` (see below).| +|`#else`|Supports conditional compilation. Marks a section of code to include if the symbol used with the previous `#if` does not evaluate to `defined`.| |`#endif`|Supports conditional compilation. Marks the end of a conditional section of code.| |`#`[line] *int*,
`#`[line] *int* *string*,
`#`[line] *int* *verbatim-string*|Indicates the original source code line and file name, for debugging. This feature is provided for tools that generate F# source code.| -|`#nowarn` *warningcode*|Disables a compiler warning or warnings. To disable multiple warning numbers on the same line, separate each string by a space.
For example: `#nowarn 9 42`| +|`#nowarn` *warningcode*|Disables a compiler warning or warnings. To disable multiple warning numbers on the same line, separate each string by a space.
For example: `#nowarn 9 42`
The warning is disabled until eof or until a `#warnon` directive for that same warning number is foud.| +|`#warnon` *warningcode*|Enables a compiler warning (or warnings) that was disabled by a compiler option or by a `#nowarn` directive..
The warning is enabled until eof or until a `#nowarn` directive for that same warning number is found.| -The effect of disabling a warning applies to the entire file, including portions of the file that precede the directive.| ## Conditional Compilation Directives Code that is deactivated by one of these directives appears dimmed in the Visual Studio Code Editor. -> [!NOTE] -> The behavior of the conditional compilation directives is not the same as it is in other languages. For example, you cannot use Boolean expressions involving symbols, and `true` and `false` have no special meaning. Symbols that you use in the `if` directive must be defined by the command line or in the project settings; there is no `define` preprocessor directive. - The following code illustrates the use of the `#if`, `#else`, and `#endif` directives. In this example, the code contains two versions of the definition of `function1`. When `VERSION1` is defined by using the [-define compiler option](./compiler-options.md), the code between the `#if` directive and the `#else` directive is activated. Otherwise, the code between `#else` and `#endif` is activated. [!code-fsharp[Main](~/samples/snippets/fsharp/lang-ref-2/snippet7301.fs)] -There is no `#define` preprocessor directive in F#. You must use the compiler option or project settings to define the symbols used by the `#if` directive. - -Conditional compilation directives can be nested. Indentation is not significant for preprocessor directives. - -You can also negate a symbol with `!`. In this example, a string's value is something only when _not_ debugging: +The `#if` directive also accepts logical expressions: ```fsharp -#if !DEBUG -let str = "Not debugging!" -#else -let str = "Debugging!" +#if SILVERLIGHT || COMPILED && (NETCOREFX || !DEBUG) #endif ``` +The following expressions can be used. + +| if-expr | evaluation | +| --- | --- | +| `if-expr1 \|\| if-expr2` | `defined` if `if-expr1` or `if-expr2` is `defined`. | +| `if-expr1 && if-expr2` | `defined` if `if-expr1` and `if-expr2` are `defined`. | +| `!if-expr1` | `defined` if `if-expr1` is not `defined`. | +| `( if-expr1 )` | defined if `if-expr1` is defined. | +| `symbol` | `defined` if it is flagged as defined by the `-define` compiler option. | + +The logical operators have the usual logical precedence. + +There is no `#define` preprocessor directive in F#. You must use the compiler option or project settings to define the symbols used by the `#if` directive. + +Conditional compilation directives can be nested. Indentation is not significant for preprocessor directives. + ## NULLABLE directive Starting with F# 9, you can enable nullable reference types in the project: @@ -84,6 +90,8 @@ When you use the `#line` directive, file names must be enclosed in quotation mar These tokens indicate that the F# code generated at this location is derived from some constructs at or near line `25` in `Script1`. +Note that `#line` directives do not influence the behavior of `#nowarn` / `#warnon`. These two directives always relate the the file that is being compiled. + ## See also - [F# Language Reference](index.md) From 102795d9545c399576cb9d6886b864b12389f0f0 Mon Sep 17 00:00:00 2001 From: Martin <29605222+Martin521@users.noreply.github.com> Date: Tue, 8 Jul 2025 17:16:47 +0200 Subject: [PATCH 2/7] Update docs/fsharp/language-reference/compiler-directives.md Co-authored-by: Tomas Grosup --- docs/fsharp/language-reference/compiler-directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fsharp/language-reference/compiler-directives.md b/docs/fsharp/language-reference/compiler-directives.md index 958eb754a0545..16312e9630e6a 100644 --- a/docs/fsharp/language-reference/compiler-directives.md +++ b/docs/fsharp/language-reference/compiler-directives.md @@ -19,7 +19,7 @@ The following table lists the preprocessor directives that are available in F#. |Directive|Description| |---------|-----------| -|`#if` *if-expression*|Supports conditional compilation. Code in the section after the `#if` is included if the *if-eyxpression* evaluates to `defined` (see below).| +|`#if` *if-expression*|Supports conditional compilation. Code in the section after the `#if` is included if the *if-expression* evaluates to `defined` (see below).| |`#else`|Supports conditional compilation. Marks a section of code to include if the symbol used with the previous `#if` does not evaluate to `defined`.| |`#endif`|Supports conditional compilation. Marks the end of a conditional section of code.| |`#`[line] *int*,
`#`[line] *int* *string*,
`#`[line] *int* *verbatim-string*|Indicates the original source code line and file name, for debugging. This feature is provided for tools that generate F# source code.| From c6983feba32fefb7dfd19c2de97324df304c334c Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Tue, 8 Jul 2025 17:18:39 +0200 Subject: [PATCH 3/7] removed empty line (for the linter) --- docs/fsharp/language-reference/compiler-directives.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/fsharp/language-reference/compiler-directives.md b/docs/fsharp/language-reference/compiler-directives.md index 16312e9630e6a..eadd54c384be0 100644 --- a/docs/fsharp/language-reference/compiler-directives.md +++ b/docs/fsharp/language-reference/compiler-directives.md @@ -26,7 +26,6 @@ The following table lists the preprocessor directives that are available in F#. |`#nowarn` *warningcode*|Disables a compiler warning or warnings. To disable multiple warning numbers on the same line, separate each string by a space.
For example: `#nowarn 9 42`
The warning is disabled until eof or until a `#warnon` directive for that same warning number is foud.| |`#warnon` *warningcode*|Enables a compiler warning (or warnings) that was disabled by a compiler option or by a `#nowarn` directive..
The warning is enabled until eof or until a `#nowarn` directive for that same warning number is found.| - ## Conditional Compilation Directives Code that is deactivated by one of these directives appears dimmed in the Visual Studio Code Editor. From 8c9305ca1e4fc67444571e1b96c4a60202a2a14b Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:02:59 +0200 Subject: [PATCH 4/7] more details on warn directives --- .../language-reference/compiler-directives.md | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/docs/fsharp/language-reference/compiler-directives.md b/docs/fsharp/language-reference/compiler-directives.md index eadd54c384be0..54888c984ba37 100644 --- a/docs/fsharp/language-reference/compiler-directives.md +++ b/docs/fsharp/language-reference/compiler-directives.md @@ -1,21 +1,17 @@ --- title: Compiler Directives -description: Learn about F# language preprocessor directives, conditional compilation directives, line directives, and compiler directives. +description: Learn about F# language conditional compilation directives, line directives, and warn directives. ms.date: 12/10/2018 f1_keywords: - "#endif_FS" --- # Compiler Directives -This topic describes processor directives and compiler directives. +This topic describes compiler directives, for F# Interactive (`dotnet fsi`) directives, see [Interactive Programming with F#](../tools/fsharp-interactive/index.md). -For F# Interactive (`dotnet fsi`) directives, see [Interactive Programming with F#](../tools/fsharp-interactive/index.md). +A compiler directive is prefixed with the # symbol and appears on a line by itself. -## Preprocessor Directives - -A preprocessor directive is prefixed with the # symbol and appears on a line by itself. It is interpreted by the preprocessor, which runs before the compiler itself. - -The following table lists the preprocessor directives that are available in F#. +The following table lists the compiler directives that are available in F#. |Directive|Description| |---------|-----------| @@ -23,8 +19,8 @@ The following table lists the preprocessor directives that are available in F#. |`#else`|Supports conditional compilation. Marks a section of code to include if the symbol used with the previous `#if` does not evaluate to `defined`.| |`#endif`|Supports conditional compilation. Marks the end of a conditional section of code.| |`#`[line] *int*,
`#`[line] *int* *string*,
`#`[line] *int* *verbatim-string*|Indicates the original source code line and file name, for debugging. This feature is provided for tools that generate F# source code.| -|`#nowarn` *warningcode*|Disables a compiler warning or warnings. To disable multiple warning numbers on the same line, separate each string by a space.
For example: `#nowarn 9 42`
The warning is disabled until eof or until a `#warnon` directive for that same warning number is foud.| -|`#warnon` *warningcode*|Enables a compiler warning (or warnings) that was disabled by a compiler option or by a `#nowarn` directive..
The warning is enabled until eof or until a `#nowarn` directive for that same warning number is found.| +|`#nowarn` *warningcodes*|Disables one or more compiler warnings as specified by *warningcodes* (see below).| +|`#warnon` *warningcodes*|Enables one or more compiler warnings as specified by *warningcodes* (see below).| ## Conditional Compilation Directives @@ -53,9 +49,9 @@ The following expressions can be used. The logical operators have the usual logical precedence. -There is no `#define` preprocessor directive in F#. You must use the compiler option or project settings to define the symbols used by the `#if` directive. +There is no `#define` compiler directive in F#. You must use the compiler option or project settings to define the symbols used by the `#if` directive. -Conditional compilation directives can be nested. Indentation is not significant for preprocessor directives. +Conditional compilation directives can be nested. Indentation is not significant for compiler directives. ## NULLABLE directive @@ -91,6 +87,40 @@ These tokens indicate that the F# code generated at this location is derived fro Note that `#line` directives do not influence the behavior of `#nowarn` / `#warnon`. These two directives always relate the the file that is being compiled. +## Warn Directives + +Warn directives disable or enable specified compiler warnings for parts of a source file. + +A warn directive is a single line of source code that consists of + +- Optional leading whitespace +- The string `#nowarn` or `#warnon` +- Whitespace +- One or more *warningcodes* (see below), separated by whitespace +- Optional whitespace +- Optional line comment + +A *warningcode* is a sequence of digits (representing the warning number), optionally preceded by `FS`, optionally surrounded by double quotes. + +A `#nowarn` directive disables a warning until a `#warnon` directive for the same warning number is found, or else until end of file. Similarly, a `#nowarn` directive disables a warning until a `#warnon` directive for the same warning numberis found, or else until end of file. Before and after such pairs, the compilation default applies, which is + +- no warning if disabled by a --nowarn compiler option (or the respective msbuild property) +- no warning for [opt-in warnings](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/compiler-options#opt-in-warnings), unless enabled by the --warnon compiler option (or the respective msbuild property) + +Here is a (contrived) example. + +``` +module A +match None with None -> () // warning +let x = + #nowarn 25 + match None with None -> 1 // no warning + #warnon FS25 +match None with None -> () // warning +#nowarn "FS25" FS007 "42" +match None with None -> () // no warning +``` + ## See also - [F# Language Reference](index.md) From 905f918a33ab9674597e153b9c47ece1f9920845 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:40:54 +0200 Subject: [PATCH 5/7] fixed link --- docs/fsharp/language-reference/compiler-directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fsharp/language-reference/compiler-directives.md b/docs/fsharp/language-reference/compiler-directives.md index 54888c984ba37..39c9c6be93ea0 100644 --- a/docs/fsharp/language-reference/compiler-directives.md +++ b/docs/fsharp/language-reference/compiler-directives.md @@ -105,7 +105,7 @@ A *warningcode* is a sequence of digits (representing the warning number), optio A `#nowarn` directive disables a warning until a `#warnon` directive for the same warning number is found, or else until end of file. Similarly, a `#nowarn` directive disables a warning until a `#warnon` directive for the same warning numberis found, or else until end of file. Before and after such pairs, the compilation default applies, which is - no warning if disabled by a --nowarn compiler option (or the respective msbuild property) -- no warning for [opt-in warnings](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/compiler-options#opt-in-warnings), unless enabled by the --warnon compiler option (or the respective msbuild property) +- no warning for [opt-in warnings](../compiler-options#opt-in-warnings), unless enabled by the --warnon compiler option (or the respective msbuild property) Here is a (contrived) example. From 70b835e00a3266472553b3f02ecdb953d5362f42 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:47:54 +0200 Subject: [PATCH 6/7] fixed the fix --- docs/fsharp/language-reference/compiler-directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fsharp/language-reference/compiler-directives.md b/docs/fsharp/language-reference/compiler-directives.md index 39c9c6be93ea0..551b4932130af 100644 --- a/docs/fsharp/language-reference/compiler-directives.md +++ b/docs/fsharp/language-reference/compiler-directives.md @@ -105,7 +105,7 @@ A *warningcode* is a sequence of digits (representing the warning number), optio A `#nowarn` directive disables a warning until a `#warnon` directive for the same warning number is found, or else until end of file. Similarly, a `#nowarn` directive disables a warning until a `#warnon` directive for the same warning numberis found, or else until end of file. Before and after such pairs, the compilation default applies, which is - no warning if disabled by a --nowarn compiler option (or the respective msbuild property) -- no warning for [opt-in warnings](../compiler-options#opt-in-warnings), unless enabled by the --warnon compiler option (or the respective msbuild property) +- no warning for [opt-in warnings](./compiler-options#opt-in-warnings), unless enabled by the --warnon compiler option (or the respective msbuild property) Here is a (contrived) example. From d3fbed5203e0e2e53923faab80cf506c865ea46c Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:53:59 +0200 Subject: [PATCH 7/7] sorry, yet another correction --- docs/fsharp/language-reference/compiler-directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fsharp/language-reference/compiler-directives.md b/docs/fsharp/language-reference/compiler-directives.md index 551b4932130af..585478b98e0bc 100644 --- a/docs/fsharp/language-reference/compiler-directives.md +++ b/docs/fsharp/language-reference/compiler-directives.md @@ -105,7 +105,7 @@ A *warningcode* is a sequence of digits (representing the warning number), optio A `#nowarn` directive disables a warning until a `#warnon` directive for the same warning number is found, or else until end of file. Similarly, a `#nowarn` directive disables a warning until a `#warnon` directive for the same warning numberis found, or else until end of file. Before and after such pairs, the compilation default applies, which is - no warning if disabled by a --nowarn compiler option (or the respective msbuild property) -- no warning for [opt-in warnings](./compiler-options#opt-in-warnings), unless enabled by the --warnon compiler option (or the respective msbuild property) +- no warning for [opt-in warnings](./compiler-options.md#opt-in-warnings), unless enabled by the --warnon compiler option (or the respective msbuild property) Here is a (contrived) example.