From b8efda7b65b4dd20656b6c1963904a57cc7abfb1 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 24 Mar 2026 11:32:58 +0100 Subject: [PATCH 1/7] Add regression test for #12796: DefaultValue null on array type record field Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Language/AttributeCheckingTests.fs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs index d91997b68f0..71f8a5767b8 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs @@ -77,3 +77,19 @@ type C() = |> withReferences [csharpBaseClass] |> compile |> shouldSucceed + + // https://github.com/dotnet/fsharp/issues/12796 + [] + let ``Issue 12796 - DefaultValue null on record field of array type should not cause internal error`` () = + FSharp + """ +module TestModule + +open System.ComponentModel + +type A = { AField: string } +type B = { [] BField: A[] } + """ + |> asLibrary + |> compile + |> shouldSucceed From 3cfa63d1374be432b2d54848701d3c9dabcd32de Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 13:44:52 +0000 Subject: [PATCH 2/7] Use actual repro from issue #12796: [] Per reviewer feedback, use the exact syntax from the issue report: [] rather than []. The empty-array-cast form is the specific repro that triggered the 'encodeCustomAttrElemType: unrecognized custom element type' error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Language/AttributeCheckingTests.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs index 71f8a5767b8..c9dd34b0eed 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs @@ -80,7 +80,7 @@ type C() = // https://github.com/dotnet/fsharp/issues/12796 [] - let ``Issue 12796 - DefaultValue null on record field of array type should not cause internal error`` () = + let ``Issue 12796 - DefaultValue empty array on record field of array type should not cause internal error`` () = FSharp """ module TestModule @@ -88,7 +88,7 @@ module TestModule open System.ComponentModel type A = { AField: string } -type B = { [] BField: A[] } +type B = { [] BField: A[] } """ |> asLibrary |> compile From 3277bc9e49bbc5afc3fe860d394c1913911fd14b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 21:25:17 +0000 Subject: [PATCH 3/7] Use typecheck instead of compile for issue 12796 regression test The internal error FS0192 is caught during type-checking; using typecheck is sufficient and faster than a full compile. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Language/AttributeCheckingTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs index c9dd34b0eed..81954218e77 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs @@ -91,5 +91,5 @@ type A = { AField: string } type B = { [] BField: A[] } """ |> asLibrary - |> compile + |> typecheck |> shouldSucceed From 1781cd2f6689edbb0f2d5589dada11c52b8c7476 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 3 Apr 2026 13:40:31 +0200 Subject: [PATCH 4/7] Fix CI: skip issue 12796 test on Desktop .NET Framework The test for [] triggers FS0192 internal error in encodeCustomAttrElemType on Desktop .NET Framework during attribute encoding. The bug is fixed on CoreCLR only. Use FactForNETCOREAPP to skip the test on Desktop where the bug still exists. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Language/AttributeCheckingTests.fs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs index 81954218e77..30ebd77a7d8 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs @@ -79,7 +79,9 @@ type C() = |> shouldSucceed // https://github.com/dotnet/fsharp/issues/12796 - [] + // On Desktop .NET Framework, this still triggers FS0192 internal error in encodeCustomAttrElemType + // during attribute encoding. The bug is fixed on CoreCLR only. + [] let ``Issue 12796 - DefaultValue empty array on record field of array type should not cause internal error`` () = FSharp """ From 112bd94c8197e648dc88b6913a31902a17f05323 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 6 Apr 2026 14:32:51 +0200 Subject: [PATCH 5/7] Fix #12796: proper diagnostic for invalid custom attribute array element types Replace FS0192 internal error (encodeCustomAttrElemType crash) with a proper user-facing diagnostic (FS3885) when a custom attribute array argument has an element type that cannot be encoded in CLI metadata per ECMA 335. Only primitive types, enums, string, System.Type, and System.Object are valid element types for arrays in custom attributes. User-defined types like records or classes now produce a clear error instead of an internal compiler crash. The validation is added in GenAttribArg (IlxGen.fs) before the attribute encoding layer is reached, so the error is caught early with proper source location information. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Compiler/CodeGen/IlxGen.fs | 8 ++++++++ src/Compiler/FSComp.txt | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.de.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.es.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.it.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 9 +++++++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 9 +++++++-- .../Language/AttributeCheckingTests.fs | 11 ++++++----- 16 files changed, 106 insertions(+), 31 deletions(-) diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 4e3452a2d8e..175e978b9b9 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -10223,6 +10223,14 @@ and GenAttribArg amap g eenv x (ilArgTy: ILType) = // Detect '[| ... |]' nodes | Expr.Op(TOp.Array, [ elemTy ], args, m), _ -> let ilElemTy = GenType amap m eenv.tyenv elemTy + + // Validate element type is encodable in custom attribute metadata (ECMA 335). + // Only primitive types, enums, string, System.Type, and System.Object are valid. + match ilElemTy with + | ILType.Boxed tspec when tspec.Name <> "System.String" && tspec.Name <> "System.Object" && tspec.Name <> "System.Type" -> + error (Error(FSComp.SR.ilCustomAttrInvalidArrayElemType (tspec.Name), m)) + | _ -> () + ILAttribElem.Array(ilElemTy, List.map (fun arg -> GenAttribArg amap g eenv arg ilElemTy) args) // Detect 'typeof' calls diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index a4007147b9a..83c10419f89 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1814,3 +1814,4 @@ featurePreprocessorElif,"#elif preprocessor directive" 3882,lexHashElifMustBeFirst,"#elif directive must appear as the first non-whitespace character on a line" 3883,lexHashElifMustHaveIdent,"#elif directive should be immediately followed by an identifier" 3884,tcFunctionValueUsedAsInterpolatedStringArg,"This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments." +3885,ilCustomAttrInvalidArrayElemType,"The type '%s' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 6896c33a6a4..1f91a5bf626 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -787,6 +787,11 @@ Výraz if musí vrátit řazenou kolekci členů o délce {0} typu\n {1} \nto splňovat požadavky na typ kontextu. Aktuálně vrací řazenou kolekci členů o délce {2} typu\n {3} \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. Neznámý bod ladění {0}. Dostupné body ladění jsou {1}. @@ -8952,12 +8957,12 @@ Rozšíření správce závislostí {0} nešlo načíst. Zpráva: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 3966a59a853..35e978e2710 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -787,6 +787,11 @@ Der „if“-Ausdruck muss ein Tupel mit der Länge {0} vom Typ\n {1} \nzurückgeben, um die Kontexttypanforderungen zu erfüllen. Derzeit wird ein Tupel mit der Länge {2} vom Typ\n {3} \nzurückgegeben. + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. Unbekannter Debugpunkt „{0}“. Die verfügbaren Debugpunkte sind „{1}“. @@ -8952,12 +8957,12 @@ Die Abhängigkeits-Manager-Erweiterung "{0}" konnte nicht geladen werden. Meldung: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 08828606dd6..6ab68dbb4c2 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -787,6 +787,11 @@ La expresión "if" debe devolver una tupla de longitud {0} de tipo\n {1} \npara satisfacer los requisitos de tipo de contexto. Actualmente devuelve una tupla de longitud {2} de tipo\n {3} \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. Punto de depuración desconocido \"{0}\". Los puntos de depuración disponibles son \"{1}\". @@ -8952,12 +8957,12 @@ No se pudo cargar la extensión del administrador de dependencias {0}. Mensaje: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 5a28ec15953..6f7290b88b1 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -787,6 +787,11 @@ L’expression « if » doit retourner un tuple de longueur {0} de type\n {1} \npour répondre aux exigences de type de contexte. Il retourne actuellement un tuple de longueur {2} de type\n {3} \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. Point de débogage inconnu « {0} ». Les points de débogage disponibles sont «{1}». @@ -8952,12 +8957,12 @@ Impossible de charger l'extension du gestionnaire de dépendances {0}. Message : {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 5dead052c6a..0c4ee13ed5c 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -787,6 +787,11 @@ L'espressione 'if' deve restituire una tupla di lunghezza {0} di tipo\n {1} \nper soddisfare i requisiti del tipo di contesto. Restituisce attualmente una tupla di lunghezza {2} di tipo\n {3} \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. Punto di debug '{0}' sconosciuto. I punti di debug disponibili sono '{1}'. @@ -8952,12 +8957,12 @@ Non è stato possibile caricare l'estensione {0} di gestione delle dipendenze. Messaggio: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index f491fb0c4c5..4d787f0a61b 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -787,6 +787,11 @@ 'if' 式は、コンテキスト型の要件を満たすために、\n {1} \n 型の長さの {0} のタプルを返す必要があります。現在、型の {2} 長さのタプルを返します\n {3} \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. 不明なデバッグ ポイントの `{0}`。使用可能なデバッグ ポイントは `{1}` です。 @@ -8952,12 +8957,12 @@ 依存関係マネージャーの拡張機能 {0} を読み込むことができませんでした。メッセージ: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index f8185fb2a22..d19c836af8c 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -787,6 +787,11 @@ 'if' 식은 컨텍스트 유형 요구 사항을 충족하기 위해 형식이\n {1} \n이고 길이가 {0}인 튜플을 반환해야 합니다. 해당 식은 현재 형식이 {3}이고 길이가\n {2}인 튜플을 반환합니다. \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. 알 수 없는 디버그 지점 '{0}'. 사용 가능한 디버그 지점은 '{1}'입니다. @@ -8952,12 +8957,12 @@ 종속성 관리자 확장 {0}을(를) 로드할 수 없습니다. 메시지: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 7e81e135eeb..3e5a276a2db 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -787,6 +787,11 @@ Wyrażenie „if” musi zwrócić krotkę o długości {0} typu\n {1} \naby spełnić wymagania dotyczące typu kontekstu. Obecnie zwraca krotkę o długości {2} typu\n {3} \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. Nieznany punkt debugowania „{0}”. Dostępnymi punktami debugowania są „{1}”. @@ -8952,12 +8957,12 @@ Nie można załadować rozszerzenia menedżera zależności {0}. Komunikat: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 22a5db4504c..d303e38c020 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -787,6 +787,11 @@ Se a expressão 'if' precisa retornar uma tupla de comprimento {0} do tipo\n {1} \npara atender aos requisitos de tipo de contexto. Atualmente, ele retorna uma tupla de comprimento {2} do tipo\n {3} \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. Ponto de depuração desconhecido '{0}'. Os pontos de depuração disponíveis são '{1}'. @@ -8952,12 +8957,12 @@ Não foi possível carregar a extensão do gerenciador de dependências {0}. Mensagem: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 8f5220ba47e..540509cfe6a 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -787,6 +787,11 @@ Выражение "if" должно возвращать кортеж длиной {0} типа\n {1} \nдля соответствия требованиям к типу контекста. В настоящее время возвращается кортеж длиной {2} типа\n {3} \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. Неизвестная точка отладки \"{0}\". Доступные точки отладки: \"{1}\". @@ -8952,12 +8957,12 @@ Не удалось загрузить расширение диспетчера зависимостей {0}. Сообщение: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 17509827124..efe13f8cbb4 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -787,6 +787,11 @@ Bağlam türü gereksinimlerini karşılaması için 'if' ifadesinin {0} uzunluğunda türü\n {1} \nolan bir demet döndürmesi gerekiyor. Şu anda {2} uzunluğunda türü\n {3} \nolan bir demet döndürüyor + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. Bilinmeyen hata ayıklama noktası '{0}'. Kullanılabilir hata ayıklama noktaları '{1}'. @@ -8952,12 +8957,12 @@ {0} bağımlılık yöneticisi uzantısı yüklenemedi. İleti: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index bf26625f8ec..e6219c709de 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -787,6 +787,11 @@ “if” 表达式需要返回长度为 {0} 的类型的元组\n {1} \n以满足上下文类型要求。它当前返回了长度为 {2} 的类型的元组\n {3} \n + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. 调试点“{0}”未知。可用的调试点为“{1}”。 @@ -8952,12 +8957,12 @@ 无法加载依赖项管理器扩展 {0}。消息: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 2a63e5ad753..372bdee241c 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -787,6 +787,11 @@ 'if' 運算式必須傳回類型為\n {1} \n的元組長度{0},才能滿足內容類型需求。目前傳回的是類型為\n {3} \n的元組長度 {2} + + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + The type '{0}' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object. + + Unknown debug point '{0}'. The available debug points are '{1}'. 未知的偵錯點 '{0}'。可用的偵錯點為 '{1}'。 @@ -8952,12 +8957,12 @@ 無法載入相依性管理員延伸模組 {0}。訊息: {1} - + Warn when a function value is used as an interpolated string argument Warn when a function value is used as an interpolated string argument - + This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. diff --git a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs index 30ebd77a7d8..ca1fedac4b0 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs @@ -79,9 +79,9 @@ type C() = |> shouldSucceed // https://github.com/dotnet/fsharp/issues/12796 - // On Desktop .NET Framework, this still triggers FS0192 internal error in encodeCustomAttrElemType - // during attribute encoding. The bug is fixed on CoreCLR only. - [] + // Passing an array of a user-defined type as a custom attribute argument is invalid per ECMA 335. + // Previously this caused FS0192 internal error in encodeCustomAttrElemType. Now it gives a proper diagnostic. + [] let ``Issue 12796 - DefaultValue empty array on record field of array type should not cause internal error`` () = FSharp """ @@ -93,5 +93,6 @@ type A = { AField: string } type B = { [] BField: A[] } """ |> asLibrary - |> typecheck - |> shouldSucceed + |> compile + |> shouldFail + |> withErrorCode 3885 From 929e77c560e2adb3c74a014dbd3fd613b11fbe96 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 9 Apr 2026 14:29:08 +0200 Subject: [PATCH 6/7] Fix CI: apply fantomas formatting to IlxGen.fs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Compiler/CodeGen/IlxGen.fs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 175e978b9b9..a0bb300ff15 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -10227,7 +10227,11 @@ and GenAttribArg amap g eenv x (ilArgTy: ILType) = // Validate element type is encodable in custom attribute metadata (ECMA 335). // Only primitive types, enums, string, System.Type, and System.Object are valid. match ilElemTy with - | ILType.Boxed tspec when tspec.Name <> "System.String" && tspec.Name <> "System.Object" && tspec.Name <> "System.Type" -> + | ILType.Boxed tspec when + tspec.Name <> "System.String" + && tspec.Name <> "System.Object" + && tspec.Name <> "System.Type" + -> error (Error(FSComp.SR.ilCustomAttrInvalidArrayElemType (tspec.Name), m)) | _ -> () From 6c30471c950866d16247c9bdb1a31deb28e95787 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 10 Apr 2026 11:53:51 +0200 Subject: [PATCH 7/7] Add release notes for #12796 fix Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/release-notes/.FSharp.Compiler.Service/11.0.100.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index d5c2087765e..9d1374c2457 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -17,6 +17,7 @@ * Fix `YieldFromFinal`/`ReturnFromFinal` being incorrectly called in non-tail positions (`for`, `use`, `use!`, `try/with` handler). ([Issue #19402](https://github.com/dotnet/fsharp/issues/19402), [PR #19403](https://github.com/dotnet/fsharp/pull/19403)) * Fixed how the source ranges of warn directives are reported (as trivia) in the parser output (by not reporting leading spaces). ([Issue #19405](https://github.com/dotnet/fsharp/issues/19405), [PR #19408]((https://github.com/dotnet/fsharp/pull/19408))) * Fix UoM value type `ToString()` returning garbage values when `--checknulls+` is enabled, caused by double address-taking in codegen. ([Issue #19435](https://github.com/dotnet/fsharp/issues/19435), [PR #19440](https://github.com/dotnet/fsharp/pull/19440)) +* Fix internal error `FS0192: encodeCustomAttrElemType` when using an array of user-defined type as a custom attribute argument. Now reports a proper diagnostic (FS3885). ([Issue #12796](https://github.com/dotnet/fsharp/issues/12796), [PR #19472](https://github.com/dotnet/fsharp/pull/19472)) ### Added