From 80ef33721adc4b8ec3266e9cc1856d089d7ef0d1 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 13 Jan 2025 21:33:24 +0000 Subject: [PATCH 1/4] Fix internal error when missing Measure attribute in a unsolved measure typar --- 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 | 42 +++++++++++++++++++ .../FSharp.Compiler.ComponentTests.fsproj | 1 + 17 files changed, 112 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs 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..b50722b0e82 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs @@ -0,0 +1,42 @@ +// 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 + """ + |> 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 + """ + |> 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 @@ + From b8561be57372c6b0e24971b8d045e81ffb7087fc Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 14 Jan 2025 13:40:45 +0000 Subject: [PATCH 2/4] release notes --- docs/release-notes/.FSharp.Compiler.Service/9.0.300.md | 1 + 1 file changed, 1 insertion(+) 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 375263a2a0e..9fb02c79800 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)) ### Added From 049158206527bd6ea21506c3b713d448a0a55d4d Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 14 Jan 2025 13:57:49 +0000 Subject: [PATCH 3/4] more tests --- .../ErrorMessages/UnitOfMeasureTests.fs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs index b50722b0e82..f110cf0caf3 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs @@ -20,6 +20,11 @@ module M = 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 @@ -36,6 +41,14 @@ type A<[]'u>(x : int<'u>) = module M = type A<[] 'u> with // Note the 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 |> shouldSucceed From 1ee9b571b2c848b05c9fd3de0f5ad58db95a67c6 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sat, 18 Jan 2025 13:59:54 +0000 Subject: [PATCH 4/4] fix test --- .../ErrorMessages/UnitOfMeasureTests.fs | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs index f110cf0caf3..36ef76e772d 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs @@ -41,9 +41,6 @@ type A<[]'u>(x : int<'u>) = module M = type A<[] 'u> with // Note the Measure attribute member this.Y = this.X - - type B<'u> with - member this.Y = this.X open System.Runtime.CompilerServices type FooExt =