Draft
Add ExtendedLayoutAttribute support for F# compiler#19194
Conversation
Copilot
AI
changed the title
[WIP] Add ExtendedLayoutAttribute support for F# compiler
Add ExtendedLayoutAttribute support for F# compiler
Jan 6, 2026
T-Gro
reviewed
Jan 6, 2026
jkoritzinsky
reviewed
Jan 6, 2026
Member
|
Note to self: This waits for NET11 alpha to have the attribute available. |
Contributor
❗ Release notes requiredYou can open this PR in browser to add release notes: open in github.dev
|
T-Gro
force-pushed
the
copilot/add-extended-layout-attribute-support
branch
6 times, most recently
from
April 21, 2026 06:44
0625d3d to
1d053ed
Compare
…alidation Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
… IL test Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
- 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>
- 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>
- 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>
…, 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>
- 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>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…reviations, 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>
T-Gro
force-pushed
the
copilot/add-extended-layout-attribute-support
branch
from
April 21, 2026 08:48
8b17336 to
cee99f5
Compare
Resolve conflict in FSComp.txt by keeping main's 3887 (ilCustomAttrInvalidArrayElemType) and renumbering feature branch entries to 3888-3890. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…layout-attribute-support # Conflicts: # src/Compiler/Checking/CheckDeclarations.fs # src/Compiler/FSComp.txt
… .executor-pid) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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 [<ExtendedLayout(ExtendedLayoutKind.CStruct)>] 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>
Review of the ExtendedLayoutAttribute feature found that [<Struct>] records (which are value types) were rejected with FS3911 'Only structs may be given the ExtendedLayoutAttribute' - a message that contradicts itself, since a [<Struct>] 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: [<Struct>] 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>
Follow-up to the [<Struct>] record fix: a [<Struct>] discriminated union was still rejected with FS3911 'Only structs may be given the ExtendedLayoutAttribute' - the same self-contradiction, since a [<Struct>] 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>
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>
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ExtendedLayoutAttribute Support Implementation - COMPLETE ✅
Phase 1: IL Layer Changes ✅
Extendedcase toILTypeDefLayouttype inil.fsiandil.fsconvertLayoutfunction inil.fsto handleExtended→TypeAttributes0x18typeLayoutOfFlagsinilread.fsto read 0x18 flagsGenTypeDefPass3inilwrite.fsto handleExtendedlayouttypeAttributesOfTypeLayoutinilreflect.fsforExtendedsplitTypeLayoutinilprint.fsforExtendedPhase 2: Compiler Infrastructure ✅
attrib_ExtendedLayoutAttribute_opttoTcGlobals.fsandTcGlobals.fsiFSComp.txt(errors 3879-3882) for new validationsPhase 3: Type Checking & Validation ✅
CheckDeclarations.fsPhase 4: IL Generation ✅
IlxGen.fsto detect ExtendedLayoutAttribute and setILTypeDefLayout.ExtendedPhase 5: Testing ✅
Quality Assurance ✅
Implementation Complete
All tasks have been successfully completed. The F# compiler now supports ExtendedLayoutAttribute with:
Original prompt
ExtendedLayoutAttribute Support for F# Compiler
Summary
Add support for
System.Runtime.InteropServices.ExtendedLayoutAttribute, a new .NET runtime feature that allows specifying extended type layouts (like C structs/unions) for interop scenarios. When a user applies[<ExtendedLayout(ExtendedLayoutKind.CStruct)>]to a struct, the compiler must:TypeAttributes.ExtendedLayoutbit (0x18) in metadataStructLayoutAttribute, noFieldOffseton fields, runtime support check)The compiler intentionally does not validate the specific
ExtendedLayoutKindvalues or field types - those semantics are owned by the runtime and may evolve.Reference: #19190
Architecture Overview
The layout information flows through the system as follows:
Implementation Tasks
Task 1: Add Attribute Reference to TcGlobals
Files:
src/Compiler/TypedTree/TcGlobals.fssrc/Compiler/TypedTree/TcGlobals.fsiLocation in TcGlobals.fs: Near line 1489, where
attrib_StructLayoutAttributeis defined.Add:
Location in TcGlobals.fsi: Near line 477, where
attrib_StructLayoutAttributeis declared.Add:
Task 2: Add
ILTypeDefLayout.ExtendedCaseFiles:
src/Compiler/AbstractIL/il.fssrc/Compiler/AbstractIL/il.fsiLocation in il.fsi: Around line 1456, the
ILTypeDefLayouttype definition.Change from:
To:
Location in il.fs: Around line 2517, the
ILTypeDefLayouttype definition. Same change.Location in il.fs: Around line 2630, the
convertLayoutfunction.Change from:
To:
Task 3: Update IL Reading
File:
src/Compiler/AbstractIL/ilread.fsLocation: Around line 2040, the
typeLayoutOfFlagsfunction.Change from:
To:
Task 4: Update IL Writing
File:
src/Compiler/AbstractIL/ilwrite.fsLocation: Around line 2884, in
GenTypeDefPass3, the ClassLayout handling.Change from:
To: