Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions docs/fsharp/language-reference/compiler-messages/fs0001.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: "Compiler error FS0001"
ms.date: 12/21/2019
f1_keywords:
- "FS0001"
helpviewer_keywords:
- "FS0001"
---

# FS0001: Error from adding type equation

This message is given when a value is determined to have a type that doesn't unify with a type that has been expected.

The following code demonstrates a simple version of the error:

[!code-fsharp[FS0001-simple](~/samples/snippets/fsharp/compiler-messages/fs0001.fs#L2)]

This code results in the following output:

```text
error FS0001: This expression was expected to have type
'bool'
but here has type
'int'
```

Here, the type of the `booleanBinding` is required to be `bool` by the type annotation. However the value `10` is inferred to be `int`. Because `int` is not the same as `bool`, this message is reported.

This message can be issued in many different circumstances, and they all follow this same pattern. Type inference (or programmer-given type annotations) 'fixes' the type of a function or value to a certain type, and then later that type is used as if it were of a different type than the 'fixed' type. The following code demonstrates a more complex version of the error, where inference across functions causes the error to appear far away from where you might expect:

[!code-fsharp[FS0001-complex](~/samples/snippets/fsharp/compiler-messages/fs0001.fs#L5-L26)]

To solve this message, you must change one of the two parts of the binding: the type annotation or the value binding.

- If the value is correct, change or remove the type annotation.

- If the type annotation is correct, check the value bound and ensure that no logic errors have been made.
28 changes: 28 additions & 0 deletions docs/fsharp/language-reference/compiler-messages/fs0002.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: "Compiler error FS0002"
ms.date: 01/27/2020
f1_keywords:
- "FS0002"
helpviewer_keywords:
- "FS0002"
---

# FS0002: Function Unexpected

This message is given when a lambda is passed as a parameter where a value is expected.

The following code demonstrates the error:

[!code-fsharp[FS0002-error](~/samples/snippets/fsharp/compiler-messages/fs0002.fs#L1-L3)]

This code results in the following output:

```text
error FS0002: This function takes too many arguments, or is used in a context where a function is not expected
```

Here, the type of `ignoreInt` is defined to be a function of `int -> unit`, but a lambda of type `int -> int` is passed instead. Because `int -> int` is not the same type as `int` this message is reported.

To fix this message, the code should be changed so that a non-lambda argument is passed to the function, as in this example:

[!code-fsharp[FS0002-fixed](~/samples/snippets/fsharp/compiler-messages/fs0002.fs#L6-L8)]
38 changes: 38 additions & 0 deletions docs/fsharp/language-reference/compiler-messages/fs0003.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: "Compiler error FS0003"
ms.date: 01/27/2020
f1_keywords:
- "FS0003"
helpviewer_keywords:
- "FS0003"
---

# FS0003: This value is not a function and cannot be applied

This message is given when a parameter is given to a value that cannot accept parameters. This is often the case when attempting to use an indexer into a collection like a list, array, or IEnumerable.

The following code demonstrates one way the error can be seen:

[!code-fsharp[FS0003-pass-parameter-to-value](~/samples/snippets/fsharp/compiler-messages/fs0003.fs#L2-L4)]

In the previous snippet, the FS0003 error is shown because the value `v` is not a function that accepts parameters.

```text
error FS0003: This value is not a function and cannot be applied.
```

Another way the error can be seen is when incorrectly using the indexer available on a type:

[!code-fsharp[FS0003-indexer-missing-dot](~/samples/snippets/fsharp/compiler-messages/fs0003.fs#L7-L8)]

In the previous snippet, the FS0003 error is shown because in F# indexers are accessed via `.[index]` syntax instead of `[index]` syntax.

```text
error FS0003: This value is not a function and cannot be applied. Did you intend to access the indexer via listOfInts.[index] instead?
```

To solve this message, you must determine which of these two scenarios is the root cause.

- If an indexer was intended to be used, make sure the syntax is correct as suggested by the error message. In this case, the correct usage would be `listOfInts.[1]` instead of `listOfInts[1]`

- If a function was intended to be called, make sure the value you're calling is in fact a function. Is there a typo in the name? Try adding type annotations to let-bindings to ensure the code is in line with the intended types.
34 changes: 34 additions & 0 deletions docs/fsharp/language-reference/compiler-messages/fs0005.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: "Compiler error FS0005"
ms.date: 01/27/2020
f1_keywords:
- "FS0005"
helpviewer_keywords:
- "FS0005"
---

# FS0005: This field is not mutable

This message is given when a record field is mutably assigned, but the record field is not marked mutable.

In the following code, a record with immutable fields is declared, an instance of that record is created, and a field of that record is mutably assigned, showing the error:

[!code-fsharp[FS0005-simple](~/samples/snippets/fsharp/compiler-messages/fs0005.fs#L2-L8)]

This code results in the following output:

```text
error FS0005: This field is not mutable
```

Here, the immutable record field `Kind` was assigned the string value "orange", but F# doesn't support mutable assignment unless the field is explicitly marked that way.

To solve this message you have to change either the way the field is defined, or how you're setting the new value.

If you actually intended for the record to have a mutable field (which is a fairly rare practice) you can mark the field as `mutable` in the type definition, as shown here:

[!code-fsharp[FS0005-mutable](~/samples/snippets/fsharp/compiler-messages/fs0005.fs#L11-L17)]

However, it is more idiomatic in F# to perform an immutable update of a record via the `with` expression, which creates a copy of the original record with the fields you specified set to new values as shown here:

[!code-fsharp[FS0005-record-update](~/samples/snippets/fsharp/compiler-messages/fs0005.fs#L20-L26)]
40 changes: 40 additions & 0 deletions docs/fsharp/language-reference/compiler-messages/fs0008.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: "Compiler error FS0008"
ms.date: 01/27/2020
f1_keywords:
- "FS0008"
helpviewer_keywords:
- "FS0008"
---

# FS0008: Indeterminate runtime coercion

This message is given when a type-test pattern is used to match a value, but the cast cannot be safely proven at compile time because the type value has not been determined by the compiler. This often happens when matching on a function parameter whose type has been inferred. The following code illustrates an example of this:

[!code-fsharp[FS0008-error](~/samples/snippets/fsharp/compiler-messages/fs0008.fs#L2-L5)]

This code results in the following output:

```text
This runtime coercion or type test from type
'a
to
string
involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed.
```

In this code, the function parameter `x` has not had a type inferred for it. This could be for any number of reasons, ranging from the parameter not being used in ways that give the type-inference algorithm any information, to the function not being called anywhere else in the code. Because the type of `x` has not been inferred, the compiler cannot guarantee that the type of `x` is able to be cast as a string. Because the compiler cannot guarantee that this cast is able to be performed at runtime, it gives this message.

To fix this message you must provide the compiler more information about the type of the value for which you are using the type-test pattern.

One way of fixing the above code would be to apply a type to the `x` parameter directly:

[!code-fsharp[FS0008-x-given-type](~/samples/snippets/fsharp/compiler-messages/fs0008.fs#L8-L11)]

In this code, the `x` parameter is given a type of `obj`, and since `obj` is able to be type-tested to see if the underlying representation is `string`, the function now compiles.

Another way of fixing the erroneous code is to use a different way of converting the `x` parameter to a `string`:

[!code-fsharp[FS0008-x-given-type](~/samples/snippets/fsharp/compiler-messages/fs0008.fs#L14-L15)]

In this code, the use of the `string` function on the `x` parameter has given the compiler enough information to infer the type of `x` as `string`, so the error is resolved by refactoring the function.
32 changes: 32 additions & 0 deletions docs/fsharp/language-reference/compiler-messages/fs0009.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: "Compiler error FS0009"
ms.date: 01/27/2020
f1_keywords:
- "FS0009"
helpviewer_keywords:
- "FS0009"
---

# FS0009: Possible unverifiable code

This message is given when:

* a function marked with the `Unverifiable` attribute is used,

[!code-fsharp[FS0009-unverifiable-function](~/samples/snippets/fsharp/compiler-messages/fs0009.fs#L2)]

* the `fixed` expression is used, or

[!code-fsharp[FS0009-fixed-expression](~/samples/snippets/fsharp/compiler-messages/fs0009.fs#L5-L9)]

* `LayoutKind.Explicit` is set in the `StructLayoutAttribute` of a struct definition

[!code-fsharp[FS0009-explicit-layout](~/samples/snippets/fsharp/compiler-messages/fs0009.fs#L12-L16)]

In each of these cases, the compiler will give the following message:

```text
FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'
```

To fix this message, you can either add the `#nowarn` directive to the source code file containing the usage, add `<NoWarn>9</NoWarn>` to your project file, or manually add `--nowarn:9` to your F# compiler invocations. Note that the last two mechanisms will disable the warning for your entire project, whereas the first mechanism will disable the warning for only one file.
19 changes: 19 additions & 0 deletions docs/fsharp/language-reference/compiler-messages/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: "Compiler errors and warnings"
description: Descriptions and solutions for errors and warnings that the F# compiler will emit
ms.date: 12/21/2019
---

# F# compiler messages

This section details compiler errors and warnings that the F# compiler will emit for certain constructs. The default sets of errors can be changed by:

- Treating specific warnings as if they were errors by using the `-warnaserror+` compiler option,

- Ignoring specific warnings by using the `-nowarn` compiler option

If a particular warning or error is not yet recorded in this section, go to the end of this page and send feedback that includes the number or text of the error.

## See also

- [F# Compiler Options](../compiler-options.md)
15 changes: 15 additions & 0 deletions docs/fsharp/language-reference/compiler-messages/toc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
- name: Compiler errors and warnings
href: index.md
items:
- name: FS0001 - Error from adding type equation
href: ./fs0001.md
- name: FS0002 - Function Unexpected
href: ./fs0002.md
- name: FS0003 - This value is not a function and cannot be applied
href: ./fs0003.md
- name: FS0005 - This field is not mutable
href: ./fs0005.md
- name: FS0008 - Indeterminate runtime coercion
href: ./fs0008.md
- name: FS0009 - Possible unverifiable code
href: ./fs0009.md
43 changes: 43 additions & 0 deletions docs/fsharp/language-reference/compiler-messages/util/new-message
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#! /usr/bin/env bash

# This script is a helper for generating a new, templated doc entry.
# It can be invoked like: `./new-message <4-digit error number> "title of new error page"`
# It ensures some title, date, and SEO keywords are in place for the new file.

set +eux

function usage () {
echo "usage: new-message <####> <title>"
exit 1;
}

[[ -z $1 || $# -gt 2 ]] && usage

message_number="FS$1"
message_title=$2
year=$(date "+%Y")
month=$(date "+%m")
day=$(date "+%d")
file_name="fs$1.md"

echo "Writing new migration to ${file_name}"

cat >"${file_name}" <<EOF
---
title: "Compiler error $message_number"
ms.date: $month/$day/$year
f1_keywords:
- "$message_number"
helpviewer_keywords:
- "$message_number"
---

# $message_number: $message_title
EOF

echo "Writing TOC entry"

cat >>toc.yml <<EOF
- name: $message_number - $message_title
href: ./$file_name
EOF
2 changes: 2 additions & 0 deletions docs/fsharp/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@
href: language-reference/caller-information.md
- name: Verbose Syntax
href: language-reference/verbose-syntax.md
- name: Compiler errors and warnings
href: language-reference/compiler-messages/index.md
- name: F# style guide
href: style-guide/index.md
items:
Expand Down