From 5bfbc6dd4213ac8628a6df77dfe144ccd5fc450c Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 20 Jan 2025 15:34:41 +0000 Subject: [PATCH] Fix internal error when missing measure attribute in an unsolved measure typar (#18234) --- .../.FSharp.Compiler.Service/9.0.300.md | 1 + src/Compiler/FSComp.txt | 1 + src/Compiler/TypedTree/TypedTreeOps.fs | 3 ++ src/Compiler/xlf/FSComp.txt.cs.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 ++ .../ErrorMessages/UnitOfMeasureTests.fs | 52 +++++++++++++++++++ .../FSharp.Compiler.ComponentTests.fsproj | 1 + 18 files changed, 123 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md index 5997ca29bd4..f68fffaf418 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md @@ -1,6 +1,7 @@ ### Fixed * Fix Realsig+ generates nested closures with incorrect Generic ([Issue #17797](https://github.com/dotnet/fsharp/issues/17797), [PR #17877](https://github.com/dotnet/fsharp/pull/17877)) +* Fix internal error when missing measure attribute in an unsolved measure typar. ([Issue #7491](https://github.com/dotnet/fsharp/issues/7491), [PR #18234](https://github.com/dotnet/fsharp/pull/18234)== * Set `Cancellable.token` from async computation ([Issue #18235](https://github.com/dotnet/fsharp/issues/18235), [PR #18238](https://github.com/dotnet/fsharp/pull/18238)) ### Added diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index f16be8658dd..4bdee0183ea 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1789,5 +1789,6 @@ featureUseTypeSubsumptionCache,"Use type conversion cache during compilation" 3872,tcPartialActivePattern,"Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern." featureDontWarnOnUppercaseIdentifiersInBindingPatterns,"Don't warn on uppercase identifiers in binding patterns" 3873,chkDeprecatePlacesWhereSeqCanBeOmitted,"This construct is deprecated. Sequence expressions should be of the form 'seq {{ ... }}'" +3874,tcExpectedTypeParamMarkedWithUnitOfMeasureAttribute,"Expected unit-of-measure type parameter must be marked with the [] attribute." featureDeprecatePlacesWhereSeqCanBeOmitted,"Deprecate places where 'seq' can be omitted" featureSupportValueOptionsAsOptionalParameters,"Support ValueOption as valid type for optional member parameters" diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index e2bc362c784..e7caeaeec71 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -243,6 +243,9 @@ and remapMeasureAux tyenv unt = | Some tpTy -> match tpTy with | TType_measure unt -> unt + | TType_var(typar= typar) when tp.Kind = TyparKind.Measure -> + // This is a measure typar that is not yet solved, so we can't remap it + error(Error(FSComp.SR.tcExpectedTypeParamMarkedWithUnitOfMeasureAttribute(), typar.Range)) | _ -> failwith "remapMeasureAux: incorrect kinds" | None -> unt | Some (TType_measure unt) -> remapMeasureAux tyenv unt diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 46543dceeda..94d0739a8ce 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Syntaxe expr1[expr2] se používá pro indexování. Pokud chcete povolit indexování, zvažte možnost přidat anotaci typu, nebo pokud voláte funkci, přidejte mezeru, třeba expr1 [expr2]. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 15daa1c6f0c..b24a332b3cb 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Die Syntax "expr1[expr2]" wird für die Indizierung verwendet. Fügen Sie ggf. eine Typanmerkung hinzu, um die Indizierung zu aktivieren, oder fügen Sie beim Aufrufen einer Funktion ein Leerzeichen hinzu, z. B. "expr1 [expr2]". diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index e7da4d1c8c0..40dbae13a65 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. La sintaxis "expr1[expr2]" se usa para la indexación. Considere la posibilidad de agregar una anotación de tipo para habilitar la indexación, si se llama a una función, agregue un espacio, por ejemplo, "expr1 [expr2]". diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index b45be9ead6f..6ee0c6f3dd1 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. La syntaxe « expr1[expr2] » est utilisée pour l’indexation. Envisagez d’ajouter une annotation de type pour activer l’indexation, ou si vous appelez une fonction, ajoutez un espace, par exemple « expr1 [expr2] ». diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index a2836525b32..95d709d785e 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. La sintassi 'expr1[expr2]' viene usata per l'indicizzazione. Provare ad aggiungere un'annotazione di tipo per abilitare l'indicizzazione oppure se la chiamata a una funzione aggiunge uno spazio, ad esempio 'expr1 [expr2]'. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 1c4d2a34843..8d7e59c2726 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. 構文 'expr1[expr2]' はインデックス作成に使用されます。インデックスを有効にするために型の注釈を追加するか、関数を呼び出す場合には、'expr1 [expr2]' のようにスペースを入れます。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 191f33e9eca..d63fbeba99c 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. 인덱싱에는 'expr1[expr2]' 구문이 사용됩니다. 인덱싱을 사용하도록 설정하기 위해 형식 주석을 추가하는 것을 고려하거나 함수를 호출하는 경우 공백을 추가하세요(예: 'expr1 [expr2]'). diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 46ddfa1e868..b34ec2ab246 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Do indeksowania używana jest składnia „expr1[expr2]”. Rozważ dodanie adnotacji typu, aby umożliwić indeksowanie, lub jeśli wywołujesz funkcję dodaj spację, np. „expr1 [expr2]”. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 2a86f172c2b..04ae53e1fa8 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. A sintaxe 'expr1[expr2]' é usada para indexação. Considere adicionar uma anotação de tipo para habilitar a indexação ou, se chamar uma função, adicione um espaço, por exemplo, 'expr1 [expr2]'. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 3e52e4501b4..66c68dbe5e0 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Для индексирования используется синтаксис "expr1[expr2]". Рассмотрите возможность добавления аннотации типа для включения индексации или при вызове функции добавьте пробел, например "expr1 [expr2]". diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 81ed83f5717..b6979546951 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Söz dizimi “expr1[expr2]” dizin oluşturma için kullanılıyor. Dizin oluşturmayı etkinleştirmek için bir tür ek açıklama eklemeyi düşünün veya bir işlev çağırıyorsanız bir boşluk ekleyin, örn. “expr1 [expr2]”. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 35e9ec9073e..2101acb475e 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. 语法“expr1[expr2]”用于索引。考虑添加类型批注来启用索引,或者在调用函数添加空格,例如“expr1 [expr2]”。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index bed34cb225b..0a02ec6669c 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1362,6 +1362,11 @@ An empty body may only be used if the computation expression builder defines a 'Zero' method. + + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. 語法 'expr1[expr2]' 已用於編製索引。請考慮新增類型註釋來啟用編製索引,或是呼叫函式並新增空格,例如 'expr1 [expr2]'。 diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs new file mode 100644 index 00000000000..36ef76e772d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module ErrorMessages.UnitOfMeasureTests + +open Xunit +open FSharp.Test.Compiler + +[] +let ``Error - Expected unit-of-measure type parameter must be marked with the [] attribute.`` () = + Fsx """ +type A<[]'u>(x : int<'u>) = + member this.X = x + +type B<'u>(x: 'u) = + member this.X = x + +module M = + type A<'u> with // Note the missing Measure attribute + member this.Y = this.X + + type B<'u> with + member this.Y = this.X + +open System.Runtime.CompilerServices +type FooExt = + [] + static member Bar(this: A<'u>, value: A<'u>) = this + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3874, Line 9, Col 12, Line 9, Col 14, "Expected unit-of-measure type parameter must be marked with the [] attribute.") + ] + +[] +let ``Expected unit-of-measure type parameter must be marked with the [] attribute.`` () = + Fsx """ +type A<[]'u>(x : int<'u>) = + member this.X = x + +module M = + type A<[] 'u> with // Note the Measure attribute + member this.Y = this.X + +open System.Runtime.CompilerServices +type FooExt = + [] + static member Bar(this: A<'u>, value: A<'u>) = this + """ + |> typecheck + |> shouldSucceed + diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index b96aba6777b..9eb31c35e0d 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -218,6 +218,7 @@ +