Skip to content

Flatten anonymous bitfield sub-properties (#408 phase 2)#1727

Merged
jevansaks merged 2 commits into
microsoft:mainfrom
JeremyKuhne:feature/408-flatten-bitfields-phase2
Jun 13, 2026
Merged

Flatten anonymous bitfield sub-properties (#408 phase 2)#1727
jevansaks merged 2 commits into
microsoft:mainfrom
JeremyKuhne:feature/408-flatten-bitfields-phase2

Conversation

@JeremyKuhne

@JeremyKuhne JeremyKuhne commented Jun 12, 2026

Copy link
Copy Markdown
Member

Summary

Phase 2 follow-up to #1721. Phase 1 surfaces fields nested in anonymous structs/unions as [UnscopedRef] ref accessors on the declaring struct, but for a bitfield-bearing nested struct only the raw backing field was reachable that way. This forwards the computed bitfield sub-properties (e.g. PSAPI_WORKING_SET_EX_BLOCK''s Valid / ShareCount / Win32Protection) as value get/set properties on the declaring struct, so callers can read and write them directly as value.ShareCount instead of value.Anonymous.Anonymous.ShareCount.

Details

  • Each forwarded property delegates to the nested property (readonly get => this.Anonymous...Prop; set => ... = value;) and inherits its docs via <inheritdoc>.
  • The projected type is computed from the bit width (1 bit -> bool, otherwise the smallest integer of the backing field''s signedness that fits), matching the nested property exactly — so no narrowing occurs even when the backing field is wider (e.g. an nuint backing field with byte/ushort sub-properties).
  • The raw backing field continues to be surfaced as a ref (Phase 1 behavior unchanged; this is purely additive).
  • Only bitfields reached through anonymous holders are forwarded; bitfields under a named holder are not. Gated on C# 11, like the rest of the feature.

Tests

  • Syntax (StructTests): forwarding shape + types on PSAPI_WORKING_SET_EX_BLOCK, a negative case proving the sibling named Invalid holder''s bitfields are not forwarded, and the C# 10 gate.
  • Functional (GenerationSandbox.Tests, compiled & executed): the forwarded properties alias the same storage as the nested path; all nine sub-fields pack without bit overlap (the exact backing-field bit pattern is asserted); and writes to one field do not disturb its neighbors.
  • Validated across net8.0, net472, and net10.0.

Fixes #408

Phase 1 (microsoft#1721) surfaces fields nested in anonymous structs/unions as [UnscopedRef] ref accessors, but only the raw bitfield backing field was reachable that way. This forwards the computed bitfield sub-properties (e.g. PSAPI_WORKING_SET_EX_BLOCK's Valid/ShareCount/Win32Protection) as value get/set properties on the declaring struct, so they can be read and written directly as value.Field instead of value.Anonymous.Anonymous.Field.

Each forwarded property delegates to the nested property (readonly get => this.Anonymous...Prop; set => ... = value) and inherits its docs via <inheritdoc>. The projected type is computed from the bitfield width (1 bit => bool, else smallest fitting integer of the backing field's signedness), matching the nested property exactly, so no narrowing occurs even when the backing field is wider (e.g. nuint backing, byte/ushort sub-properties). The raw backing field continues to be surfaced as a ref (phase 1 behavior is unchanged; this is additive).

Only fields reached through anonymous holders are forwarded; bitfields under a named holder are not. Gated on C# 11 like the rest of the feature.

Adds syntax-shape unit tests (PSAPI_WORKING_SET_EX_BLOCK, including the named-holder negative case and the C# 10 gate) and functional tests proving the forwarded properties alias the same storage, pack without bit overlap (exact backing-field bit pattern asserted), and isolate neighbors. Validated across net8.0, net472, and net10.0.
The aligned trailing comments in FlattenedBitfieldPropertiesPackWithoutOverlap used multiple consecutive spaces, which fails the CI -warnAsError build (SA1025). Collapse to a single space before each comment.
@JeremyKuhne

Copy link
Copy Markdown
Member Author

Fixes #408

@jevansaks

Copy link
Copy Markdown
Member

Fixes #408

The "Fixes" has to go in the description I'm pretty sure (which I did by editing yours)

@jevansaks jevansaks merged commit c434a15 into microsoft:main Jun 13, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fields in Anonymous nested structs should be exposed with property getters on the nesting struct

2 participants