From f00ee9275f68611f2750b4935639e28fbff40ca8 Mon Sep 17 00:00:00 2001 From: Stuart Mosquera Date: Wed, 10 Sep 2025 13:49:03 -0300 Subject: [PATCH 1/4] add FS0067 compiler message --- .../compiler-messages/fs0067.md | 32 +++++++++++++++++++ .../compiler-messages/toc.yml | 2 ++ .../fsharp/compiler-messages/fs0067.fsx | 18 +++++++++++ 3 files changed, 52 insertions(+) create mode 100644 docs/fsharp/language-reference/compiler-messages/fs0067.md create mode 100644 samples/snippets/fsharp/compiler-messages/fs0067.fsx diff --git a/docs/fsharp/language-reference/compiler-messages/fs0067.md b/docs/fsharp/language-reference/compiler-messages/fs0067.md new file mode 100644 index 0000000000000..1917be0dafa82 --- /dev/null +++ b/docs/fsharp/language-reference/compiler-messages/fs0067.md @@ -0,0 +1,32 @@ +--- +description: "Learn more about: FS0067: This type test or downcast will always hold" +title: "Compiler error FS0067" +ms.date: 9/10/2025 +f1_keywords: + - "FS0067" +helpviewer_keywords: + - "FS0067" +--- + +# FS0067: This type test or downcast will always hold + +This message is given when attempting to perform a type test ([:?](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/match-expressions)) or downcast ([:?>](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/casting-and-conversions#downcasting)) that will always succeed based on the types involved, making the operation unnecessary. + +Redundant Type test: + +[!code-fsharp[FS0067-redundant-type-test](~/samples/snippets/fsharp/compiler-messages/fs0067.fsx#L2-L8)] + +Redundant Downcast: + +[!code-fsharp[FS0067-redundant-downcast](~/samples/snippets/fsharp/compiler-messages/fs0003.fsx#L11-L18)] + +The two examples above cause the compiler to display the following message: + +```text +FS0067: This type test or downcast will always hold +``` + +The use of `:?` and `:?>` operators is preferable when working with: + +- Base classes when the runtime type might differ. +- Values of type `obj` or interfaces types. diff --git a/docs/fsharp/language-reference/compiler-messages/toc.yml b/docs/fsharp/language-reference/compiler-messages/toc.yml index bd3d78920cd34..9e1a0a553ecd1 100644 --- a/docs/fsharp/language-reference/compiler-messages/toc.yml +++ b/docs/fsharp/language-reference/compiler-messages/toc.yml @@ -19,5 +19,7 @@ href: ./fs0037.md - name: FS0052 - Defensive copy href: ./fs0052.md + - name: FS0067 - This type test or downcast will always hold + href: ./fs0067.md - name: FS0703 - Expected type parameter, not unit-of-measure parameter href: ./fs0703.md diff --git a/samples/snippets/fsharp/compiler-messages/fs0067.fsx b/samples/snippets/fsharp/compiler-messages/fs0067.fsx new file mode 100644 index 0000000000000..ebbe30b6b31ae --- /dev/null +++ b/samples/snippets/fsharp/compiler-messages/fs0067.fsx @@ -0,0 +1,18 @@ +(* Redundant Type test *) +type Dog() = + member this.Name = "Dog" + +let dog = Dog() + +if dog :? Dog then + printfn "It always be a dog" + +(* Redundant Downcast *) +type Cat(name: string) = + member this.Name = name + +let cat = Cat("Kitten") + +let sameCat = cat :?> Cat + +printfn "It's still a %s" sameCat.Name From 072b086a8f24ee188623d385ce20f61589866804 Mon Sep 17 00:00:00 2001 From: Stuart Mosquera Date: Wed, 10 Sep 2025 14:35:34 -0300 Subject: [PATCH 2/4] fix snippet link --- docs/fsharp/language-reference/compiler-messages/fs0067.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fsharp/language-reference/compiler-messages/fs0067.md b/docs/fsharp/language-reference/compiler-messages/fs0067.md index 1917be0dafa82..7a7cf25c94c3e 100644 --- a/docs/fsharp/language-reference/compiler-messages/fs0067.md +++ b/docs/fsharp/language-reference/compiler-messages/fs0067.md @@ -18,7 +18,7 @@ Redundant Type test: Redundant Downcast: -[!code-fsharp[FS0067-redundant-downcast](~/samples/snippets/fsharp/compiler-messages/fs0003.fsx#L11-L18)] +[!code-fsharp[FS0067-redundant-downcast](~/samples/snippets/fsharp/compiler-messages/fs0067.fsx#L11-L18)] The two examples above cause the compiler to display the following message: From 6d10419db624e08abac6ccd7249a3ba84c7fceaa Mon Sep 17 00:00:00 2001 From: Stuart Mosquera Date: Wed, 10 Sep 2025 15:14:12 -0300 Subject: [PATCH 3/4] fix reference links --- docs/fsharp/language-reference/compiler-messages/fs0067.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fsharp/language-reference/compiler-messages/fs0067.md b/docs/fsharp/language-reference/compiler-messages/fs0067.md index 7a7cf25c94c3e..90069a502adb9 100644 --- a/docs/fsharp/language-reference/compiler-messages/fs0067.md +++ b/docs/fsharp/language-reference/compiler-messages/fs0067.md @@ -10,7 +10,7 @@ helpviewer_keywords: # FS0067: This type test or downcast will always hold -This message is given when attempting to perform a type test ([:?](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/match-expressions)) or downcast ([:?>](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/casting-and-conversions#downcasting)) that will always succeed based on the types involved, making the operation unnecessary. +This message is given when attempting to perform a type test ([:?](../match-expressions.md)) or downcast ([:?>](../casting-and-conversions.md#downcasting)) that will always succeed based on the types involved, making the operation unnecessary. Redundant Type test: From 0091e2c7d5820a69dfbd14c9e4621adbe8619f83 Mon Sep 17 00:00:00 2001 From: Stuart Mosquera Date: Wed, 10 Sep 2025 17:40:04 -0300 Subject: [PATCH 4/4] minor fixes in examples --- samples/snippets/fsharp/compiler-messages/fs0067.fsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/snippets/fsharp/compiler-messages/fs0067.fsx b/samples/snippets/fsharp/compiler-messages/fs0067.fsx index ebbe30b6b31ae..6f5eb276bdef3 100644 --- a/samples/snippets/fsharp/compiler-messages/fs0067.fsx +++ b/samples/snippets/fsharp/compiler-messages/fs0067.fsx @@ -1,11 +1,11 @@ (* Redundant Type test *) type Dog() = - member this.Name = "Dog" + member this.Bark() = printfn "Woof!" let dog = Dog() if dog :? Dog then - printfn "It always be a dog" + dog.Bark() (* Redundant Downcast *) type Cat(name: string) =