It's not unusual in the F# world to treat warnings as errors, particularly as there are only a few specific warnings that regularly crop up in F#. For example, FS0025 is a warning for a non-exhaustive pattern match:
let x : int = ....
// warning FS0025: Incomplete pattern matches on this expression. For example, the value '2' may indicate a case not covered by the pattern(s).
let description =
match x with
| 0 -> "Zero"
| 1 -> "A single number"
It's good habit to treat FS0025 as an error since an incomplete pattern match can lead to a runtime failure.
You can opt to treat this warning as an error (or indeed all warnings as errors) through either MSBuild arguments, or as settings in the fsproj
file associated with your project:
<WarningsAsErrors>0025</WarningsAsErrors>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsNotAsErrors>3391</WarningsNotAsErrors>
<NoWarn>3391</NoWarn>
- TreatWarningsAsErrors treats all compiler warnings as errors.
- WarningsAsErrors specifically targets a comma-separated list of error codes.
- WarningsNotAsErrors opts out a specific warning as an error.
- NoWarn turns off a specific compiler warning completely.
You can also disable warnings for specific cases using an inline #nowarn
:
#nowarn "0025"
// code now compiles
let description =
match x with
| 0 -> "Zero"
| 1 -> "A single number"
Disabling a warning here ultimately means that no compiler error is raised, even if you have
TreatWarningsAsErrors
set, since no warning is raised in the first place.
Applying across all projects in a solution
If you want to enforce such a standard in your application, if you have only a single project, this is easy enough to do: simply modify the fsproj
as described above. However, if you have multiple projects, you can make use of the Directory.Build.Props file that .NET understands in order to apply it across all projects in a directory:
<Project>
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsNotAsErrors>3391</WarningsNotAsErrors>
</PropertyGroup>
</Project>
The above file should exist at the root of the directory / repository in which your .NET projects live, and will automatically apply these settings across all projects. Any new projects that you create will automatically "inherit" these settings.
The CIT Application template
We've recently applied this to the latest version of our CIT Console Template, so that you get this for free. By default we've set it to treat all warnings as errors, but you can of course tweak this as you see fit.
Conclusion
Treating warnings as errors is a good way to enforce compile-time safety, specifically in situations such as incomplete pattern matching and, when F# Nullness Support is released, for unsafely accessing nullable reference values. The Directory.Build.Props
file is a great way to enforce this across all projects, and can be easily added to existing projects.