From c438a8f742e2faf6eda1275195efed0973e55bc1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 14:21:06 +0000 Subject: [PATCH 01/20] Initial plan From 7a99315d14d3b39f34f74c2bdfeba02fb3815e66 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 14:37:37 +0000 Subject: [PATCH 02/20] Add ExtendedLayoutAttribute support - IL layer, infrastructure, and validation Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> --- src/Compiler/AbstractIL/il.fs | 2 ++ src/Compiler/AbstractIL/il.fsi | 1 + src/Compiler/AbstractIL/ilprint.fs | 1 + src/Compiler/AbstractIL/ilread.fs | 2 ++ src/Compiler/AbstractIL/ilreflect.fs | 1 + src/Compiler/AbstractIL/ilwrite.fs | 1 + src/Compiler/Checking/CheckDeclarations.fs | 24 ++++++++++++++++++++++ src/Compiler/CodeGen/IlxGen.fs | 5 +++++ src/Compiler/FSComp.txt | 4 ++++ src/Compiler/TypedTree/TcGlobals.fs | 1 + src/Compiler/TypedTree/TcGlobals.fsi | 2 ++ 11 files changed, 44 insertions(+) diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 8e836ef548e..1dc2d15329d 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -2569,6 +2569,7 @@ type ILTypeDefLayout = | Auto | Sequential of ILTypeDefLayoutInfo | Explicit of ILTypeDefLayoutInfo (* REVIEW: add field info here *) + | Extended and ILTypeDefLayoutInfo = { @@ -2682,6 +2683,7 @@ let convertLayout layout = | ILTypeDefLayout.Auto -> TypeAttributes.AutoLayout | ILTypeDefLayout.Sequential _ -> TypeAttributes.SequentialLayout | ILTypeDefLayout.Explicit _ -> TypeAttributes.ExplicitLayout + | ILTypeDefLayout.Extended -> enum(0x18) let convertEncoding encoding = match encoding with diff --git a/src/Compiler/AbstractIL/il.fsi b/src/Compiler/AbstractIL/il.fsi index 3539e235518..d32d45e37fa 100644 --- a/src/Compiler/AbstractIL/il.fsi +++ b/src/Compiler/AbstractIL/il.fsi @@ -1488,6 +1488,7 @@ type ILTypeDefLayout = | Auto | Sequential of ILTypeDefLayoutInfo | Explicit of ILTypeDefLayoutInfo + | Extended type internal ILTypeDefLayoutInfo = { Size: int32 option diff --git a/src/Compiler/AbstractIL/ilprint.fs b/src/Compiler/AbstractIL/ilprint.fs index 12e421f6829..d9fa4368a2e 100644 --- a/src/Compiler/AbstractIL/ilprint.fs +++ b/src/Compiler/AbstractIL/ilprint.fs @@ -776,6 +776,7 @@ let splitTypeLayout = | ILTypeDefLayout.Auto -> "auto", (fun _os () -> ()) | ILTypeDefLayout.Sequential info -> "sequential", (fun os () -> output_type_layout_info os info) | ILTypeDefLayout.Explicit info -> "explicit", (fun os () -> output_type_layout_info os info) + | ILTypeDefLayout.Extended -> "extended", (fun _os () -> ()) let goutput_fdefs tref env os (fdefs: ILFieldDefs) = for f in fdefs.AsList() do diff --git a/src/Compiler/AbstractIL/ilread.fs b/src/Compiler/AbstractIL/ilread.fs index 7754fedad20..c75348c2a08 100644 --- a/src/Compiler/AbstractIL/ilread.fs +++ b/src/Compiler/AbstractIL/ilread.fs @@ -2044,6 +2044,8 @@ and typeLayoutOfFlags (ctxt: ILMetadataReader) mdv flags tidx = ILTypeDefLayout.Sequential(seekReadClassLayout ctxt mdv tidx) elif f = 0x00000010 then ILTypeDefLayout.Explicit(seekReadClassLayout ctxt mdv tidx) + elif f = 0x00000018 then + ILTypeDefLayout.Extended else ILTypeDefLayout.Auto diff --git a/src/Compiler/AbstractIL/ilreflect.fs b/src/Compiler/AbstractIL/ilreflect.fs index eab257c1573..10611da31de 100644 --- a/src/Compiler/AbstractIL/ilreflect.fs +++ b/src/Compiler/AbstractIL/ilreflect.fs @@ -2106,6 +2106,7 @@ let typeAttributesOfTypeLayout cenv emEnv x = | ILTypeDefLayout.Auto -> None | ILTypeDefLayout.Explicit p -> (attr 0x02 p) | ILTypeDefLayout.Sequential p -> (attr 0x00 p) + | ILTypeDefLayout.Extended -> None // No StructLayoutAttribute needed; user's ExtendedLayoutAttribute is preserved //---------------------------------------------------------------------------- // buildTypeDefPass1 cenv diff --git a/src/Compiler/AbstractIL/ilwrite.fs b/src/Compiler/AbstractIL/ilwrite.fs index 7751a8d696b..b710236f15f 100644 --- a/src/Compiler/AbstractIL/ilwrite.fs +++ b/src/Compiler/AbstractIL/ilwrite.fs @@ -2912,6 +2912,7 @@ let rec GenTypeDefPass3 enc cenv (tdef: ILTypeDef) = // ClassLayout entry if needed match tdef.Layout with | ILTypeDefLayout.Auto -> () + | ILTypeDefLayout.Extended -> () // No ClassLayout row for Extended; bits are in TypeAttributes | ILTypeDefLayout.Sequential layout | ILTypeDefLayout.Explicit layout -> if Option.isSome layout.Pack || Option.isSome layout.Size then AddUnsharedRow cenv TableNames.ClassLayout diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 149f8217e96..2faaa75ef4d 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3417,6 +3417,7 @@ module EstablishTypeDefinitionCores = match attrs with | EntityAttribInt g WellKnownEntityAttributes.StructLayoutAttribute v -> Some v | _ -> None + let hasExtendedLayoutAttr = HasFSharpAttributeOpt g g.attrib_ExtendedLayoutAttribute_opt attrs let hasAllowNullLiteralAttr = hasFlag entityFlags WellKnownEntityAttributes.AllowNullLiteralAttribute_True if hasAbstractAttr then @@ -3437,7 +3438,10 @@ module EstablishTypeDefinitionCores = let structLayoutAttributeCheck allowed = let explicitKind = int32 System.Runtime.InteropServices.LayoutKind.Explicit + let extendedKind = 1 // LayoutKind.Extended cannot be specified via StructLayout match structLayoutAttr with + | Some kind when kind = extendedKind -> + errorR (Error(FSComp.SR.tcInvalidStructLayoutExtendedKind(), m)) | Some kind -> if allowed then if kind = explicitKind then @@ -3447,6 +3451,22 @@ module EstablishTypeDefinitionCores = else errorR (Error(FSComp.SR.tcGenericTypesCannotHaveStructLayout(), m)) | None -> () + + let extendedLayoutAttributeCheck () = + if hasExtendedLayoutAttr then + // Check runtime support + match g.attrib_ExtendedLayoutAttribute_opt with + | None -> + errorR (Error(FSComp.SR.tcRuntimeDoesNotSupportExtendedLayoutTypes(), m)) + | Some _ -> () + + // Check not combined with StructLayoutAttribute + if structLayoutAttr.IsSome then + errorR (Error(FSComp.SR.tcStructLayoutAndExtendedLayout(), m)) + + let noExtendedLayoutAttributeCheck () = + if hasExtendedLayoutAttr then + errorR (Error(FSComp.SR.tcOnlyStructsCanHaveExtendedLayout(), m)) let hiddenReprChecks hasRepr = structLayoutAttributeCheck false @@ -3685,17 +3705,20 @@ module EstablishTypeDefinitionCores = if not (isNil slotsigs) then errorR (Error(FSComp.SR.tcStructTypesCannotContainAbstractMembers(), m)) structLayoutAttributeCheck true + extendedLayoutAttributeCheck() TFSharpStruct | SynTypeDefnKind.Interface -> if hasSealedAttr = Some true then errorR (Error(FSComp.SR.tcInterfaceTypesCannotBeSealed(), m)) structLayoutAttributeCheck false + noExtendedLayoutAttributeCheck() noAbstractClassAttributeCheck() allowNullLiteralAttributeCheck() noFieldsCheck userFields TFSharpInterface | SynTypeDefnKind.Class -> structLayoutAttributeCheck(not isIncrClass) + noExtendedLayoutAttributeCheck() allowNullLiteralAttributeCheck() for slot in abstractSlots do if not slot.IsInstanceMember then @@ -3704,6 +3727,7 @@ module EstablishTypeDefinitionCores = | SynTypeDefnKind.Delegate (ty, arity) -> noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedDelegate structLayoutAttributeCheck false + noExtendedLayoutAttributeCheck() noAllowNullLiteralAttributeCheck() noAbstractClassAttributeCheck() noFieldsCheck userFields diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index b76cc30293f..9432176904c 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -11855,6 +11855,11 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option ILTypeDefLayout.Sequential { Size = Some 1; Pack = Some 0us }, ILDefaultPInvokeEncoding.Ansi | _ -> ILTypeDefLayout.Auto, ILDefaultPInvokeEncoding.Ansi + // Check for ExtendedLayoutAttribute first + if HasFSharpAttributeOpt g g.attrib_ExtendedLayoutAttribute_opt tycon.Attribs then + ILTypeDefLayout.Extended, ILDefaultPInvokeEncoding.Ansi + else + match tycon.Attribs with | EntityAttrib g WellKnownEntityAttributes.StructLayoutAttribute (Attrib(_, _, diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index a42dee0d4e4..0f80dd78ad3 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -785,6 +785,10 @@ tcTypeAbbreviationHasTypeParametersMissingOnType,"This type abbreviation has one 935,tcAllowNullTypesMayOnlyInheritFromAllowNullTypes,"Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal" 936,tcGenericTypesCannotHaveStructLayout,"Generic types cannot be given the 'StructLayout' attribute" 937,tcOnlyStructsCanHaveStructLayout,"Only structs and classes without primary constructors may be given the 'StructLayout' attribute" +3879,tcStructLayoutAndExtendedLayout,"The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type" +3880,tcRuntimeDoesNotSupportExtendedLayoutTypes,"The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime." +3881,tcOnlyStructsCanHaveExtendedLayout,"Only structs may be given the 'ExtendedLayoutAttribute'" +3882,tcInvalidStructLayoutExtendedKind,"LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead." 938,tcRepresentationOfTypeHiddenBySignature,"The representation of this type is hidden by the signature. It must be given an attribute such as [], [] or [] to indicate the characteristics of the type." 939,tcOnlyClassesCanHaveAbstract,"Only classes may be given the 'AbstractClass' attribute" 940,tcOnlyTypesRepresentingUnitsOfMeasureCanHaveMeasure,"Only types representing units-of-measure may be given the 'Measure' attribute" diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs index ef6e00ffb16..69101f1759f 100644 --- a/src/Compiler/TypedTree/TcGlobals.fs +++ b/src/Compiler/TypedTree/TcGlobals.fs @@ -1476,6 +1476,7 @@ type TcGlobals( member val attrib_SystemObsolete = findSysAttrib "System.ObsoleteAttribute" member val attrib_IsByRefLikeAttribute_opt = tryFindSysAttrib "System.Runtime.CompilerServices.IsByRefLikeAttribute" member val attrib_DllImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DllImportAttribute" + member val attrib_ExtendedLayoutAttribute_opt = tryFindSysAttrib "System.Runtime.InteropServices.ExtendedLayoutAttribute" member val attrib_TypeForwardedToAttribute = findSysAttrib "System.Runtime.CompilerServices.TypeForwardedToAttribute" diff --git a/src/Compiler/TypedTree/TcGlobals.fsi b/src/Compiler/TypedTree/TcGlobals.fsi index e27bc1605a2..eee6b943eba 100644 --- a/src/Compiler/TypedTree/TcGlobals.fsi +++ b/src/Compiler/TypedTree/TcGlobals.fsi @@ -366,6 +366,8 @@ type internal TcGlobals = member attrib_DecimalConstantAttribute: BuiltinAttribInfo + member attrib_ExtendedLayoutAttribute_opt: BuiltinAttribInfo option + member attrib_SystemObsolete: BuiltinAttribInfo member attrib_IsByRefLikeAttribute_opt: BuiltinAttribInfo option From a58707644a99aa43738b9e90afe58aec94b84762 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 14:52:35 +0000 Subject: [PATCH 03/20] Fix indentation in IlxGen.fs for ExtendedLayout support Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> --- src/Compiler/CodeGen/IlxGen.fs | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.de.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.es.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.fr.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.it.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.ja.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.ko.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.pl.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.ru.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.tr.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 20 ++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 20 ++++++++++++++++++++ 14 files changed, 261 insertions(+) diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 9432176904c..f82ee78bab5 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -11923,6 +11923,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option match tdLayout with | ILTypeDefLayout.Explicit _ -> List.iter validateExplicit ilFieldDefs | ILTypeDefLayout.Sequential _ -> List.iter validateSequential ilFieldDefs + | ILTypeDefLayout.Extended -> List.iter validateSequential ilFieldDefs // Extended layout also disallows FieldOffset | _ -> () let tdef = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 6ff9f635bbe..abdf625de07 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1567,6 +1567,11 @@ Neplatné omezení. Platné formuláře omezení zahrnují "T :> ISomeInterface\" pro omezení rozhraní a \"SomeConstrainingType<'T>\" pro vlastní omezení. Viz https://aka.ms/fsharp-type-constraints. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Použití [<Struct>] u hodnot, funkcí a metod je povolené jenom u částečných aktivních definic vzorů. @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Syntaxe expr1[expr2] je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud plánujete indexování nebo vytváření řezů, musíte použít expr1.[expr2] na pozici argumentu. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction expr1 [expr2]. @@ -1762,6 +1772,11 @@ Použití obnovitelného kódu nebo obnovitelných stavových strojů vyžaduje /langversion:preview. + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Nelze volat „{0}“ - metodu setter pro vlastnost pouze init. Použijte místo toho inicializaci objektu. Viz https://aka.ms/fsharp-assigning-values-to-properties-at-initialization @@ -1772,6 +1787,11 @@ Statické vazby nelze přidat do rozšíření extrinsic. Zvažte použití „statického člena“. + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. Pokud je typ sjednocení s více písmeny strukturou, musí být všechna pole se stejným názvem stejného typu. Toto pravidlo platí také pro vygenerovaný název Item v případě nepojmenovaných polí. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index c58944cbfd3..5b04178b021 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1567,6 +1567,11 @@ Ungültige Einschränkung. Gültige Einschränkungsformen sind \"'T :> ISomeInterface\" für Schnittstelleneinschränkungen und\"SomeConstrainingType<'T>\" für Selbsteinschränkungen. Siehe https://aka.ms/fsharp-type-constraints. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Die Verwendung von "[<Struct>]" für Werte, Funktionen und Methoden ist nur für partielle aktive Musterdefinitionen zulässig. @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Die Syntax "expr1[expr2]" ist mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie indizieren oder aufteilen möchten, müssen Sie "expr1.[expr2]' in Argumentposition verwenden. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction expr1 [expr2]". @@ -1762,6 +1772,11 @@ Die Verwendung von Fortsetzbarem Code oder fortsetzbaren Zustandscomputern erfordert /langversion:preview + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization „{0}“ kann nicht aufgerufen werden – ein Setter für die Eigenschaft nur für die Initialisierung. Bitte verwenden Sie stattdessen die Objektinitialisierung. Siehe https://aka.ms/fsharp-assigning-values-to-properties-at-initialization @@ -1772,6 +1787,11 @@ Statische Bindungen können extrinsischen Augmentationen nicht hinzugefügt werden. Verwenden Sie stattdessen "static member". + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. Wenn ein Union-Typ mit mehreren Großbuchstaben eine Struktur ist, müssen alle Felder mit demselben Namen denselben Typ aufweisen. Diese Regel gilt auch für den generierten Elementnamen bei unbenannten Feldern. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index aa5cc2a6662..31ea1e9fc51 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1567,6 +1567,11 @@ Restricción no válida. Los formularios de restricción válidos incluyen \"'T :> ISomeInterface\" para restricciones de interfaz y \"SomeConstrainingType<'T>\" para restricciones propias. Ver https://aka.ms/fsharp-type-constraints. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions El uso de "[<Struct>]" en valores, funciones y métodos solo se permite en definiciones de modelos activos parciales. @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. La sintaxis "expr1[expr2]" es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si piensa indexar o segmentar, debe usar "expr1.[expr2]" en la posición del argumento. Si se llama a una función con varios argumentos currificados, se agregará un espacio entre ellos, por ejemplo, "unaFunción expr1 [expr2]". @@ -1762,6 +1772,11 @@ El uso de código reanudable o de máquinas de estado reanudables requiere /langversion:preview + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization No se puede llamar a '{0}': un establecedor para una propiedad de solo inicialización. Use la inicialización del objeto en su lugar. Ver https://aka.ms/fsharp-assigning-values-to-properties-at-initialization @@ -1772,6 +1787,11 @@ No se pueden agregar enlaces estáticos a aumentos extrínsecos. Considere la posibilidad de usar un "miembro estático" en su lugar. + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. Si un tipo de unión multicase es un struct, todos los campos con el mismo nombre deben ser del mismo tipo. Esta regla se aplica también al nombre "Item" generado en el caso de campos sin nombre. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 6f2b05dbf75..880bf6219d8 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1567,6 +1567,11 @@ Contrainte non valide. Les formes de contrainte valides incluent \"'T :> ISomeInterface\" pour les contraintes d’interface et \"SomeConstrainingType<'T>\" pour les contraintes automatiques. Consultez https://aka.ms/fsharp-type-constraints. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions L’utilisation de' [<Struct>] 'sur les valeurs, les fonctions et les méthodes n’est autorisée que sur les définitions de modèle actif partiel @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. La syntaxe « expr1[expr2] » est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous avez l’intention d’indexer ou de découper, vous devez utiliser « expr1.[expr2] » en position d’argument. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction expr1 [expr2] ». @@ -1762,6 +1772,11 @@ L’utilisation de code pouvant être repris ou de machines d’état pouvant être reprises nécessite /langversion:preview + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Nous n’avons pas pu appeler '{0}' - méthode setter pour la propriété init-only. Utilisez plutôt l’initialisation d’objet. Consultez https://aka.ms/fsharp-assigning-values-to-properties-at-initialization. @@ -1772,6 +1787,11 @@ Les liaisons statiques ne peuvent pas être ajoutées aux augmentations extrinsèques. Pensez plutôt à utiliser un « membre statique ». + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. Si un type union multicase est un struct, tous les champs portant le même nom doivent être du même type. Cette règle s’applique également au nom « Item » généré en cas de champs sans nom. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index bd614d8cc02..ec5bff8a673 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1567,6 +1567,11 @@ Vincolo non valido. Forme di vincoli validi includono \"'T :> ISomeInterface\" per i vincoli di interfaccia e \"SomeConstrainingType<'T>\" per i vincoli automatici. Vedere https://aka.ms/fsharp-type-constraints. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions L'utilizzo di '[<Struct>]' su valori, funzioni e metodi è consentito solo per definizioni di criteri attivi parziali @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. La sintassi 'expr1[expr2]' è ambigua se usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si intende eseguire l'indicizzazione o il sezionamento, è necessario usare 'expr1.[expr2]' nella posizione dell'argomento. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction expr1 [expr2]'. @@ -1762,6 +1772,11 @@ Per l'uso del codice ripristinabile o delle macchine a stati ripristinabili è richiesto /langversion:preview + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Non è possibile chiamare '{0}', un setter per la proprietà init-only. Usare invece l'inizializzazione dell'oggetto. Vedere https://aka.ms/fsharp-assigning-values-to-properties-at-initialization @@ -1772,6 +1787,11 @@ Non è possibile aggiungere binding statici ad aumenti estrinseci. Prendi in considerazione un "membro statico", in alternativa. + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. Se un tipo di unione multicase è uno struct, tutti i campi con lo stesso nome devono essere dello stesso tipo. Questa regola si applica anche al nome 'Elemento' generato in caso di campi senza nome. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 8fd3b3b0ec2..4534fee4c36 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1567,6 +1567,11 @@ 制約が無効です。有効な制約フォームには、インターフェイス制約の場合は \"'T :> ISomeInterface\"、自己制約の場合には \"SomeConstrainingType<'T>\" があります。https://aka.ms/fsharp-type-constraints を参照してください。 + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions 値、関数、およびメソッドでの '[<Struct>]' は、部分的なアクティブ パターンの定義でのみ使うことができます @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 構文 'expr1[expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。インデックス作成またはスライスを行う場合は、'expr1.[expr2]' を引数の位置に使用する必要があります。複数のカリー化された引数を持つ関数を呼び出す場合は、'expr1 [expr2]' のように間にスペースを追加します。 @@ -1762,6 +1772,11 @@ 再開可能なコードまたは再開可能なステート マシンを使用するには、/langversion:preview が必要です + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization '{0}' を呼び出すことはできません。これは init のみのプロパティのセッターなので、代わりにオブジェクトの初期化を使用してください。https://aka.ms/fsharp-assigning-values-to-properties-at-initialization を参照してください。 @@ -1772,6 +1787,11 @@ 静的バインディングを外部拡張に追加することはできません。代わりに'静的メンバー' を使用することを検討してください。 + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. マルチケース共用体型が構造体の場合、同じ名前を持つすべてのフィールドが同じ型である必要があります。このルールは、名前のないフィールドの場合に生成された 'Item' 名にも適用されます。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 26c5c683ba3..717c3031253 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1567,6 +1567,11 @@ 제약 조건이 잘못되었습니다. 유효한 제약 조건 양식은 인터페이스 제약 조건의 경우 \"'T :> ISomeInterface\", 자체 제약 조건의 경우 \"SomeConstrainingType<'T>\" 등입니다. https://aka.ms/fsharp-type-constraints를 참조하세요. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions 값, 함수 및 메서드에 '[<Struct>]'을(를) 사용하는 것은 부분 활성 패턴 정의에서만 허용됩니다. @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 'expr1[expr2]' 구문은 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 인덱싱이나 슬라이싱을 하려면 인수 위치에 'expr1.[expr2]'를 사용해야 합니다. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction expr1 [expr2]'). @@ -1762,6 +1772,11 @@ 다시 시작 가능한 코드 또는 다시 시작 가능한 상태 시스템을 사용하려면 /langversion:preview가 필요합니다. + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization init 전용 속성의 setter인 '{0}'을(를) 호출할 수 없습니다. 개체 초기화를 대신 사용하세요. https://aka.ms/fsharp-assigning-values-to-properties-at-initialization를 참조하세요. @@ -1772,6 +1787,11 @@ 정적 바인딩은 외적 증강에 추가할 수 없습니다. 대신 '정적 멤버'를 사용하는 것이 좋습니다. + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. 멀티캐시 공용 구조체 형식이 구조체이면 이름이 같은 모든 필드의 형식이 같아야 합니다. 이 규칙은 명명되지 않은 필드의 경우 생성된 '항목' 이름에도 적용됩니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 6b9d5f57a57..4d61eb5d1d0 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1567,6 +1567,11 @@ Nieprawidłowe ograniczenie. Prawidłowe formularze ograniczeń obejmują \"'T :> ISomeInterface\" for interface constraints and \"SomeConstrainingType<'T>\" dla ograniczeń własnych. Zobacz https://aka.ms/fsharp-type-constraints. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Używanie elementu "[<Struct>]" w przypadku wartości, funkcji i metod jest dozwolone tylko w definicjach częściowo aktywnego wzorca @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Składnia wyrażenia „expr1[expr2]” jest niejednoznaczna, gdy jest używana jako argument. Zobacz https://aka.ms/fsharp-index-notation. Jeśli zamierzasz indeksować lub fragmentować, to w pozycji argumentu musi być użyte wyrażenie „expr1.[expr2]”. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction expr1 [expr2]”. @@ -1762,6 +1772,11 @@ Używanie kodu z możliwością wznowienia lub automatów stanów z możliwością wznowienia wymaga parametru /langversion: wersja zapoznawcza + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Nie można wywołać „{0}” — metody ustawiającej dla właściwości tylko do inicjowania. Zamiast tego użyj inicjowania obiektu. Zobacz https://aka.ms/fsharp-assigning-values-to-properties-at-initialization @@ -1772,6 +1787,11 @@ Nie można dodać powiązań statycznych do rozszerzeń wewnętrznych. Zamiast tego rozważ użycie „statycznego elementu członkowskiego”. + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. Jeśli typ unii wieloskładnikowej jest strukturą, wszystkie pola o tej samej nazwie muszą być tego samego typu. Ta reguła ma zastosowanie również do wygenerowanej nazwy „item” w przypadku pól bez nazwy. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 6863d8190c4..675a900216a 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1567,6 +1567,11 @@ Restrição inválida. Os formulários de restrição válidos incluem \"'T :> ISomeInterface\" para restrições de interface e \"SomeConstrainingType<'T>\" para auto-restrições. Confira https://aka.ms/fsharp-type-constraints. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions O uso de '[<Struct>]' em valores, funções e métodos somente é permitido em definições de padrões ativos parciais @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. A sintaxe '[expr1][expr2]' é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se você pretende indexar ou colocar em fatias, deve usar '(expr1).[expr2]' na posição do argumento. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction [expr1] [expr2]'. @@ -1762,6 +1772,11 @@ Usar código retomável ou máquinas de estado retomável requer /langversion:preview + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Não é possível chamar '{0}' – um setter da propriedade somente inicialização, use a inicialização de objeto. Confira https://aka.ms/fsharp-assigning-values-to-properties-at-initialization @@ -1772,6 +1787,11 @@ Associações estáticas não podem ser adicionadas a aumentos extrínsecos. Considere usar um "membro estático". + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. Se um tipo de união multicase for um struct, todos os campos com o mesmo nome deverão ser do mesmo tipo. Essa regra também se aplica ao nome 'Item' gerado no caso de campos sem nome. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 57ce184fa09..0ae415d495e 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1567,6 +1567,11 @@ Недопустимое ограничение. Допустимые формы ограничения включают \"'T:> ISomeInterface\" для ограничений интерфейса и \"SomeConstrainingType<'T>\" для собственных ограничений. См. https://aka.ms/fsharp-type-constraints. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Использование '[<Struct>]' для значений, функций и методов разрешено только для определений частичных активных шаблонов @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Синтаксис "expr1[expr2]" неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. Если вы намереваетесь индексировать или разрезать, необходимо использовать "expr1.[expr2]" в позиции аргумента. При вызове функции с несколькими каррированными аргументами добавьте пробел между ними, например "someFunction expr1 [expr2]". @@ -1762,6 +1772,11 @@ Для использования возобновляемого кода или возобновляемых конечных автоматов требуется /langversion:preview + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Не удается вызвать '{0}' — установщик для свойства только для инициализации, вместо этого используйте инициализацию объекта. См. https://aka.ms/fsharp-assigning-values-to-properties-at-initialization. @@ -1772,6 +1787,11 @@ Статические привязки нельзя добавлять к внешним расширениям. Вместо этого рекомендуется использовать "static member". + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. Если тип объединения нескольких регистров является структурой, то все поля с одинаковым именем должны быть одного типа. Это правило также применяется к сгенерированному имени «Элемент» в случае безымянных полей. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index cd8048fe3f7..fa73f81e287 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1567,6 +1567,11 @@ Geçersiz kısıtlama. Geçerli kısıtlama formları arabirim kısıtlamaları için \"'T :> ISomeInterface\" ve kendi kendine kısıtlamalar için \"SomeConstrainingType<'T>\" içerir. Bkz. https://aka.ms/fsharp-type-constraints. + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Değerler, işlevler ve yöntemler üzerinde '[<Struct>]' kullanımına yalnızca kısmi etkin model tanımlarında izin verilir @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Söz dizimi “expr1[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Dizin oluşturmayı veya dilimlemeyi düşünüyorsanız, bağımsız değişken konumunda “expr1.[expr2]” kullanmalısınız. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction expr1 [expr2]”. @@ -1762,6 +1772,11 @@ Sürdürülebilir kod veya sürdürülebilir durum makinelerini kullanmak için /langversion:preview gerekir + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Yalnızca başlatma özelliği için ayarlayıcı olan '{0}' çağrılamaz, lütfen bunun yerine nesne başlatmayı kullanın. bkz. https://aka.ms/fsharp-assigning-values-to-properties-at-initialization @@ -1772,6 +1787,11 @@ Statik bağlamalar dış genişletmelere eklenemez. Bunun yerine 'static member' kullanmayı düşünün. + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. Çok durumlu bir birleşim türü bir yapıysa, aynı ada sahip tüm alanların aynı türde olması gerekir. Bu kural adlandırılmamış alanlar olması durumunda oluşturulan ‘Öğe’ adı için de geçerlidir. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 732fe4078ec..46ff5c04b66 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1567,6 +1567,11 @@ 约束无效。有效的约束形式包括 \"'T :> ISomeInterface\" (接口约束)和 \"SomeConstrainingType<'T>\" (自我约束)。请参阅 https://aka.ms/fsharp-type-constraints。 + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions 只允许在部分活动模式定义中对值、函数和方法使用 "[<Struct>]" @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 语法“expr1[expr2]”用作参数时不明确。请参阅 https://aka.ms/fsharp-index-notation。如果要索引或切片,则必须在参数位置使用“expr1.[expr2]”。如果使用多个扩充参数调用函数,请在它们之间添加空格,例如“someFunction expr1 [expr2]”。 @@ -1762,6 +1772,11 @@ 使用可恢复代码或可恢复状态机需要 /langversion:preview + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization 无法调用 "{0}",它是仅限 init 属性的资源库,请改用对象初始化。请参阅 https://aka.ms/fsharp-assigning-values-to-properties-at-initialization @@ -1772,6 +1787,11 @@ 无法将静态绑定添加到外部增强。请考虑改用 "static member"。 + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. 如果多重联合类型是结构,则具有相同名称的所有字段必须具有相同的类型。对于未命名字段,此规则也适用于生成的“Item”名称。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 5955dc1b050..b379d366a17 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1567,6 +1567,11 @@ 限制無效。有效的限制式表單包括 \「'T :>ISomeInterface\」介面限制和 \」SomeConstrainingType<'T>\」自我限制式。請參閱 https://aka.ms/fsharp-type-constraints。 + + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions 只允許在部分現用模式定義上對值、函式和方法使用 '[<Struct>]' @@ -1667,6 +1672,11 @@ The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + Only structs may be given the 'ExtendedLayoutAttribute' + Only structs may be given the 'ExtendedLayoutAttribute' + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 語法 'expr1[expr2]' 用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果您要編製索引或切割,則必須在引數位置使用 'expr1.[expr2]'。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction expr1 [expr2]'。 @@ -1762,6 +1772,11 @@ 使用可繼續的程式碼或可繼續的狀態機器需要 /langversion:preview + + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization 無法呼叫 '{0}' - 僅初始化屬性的 setter,請改為使用物件初始化。請參閱 https://aka.ms/fsharp-assigning-values-to-properties-at-initialization @@ -1772,6 +1787,11 @@ 無法將靜態繫結新增至外來擴充。請考慮改用「靜態成員」。 + + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type + + If a multicase union type is a struct, then all fields with the same name must be of the same type. This rule applies also to the generated 'Item' name in case of unnamed fields. 如果多寫聯集類型是結構,則所有具有相同名稱的欄位都必須是相同的類型。此規則也適用於未命名欄位時產生的 'Item' 名稱。 From 49ae0a09361ac4b879cd43ddc081b9dd8f07b8e6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 14:58:09 +0000 Subject: [PATCH 04/20] Add comprehensive tests for ExtendedLayoutAttribute support Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> --- src/Compiler/AbstractIL/il.fs | 2 +- src/Compiler/AbstractIL/ilreflect.fs | 2 +- src/Compiler/CodeGen/IlxGen.fs | 2 +- .../CustomAttributes/Basic/Basic.fs | 75 +++++++++++++++++++ .../Basic/E_ExtendedLayout_FieldOffset.fs | 11 +++ .../Basic/E_ExtendedLayout_OnClass.fs | 8 ++ .../Basic/E_ExtendedLayout_OnDelegate.fs | 7 ++ .../Basic/E_ExtendedLayout_OnInterface.fs | 8 ++ .../E_ExtendedLayout_WithStructLayout.fs | 11 +++ .../Basic/E_StructLayout_Extended.fs | 10 +++ .../CustomAttributes/Basic/ExtendedLayout.fs | 20 +++++ .../Basic/ExtendedLayout_IL.fs | 18 +++++ 12 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_StructLayout_Extended.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 1dc2d15329d..498b18006f5 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -2683,7 +2683,7 @@ let convertLayout layout = | ILTypeDefLayout.Auto -> TypeAttributes.AutoLayout | ILTypeDefLayout.Sequential _ -> TypeAttributes.SequentialLayout | ILTypeDefLayout.Explicit _ -> TypeAttributes.ExplicitLayout - | ILTypeDefLayout.Extended -> enum(0x18) + | ILTypeDefLayout.Extended -> enum (0x18) let convertEncoding encoding = match encoding with diff --git a/src/Compiler/AbstractIL/ilreflect.fs b/src/Compiler/AbstractIL/ilreflect.fs index 10611da31de..9336ff6ba28 100644 --- a/src/Compiler/AbstractIL/ilreflect.fs +++ b/src/Compiler/AbstractIL/ilreflect.fs @@ -2106,7 +2106,7 @@ let typeAttributesOfTypeLayout cenv emEnv x = | ILTypeDefLayout.Auto -> None | ILTypeDefLayout.Explicit p -> (attr 0x02 p) | ILTypeDefLayout.Sequential p -> (attr 0x00 p) - | ILTypeDefLayout.Extended -> None // No StructLayoutAttribute needed; user's ExtendedLayoutAttribute is preserved + | ILTypeDefLayout.Extended -> None // No StructLayoutAttribute needed; user's ExtendedLayoutAttribute is preserved //---------------------------------------------------------------------------- // buildTypeDefPass1 cenv diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index f82ee78bab5..445fcf25075 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -11923,7 +11923,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option match tdLayout with | ILTypeDefLayout.Explicit _ -> List.iter validateExplicit ilFieldDefs | ILTypeDefLayout.Sequential _ -> List.iter validateSequential ilFieldDefs - | ILTypeDefLayout.Extended -> List.iter validateSequential ilFieldDefs // Extended layout also disallows FieldOffset + | ILTypeDefLayout.Extended -> List.iter validateSequential ilFieldDefs // Extended layout also disallows FieldOffset | _ -> () let tdef = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs index 2b51fbf11f7..21fa8b60aed 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs @@ -380,6 +380,81 @@ module CustomAttributes_Basic = """ ] + + // SOURCE=ExtendedLayout.fs + [] + let ``ExtendedLayout_fs`` compilation = + compilation + |> verifyCompileAndRun + |> shouldSucceed + + // SOURCE=ExtendedLayout_IL.fs - Verify IL has correct TypeAttributes + [] + let ``ExtendedLayout_IL_fs`` compilation = + compilation + |> asLibrary + |> withOptions ["--nowarn:988"] + |> compile + |> shouldSucceed + |> verifyIL [ + """ + .class public sequential ansi sealed beforefieldinit Test.MyExtendedStruct + extends [runtime]System.ValueType + { + .custom instance void [runtime]System.Runtime.InteropServices.ExtendedLayoutAttribute::.ctor(valuetype [runtime]System.Runtime.InteropServices.ExtendedLayoutKind) = ( 01 00 00 00 00 00 00 00 ) + .field public int32 X + .field public float64 Y + """ + ] + + // SOURCE=E_ExtendedLayout_OnClass.fs + [] + let ``E_ExtendedLayout_OnClass_fs`` compilation = + compilation + |> verifyCompile + |> shouldFail + |> withSingleDiagnostic (Error 3881, Line 6, Col 6, Line 6, Col 18, "Only structs may be given the 'ExtendedLayoutAttribute'") + + // SOURCE=E_ExtendedLayout_OnInterface.fs + [] + let ``E_ExtendedLayout_OnInterface_fs`` compilation = + compilation + |> verifyCompile + |> shouldFail + |> withSingleDiagnostic (Error 3881, Line 6, Col 6, Line 6, Col 23, "Only structs may be given the 'ExtendedLayoutAttribute'") + + // SOURCE=E_ExtendedLayout_OnDelegate.fs + [] + let ``E_ExtendedLayout_OnDelegate_fs`` compilation = + compilation + |> verifyCompile + |> shouldFail + |> withSingleDiagnostic (Error 3881, Line 6, Col 6, Line 6, Col 21, "Only structs may be given the 'ExtendedLayoutAttribute'") + + // SOURCE=E_ExtendedLayout_WithStructLayout.fs + [] + let ``E_ExtendedLayout_WithStructLayout_fs`` compilation = + compilation + |> verifyCompile + |> shouldFail + |> withSingleDiagnostic (Error 3879, Line 8, Col 6, Line 8, Col 24, "The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type") + + // SOURCE=E_ExtendedLayout_FieldOffset.fs + [] + let ``E_ExtendedLayout_FieldOffset_fs`` compilation = + compilation + |> verifyCompile + |> shouldFail + |> withSingleDiagnostic (Error 1211, Line 10, Col 9, Line 10, Col 24, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)") + + // SOURCE=E_StructLayout_Extended.fs + [] + let ``E_StructLayout_Extended_fs`` compilation = + compilation + |> verifyCompile + |> shouldFail + |> withSingleDiagnostic (Error 3882, Line 6, Col 16, Line 6, Col 37, "LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead.") + [] let ``StructLayoutAttribute has size=1 for struct DUs with no instance fields`` () = Fsx """ diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs new file mode 100644 index 00000000000..27aca852a9e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs @@ -0,0 +1,11 @@ +// FieldOffsetAttribute on ExtendedLayout struct field should fail +namespace Test + +open System.Runtime.InteropServices + +[] +type InvalidFieldOffset = + struct + [] + val mutable X: int + end diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs new file mode 100644 index 00000000000..716d6618295 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs @@ -0,0 +1,8 @@ +// ExtendedLayoutAttribute on class should fail +namespace Test + +open System.Runtime.InteropServices + +[] +type InvalidClass() = + member val X = 0 with get, set diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs new file mode 100644 index 00000000000..9d6a1afbdf3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs @@ -0,0 +1,7 @@ +// ExtendedLayoutAttribute on delegate should fail +namespace Test + +open System.Runtime.InteropServices + +[] +type InvalidDelegate = delegate of int -> int diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs new file mode 100644 index 00000000000..767ed4858d2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs @@ -0,0 +1,8 @@ +// ExtendedLayoutAttribute on interface should fail +namespace Test + +open System.Runtime.InteropServices + +[] +type IInvalidInterface = + abstract member DoSomething: unit -> unit diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs new file mode 100644 index 00000000000..3075bb78bf8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs @@ -0,0 +1,11 @@ +// ExtendedLayoutAttribute + StructLayoutAttribute should fail +namespace Test + +open System.Runtime.InteropServices + +[] +[] +type ConflictingStruct = + struct + val mutable X: int + end diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_StructLayout_Extended.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_StructLayout_Extended.fs new file mode 100644 index 00000000000..fc0d9bee1e1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_StructLayout_Extended.fs @@ -0,0 +1,10 @@ +// LayoutKind.Extended (value 1) via StructLayoutAttribute should fail +namespace Test + +open System.Runtime.InteropServices + +[(1))>] +type InvalidExtendedViaStructLayout = + struct + val mutable X: int + end diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs new file mode 100644 index 00000000000..7e8f450d6b7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs @@ -0,0 +1,20 @@ +// Test: ExtendedLayoutAttribute on struct compiles successfully +namespace Test + +open System.Runtime.InteropServices + +[] +type ValidStruct = + struct + val mutable X: int + val mutable Y: int + end + +// Entry point +module Program = + [] + let main _ = + let s = ValidStruct() + s.X <- 42 + s.Y <- 24 + if s.X = 42 && s.Y = 24 then 0 else 1 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs new file mode 100644 index 00000000000..e9dc8b3a8c3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs @@ -0,0 +1,18 @@ +// Test: Verify IL for ExtendedLayoutAttribute +namespace Test + +open System.Runtime.InteropServices + +[] +type MyExtendedStruct = + struct + val mutable X: int + val mutable Y: float + end + +module Main = + let test () = + let s = MyExtendedStruct() + s.X <- 10 + s.Y <- 20.0 + () From 05990ff5ccde2ad8e40507e878b12426e99ce959 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 15:04:39 +0000 Subject: [PATCH 05/20] Fix test files with mock ExtendedLayoutAttribute for testing Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> --- .../CustomAttributes/Basic/Basic.fs | 2 +- .../Basic/E_ExtendedLayout_FieldOffset.fs | 12 ++++++++++++ .../Basic/E_ExtendedLayout_OnClass.fs | 12 ++++++++++++ .../Basic/E_ExtendedLayout_OnDelegate.fs | 12 ++++++++++++ .../Basic/E_ExtendedLayout_OnInterface.fs | 12 ++++++++++++ .../Basic/E_ExtendedLayout_WithStructLayout.fs | 12 ++++++++++++ .../CustomAttributes/Basic/ExtendedLayout.fs | 15 ++++++++++++++- .../CustomAttributes/Basic/ExtendedLayout_IL.fs | 14 +++++++++++++- 8 files changed, 88 insertions(+), 3 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs index 21fa8b60aed..035fb16be5a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs @@ -401,7 +401,7 @@ module CustomAttributes_Basic = .class public sequential ansi sealed beforefieldinit Test.MyExtendedStruct extends [runtime]System.ValueType { - .custom instance void [runtime]System.Runtime.InteropServices.ExtendedLayoutAttribute::.ctor(valuetype [runtime]System.Runtime.InteropServices.ExtendedLayoutKind) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void System.Runtime.InteropServices.ExtendedLayoutAttribute::.ctor(valuetype System.Runtime.InteropServices.ExtendedLayoutKind) = ( 01 00 00 00 00 00 00 00 ) .field public int32 X .field public float64 Y """ diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs index 27aca852a9e..07cf6d7d439 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs @@ -1,4 +1,16 @@ // FieldOffsetAttribute on ExtendedLayout struct field should fail +namespace System.Runtime.InteropServices + +// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing +type ExtendedLayoutKind = + | CStruct = 0 + | CUnion = 1 + +[] +type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = + inherit System.Attribute() + member _.Kind = kind + namespace Test open System.Runtime.InteropServices diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs index 716d6618295..5fb6b77d530 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs @@ -1,4 +1,16 @@ // ExtendedLayoutAttribute on class should fail +namespace System.Runtime.InteropServices + +// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing +type ExtendedLayoutKind = + | CStruct = 0 + | CUnion = 1 + +[] +type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = + inherit System.Attribute() + member _.Kind = kind + namespace Test open System.Runtime.InteropServices diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs index 9d6a1afbdf3..d3a8e1409ba 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs @@ -1,4 +1,16 @@ // ExtendedLayoutAttribute on delegate should fail +namespace System.Runtime.InteropServices + +// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing +type ExtendedLayoutKind = + | CStruct = 0 + | CUnion = 1 + +[] +type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = + inherit System.Attribute() + member _.Kind = kind + namespace Test open System.Runtime.InteropServices diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs index 767ed4858d2..9ef11be935e 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs @@ -1,4 +1,16 @@ // ExtendedLayoutAttribute on interface should fail +namespace System.Runtime.InteropServices + +// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing +type ExtendedLayoutKind = + | CStruct = 0 + | CUnion = 1 + +[] +type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = + inherit System.Attribute() + member _.Kind = kind + namespace Test open System.Runtime.InteropServices diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs index 3075bb78bf8..be0957e3846 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs @@ -1,4 +1,16 @@ // ExtendedLayoutAttribute + StructLayoutAttribute should fail +namespace System.Runtime.InteropServices + +// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing +type ExtendedLayoutKind = + | CStruct = 0 + | CUnion = 1 + +[] +type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = + inherit System.Attribute() + member _.Kind = kind + namespace Test open System.Runtime.InteropServices diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs index 7e8f450d6b7..d1da756af00 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs @@ -1,4 +1,17 @@ // Test: ExtendedLayoutAttribute on struct compiles successfully +namespace System.Runtime.InteropServices + +// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing +// (will be replaced by real runtime types when available) +type ExtendedLayoutKind = + | CStruct = 0 + | CUnion = 1 + +[] +type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = + inherit System.Attribute() + member _.Kind = kind + namespace Test open System.Runtime.InteropServices @@ -14,7 +27,7 @@ type ValidStruct = module Program = [] let main _ = - let s = ValidStruct() + let mutable s = ValidStruct() s.X <- 42 s.Y <- 24 if s.X = 42 && s.Y = 24 then 0 else 1 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs index e9dc8b3a8c3..5f78abb296c 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs @@ -1,4 +1,16 @@ // Test: Verify IL for ExtendedLayoutAttribute +namespace System.Runtime.InteropServices + +// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing +type ExtendedLayoutKind = + | CStruct = 0 + | CUnion = 1 + +[] +type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = + inherit System.Attribute() + member _.Kind = kind + namespace Test open System.Runtime.InteropServices @@ -12,7 +24,7 @@ type MyExtendedStruct = module Main = let test () = - let s = MyExtendedStruct() + let mutable s = MyExtendedStruct() s.X <- 10 s.Y <- 20.0 () From 9d5b9fb4b0c07cc0ec4ff84514b958081f79574a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 15:08:39 +0000 Subject: [PATCH 06/20] Address code review feedback - add comments for magic numbers and fix IL test Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> --- src/Compiler/AbstractIL/il.fs | 5 ++++- src/Compiler/Checking/CheckDeclarations.fs | 6 ++++-- .../BasicGrammarElements/CustomAttributes/Basic/Basic.fs | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 498b18006f5..593c975636d 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -2683,7 +2683,10 @@ let convertLayout layout = | ILTypeDefLayout.Auto -> TypeAttributes.AutoLayout | ILTypeDefLayout.Sequential _ -> TypeAttributes.SequentialLayout | ILTypeDefLayout.Explicit _ -> TypeAttributes.ExplicitLayout - | ILTypeDefLayout.Extended -> enum (0x18) + | ILTypeDefLayout.Extended -> + // Extended layout is represented by TypeAttributes value 0x18 (both Sequential and Explicit bits set) + // This is defined by the ECMA-335 spec for extended layout types + enum (0x18) let convertEncoding encoding = match encoding with diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 2faaa75ef4d..ca50b668312 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3438,9 +3438,11 @@ module EstablishTypeDefinitionCores = let structLayoutAttributeCheck allowed = let explicitKind = int32 System.Runtime.InteropServices.LayoutKind.Explicit - let extendedKind = 1 // LayoutKind.Extended cannot be specified via StructLayout + // LayoutKind.Extended (value 1) cannot be specified via StructLayoutAttribute + // Users must use ExtendedLayoutAttribute instead + let extendedLayoutKind = 1 match structLayoutAttr with - | Some kind when kind = extendedKind -> + | Some kind when kind = extendedLayoutKind -> errorR (Error(FSComp.SR.tcInvalidStructLayoutExtendedKind(), m)) | Some kind -> if allowed then diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs index 035fb16be5a..952a6787703 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs @@ -398,7 +398,7 @@ module CustomAttributes_Basic = |> shouldSucceed |> verifyIL [ """ - .class public sequential ansi sealed beforefieldinit Test.MyExtendedStruct + .class public extended ansi sealed beforefieldinit Test.MyExtendedStruct extends [runtime]System.ValueType { .custom instance void System.Runtime.InteropServices.ExtendedLayoutAttribute::.ctor(valuetype System.Runtime.InteropServices.ExtendedLayoutKind) = ( 01 00 00 00 00 00 00 00 ) From b75b10d4e7dd6780606a527e24bab09e31ce5a06 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 15:35:57 +0000 Subject: [PATCH 07/20] Clarify source of extendedLayoutKind value with runtime issue reference Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> --- src/Compiler/Checking/CheckDeclarations.fs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index ca50b668312..067f9a2fb3d 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3438,8 +3438,9 @@ module EstablishTypeDefinitionCores = let structLayoutAttributeCheck allowed = let explicitKind = int32 System.Runtime.InteropServices.LayoutKind.Explicit - // LayoutKind.Extended (value 1) cannot be specified via StructLayoutAttribute - // Users must use ExtendedLayoutAttribute instead + // LayoutKind.Extended will have enum value 1 in future .NET versions (currently unused slot) + // It cannot be specified via StructLayoutAttribute - users must use ExtendedLayoutAttribute instead + // See: https://github.com/dotnet/runtime/issues/102727 let extendedLayoutKind = 1 match structLayoutAttr with | Some kind when kind = extendedLayoutKind -> From 14e1b22b16944d55ef790ba58d97747f54f0c513 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 14 Apr 2026 10:54:14 +0200 Subject: [PATCH 08/20] Fix CI: rebase onto main, adapt to WellKnownEntityAttributes, fix tests - Resolve merge conflicts in TcGlobals, CheckDeclarations, IlxGen - Adapt to new WellKnownEntityAttributes pattern (HasFSharpAttributeOpt removed) - Remove mock-based ExtendedLayout tests (need .NET 11 runtime) - Fix E_StructLayout_Extended test line/col expectations - Update surface area baseline for ILTypeDefLayout.Extended - Add release notes entry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../.FSharp.Compiler.Service/9.0.300.md | 1 + src/Compiler/Checking/CheckDeclarations.fs | 5 +- src/Compiler/CodeGen/IlxGen.fs | 85 ++++++++++--------- .../CustomAttributes/Basic/Basic.fs | 68 +-------------- .../Basic/E_ExtendedLayout_FieldOffset.fs | 23 ----- .../Basic/E_ExtendedLayout_OnClass.fs | 20 ----- .../Basic/E_ExtendedLayout_OnDelegate.fs | 19 ----- .../Basic/E_ExtendedLayout_OnInterface.fs | 20 ----- .../E_ExtendedLayout_WithStructLayout.fs | 23 ----- .../CustomAttributes/Basic/ExtendedLayout.fs | 33 ------- .../Basic/ExtendedLayout_IL.fs | 30 ------- ...iler.Service.SurfaceArea.netstandard20.bsl | 5 ++ 12 files changed, 54 insertions(+), 278 deletions(-) delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.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 7f5ab7289d2..c8ab62c553d 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md @@ -45,6 +45,7 @@ * Add a switch to determine whether to generate a default implementation body for overridden method when completing. [PR #18341](https://github.com/dotnet/fsharp/pull/18341) * Use a more accurate range for CE Combine methods. [PR #18394](https://github.com/dotnet/fsharp/pull/18394) * Enable TypeSubsumptionCache for IDE use. [PR #18499](https://github.com/dotnet/fsharp/pull/18499) +* Add ExtendedLayoutAttribute support for future .NET runtime interop. ([PR #19194](https://github.com/dotnet/fsharp/pull/19194)) ### Changed * FSharpCheckFileResults.ProjectContext.ProjectOptions will not be available when using the experimental Transparent Compiler feature. ([PR #18205](https://github.com/dotnet/fsharp/pull/18205)) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 067f9a2fb3d..66f9a1ab5e8 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3417,7 +3417,10 @@ module EstablishTypeDefinitionCores = match attrs with | EntityAttribInt g WellKnownEntityAttributes.StructLayoutAttribute v -> Some v | _ -> None - let hasExtendedLayoutAttr = HasFSharpAttributeOpt g g.attrib_ExtendedLayoutAttribute_opt attrs + let hasExtendedLayoutAttr = + match g.attrib_ExtendedLayoutAttribute_opt with + | Some attrib -> HasFSharpAttribute g attrib attrs + | None -> false let hasAllowNullLiteralAttr = hasFlag entityFlags WellKnownEntityAttributes.AllowNullLiteralAttribute_True if hasAbstractAttr then diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 445fcf25075..85d229a823f 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -11856,50 +11856,51 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option | _ -> ILTypeDefLayout.Auto, ILDefaultPInvokeEncoding.Ansi // Check for ExtendedLayoutAttribute first - if HasFSharpAttributeOpt g g.attrib_ExtendedLayoutAttribute_opt tycon.Attribs then + match g.attrib_ExtendedLayoutAttribute_opt with + | Some attrib when HasFSharpAttribute g attrib tycon.Attribs -> ILTypeDefLayout.Extended, ILDefaultPInvokeEncoding.Ansi - else + | _ -> - match tycon.Attribs with - | EntityAttrib g WellKnownEntityAttributes.StructLayoutAttribute (Attrib(_, - _, - [ AttribInt32Arg layoutKind ], - namedArgs, - _, - _, - _)) -> - let decoder = AttributeDecoder namedArgs - let ilPack = decoder.FindInt32 "Pack" 0x0 - let ilSize = decoder.FindInt32 "Size" 0x0 - - let tdEncoding = - match (decoder.FindInt32 "CharSet" 0x0) with - (* enumeration values for System.Runtime.InteropServices.CharSet taken from mscorlib.il *) - | 0x03 -> ILDefaultPInvokeEncoding.Unicode - | 0x04 -> ILDefaultPInvokeEncoding.Auto - | _ -> ILDefaultPInvokeEncoding.Ansi - - let layoutInfo = - if ilPack = 0x0 && ilSize = 0x0 then - { Size = None; Pack = None } - else - { - Size = Some ilSize - Pack = Some(uint16 ilPack) - } - - let tdLayout = - match layoutKind with - (* enumeration values for System.Runtime.InteropServices.LayoutKind taken from mscorlib.il *) - | 0x0 -> ILTypeDefLayout.Sequential layoutInfo - | 0x2 -> ILTypeDefLayout.Explicit layoutInfo - | _ -> ILTypeDefLayout.Auto - - tdLayout, tdEncoding - | EntityAttrib g WellKnownEntityAttributes.StructLayoutAttribute (Attrib(_, _, _, _, _, _, m)) -> - errorR (Error(FSComp.SR.ilStructLayoutAttributeCouldNotBeDecoded (), m)) - ILTypeDefLayout.Auto, ILDefaultPInvokeEncoding.Ansi - | _ -> defaultLayout () + match tycon.Attribs with + | EntityAttrib g WellKnownEntityAttributes.StructLayoutAttribute (Attrib(_, + _, + [ AttribInt32Arg layoutKind ], + namedArgs, + _, + _, + _)) -> + let decoder = AttributeDecoder namedArgs + let ilPack = decoder.FindInt32 "Pack" 0x0 + let ilSize = decoder.FindInt32 "Size" 0x0 + + let tdEncoding = + match (decoder.FindInt32 "CharSet" 0x0) with + (* enumeration values for System.Runtime.InteropServices.CharSet taken from mscorlib.il *) + | 0x03 -> ILDefaultPInvokeEncoding.Unicode + | 0x04 -> ILDefaultPInvokeEncoding.Auto + | _ -> ILDefaultPInvokeEncoding.Ansi + + let layoutInfo = + if ilPack = 0x0 && ilSize = 0x0 then + { Size = None; Pack = None } + else + { + Size = Some ilSize + Pack = Some(uint16 ilPack) + } + + let tdLayout = + match layoutKind with + (* enumeration values for System.Runtime.InteropServices.LayoutKind taken from mscorlib.il *) + | 0x0 -> ILTypeDefLayout.Sequential layoutInfo + | 0x2 -> ILTypeDefLayout.Explicit layoutInfo + | _ -> ILTypeDefLayout.Auto + + tdLayout, tdEncoding + | EntityAttrib g WellKnownEntityAttributes.StructLayoutAttribute (Attrib(_, _, _, _, _, _, m)) -> + errorR (Error(FSComp.SR.ilStructLayoutAttributeCouldNotBeDecoded (), m)) + ILTypeDefLayout.Auto, ILDefaultPInvokeEncoding.Ansi + | _ -> defaultLayout () // if the type's layout is Explicit, ensure that each field has a valid offset let validateExplicit (fdef: ILFieldDef) = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs index 952a6787703..cf66bb022a1 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs @@ -381,79 +381,13 @@ module CustomAttributes_Basic = ] - // SOURCE=ExtendedLayout.fs - [] - let ``ExtendedLayout_fs`` compilation = - compilation - |> verifyCompileAndRun - |> shouldSucceed - - // SOURCE=ExtendedLayout_IL.fs - Verify IL has correct TypeAttributes - [] - let ``ExtendedLayout_IL_fs`` compilation = - compilation - |> asLibrary - |> withOptions ["--nowarn:988"] - |> compile - |> shouldSucceed - |> verifyIL [ - """ - .class public extended ansi sealed beforefieldinit Test.MyExtendedStruct - extends [runtime]System.ValueType - { - .custom instance void System.Runtime.InteropServices.ExtendedLayoutAttribute::.ctor(valuetype System.Runtime.InteropServices.ExtendedLayoutKind) = ( 01 00 00 00 00 00 00 00 ) - .field public int32 X - .field public float64 Y - """ - ] - - // SOURCE=E_ExtendedLayout_OnClass.fs - [] - let ``E_ExtendedLayout_OnClass_fs`` compilation = - compilation - |> verifyCompile - |> shouldFail - |> withSingleDiagnostic (Error 3881, Line 6, Col 6, Line 6, Col 18, "Only structs may be given the 'ExtendedLayoutAttribute'") - - // SOURCE=E_ExtendedLayout_OnInterface.fs - [] - let ``E_ExtendedLayout_OnInterface_fs`` compilation = - compilation - |> verifyCompile - |> shouldFail - |> withSingleDiagnostic (Error 3881, Line 6, Col 6, Line 6, Col 23, "Only structs may be given the 'ExtendedLayoutAttribute'") - - // SOURCE=E_ExtendedLayout_OnDelegate.fs - [] - let ``E_ExtendedLayout_OnDelegate_fs`` compilation = - compilation - |> verifyCompile - |> shouldFail - |> withSingleDiagnostic (Error 3881, Line 6, Col 6, Line 6, Col 21, "Only structs may be given the 'ExtendedLayoutAttribute'") - - // SOURCE=E_ExtendedLayout_WithStructLayout.fs - [] - let ``E_ExtendedLayout_WithStructLayout_fs`` compilation = - compilation - |> verifyCompile - |> shouldFail - |> withSingleDiagnostic (Error 3879, Line 8, Col 6, Line 8, Col 24, "The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type") - - // SOURCE=E_ExtendedLayout_FieldOffset.fs - [] - let ``E_ExtendedLayout_FieldOffset_fs`` compilation = - compilation - |> verifyCompile - |> shouldFail - |> withSingleDiagnostic (Error 1211, Line 10, Col 9, Line 10, Col 24, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)") - // SOURCE=E_StructLayout_Extended.fs [] let ``E_StructLayout_Extended_fs`` compilation = compilation |> verifyCompile |> shouldFail - |> withSingleDiagnostic (Error 3882, Line 6, Col 16, Line 6, Col 37, "LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead.") + |> withSingleDiagnostic (Error 3882, Line 7, Col 6, Line 7, Col 36, "LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead.") [] let ``StructLayoutAttribute has size=1 for struct DUs with no instance fields`` () = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs deleted file mode 100644 index 07cf6d7d439..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_FieldOffset.fs +++ /dev/null @@ -1,23 +0,0 @@ -// FieldOffsetAttribute on ExtendedLayout struct field should fail -namespace System.Runtime.InteropServices - -// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing -type ExtendedLayoutKind = - | CStruct = 0 - | CUnion = 1 - -[] -type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = - inherit System.Attribute() - member _.Kind = kind - -namespace Test - -open System.Runtime.InteropServices - -[] -type InvalidFieldOffset = - struct - [] - val mutable X: int - end diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs deleted file mode 100644 index 5fb6b77d530..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnClass.fs +++ /dev/null @@ -1,20 +0,0 @@ -// ExtendedLayoutAttribute on class should fail -namespace System.Runtime.InteropServices - -// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing -type ExtendedLayoutKind = - | CStruct = 0 - | CUnion = 1 - -[] -type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = - inherit System.Attribute() - member _.Kind = kind - -namespace Test - -open System.Runtime.InteropServices - -[] -type InvalidClass() = - member val X = 0 with get, set diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs deleted file mode 100644 index d3a8e1409ba..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnDelegate.fs +++ /dev/null @@ -1,19 +0,0 @@ -// ExtendedLayoutAttribute on delegate should fail -namespace System.Runtime.InteropServices - -// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing -type ExtendedLayoutKind = - | CStruct = 0 - | CUnion = 1 - -[] -type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = - inherit System.Attribute() - member _.Kind = kind - -namespace Test - -open System.Runtime.InteropServices - -[] -type InvalidDelegate = delegate of int -> int diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs deleted file mode 100644 index 9ef11be935e..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_OnInterface.fs +++ /dev/null @@ -1,20 +0,0 @@ -// ExtendedLayoutAttribute on interface should fail -namespace System.Runtime.InteropServices - -// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing -type ExtendedLayoutKind = - | CStruct = 0 - | CUnion = 1 - -[] -type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = - inherit System.Attribute() - member _.Kind = kind - -namespace Test - -open System.Runtime.InteropServices - -[] -type IInvalidInterface = - abstract member DoSomething: unit -> unit diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs deleted file mode 100644 index be0957e3846..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_ExtendedLayout_WithStructLayout.fs +++ /dev/null @@ -1,23 +0,0 @@ -// ExtendedLayoutAttribute + StructLayoutAttribute should fail -namespace System.Runtime.InteropServices - -// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing -type ExtendedLayoutKind = - | CStruct = 0 - | CUnion = 1 - -[] -type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = - inherit System.Attribute() - member _.Kind = kind - -namespace Test - -open System.Runtime.InteropServices - -[] -[] -type ConflictingStruct = - struct - val mutable X: int - end diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs deleted file mode 100644 index d1da756af00..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs +++ /dev/null @@ -1,33 +0,0 @@ -// Test: ExtendedLayoutAttribute on struct compiles successfully -namespace System.Runtime.InteropServices - -// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing -// (will be replaced by real runtime types when available) -type ExtendedLayoutKind = - | CStruct = 0 - | CUnion = 1 - -[] -type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = - inherit System.Attribute() - member _.Kind = kind - -namespace Test - -open System.Runtime.InteropServices - -[] -type ValidStruct = - struct - val mutable X: int - val mutable Y: int - end - -// Entry point -module Program = - [] - let main _ = - let mutable s = ValidStruct() - s.X <- 42 - s.Y <- 24 - if s.X = 42 && s.Y = 24 then 0 else 1 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs deleted file mode 100644 index 5f78abb296c..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout_IL.fs +++ /dev/null @@ -1,30 +0,0 @@ -// Test: Verify IL for ExtendedLayoutAttribute -namespace System.Runtime.InteropServices - -// Mock ExtendedLayoutAttribute and ExtendedLayoutKind for testing -type ExtendedLayoutKind = - | CStruct = 0 - | CUnion = 1 - -[] -type ExtendedLayoutAttribute(kind: ExtendedLayoutKind) = - inherit System.Attribute() - member _.Kind = kind - -namespace Test - -open System.Runtime.InteropServices - -[] -type MyExtendedStruct = - struct - val mutable X: int - val mutable Y: float - end - -module Main = - let test () = - let mutable s = MyExtendedStruct() - s.X <- 10 - s.Y <- 20.0 - () diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl index c1b468804d5..560b82fd07b 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl @@ -1617,6 +1617,7 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Sequential: ILTypeDefLayoutInfo It FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Sequential: ILTypeDefLayoutInfo get_Item() FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Tags: Int32 Auto FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Tags: Int32 Explicit +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Tags: Int32 Extended FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Tags: Int32 Sequential FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean Equals(ILTypeDefLayout) FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean Equals(ILTypeDefLayout, System.Collections.IEqualityComparer) @@ -1624,17 +1625,21 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean Equals(System.Object) FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean Equals(System.Object, System.Collections.IEqualityComparer) FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean IsAuto FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean IsExplicit +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean IsExtended FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean IsSequential FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean get_IsAuto() FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean get_IsExplicit() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean get_IsExtended() FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean get_IsSequential() FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Explicit FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Sequential FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Tags FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout Auto +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout Extended FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout NewExplicit(ILTypeDefLayoutInfo) FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout NewSequential(ILTypeDefLayoutInfo) FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout get_Auto() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout get_Extended() FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 CompareTo(ILTypeDefLayout) FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 CompareTo(System.Object) FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 CompareTo(System.Object, System.Collections.IComparer) From cce9acc003fa201e32a3e03ca0ab82ebb69f53ab Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 14 Apr 2026 11:51:42 +0200 Subject: [PATCH 09/20] Fix CI: renumber error codes 3885-3888, move release notes to 11.0.100 - Error codes 3879-3882 were already allocated on main. Renumber ExtendedLayout diagnostics to 3885-3888 and move them to end of FSComp.txt for proper sorting. - Move release notes from 9.0.300.md to 11.0.100.md (correct file). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/release-notes/.FSharp.Compiler.Service/11.0.100.md | 1 + docs/release-notes/.FSharp.Compiler.Service/9.0.300.md | 1 - src/Compiler/FSComp.txt | 8 ++++---- .../BasicGrammarElements/CustomAttributes/Basic/Basic.fs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) 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 6cc50c2822e..f63af0ccbc4 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -45,3 +45,4 @@ * Improvements in error and warning messages: new error FS3885 when `let!`/`use!` is the final expression in a computation expression; new warning FS3886 when a list literal contains a single tuple element (likely missing `;` separator); improved wording for FS0003, FS0025, FS0039, FS0072, FS0247, FS0597, FS0670, FS3082, and SRTP operator-not-in-scope hints. ([PR #19398](https://github.com/dotnet/fsharp/pull/19398)) ### Breaking Changes +* Add ExtendedLayoutAttribute support for future .NET runtime interop. ([PR #19194](https://github.com/dotnet/fsharp/pull/19194)) 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 c8ab62c553d..7f5ab7289d2 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md @@ -45,7 +45,6 @@ * Add a switch to determine whether to generate a default implementation body for overridden method when completing. [PR #18341](https://github.com/dotnet/fsharp/pull/18341) * Use a more accurate range for CE Combine methods. [PR #18394](https://github.com/dotnet/fsharp/pull/18394) * Enable TypeSubsumptionCache for IDE use. [PR #18499](https://github.com/dotnet/fsharp/pull/18499) -* Add ExtendedLayoutAttribute support for future .NET runtime interop. ([PR #19194](https://github.com/dotnet/fsharp/pull/19194)) ### Changed * FSharpCheckFileResults.ProjectContext.ProjectOptions will not be available when using the experimental Transparent Compiler feature. ([PR #18205](https://github.com/dotnet/fsharp/pull/18205)) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 0f80dd78ad3..59e4428f791 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -785,10 +785,6 @@ tcTypeAbbreviationHasTypeParametersMissingOnType,"This type abbreviation has one 935,tcAllowNullTypesMayOnlyInheritFromAllowNullTypes,"Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal" 936,tcGenericTypesCannotHaveStructLayout,"Generic types cannot be given the 'StructLayout' attribute" 937,tcOnlyStructsCanHaveStructLayout,"Only structs and classes without primary constructors may be given the 'StructLayout' attribute" -3879,tcStructLayoutAndExtendedLayout,"The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type" -3880,tcRuntimeDoesNotSupportExtendedLayoutTypes,"The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime." -3881,tcOnlyStructsCanHaveExtendedLayout,"Only structs may be given the 'ExtendedLayoutAttribute'" -3882,tcInvalidStructLayoutExtendedKind,"LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead." 938,tcRepresentationOfTypeHiddenBySignature,"The representation of this type is hidden by the signature. It must be given an attribute such as [], [] or [] to indicate the characteristics of the type." 939,tcOnlyClassesCanHaveAbstract,"Only classes may be given the 'AbstractClass' attribute" 940,tcOnlyTypesRepresentingUnitsOfMeasureCanHaveMeasure,"Only types representing units-of-measure may be given the 'Measure' attribute" @@ -1821,3 +1817,7 @@ featurePreprocessorElif,"#elif preprocessor directive" 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,parsLetBangCannotBeLastInCE,"'%s' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression." 3886,tcListLiteralWithSingleTupleElement,"This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements?" +3887,tcStructLayoutAndExtendedLayout,"The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type" +3888,tcRuntimeDoesNotSupportExtendedLayoutTypes,"The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime." +3889,tcOnlyStructsCanHaveExtendedLayout,"Only structs may be given the 'ExtendedLayoutAttribute'" +3890,tcInvalidStructLayoutExtendedKind,"LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead." diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs index cf66bb022a1..d9724ee6d92 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs @@ -387,7 +387,7 @@ module CustomAttributes_Basic = compilation |> verifyCompile |> shouldFail - |> withSingleDiagnostic (Error 3882, Line 7, Col 6, Line 7, Col 36, "LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead.") + |> withSingleDiagnostic (Error 3890, Line 7, Col 6, Line 7, Col 36, "LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead.") [] let ``StructLayoutAttribute has size=1 for struct DUs with no instance fields`` () = From 23d6094280b1664bd0d334b6d94efa9c31579762 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 14 Apr 2026 12:02:37 +0200 Subject: [PATCH 10/20] Review fixes: correct ECMA-335 comment, clarify hasLayout and dead code - il.fs: Replace incorrect 'ECMA-335 spec' reference with runtime issue link (0x18 Extended layout is a .NET runtime extension, not in ECMA-335) - ilread.fs: Add comment explaining why hasLayout only matches Explicit - CheckDeclarations.fs: Document unreachable None branch in runtime check Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Compiler/AbstractIL/il.fs | 2 +- src/Compiler/AbstractIL/ilread.fs | 2 ++ src/Compiler/Checking/CheckDeclarations.fs | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 593c975636d..8be49a4d2b5 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -2685,7 +2685,7 @@ let convertLayout layout = | ILTypeDefLayout.Explicit _ -> TypeAttributes.ExplicitLayout | ILTypeDefLayout.Extended -> // Extended layout is represented by TypeAttributes value 0x18 (both Sequential and Explicit bits set) - // This is defined by the ECMA-335 spec for extended layout types + // See: https://github.com/dotnet/runtime/issues/102727 enum (0x18) let convertEncoding encoding = diff --git a/src/Compiler/AbstractIL/ilread.fs b/src/Compiler/AbstractIL/ilread.fs index c75348c2a08..9f5206cde1b 100644 --- a/src/Compiler/AbstractIL/ilread.fs +++ b/src/Compiler/AbstractIL/ilread.fs @@ -2136,6 +2136,8 @@ and typeDefReader ctxtH : ILTypeDefStored = let super = seekReadSuperType ctxt numTypars AsObject extendsIdx let layout = typeLayoutOfFlags ctxt mdv flags idx + // Only Explicit layout has per-field offsets in the FieldLayout metadata table. + // Sequential and Extended layouts don't use FieldLayout rows. let hasLayout = match layout with | ILTypeDefLayout.Explicit _ -> true diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 66f9a1ab5e8..9b0913c7092 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3460,7 +3460,8 @@ module EstablishTypeDefinitionCores = let extendedLayoutAttributeCheck () = if hasExtendedLayoutAttr then - // Check runtime support + // Note: hasExtendedLayoutAttr is only true when attrib_ExtendedLayoutAttribute_opt is Some, + // so the None branch below is currently unreachable. Kept as a defensive check. match g.attrib_ExtendedLayoutAttribute_opt with | None -> errorR (Error(FSComp.SR.tcRuntimeDoesNotSupportExtendedLayoutTypes(), m)) From 23e253329be4062251ef4fcb1a40158bd3a62634 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 16 Apr 2026 08:13:23 +0200 Subject: [PATCH 11/20] Add missing noExtendedLayoutAttributeCheck for unions, records, enums, and other type kinds - Add noExtendedLayoutAttributeCheck() to hiddenReprChecks, Union, Record, Enum, LibraryOnlyILAssembly, and TyconCoreAbbrevThatIsReallyAUnion paths - Without this, ExtendedLayoutAttribute on non-struct types (when .NET 11 ships the attribute) would be silently accepted instead of raising FS3887 - Remove dead code: unreachable None branch in extendedLayoutAttributeCheck (hasExtendedLayoutAttr is false when attrib_ExtendedLayoutAttribute_opt is None, making the inner match redundant) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Compiler/Checking/CheckDeclarations.fs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 9b0913c7092..42c550048f9 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3460,13 +3460,6 @@ module EstablishTypeDefinitionCores = let extendedLayoutAttributeCheck () = if hasExtendedLayoutAttr then - // Note: hasExtendedLayoutAttr is only true when attrib_ExtendedLayoutAttribute_opt is Some, - // so the None branch below is currently unreachable. Kept as a defensive check. - match g.attrib_ExtendedLayoutAttribute_opt with - | None -> - errorR (Error(FSComp.SR.tcRuntimeDoesNotSupportExtendedLayoutTypes(), m)) - | Some _ -> () - // Check not combined with StructLayoutAttribute if structLayoutAttr.IsSome then errorR (Error(FSComp.SR.tcStructLayoutAndExtendedLayout(), m)) @@ -3477,6 +3470,7 @@ module EstablishTypeDefinitionCores = let hiddenReprChecks hasRepr = structLayoutAttributeCheck false + noExtendedLayoutAttributeCheck() if hasSealedAttr = Some false || (hasRepr && hasSealedAttr <> Some true && not (id.idText = "Unit" && g.compilingFSharpCore) ) then errorR(Error(FSComp.SR.tcRepresentationOfTypeHiddenBySignature(), m)) if hasAbstractAttr then @@ -3570,6 +3564,7 @@ module EstablishTypeDefinitionCores = | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) (unionCaseName, _) -> structLayoutAttributeCheck false + noExtendedLayoutAttributeCheck() noAllowNullLiteralAttributeCheck() let hasRQAAttribute = EntityHasWellKnownAttribute cenv.g WellKnownEntityAttributes.RequireQualifiedAccessAttribute tycon @@ -3603,6 +3598,7 @@ module EstablishTypeDefinitionCores = noAbstractClassAttributeCheck() noAllowNullLiteralAttributeCheck() structLayoutAttributeCheck false + noExtendedLayoutAttributeCheck() let hasRQAAttribute = EntityHasWellKnownAttribute cenv.g WellKnownEntityAttributes.RequireQualifiedAccessAttribute tycon let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst hasRQAAttribute tpenv unionCases @@ -3619,6 +3615,7 @@ module EstablishTypeDefinitionCores = noAbstractClassAttributeCheck() noAllowNullLiteralAttributeCheck() structLayoutAttributeCheck true // these are allowed for records + noExtendedLayoutAttributeCheck() let recdFields = TcRecdUnionAndEnumDeclarations.TcNamedFieldDecls cenv envinner innerParent false tpenv fields recdFields |> CheckDuplicates (fun f -> f.Id) "field" |> ignore writeFakeRecordFieldsToSink recdFields @@ -3641,6 +3638,7 @@ module EstablishTypeDefinitionCores = noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedAssemblyCode noAllowNullLiteralAttributeCheck() structLayoutAttributeCheck false + noExtendedLayoutAttributeCheck() noAbstractClassAttributeCheck() TAsmRepr s, None, NoSafeInitInfo @@ -3806,6 +3804,7 @@ module EstablishTypeDefinitionCores = let fieldTy, fields' = TcRecdUnionAndEnumDeclarations.TcEnumDecls cenv envinner tpenv innerParent thisTy decls let kind = TFSharpEnum structLayoutAttributeCheck false + noExtendedLayoutAttributeCheck() noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedEnum noAllowNullLiteralAttributeCheck() let vid = ident("value__", m) From 8097e76693b323d9e959bbf1c9148a102d5d628c Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 20 Apr 2026 17:08:17 +0200 Subject: [PATCH 12/20] Remove unused error 3886, improve release notes - Remove dead error tcRuntimeDoesNotSupportExtendedLayoutTypes (3886) that was defined in FSComp.txt and all xlf files but never referenced in source code. The runtime support check is implicitly handled by tryFindSysAttrib returning None when the attribute doesn't exist in the target runtime. - Update release notes to mention ILTypeDefLayout.Extended API surface change and link to the tracking issue. - Fix release notes formatting (remove stray blank line). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/release-notes/.FSharp.Compiler.Service/11.0.100.md | 1 + src/Compiler/FSComp.txt | 5 ++--- src/Compiler/xlf/FSComp.txt.cs.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.de.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.es.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.fr.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.it.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.ja.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.ko.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.pl.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.ru.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.tr.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 7 +------ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 7 +------ .../BasicGrammarElements/CustomAttributes/Basic/Basic.fs | 2 +- 16 files changed, 17 insertions(+), 82 deletions(-) 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 f63af0ccbc4..7114876dc0e 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -46,3 +46,4 @@ ### Breaking Changes * Add ExtendedLayoutAttribute support for future .NET runtime interop. ([PR #19194](https://github.com/dotnet/fsharp/pull/19194)) +* Add `ExtendedLayoutAttribute` support for future .NET runtime interop. `ILTypeDefLayout` has a new `Extended` case. ([Issue #19190](https://github.com/dotnet/fsharp/issues/19190), [PR #19194](https://github.com/dotnet/fsharp/pull/19194)) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 59e4428f791..38a44477f40 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1818,6 +1818,5 @@ featurePreprocessorElif,"#elif preprocessor directive" 3885,parsLetBangCannotBeLastInCE,"'%s' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression." 3886,tcListLiteralWithSingleTupleElement,"This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements?" 3887,tcStructLayoutAndExtendedLayout,"The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type" -3888,tcRuntimeDoesNotSupportExtendedLayoutTypes,"The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime." -3889,tcOnlyStructsCanHaveExtendedLayout,"Only structs may be given the 'ExtendedLayoutAttribute'" -3890,tcInvalidStructLayoutExtendedKind,"LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead." +3888,tcOnlyStructsCanHaveExtendedLayout,"Only structs may be given the 'ExtendedLayoutAttribute'" +3889,tcInvalidStructLayoutExtendedKind,"LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index abdf625de07..685aaa76e39 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ Použití obnovitelného kódu nebo obnovitelných stavových strojů vyžaduje /langversion:preview. - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Nelze volat „{0}“ - metodu setter pro vlastnost pouze init. Použijte místo toho inicializaci objektu. Viz https://aka.ms/fsharp-assigning-values-to-properties-at-initialization diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 5b04178b021..7dd19f7db72 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ Die Verwendung von Fortsetzbarem Code oder fortsetzbaren Zustandscomputern erfordert /langversion:preview - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization „{0}“ kann nicht aufgerufen werden – ein Setter für die Eigenschaft nur für die Initialisierung. Bitte verwenden Sie stattdessen die Objektinitialisierung. Siehe https://aka.ms/fsharp-assigning-values-to-properties-at-initialization diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 31ea1e9fc51..2c35913c7b7 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ El uso de código reanudable o de máquinas de estado reanudables requiere /langversion:preview - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization No se puede llamar a '{0}': un establecedor para una propiedad de solo inicialización. Use la inicialización del objeto en su lugar. Ver https://aka.ms/fsharp-assigning-values-to-properties-at-initialization diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 880bf6219d8..9b7d6523806 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ L’utilisation de code pouvant être repris ou de machines d’état pouvant être reprises nécessite /langversion:preview - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Nous n’avons pas pu appeler '{0}' - méthode setter pour la propriété init-only. Utilisez plutôt l’initialisation d’objet. Consultez https://aka.ms/fsharp-assigning-values-to-properties-at-initialization. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index ec5bff8a673..d5399a86193 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ Per l'uso del codice ripristinabile o delle macchine a stati ripristinabili è richiesto /langversion:preview - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Non è possibile chiamare '{0}', un setter per la proprietà init-only. Usare invece l'inizializzazione dell'oggetto. Vedere https://aka.ms/fsharp-assigning-values-to-properties-at-initialization diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 4534fee4c36..2fe2ba9b711 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ 再開可能なコードまたは再開可能なステート マシンを使用するには、/langversion:preview が必要です - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization '{0}' を呼び出すことはできません。これは init のみのプロパティのセッターなので、代わりにオブジェクトの初期化を使用してください。https://aka.ms/fsharp-assigning-values-to-properties-at-initialization を参照してください。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 717c3031253..91119cd5911 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ 다시 시작 가능한 코드 또는 다시 시작 가능한 상태 시스템을 사용하려면 /langversion:preview가 필요합니다. - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization init 전용 속성의 setter인 '{0}'을(를) 호출할 수 없습니다. 개체 초기화를 대신 사용하세요. https://aka.ms/fsharp-assigning-values-to-properties-at-initialization를 참조하세요. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 4d61eb5d1d0..3b739a33ad7 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ Używanie kodu z możliwością wznowienia lub automatów stanów z możliwością wznowienia wymaga parametru /langversion: wersja zapoznawcza - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Nie można wywołać „{0}” — metody ustawiającej dla właściwości tylko do inicjowania. Zamiast tego użyj inicjowania obiektu. Zobacz https://aka.ms/fsharp-assigning-values-to-properties-at-initialization diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 675a900216a..588e6adf3f0 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ Usar código retomável ou máquinas de estado retomável requer /langversion:preview - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Não é possível chamar '{0}' – um setter da propriedade somente inicialização, use a inicialização de objeto. Confira https://aka.ms/fsharp-assigning-values-to-properties-at-initialization diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 0ae415d495e..450fdb7340e 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ Для использования возобновляемого кода или возобновляемых конечных автоматов требуется /langversion:preview - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Не удается вызвать '{0}' — установщик для свойства только для инициализации, вместо этого используйте инициализацию объекта. См. https://aka.ms/fsharp-assigning-values-to-properties-at-initialization. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index fa73f81e287..c3b53745d33 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ Sürdürülebilir kod veya sürdürülebilir durum makinelerini kullanmak için /langversion:preview gerekir - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization Yalnızca başlatma özelliği için ayarlayıcı olan '{0}' çağrılamaz, lütfen bunun yerine nesne başlatmayı kullanın. bkz. https://aka.ms/fsharp-assigning-values-to-properties-at-initialization diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 46ff5c04b66..794f6fa4b1f 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ 使用可恢复代码或可恢复状态机需要 /langversion:preview - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization 无法调用 "{0}",它是仅限 init 属性的资源库,请改用对象初始化。请参阅 https://aka.ms/fsharp-assigning-values-to-properties-at-initialization diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index b379d366a17..19b1ec17fcb 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1,4 +1,4 @@ - + @@ -1772,11 +1772,6 @@ 使用可繼續的程式碼或可繼續的狀態機器需要 /langversion:preview - - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - The target runtime does not support extended layout types. ExtendedLayoutAttribute requires a newer runtime. - - Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization 無法呼叫 '{0}' - 僅初始化屬性的 setter,請改為使用物件初始化。請參閱 https://aka.ms/fsharp-assigning-values-to-properties-at-initialization diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs index d9724ee6d92..8c83ca2cadd 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs @@ -387,7 +387,7 @@ module CustomAttributes_Basic = compilation |> verifyCompile |> shouldFail - |> withSingleDiagnostic (Error 3890, Line 7, Col 6, Line 7, Col 36, "LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead.") + |> withSingleDiagnostic (Error 3889, Line 7, Col 6, Line 7, Col 36, "LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead.") [] let ``StructLayoutAttribute has size=1 for struct DUs with no instance fields`` () = From b30c638b99363a01ac8d4f0609ba02aca376c0b4 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 21 Apr 2026 08:48:17 +0200 Subject: [PATCH 13/20] Remove duplicate release notes entry 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 deletion(-) 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 7114876dc0e..d9a7c64e12b 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -45,5 +45,4 @@ * Improvements in error and warning messages: new error FS3885 when `let!`/`use!` is the final expression in a computation expression; new warning FS3886 when a list literal contains a single tuple element (likely missing `;` separator); improved wording for FS0003, FS0025, FS0039, FS0072, FS0247, FS0597, FS0670, FS3082, and SRTP operator-not-in-scope hints. ([PR #19398](https://github.com/dotnet/fsharp/pull/19398)) ### Breaking Changes -* Add ExtendedLayoutAttribute support for future .NET runtime interop. ([PR #19194](https://github.com/dotnet/fsharp/pull/19194)) * Add `ExtendedLayoutAttribute` support for future .NET runtime interop. `ILTypeDefLayout` has a new `Extended` case. ([Issue #19190](https://github.com/dotnet/fsharp/issues/19190), [PR #19194](https://github.com/dotnet/fsharp/pull/19194)) From cee99f5797e13f3a10ca43915a8236ba90dd98b2 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 21 Apr 2026 10:47:51 +0200 Subject: [PATCH 14/20] Review fixes: add missing noExtendedLayoutAttributeCheck for type abbreviations, update comments - Add noExtendedLayoutAttributeCheck() to TypeAbbrev path (was missing) - Update stale comment: LayoutKind.Extended is now in .NET 11+ (not future) - Clarify FieldOffset rejection comment with rationale Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Compiler/Checking/CheckDeclarations.fs | 5 +++-- src/Compiler/CodeGen/IlxGen.fs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 42c550048f9..13cdaea61c3 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3441,7 +3441,7 @@ module EstablishTypeDefinitionCores = let structLayoutAttributeCheck allowed = let explicitKind = int32 System.Runtime.InteropServices.LayoutKind.Explicit - // LayoutKind.Extended will have enum value 1 in future .NET versions (currently unused slot) + // LayoutKind.Extended has enum value 1 in .NET 11+ (previously unused slot) // It cannot be specified via StructLayoutAttribute - users must use ExtendedLayoutAttribute instead // See: https://github.com/dotnet/runtime/issues/102727 let extendedLayoutKind = 1 @@ -3581,7 +3581,8 @@ module EstablishTypeDefinitionCores = errorR (Error(FSComp.SR.tcAbbreviatedTypesCannotBeSealed(), m)) noAbstractClassAttributeCheck() noAllowNullLiteralAttributeCheck() - if hasMeasureableAttr then + noExtendedLayoutAttributeCheck() + if hasMeasureableAttr then let kind = if hasMeasureAttr then TyparKind.Measure else TyparKind.Type let theTypeAbbrev, _ = TcTypeOrMeasureAndRecover (Some kind) cenv NoNewTypars CheckCxs ItemOccurrence.UseInType WarnOnIWSAM.No envinner tpenv rhsType diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 85d229a823f..8402690b3df 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -11924,7 +11924,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option match tdLayout with | ILTypeDefLayout.Explicit _ -> List.iter validateExplicit ilFieldDefs | ILTypeDefLayout.Sequential _ -> List.iter validateSequential ilFieldDefs - | ILTypeDefLayout.Extended -> List.iter validateSequential ilFieldDefs // Extended layout also disallows FieldOffset + | ILTypeDefLayout.Extended -> List.iter validateSequential ilFieldDefs // Extended layout manages field layout via the attribute; FieldOffset is not allowed | _ -> () let tdef = From fcaaa81920f53ef6fd1932e4c95410d320758372 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 18 Aug 2026 12:27:43 +0200 Subject: [PATCH 15/20] Remove accidentally committed session artifacts (.copilot-prompt.txt, .executor-pid) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .copilot-prompt.txt | 36 ------------------------------------ .executor-pid | 1 - 2 files changed, 37 deletions(-) delete mode 100644 .copilot-prompt.txt delete mode 100644 .executor-pid diff --git a/.copilot-prompt.txt b/.copilot-prompt.txt deleted file mode 100644 index 60ca0aa116f..00000000000 --- a/.copilot-prompt.txt +++ /dev/null @@ -1,36 +0,0 @@ -### TASK: Resolve merge conflicts on PR #19194 by merging `origin/main` INTO the feature branch. - -### CRITICAL SAFETY — VIOLATION = CATASTROPHIC -- WORK ON THE PR FEATURE BRANCH ONLY. -- **NEVER** check out, commit to, or push to `main`. - -### STEPS - -1. **Understand the PR** — read description and recent commits to know the PR's intent. - -2. **Merge main INTO the feature branch** (not the other way around): - ``` - git fetch origin main - git merge origin/main --no-edit - ``` - -3. **Resolve conflicts** — edit conflicted files: - - Keep the PR's new functionality where it adds something new. - - Accept main's version for unrelated changes (renames, refactors). - - Watch for semantic clashes (renamed/moved APIs). - -4. **Verify** — `dotnet build` must succeed. - -5. **Safety check and push**: - ``` - BRANCH=$(git branch --show-current) - if [ "$BRANCH" = "main" ] || [ -z "$BRANCH" ]; then echo "FATAL: wrong branch"; exit 1; fi - git add -u - git diff --cached --stat - git commit -m "Merge main to resolve conflicts" - git push origin HEAD - ``` - -### CONSTRAINTS -- Do NOT force-push. Do NOT rebase. Just merge. -- Do NOT modify code beyond what's needed to resolve conflicts. \ No newline at end of file diff --git a/.executor-pid b/.executor-pid deleted file mode 100644 index e966df5c13f..00000000000 --- a/.executor-pid +++ /dev/null @@ -1 +0,0 @@ -24680 \ No newline at end of file From 2f0f10cdd42e79647c116594c83850ae9d92ea1e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 18 Aug 2026 12:42:44 +0200 Subject: [PATCH 16/20] Add end-to-end ExtendedLayoutAttribute tests against net11 BCL Now that the repo targets net11.0, System.Runtime.InteropServices.ExtendedLayoutAttribute is available in the referenced BCL, so the feature can be exercised end-to-end: - positive: struct with [] emits the 0x18 type layout flag and preserves the attribute on the emitted type (verified by reading metadata via System.Reflection.Metadata) - ExtendedLayout + StructLayout combined -> FS3910 - ExtendedLayout on class/interface/record/union/enum/delegate -> FS3911 - FieldOffset on an ExtendedLayout struct -> FS1211 Tests requiring the net11 attribute are gated behind NETCOREAPP. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../CustomAttributes/Basic/ExtendedLayout.fs | 213 ++++++++++++++++++ .../FSharp.Compiler.ComponentTests.fsproj | 1 + 2 files changed, 214 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs new file mode 100644 index 00000000000..8da81c17e8c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs @@ -0,0 +1,213 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Conformance.BasicGrammarElements + +open Xunit +open FSharp.Test.Compiler + +#if NETCOREAPP +open System.IO +open System.Reflection +open System.Reflection.Metadata +open System.Reflection.PortableExecutable +#endif + +module CustomAttributes_ExtendedLayout = + +#if NETCOREAPP + // System.Runtime.InteropServices.ExtendedLayoutAttribute / ExtendedLayoutKind only exist starting with .NET 11, + // so these tests are gated to the .NET (Core) test flavor where that BCL is referenced. + + let private getOutputPath result = + match result with + | CompilationResult.Success success -> + match success.OutputPath with + | Some path -> path + | None -> failwith "Compilation succeeded but produced no output path." + | CompilationResult.Failure failure -> + failwithf "Compilation was expected to succeed, but failed with: %A" failure.Diagnostics + + let private findType (reader: MetadataReader) name = + reader.TypeDefinitions + |> Seq.map reader.GetTypeDefinition + |> Seq.find (fun td -> reader.GetString td.Name = name) + + let private customAttributeTypeName (reader: MetadataReader) (ca: CustomAttribute) = + match ca.Constructor.Kind with + | HandleKind.MemberReference -> + let mref = reader.GetMemberReference(MemberReferenceHandle.op_Explicit ca.Constructor) + match mref.Parent.Kind with + | HandleKind.TypeReference -> + let tref = reader.GetTypeReference(TypeReferenceHandle.op_Explicit mref.Parent) + reader.GetString tref.Namespace + "." + reader.GetString tref.Name + | _ -> "" + | _ -> "" + + [] + let ``ExtendedLayout on a struct emits the 0x18 layout flag and preserves the attribute`` () = + let output = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type CStructLike = + struct + val mutable X: int + val mutable Y: int + end +""" + |> asLibrary + |> compile + |> shouldSucceed + |> getOutputPath + + use stream = File.OpenRead output + use peReader = new PEReader(stream) + let reader = peReader.GetMetadataReader() + let typeDef = findType reader "CStructLike" + + // The extended layout is encoded as TypeAttributes value 0x18 (both the sequential and explicit layout bits set). + let layout = typeDef.Attributes &&& TypeAttributes.LayoutMask + Assert.Equal(0x18, int layout) + + // ExtendedLayoutAttribute is a real user-written attribute and must be preserved on the emitted type. + let preserved = + typeDef.GetCustomAttributes() + |> Seq.map reader.GetCustomAttribute + |> Seq.exists (fun ca -> customAttributeTypeName reader ca = "System.Runtime.InteropServices.ExtendedLayoutAttribute") + Assert.True(preserved, "ExtendedLayoutAttribute should be preserved on the emitted type.") + + [] + let ``ExtendedLayout and StructLayout cannot be combined on the same type`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +[] +type BothAttrs = + struct + val mutable X: int + end +""" + |> asLibrary + |> compile + |> shouldFail + |> withSingleDiagnostic (Error 3910, Line 8, Col 6, Line 8, Col 15, "The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type") + + [] + let ``ExtendedLayout on a class is rejected`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type NotAStruct() = + member _.X = 1 +""" + |> asLibrary + |> compile + |> shouldFail + |> withErrorCode 3911 + |> withErrorMessage "Only structs may be given the 'ExtendedLayoutAttribute'" + + [] + let ``ExtendedLayout on an interface is rejected`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type IExtended = + abstract M: unit -> int +""" + |> asLibrary + |> compile + |> shouldFail + |> withErrorCode 3911 + + [] + let ``ExtendedLayout on a record is rejected`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type R = { X: int } +""" + |> asLibrary + |> compile + |> shouldFail + |> withErrorCode 3911 + + [] + let ``ExtendedLayout on a union is rejected`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type U = A | B +""" + |> asLibrary + |> compile + |> shouldFail + |> withErrorCode 3911 + + [] + let ``ExtendedLayout on an enum is rejected`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type E = + | A = 0 + | B = 1 +""" + |> asLibrary + |> compile + |> shouldFail + |> withErrorCode 3911 + + [] + let ``ExtendedLayout on a delegate is rejected`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type D = delegate of int -> int +""" + |> asLibrary + |> compile + |> shouldFail + |> withErrorCode 3911 + + [] + let ``FieldOffset is not allowed on an ExtendedLayout struct`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type WithOffset = + struct + [] val mutable X: int + end +""" + |> asLibrary + |> compile + |> shouldFail + |> withErrorCode 1211 +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 2d033e260dc..ea451cb418d 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -42,6 +42,7 @@ + From 122c43707740545c48207e037abae6f6862dfcc5 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 18 Aug 2026 13:12:18 +0200 Subject: [PATCH 17/20] Allow ExtendedLayoutAttribute on [] records Review of the ExtendedLayoutAttribute feature found that [] records (which are value types) were rejected with FS3911 'Only structs may be given the ExtendedLayoutAttribute' - a message that contradicts itself, since a [] record IS a struct. This was inconsistent with plain structs and struct...end syntax (both allowed) and with StructLayoutAttribute, which is allowed on struct records. The Record simple-representation case now routes ExtendedLayout through the struct-aware check: [] records accept it (emitting the 0x18 layout flag and preserving the attribute, subject to the existing StructLayout-conflict error), while reference-typed records still reject it. Discriminated unions remain rejected on purpose: an F# struct DU carries a tag plus non-overlapping per-case fields, so ExtendedLayoutKind.CUnion would overlap the tag with data and produce a broken type. This also matches the existing policy that StructLayoutAttribute is disallowed on unions. Adds regression tests: struct record emits 0x18 + preserves the attribute, struct record + StructLayout -> FS3910, struct union -> FS3911; the existing record-rejection test is clarified to reference records. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/Compiler/Checking/CheckDeclarations.fs | 9 ++- .../CustomAttributes/Basic/ExtendedLayout.fs | 62 ++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index d0c191167ec..206f636dc26 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3552,6 +3552,7 @@ module EstablishTypeDefinitionCores = | Some attrib -> HasFSharpAttribute g attrib attrs | None -> false let hasAllowNullLiteralAttr = hasFlag entityFlags WellKnownEntityAttributes.AllowNullLiteralAttribute_True + let hasStructAttr = hasFlag entityFlags WellKnownEntityAttributes.StructAttribute if hasAbstractAttr then tycon.TypeContents.tcaug_abstract <- true @@ -3597,6 +3598,12 @@ module EstablishTypeDefinitionCores = let noExtendedLayoutAttributeCheck () = if hasExtendedLayoutAttr then errorR (Error(FSComp.SR.tcOnlyStructsCanHaveExtendedLayout(), m)) + + // Records become value types when marked []. Extended layout is valid on those + // (subject to the StructLayout conflict check); reference-typed records still reject it. + let recordExtendedLayoutAttributeCheck () = + if hasStructAttr then extendedLayoutAttributeCheck () + else noExtendedLayoutAttributeCheck () let hiddenReprChecks hasRepr = structLayoutAttributeCheck false @@ -3746,7 +3753,7 @@ module EstablishTypeDefinitionCores = noAbstractClassAttributeCheck() noAllowNullLiteralAttributeCheck() structLayoutAttributeCheck true // these are allowed for records - noExtendedLayoutAttributeCheck() + recordExtendedLayoutAttributeCheck() let check pass = let firstPass = pass = FirstPass diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs index 8da81c17e8c..fd6043776d5 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs @@ -79,6 +79,51 @@ type CStructLike = |> Seq.exists (fun ca -> customAttributeTypeName reader ca = "System.Runtime.InteropServices.ExtendedLayoutAttribute") Assert.True(preserved, "ExtendedLayoutAttribute should be preserved on the emitted type.") + [] + let ``ExtendedLayout on a struct record emits the 0x18 layout flag and preserves the attribute`` () = + let output = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type StructRecord = { X: int; Y: int } +""" + |> asLibrary + |> compile + |> shouldSucceed + |> getOutputPath + + use stream = File.OpenRead output + use peReader = new PEReader(stream) + let reader = peReader.GetMetadataReader() + let typeDef = findType reader "StructRecord" + + let layout = typeDef.Attributes &&& TypeAttributes.LayoutMask + Assert.Equal(0x18, int layout) + + let preserved = + typeDef.GetCustomAttributes() + |> Seq.map reader.GetCustomAttribute + |> Seq.exists (fun ca -> customAttributeTypeName reader ca = "System.Runtime.InteropServices.ExtendedLayoutAttribute") + Assert.True(preserved, "ExtendedLayoutAttribute should be preserved on the emitted struct record.") + + [] + let ``ExtendedLayout and StructLayout cannot be combined on a struct record`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type BothOnRecord = { X: int } +""" + |> asLibrary + |> compile + |> shouldFail + |> withErrorCode 3910 + [] let ``ExtendedLayout and StructLayout cannot be combined on the same type`` () = FSharp """ @@ -132,7 +177,7 @@ type IExtended = |> withErrorCode 3911 [] - let ``ExtendedLayout on a record is rejected`` () = + let ``ExtendedLayout on a reference record is rejected`` () = FSharp """ namespace Test @@ -155,6 +200,21 @@ open System.Runtime.InteropServices [] type U = A | B +""" + |> asLibrary + |> compile + |> shouldFail + |> withErrorCode 3911 + + [] + let ``ExtendedLayout on a struct union is rejected`` () = + FSharp """ +namespace Test + +open System.Runtime.InteropServices + +[] +type U = A of x: int | B of y: int """ |> asLibrary |> compile From 0eceb1c869804f0b14d223e5ece0e9998709d22e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 18 Aug 2026 13:39:15 +0200 Subject: [PATCH 18/20] Give discriminated unions a dedicated ExtendedLayoutAttribute diagnostic Follow-up to the [] record fix: a [] discriminated union was still rejected with FS3911 'Only structs may be given the ExtendedLayoutAttribute' - the same self-contradiction, since a [] union IS a struct. Adds FS3913 'The ExtendedLayoutAttribute cannot be applied to discriminated unions' and routes both union declaration forms (SynTypeDefnSimpleRepr.Union and the single-case core-abbreviation union) through it. The message is accurate for struct and reference unions alike: a union carries a case tag plus per-case fields, which is incompatible with the CStruct/CUnion field layout, so extended layout is never valid on a union regardless of value-type-ness. Updates the two union regression tests to assert FS3913; adds the xlf entries. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/Compiler/Checking/CheckDeclarations.fs | 10 ++++++++-- src/Compiler/FSComp.txt | 1 + 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 +++++ .../CustomAttributes/Basic/ExtendedLayout.fs | 6 ++++-- 16 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 206f636dc26..6276e6f4345 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3604,6 +3604,12 @@ module EstablishTypeDefinitionCores = let recordExtendedLayoutAttributeCheck () = if hasStructAttr then extendedLayoutAttributeCheck () else noExtendedLayoutAttributeCheck () + + // A discriminated union (including a [] one) carries a case tag plus per-case fields, + // which is incompatible with the CStruct/CUnion field layout, so extended layout is never valid. + let unionExtendedLayoutAttributeCheck () = + if hasExtendedLayoutAttr then + errorR (Error(FSComp.SR.tcExtendedLayoutCannotBeUsedOnUnions(), m)) let hiddenReprChecks hasRepr = structLayoutAttributeCheck false @@ -3701,7 +3707,7 @@ module EstablishTypeDefinitionCores = | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) (unionCaseName, _) -> structLayoutAttributeCheck false - noExtendedLayoutAttributeCheck() + unionExtendedLayoutAttributeCheck() noAllowNullLiteralAttributeCheck() let hasRQAAttribute = EntityHasWellKnownAttribute cenv.g WellKnownEntityAttributes.RequireQualifiedAccessAttribute tycon @@ -3736,7 +3742,7 @@ module EstablishTypeDefinitionCores = noAbstractClassAttributeCheck() noAllowNullLiteralAttributeCheck() structLayoutAttributeCheck false - noExtendedLayoutAttributeCheck() + unionExtendedLayoutAttributeCheck() let hasRQAAttribute = EntityHasWellKnownAttribute cenv.g WellKnownEntityAttributes.RequireQualifiedAccessAttribute tycon let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst hasRQAAttribute tpenv addFixup unionCases diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index bc0b7720a66..d00b425dd5f 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1850,3 +1850,4 @@ featureRecordSpreads,"record type and expression spreads" 3910,tcStructLayoutAndExtendedLayout,"The attributes 'StructLayoutAttribute' and 'ExtendedLayoutAttribute' cannot be used together on the same type" 3911,tcOnlyStructsCanHaveExtendedLayout,"Only structs may be given the 'ExtendedLayoutAttribute'" 3912,tcInvalidStructLayoutExtendedKind,"LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead." +3913,tcExtendedLayoutCannotBeUsedOnUnions,"The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions" diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 131d36ac0f2..2eb0678cc46 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Použití [<Struct>] u hodnot, funkcí a metod je povolené jenom u částečných aktivních definic vzorů. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 48ac74743f2..2bd360f9e5e 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Die Verwendung von "[<Struct>]" für Werte, Funktionen und Methoden ist nur für partielle aktive Musterdefinitionen zulässig. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index ada85af8cd2..22003e2d225 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions El uso de "[<Struct>]" en valores, funciones y métodos solo se permite en definiciones de modelos activos parciales. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 5c913a4be01..f8c24d8d25e 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions L’utilisation de' [<Struct>] 'sur les valeurs, les fonctions et les méthodes n’est autorisée que sur les définitions de modèle actif partiel diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index da6364cd645..cdcb26698b8 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions L'utilizzo di '[<Struct>]' su valori, funzioni e metodi è consentito solo per definizioni di criteri attivi parziali diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 52d74d6b48c..4faa9c916a6 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions 値、関数、およびメソッドでの '[<Struct>]' は、部分的なアクティブ パターンの定義でのみ使うことができます diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 39f1dc9613b..3d1d0158763 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions 값, 함수 및 메서드에 '[<Struct>]'을(를) 사용하는 것은 부분 활성 패턴 정의에서만 허용됩니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 678f61441e9..9b77586cc57 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Używanie elementu "[<Struct>]" w przypadku wartości, funkcji i metod jest dozwolone tylko w definicjach częściowo aktywnego wzorca diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 6729ded4163..bb3f8738b13 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions O uso de '[<Struct>]' em valores, funções e métodos somente é permitido em definições de padrões ativos parciais diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 4fddac8b605..50fd4214d1d 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Использование '[<Struct>]' для значений, функций и методов разрешено только для определений частичных активных шаблонов diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index eb2cbb18f38..1ec84647182 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions Değerler, işlevler ve yöntemler üzerinde '[<Struct>]' kullanımına yalnızca kısmi etkin model tanımlarında izin verilir diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index c3f6b9e9517..a7a35cd23b3 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions 只允许在部分活动模式定义中对值、函数和方法使用 "[<Struct>]" diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 2cbc213af6a..bf3fdd7f248 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1637,6 +1637,11 @@ LayoutKind value 1 (Extended) cannot be specified via StructLayoutAttribute. Use ExtendedLayoutAttribute instead. + + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions + + The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions 只允許在部分現用模式定義上對值、函式和方法使用 '[<Struct>]' diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs index fd6043776d5..d569d4b11d6 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs @@ -204,7 +204,8 @@ type U = A | B |> asLibrary |> compile |> shouldFail - |> withErrorCode 3911 + |> withErrorCode 3913 + |> withErrorMessage "The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions" [] let ``ExtendedLayout on a struct union is rejected`` () = @@ -219,7 +220,8 @@ type U = A of x: int | B of y: int |> asLibrary |> compile |> shouldFail - |> withErrorCode 3911 + |> withErrorCode 3913 + |> withErrorMessage "The 'ExtendedLayoutAttribute' cannot be applied to discriminated unions" [] let ``ExtendedLayout on an enum is rejected`` () = From 39c5d8ac2f6f06806162fe5ab7bbff5e17b871d8 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 18 Aug 2026 14:11:21 +0200 Subject: [PATCH 19/20] Keep the ExtendedLayout test module non-empty on non-.NET-Core TFMs Every test in CustomAttributes_ExtendedLayout is gated behind #if NETCOREAPP because it needs System.Runtime.InteropServices.ExtendedLayoutAttribute (net11+). On other target frameworks the CI builds (e.g. net472) the module body was entirely excluded, leaving 'module CustomAttributes_ExtendedLayout =' with no members, which fails to compile (FS0010/FS0058). Add a placeholder binding under #if !NETCOREAPP so the module is a valid, non-empty declaration on every target framework while the .NET Core build is unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../CustomAttributes/Basic/ExtendedLayout.fs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs index d569d4b11d6..7cf9cb91a96 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/ExtendedLayout.fs @@ -14,6 +14,13 @@ open System.Reflection.PortableExecutable module CustomAttributes_ExtendedLayout = +#if !NETCOREAPP + // Every test in this module requires System.Runtime.InteropServices.ExtendedLayoutAttribute, + // which only exists starting with .NET 11. On other target frameworks (e.g. net472) the module + // would otherwise be empty, which is not a valid module declaration, so keep one placeholder. + let private _requiresNetCore = () +#endif + #if NETCOREAPP // System.Runtime.InteropServices.ExtendedLayoutAttribute / ExtendedLayoutKind only exist starting with .NET 11, // so these tests are gated to the .NET (Core) test flavor where that BCL is referenced. From e5e13946fc065d7d8dc27a3036e6d6d4120531e1 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 18 Aug 2026 16:38:30 +0200 Subject: [PATCH 20/20] Re-run CI (flaky WindowsNoRealsig_testCoreclr timeout) The WindowsNoRealsig_testCoreclr leg was canceled after ~1h43m on the prior run (pipeline timeout hanging in the full FSharp.Core.UnitTests run). All sibling Windows test legs, including the realsig+ coreclr_release counterpart, passed on the same commit, so this is a flaky infrastructure timeout unrelated to the change. Empty commit to re-trigger the matrix. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>