Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
495ab1c
Define WellKnownILAttributes, WellKnownEntityAttributes, WellKnownVal…
T-Gro Feb 20, 2026
27e7424
Add computeILWellKnownFlags and migrate IL attribute check sites
T-Gro Feb 20, 2026
36da613
Fix IL Compute And Migration: scope-safe comparison, TypeHierarchy mi…
T-Gro Feb 20, 2026
8d37941
Add WellKnownEntityAttribs struct and migrate Entity.entity_attribs
T-Gro Feb 20, 2026
9e52b72
Migrate 30 entity-level existence checks to EntityHasWellKnownAttribute
T-Gro Feb 20, 2026
1566246
Sprint 4: Val Container And Infrastructure - WellKnownValAttribs
T-Gro Feb 21, 2026
1ccb290
Sprint 05: Migrate Val/ArgReprInfo-level existence checks to well-kno…
T-Gro Feb 21, 2026
acd72b0
Sprint 6: Hybrid mapping functions and TyconRef migration
T-Gro Feb 21, 2026
5f5a65e
Sprint 7: Final validation fixes - conditional compile mapILFlagToAtt…
T-Gro Feb 21, 2026
2fe9d42
Sprint 7: Fix isByrefLikeTyconRef to use name-based attribute matching
T-Gro Feb 21, 2026
5a99c71
Sprint 7: Fix PostInferenceChecks IsByRefLike to use name-based match…
T-Gro Feb 21, 2026
0c9e88f
Rewrite computeEntityWellKnownFlags with multi-level path dispatch
T-Gro Feb 23, 2026
6e4ad5d
Rewrite computeValWellKnownFlags with multi-level path dispatch
T-Gro Feb 23, 2026
7a42503
Rewrite computeILWellKnownFlags with prefix + string match dispatch
T-Gro Feb 23, 2026
59b64c8
Migrate getAugmentationAttribs to cached WellKnownEntityAttributes flags
T-Gro Feb 25, 2026
af7db93
Migrate remaining existence-only attribute call sites to cached flags
T-Gro Feb 25, 2026
d5358f5
Add missing enum cases to WellKnownEntityAttributes and WellKnownValA…
T-Gro Feb 25, 2026
dc15745
Bool TrueFalse encoding for three-state attributes
T-Gro Feb 25, 2026
e97f7fe
Fix NoDynamicInvocation/ReflectedDefinition default to false (AssumeF…
T-Gro Feb 25, 2026
a978929
Fix ReflectedDefinitionAttribute existence check to include _False flag
T-Gro Feb 25, 2026
7fa711d
Flatten ILAttributesStored: eliminate Computed DU case
T-Gro Feb 25, 2026
cc91bb1
Fast negative guards and perf improvements for attribute checks
T-Gro Feb 25, 2026
fafa66f
Use WellKnownValAttribs.Empty instead of WellKnownValAttribs.Create([])
T-Gro Feb 25, 2026
1f289ab
deduplicate logic for bool arg attrs
T-Gro Feb 26, 2026
a3ba5d1
Refactor WellKnownEntityAttribs and WellKnownValAttribs into generic …
T-Gro Feb 26, 2026
c9b08af
Migrate 10 additional attribute callsites to cached well-known flags
T-Gro Feb 27, 2026
aee8ae6
Remove dead TryFindFSharpBoolAttributeAssumeFalse helper
T-Gro Feb 27, 2026
c1c2173
Phase A: Use already-computed entity flags in Phase1G
T-Gro Feb 27, 2026
6a4701d
Phase B: Compute entity flags ad-hoc in Phase1B and early typar check
T-Gro Feb 27, 2026
59b08f7
Phase C: Compute val flags ad-hoc in CheckExpressions
T-Gro Feb 27, 2026
01fd4a6
Phase D: Compute val flags in GenParamAttribs
T-Gro Feb 27, 2026
f26158f
Phase E: Compute val flags ad-hoc for field-level attrs
T-Gro Feb 27, 2026
edfa431
Fix review findings: MeasureableAttribute name, AllowNullLiteral True…
T-Gro Feb 27, 2026
1ad2390
Add attribsHaveEntityFlag/attribsHaveValFlag helpers, refactor callsites
T-Gro Feb 27, 2026
d644be6
Remove dead TryFindFSharpBoolAttribute helper (zero callers remain)
T-Gro Feb 27, 2026
a70827f
Remove dead code and migrate remaining CompilationRepresentation/Comp…
T-Gro Feb 27, 2026
6994285
Delete HasFSharpAttributeOpt (zero callers), migrate CheckFSharpAttri…
T-Gro Feb 27, 2026
4e7815d
Prototype: classifyEntityAttrib + tryFindEntityAttribByFlag
T-Gro Feb 27, 2026
2b36d84
Migrate NonSerializedAttribute to val flags
T-Gro Feb 27, 2026
59e5d97
Add tryFindEntityAttribString/Int32, delete TryFindFSharpInt32Attribute
T-Gro Feb 27, 2026
aa66db9
Add (|EntityAttrib|_|) and (|ValAttrib|_|) active patterns for enum-p…
T-Gro Feb 27, 2026
a994b1f
Add typed extraction APs: EntityAttribInt, EntityAttribString, ValAtt…
T-Gro Feb 28, 2026
c98c351
Make typed APs compose on top of base (|EntityAttrib|_|) / (|ValAttri…
T-Gro Feb 28, 2026
32746c9
A1: Add 7 entity/val flag cases, migrate 11 TryFindFSharpAttribute ca…
T-Gro Feb 28, 2026
693d442
B1: Add WellKnownAssemblyAttributes, migrate all string attribute cal…
T-Gro Feb 28, 2026
c05fd9d
Delete dead helpers and g.attrib_ members after AP migration
T-Gro Feb 28, 2026
3fffcee
C3: Shared combinators tryFindAttribByClassifier + attribsHaveFlag
T-Gro Feb 28, 2026
4e750f4
Migrate remaining IsMatchingFSharpAttribute/TryFindFSharpAttribute to…
T-Gro Mar 1, 2026
3ba491b
Filter chain optimization + delete dead helpers and 18 g.attrib_ members
T-Gro Mar 1, 2026
93acbd4
Add IL-level classifyILAttrib + (|ILAttribDecoded|_|) AP, migrate 9 T…
T-Gro Mar 1, 2026
bea5489
Delete attrib_IlExperimentalAttribute (zero callers)
T-Gro Mar 1, 2026
4d36003
Audit cleanup: hasFlag helper, CheckFlag dedup, ILAttributes extensio…
T-Gro Mar 2, 2026
3a33729
Add MethInfoHasWellKnownAttribute for O(1) checks on overload resolut…
T-Gro Mar 2, 2026
5338bf3
Council fixes: resolveAttribPath DU, merge IL maps, private HasWellKn…
T-Gro Mar 2, 2026
f666ca4
Round 2 council fixes: extract WarnOnWithoutNull helper, dedup CheckI…
T-Gro Mar 2, 2026
375270b
Final cleanup: dead code, encapsulation, AllowNullLiteral migration, …
T-Gro Mar 3, 2026
90d63d5
Add ValueAsStaticPropertyAttribute to WellKnownValAttributes for O(1)…
T-Gro Mar 5, 2026
c779b76
Add HasWellKnownAttribute members on Entity and Val for transparent c…
T-Gro Mar 5, 2026
d37c588
Add WellKnownMethAttribute struct to bundle correlated attribute chec…
T-Gro Mar 5, 2026
297f8fb
Add ValTryGetBoolAttribute for three-state bool attribute queries on Val
T-Gro Mar 5, 2026
9d3789b
Remove unused parameters from AttributeChecking functions
T-Gro Mar 5, 2026
3091230
Rewrite TryFindAutoOpenAttr and TryFindInternalsVisibleToAttr to use …
T-Gro Mar 5, 2026
54e44e0
Add well-known attribute API navigation guide comment block
T-Gro Mar 5, 2026
2830d4e
Fix verifier issues: BSL baseline, CompilerCompat test bugs, trailing…
T-Gro Mar 5, 2026
7da15fa
Add TailCallAttribute to WellKnownValAttributes for O(1) flag-based l…
T-Gro Mar 5, 2026
3bb534f
Consolidate TypeProviderAssemblyAttribute detection into classifyAsse…
T-Gro Mar 6, 2026
99caa9d
Fast-path DefaultMemberAttribute in indexer resolution
T-Gro Mar 6, 2026
e31b5e4
Remove duplicate DefaultAugmentation(false) test
T-Gro Mar 6, 2026
82916ab
Merge remote-tracking branch 'origin/main' into feature/attribute-imp…
T-Gro Mar 6, 2026
9b1ef99
AugmentWishHashCompare - remove 7 bools in matches
T-Gro Mar 6, 2026
d3228b6
Fix MarshalAs regression: don't filter attribute before GenMarshal re…
T-Gro Mar 6, 2026
dc294bb
Fix fantomas formatting in TypedTree.fsi and TypedTreeOps.fsi
T-Gro Mar 6, 2026
581b9b6
Merge branch 'main' into feature/attribute-imports
T-Gro Mar 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 84 additions & 42 deletions src/Compiler/AbstractIL/il.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1229,19 +1229,75 @@ type ILAttributes(array: ILAttribute[]) =

static member val internal Empty = ILAttributes([||])

[<NoEquality; NoComparison>]
type ILAttributesStored =

/// Computed by ilread.fs based on metadata index
[<Flags>]
type WellKnownILAttributes =
| None = 0u
| IsReadOnlyAttribute = (1u <<< 0)
| IsUnmanagedAttribute = (1u <<< 1)
| IsByRefLikeAttribute = (1u <<< 2)
| ExtensionAttribute = (1u <<< 3)
| NullableAttribute = (1u <<< 4)
| ParamArrayAttribute = (1u <<< 5)
| AllowNullLiteralAttribute = (1u <<< 6)
| ReflectedDefinitionAttribute = (1u <<< 7)
| AutoOpenAttribute = (1u <<< 8)
| InternalsVisibleToAttribute = (1u <<< 9)
| CallerMemberNameAttribute = (1u <<< 10)
| CallerFilePathAttribute = (1u <<< 11)
| CallerLineNumberAttribute = (1u <<< 12)
| IDispatchConstantAttribute = (1u <<< 13)
| IUnknownConstantAttribute = (1u <<< 14)
| RequiresLocationAttribute = (1u <<< 15)
| SetsRequiredMembersAttribute = (1u <<< 16)
| NoEagerConstraintApplicationAttribute = (1u <<< 17)
| DefaultMemberAttribute = (1u <<< 18)
| ObsoleteAttribute = (1u <<< 19)
| CompilerFeatureRequiredAttribute = (1u <<< 20)
| ExperimentalAttribute = (1u <<< 21)
| RequiredMemberAttribute = (1u <<< 22)
| NullableContextAttribute = (1u <<< 23)
| AttributeUsageAttribute = (1u <<< 24)
| NotComputed = (1u <<< 31)

type internal ILAttributesStoredRepr =
| Reader of (int32 -> ILAttribute[])

/// Already computed
| Given of ILAttributes

member x.GetCustomAttrs metadataIndex =
match x with
| Reader f -> ILAttributes(f metadataIndex)
| Given attrs -> attrs
[<Sealed; NoEquality; NoComparison>]
type ILAttributesStored private (metadataIndex: int32, initial: ILAttributesStoredRepr) =
[<VolatileField>]
let mutable repr = initial

[<VolatileField>]
let mutable wellKnownFlags = WellKnownILAttributes.NotComputed

member _.MetadataIndex = metadataIndex

member x.CustomAttrs: ILAttributes =
match repr with
| Given a -> a
| Reader f ->
let r = ILAttributes(f metadataIndex)
repr <- Given r
r

member x.HasWellKnownAttribute(flag: WellKnownILAttributes, compute: ILAttributes -> WellKnownILAttributes) : bool =
x.GetOrComputeWellKnownFlags(compute) &&& flag <> WellKnownILAttributes.None

member x.GetOrComputeWellKnownFlags(compute: ILAttributes -> WellKnownILAttributes) : WellKnownILAttributes =
let f = wellKnownFlags

if f <> WellKnownILAttributes.NotComputed then
f
else
let a = x.CustomAttrs
let computed = compute a
wellKnownFlags <- computed
computed

static member CreateReader(idx: int32, f: int32 -> ILAttribute[]) = ILAttributesStored(idx, Reader f)

static member CreateGiven(attrs: ILAttributes) = ILAttributesStored(-1, Given attrs)

let emptyILCustomAttrs = ILAttributes [||]

Expand All @@ -1256,18 +1312,18 @@ let mkILCustomAttrs l =
| [] -> emptyILCustomAttrs
| _ -> mkILCustomAttrsFromArray (List.toArray l)

let emptyILCustomAttrsStored = ILAttributesStored.Given emptyILCustomAttrs
let emptyILCustomAttrsStored = ILAttributesStored.CreateGiven emptyILCustomAttrs

let storeILCustomAttrs (attrs: ILAttributes) =
if attrs.AsArray().Length = 0 then
emptyILCustomAttrsStored
else
ILAttributesStored.Given attrs
ILAttributesStored.CreateGiven attrs

let mkILCustomAttrsComputed f =
ILAttributesStored.Reader(fun _ -> f ())
ILAttributesStored.CreateReader(-1, fun _ -> f ())

let mkILCustomAttrsReader f = ILAttributesStored.Reader f
let mkILCustomAttrsReader f = ILAttributesStored.CreateReader(-1, f)

type ILCodeLabel = int

Expand Down Expand Up @@ -1791,7 +1847,7 @@ type ILParameter =
MetadataIndex: int32
}

member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

override x.ToString() =
x.Name |> Option.defaultValue "<no name>"
Expand All @@ -1809,7 +1865,7 @@ type ILReturn =

override x.ToString() = "<return>"

member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

member x.WithCustomAttrs(customAttrs) =
{ x with
Expand Down Expand Up @@ -1870,7 +1926,7 @@ type ILGenericParameterDef =
MetadataIndex: int32
}

member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
Expand Down Expand Up @@ -1916,13 +1972,7 @@ type InterfaceImpl =
mutable CustomAttrsStored: ILAttributesStored
}

member x.CustomAttrs =
match x.CustomAttrsStored with
| ILAttributesStored.Reader f ->
let res = ILAttributes(f x.Idx)
x.CustomAttrsStored <- ILAttributesStored.Given res
res
| ILAttributesStored.Given attrs -> attrs
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

static member Create(ilType: ILType, customAttrsStored: ILAttributesStored) =
{
Expand Down Expand Up @@ -2029,7 +2079,7 @@ type ILMethodDef
| Some attrs -> attrs)
)

member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs metadataIndex
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

member x.SecurityDecls = x.SecurityDeclsStored.GetSecurityDecls x.MetadataIndex

Expand Down Expand Up @@ -2266,7 +2316,7 @@ type ILEventDef

member _.MetadataIndex = metadataIndex

member x.CustomAttrs = customAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = customAttrsStored.CustomAttrs

member x.With(?eventType, ?name, ?attributes, ?addMethod, ?removeMethod, ?fireMethod, ?otherMethods, ?customAttrs) =
ILEventDef(
Expand Down Expand Up @@ -2342,7 +2392,7 @@ type ILPropertyDef
member x.Init = init
member x.Args = args
member x.CustomAttrsStored = customAttrsStored
member x.CustomAttrs = customAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = customAttrsStored.CustomAttrs
member x.MetadataIndex = metadataIndex

member x.With(?name, ?attributes, ?setMethod, ?getMethod, ?callingConv, ?propertyType, ?init, ?args, ?customAttrs) =
Expand Down Expand Up @@ -2418,7 +2468,7 @@ type ILFieldDef
member _.Offset = offset
member _.Marshal = marshal
member x.CustomAttrsStored = customAttrsStored
member x.CustomAttrs = customAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = customAttrsStored.CustomAttrs
member x.MetadataIndex = metadataIndex

member x.With
Expand Down Expand Up @@ -2677,8 +2727,6 @@ type ILTypeDef
metadataIndex: int32
) =

let mutable customAttrsStored = customAttrsStored

let hasFlag flag = additionalFlags &&& flag = flag

new
Expand Down Expand Up @@ -2829,13 +2877,7 @@ type ILTypeDef
customAttrs = defaultArg customAttrs x.CustomAttrsStored
)

member x.CustomAttrs: ILAttributes =
match customAttrsStored with
| ILAttributesStored.Reader f ->
let res = ILAttributes(f x.MetadataIndex)
customAttrsStored <- ILAttributesStored.Given res
res
| ILAttributesStored.Given res -> res
member x.CustomAttrs: ILAttributes = customAttrsStored.CustomAttrs

member x.SecurityDecls = x.SecurityDeclsStored.GetSecurityDecls x.MetadataIndex

Expand Down Expand Up @@ -2993,7 +3035,7 @@ type ILNestedExportedType =
MetadataIndex: int32
}

member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

override x.ToString() = "exported type " + x.Name

Expand All @@ -3017,7 +3059,7 @@ and [<NoComparison; NoEquality>] ILExportedTypeOrForwarder =

member x.IsForwarder = x.Attributes &&& enum<TypeAttributes> 0x00200000 <> enum 0

member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

override x.ToString() = "exported type " + x.Name

Expand Down Expand Up @@ -3057,7 +3099,7 @@ type ILResource =
| ILResourceLocation.Local bytes -> bytes.GetByteMemory()
| _ -> failwith "GetBytes"

member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

override x.ToString() = "resource " + x.Name

Expand Down Expand Up @@ -3104,7 +3146,7 @@ type ILAssemblyManifest =
MetadataIndex: int32
}

member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

member x.SecurityDecls = x.SecurityDeclsStored.GetSecurityDecls x.MetadataIndex

Expand Down Expand Up @@ -3151,7 +3193,7 @@ type ILModuleDef =
| None -> false
| _ -> true

member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
member x.CustomAttrs = x.CustomAttrsStored.CustomAttrs

override x.ToString() = "assembly " + x.Name

Expand Down
42 changes: 36 additions & 6 deletions src/Compiler/AbstractIL/il.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -878,15 +878,45 @@ type ILAttributes =

static member internal Empty: ILAttributes

[<Flags>]
type WellKnownILAttributes =
| None = 0u
| IsReadOnlyAttribute = (1u <<< 0)
| IsUnmanagedAttribute = (1u <<< 1)
| IsByRefLikeAttribute = (1u <<< 2)
| ExtensionAttribute = (1u <<< 3)
| NullableAttribute = (1u <<< 4)
| ParamArrayAttribute = (1u <<< 5)
| AllowNullLiteralAttribute = (1u <<< 6)
| ReflectedDefinitionAttribute = (1u <<< 7)
| AutoOpenAttribute = (1u <<< 8)
| InternalsVisibleToAttribute = (1u <<< 9)
| CallerMemberNameAttribute = (1u <<< 10)
| CallerFilePathAttribute = (1u <<< 11)
| CallerLineNumberAttribute = (1u <<< 12)
| IDispatchConstantAttribute = (1u <<< 13)
| IUnknownConstantAttribute = (1u <<< 14)
| RequiresLocationAttribute = (1u <<< 15)
| SetsRequiredMembersAttribute = (1u <<< 16)
| NoEagerConstraintApplicationAttribute = (1u <<< 17)
| DefaultMemberAttribute = (1u <<< 18)
| ObsoleteAttribute = (1u <<< 19)
| CompilerFeatureRequiredAttribute = (1u <<< 20)
| ExperimentalAttribute = (1u <<< 21)
| RequiredMemberAttribute = (1u <<< 22)
| NullableContextAttribute = (1u <<< 23)
| AttributeUsageAttribute = (1u <<< 24)
| NotComputed = (1u <<< 31)

/// Represents the efficiency-oriented storage of ILAttributes in another item.
[<NoEquality; NoComparison>]
[<Sealed; NoEquality; NoComparison>]
type ILAttributesStored =
/// Computed by ilread.fs based on metadata index
| Reader of (int32 -> ILAttribute[])
/// Already computed
| Given of ILAttributes
member CustomAttrs: ILAttributes

member HasWellKnownAttribute: flag: WellKnownILAttributes * compute: (ILAttributes -> WellKnownILAttributes) -> bool

member GetCustomAttrs: int32 -> ILAttributes
static member CreateReader: idx: int32 * f: (int32 -> ILAttribute[]) -> ILAttributesStored
static member CreateGiven: attrs: ILAttributes -> ILAttributesStored

/// Method parameters and return values.
[<RequireQualifiedAccess; NoEquality; NoComparison>]
Expand Down
Loading
Loading