Skip to content

Commit 3750b44

Browse files
authored
Make ILTypeDef super type calculation lazy (#18005)
1 parent 86106e3 commit 3750b44

20 files changed

+277
-223
lines changed

docs/release-notes/.FSharp.Compiler.Service/9.0.200.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@
4444
* Better ranges for #nowarn error reporting; bring back #nowarn warnings for --langVersion:80; add warnings under feature flag ([PR #17871](https://github.com/dotnet/fsharp/pull/17871))
4545
* Better ranges for #nowarn error reporting; bring back #nowarn warnings for --langVersion:80; add warnings under feature flag ([PR #17871](https://github.com/dotnet/fsharp/pull/17871))
4646
* CheckAndThrow can be invoked only from within Cancellable context ([PR #18037](https://github.com/dotnet/fsharp/pull/18037))
47+
* Make ILTypeDef base type calculation lazy. ([PR #18005](https://github.com/dotnet/fsharp/pull/18005))
4748

4849
### Breaking Changes

src/Compiler/AbstractIL/il.fs

Lines changed: 88 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,34 +2562,48 @@ let typeEncodingOfFlags flags =
25622562
elif f = 0x00010000 then ILDefaultPInvokeEncoding.Unicode
25632563
else ILDefaultPInvokeEncoding.Ansi
25642564

2565-
[<RequireQualifiedAccess>]
2566-
type ILTypeDefKind =
2567-
| Class
2568-
| ValueType
2569-
| Interface
2570-
| Enum
2571-
| Delegate
2565+
[<Flags>]
2566+
type ILTypeDefAdditionalFlags =
2567+
| Class = 1
2568+
| ValueType = 2
2569+
| Interface = 4
2570+
| Enum = 8
2571+
| Delegate = 16
2572+
| IsKnownToBeAttribute = 32
2573+
/// The type can contain extension methods,
2574+
/// or this information may not be available at the time the ILTypeDef is created
2575+
| CanContainExtensionMethods = 1024
2576+
2577+
let internal typeKindFlags =
2578+
ILTypeDefAdditionalFlags.Class |||
2579+
ILTypeDefAdditionalFlags.ValueType |||
2580+
ILTypeDefAdditionalFlags.Interface |||
2581+
ILTypeDefAdditionalFlags.Enum |||
2582+
ILTypeDefAdditionalFlags.Delegate
2583+
2584+
let inline internal resetTypeKind flags =
2585+
flags &&& ~~~typeKindFlags
2586+
2587+
let (|HasFlag|_|) (flag: ILTypeDefAdditionalFlags) flags =
2588+
flags &&& flag = flag
2589+
2590+
let inline typeKindByNames extendsName typeName =
2591+
match extendsName with
2592+
| "System.Enum" -> ILTypeDefAdditionalFlags.Enum
2593+
| "System.Delegate" when typeName <> "System.MulticastDelegate" -> ILTypeDefAdditionalFlags.Delegate
2594+
| "System.MulticastDelegate" -> ILTypeDefAdditionalFlags.Delegate
2595+
| "System.ValueType" when typeName <> "System.Enum" -> ILTypeDefAdditionalFlags.ValueType
2596+
| _ -> ILTypeDefAdditionalFlags.Class
25722597

25732598
let typeKindOfFlags nm (super: ILType option) flags =
25742599
if (flags &&& 0x00000020) <> 0x0 then
2575-
ILTypeDefKind.Interface
2600+
ILTypeDefAdditionalFlags.Interface
25762601
else
25772602
match super with
2578-
| None -> ILTypeDefKind.Class
2603+
| None -> ILTypeDefAdditionalFlags.Class
25792604
| Some ty ->
25802605
let name = ty.TypeSpec.Name
2581-
2582-
if name = "System.Enum" then
2583-
ILTypeDefKind.Enum
2584-
elif
2585-
(name = "System.Delegate" && nm <> "System.MulticastDelegate")
2586-
|| name = "System.MulticastDelegate"
2587-
then
2588-
ILTypeDefKind.Delegate
2589-
elif name = "System.ValueType" && nm <> "System.Enum" then
2590-
ILTypeDefKind.ValueType
2591-
else
2592-
ILTypeDefKind.Class
2606+
typeKindByNames name nm
25932607

25942608
let convertTypeAccessFlags access =
25952609
match access with
@@ -2605,11 +2619,8 @@ let convertTypeAccessFlags access =
26052619

26062620
let convertTypeKind kind =
26072621
match kind with
2608-
| ILTypeDefKind.Class -> TypeAttributes.Class
2609-
| ILTypeDefKind.ValueType -> TypeAttributes.Class
2610-
| ILTypeDefKind.Interface -> TypeAttributes.Abstract ||| TypeAttributes.Interface
2611-
| ILTypeDefKind.Enum -> TypeAttributes.Class
2612-
| ILTypeDefKind.Delegate -> TypeAttributes.Class
2622+
| HasFlag ILTypeDefAdditionalFlags.Interface -> TypeAttributes.Abstract ||| TypeAttributes.Interface
2623+
| _ -> TypeAttributes.Class
26132624

26142625
let convertLayout layout =
26152626
match layout with
@@ -2638,13 +2649,7 @@ let convertInitSemantics (init: ILTypeInit) =
26382649
| ILTypeInit.BeforeField -> TypeAttributes.BeforeFieldInit
26392650
| ILTypeInit.OnAny -> enum 0
26402651

2641-
[<Flags>]
2642-
type ILTypeDefAdditionalFlags =
2643-
| None = 0
2644-
| IsKnownToBeAttribute = 1
2645-
/// The type can contain extension methods,
2646-
/// or this information may not be available at the time the ILTypeDef is created
2647-
| CanContainExtensionMethods = 2
2652+
let emptyILExtends = notlazy<ILType option> None
26482653

26492654
[<NoComparison; NoEquality; StructuredFormatDisplay("{DebugText}")>]
26502655
type ILTypeDef
@@ -2654,7 +2659,7 @@ type ILTypeDef
26542659
layout: ILTypeDefLayout,
26552660
implements: InterruptibleLazy<InterfaceImpl list>,
26562661
genericParams: ILGenericParameterDefs,
2657-
extends: ILType option,
2662+
extends: InterruptibleLazy<ILType option>,
26582663
methods: ILMethodDefs,
26592664
nestedTypes: ILTypeDefs,
26602665
fields: ILFieldDefs,
@@ -2705,6 +2710,42 @@ type ILTypeDef
27052710
NoMetadataIdx
27062711
)
27072712

2713+
new(name,
2714+
attributes,
2715+
layout,
2716+
implements,
2717+
genericParams,
2718+
extends,
2719+
methods,
2720+
nestedTypes,
2721+
fields,
2722+
methodImpls,
2723+
events,
2724+
properties,
2725+
securityDecls,
2726+
customAttrs) =
2727+
let additionalFlags =
2728+
ILTypeDefAdditionalFlags.CanContainExtensionMethods |||
2729+
typeKindOfFlags name extends (int attributes)
2730+
ILTypeDef(
2731+
name,
2732+
attributes,
2733+
layout,
2734+
InterruptibleLazy.FromValue(implements),
2735+
genericParams,
2736+
InterruptibleLazy.FromValue(extends),
2737+
methods,
2738+
nestedTypes,
2739+
fields,
2740+
methodImpls,
2741+
events,
2742+
properties,
2743+
additionalFlags,
2744+
storeILSecurityDecls securityDecls,
2745+
customAttrs,
2746+
NoMetadataIdx
2747+
)
2748+
27082749
member _.Name = name
27092750

27102751
member _.Attributes = attributes
@@ -2786,20 +2827,15 @@ type ILTypeDef
27862827

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

2789-
member x.IsClass =
2790-
(typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.Class
2830+
member x.IsClass = hasFlag ILTypeDefAdditionalFlags.Class
27912831

2792-
member x.IsStruct =
2793-
(typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.ValueType
2832+
member x.IsStruct = hasFlag ILTypeDefAdditionalFlags.ValueType
27942833

2795-
member x.IsInterface =
2796-
(typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.Interface
2834+
member x.IsInterface = hasFlag ILTypeDefAdditionalFlags.Interface
27972835

2798-
member x.IsEnum =
2799-
(typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.Enum
2836+
member x.IsEnum = hasFlag ILTypeDefAdditionalFlags.Enum
28002837

2801-
member x.IsDelegate =
2802-
(typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.Delegate
2838+
member x.IsDelegate = hasFlag ILTypeDefAdditionalFlags.Delegate
28032839

28042840
member x.Access = typeAccessOfFlags (int x.Attributes)
28052841
member x.IsAbstract = x.Attributes &&& TypeAttributes.Abstract <> enum 0
@@ -2850,9 +2886,10 @@ type ILTypeDef
28502886
member x.WithKind(kind) =
28512887
x.With(
28522888
attributes = (x.Attributes ||| convertTypeKind kind),
2889+
newAdditionalFlags = (resetTypeKind additionalFlags ||| kind),
28532890
extends =
28542891
match kind with
2855-
| ILTypeDefKind.Interface -> None
2892+
| HasFlag ILTypeDefAdditionalFlags.Interface -> emptyILExtends
28562893
| _ -> x.Extends
28572894
)
28582895

@@ -2865,6 +2902,9 @@ type ILTypeDef
28652902
member x.WithInitSemantics(init) =
28662903
x.With(attributes = (x.Attributes ||| convertInitSemantics init))
28672904

2905+
member x.WithIsKnownToBeAttribute() =
2906+
x.With(newAdditionalFlags = (additionalFlags ||| ILTypeDefAdditionalFlags.IsKnownToBeAttribute))
2907+
28682908
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
28692909
member x.DebugText = x.ToString()
28702910

@@ -4259,7 +4299,7 @@ let mkILGenericClass (nm, access, genparams, extends, impls, methods, fields, ne
42594299
name = nm,
42604300
attributes = attributes,
42614301
genericParams = genparams,
4262-
implements = InterruptibleLazy.FromValue(impls),
4302+
implements = impls,
42634303
layout = ILTypeDefLayout.Auto,
42644304
extends = Some extends,
42654305
methods = methods,
@@ -4269,7 +4309,6 @@ let mkILGenericClass (nm, access, genparams, extends, impls, methods, fields, ne
42694309
methodImpls = emptyILMethodImpls,
42704310
properties = props,
42714311
events = events,
4272-
additionalFlags = ILTypeDefAdditionalFlags.None,
42734312
securityDecls = emptyILSecurityDecls
42744313
)
42754314

@@ -4283,7 +4322,7 @@ let mkRawDataValueTypeDef (iltyp_ValueType: ILType) (nm, size, pack) =
42834322
||| TypeAttributes.ExplicitLayout
42844323
||| TypeAttributes.BeforeFieldInit
42854324
||| TypeAttributes.AnsiClass),
4286-
implements = emptyILInterfaceImpls,
4325+
implements = [],
42874326
extends = Some iltyp_ValueType,
42884327
layout = ILTypeDefLayout.Explicit { Size = Some size; Pack = Some pack },
42894328
methods = emptyILMethods,
@@ -4293,7 +4332,6 @@ let mkRawDataValueTypeDef (iltyp_ValueType: ILType) (nm, size, pack) =
42934332
methodImpls = emptyILMethodImpls,
42944333
properties = emptyILProperties,
42954334
events = emptyILEvents,
4296-
additionalFlags = ILTypeDefAdditionalFlags.None,
42974335
securityDecls = emptyILSecurityDecls
42984336
)
42994337

@@ -5590,7 +5628,7 @@ and refsOfILTypeDef s (td: ILTypeDef) =
55905628
refsOfILTypeDefs s td.NestedTypes
55915629
refsOfILGenericParams s td.GenericParams
55925630
refsOfILTypes s (td.Implements.Value |> List.map _.Type)
5593-
Option.iter (refsOfILType s) td.Extends
5631+
Option.iter (refsOfILType s) td.Extends.Value
55945632
refsOfILMethodDefs s td.Methods
55955633
refsOfILFieldDefs s (td.Fields.AsList())
55965634
refsOfILMethodImpls s (td.MethodImpls.AsList())

src/Compiler/AbstractIL/il.fsi

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,15 +1483,6 @@ type ILTypeDefAccess =
14831483
| Private
14841484
| Nested of ILMemberAccess
14851485

1486-
/// A categorization of type definitions into "kinds"
1487-
[<RequireQualifiedAccess>]
1488-
type ILTypeDefKind =
1489-
| Class
1490-
| ValueType
1491-
| Interface
1492-
| Enum
1493-
| Delegate
1494-
14951486
/// Tables of named type definitions.
14961487
[<NoEquality; NoComparison; Class; Sealed>]
14971488
type ILTypeDefs =
@@ -1514,9 +1505,17 @@ type ILTypeDefs =
15141505

15151506
[<Flags>]
15161507
type ILTypeDefAdditionalFlags =
1517-
| None = 0
1518-
| IsKnownToBeAttribute = 1
1519-
| CanContainExtensionMethods = 2
1508+
| Class = 1
1509+
| ValueType = 2
1510+
| Interface = 4
1511+
| Enum = 8
1512+
| Delegate = 16
1513+
| IsKnownToBeAttribute = 32
1514+
| CanContainExtensionMethods = 1024
1515+
1516+
val (|HasFlag|_|): flag: ILTypeDefAdditionalFlags -> flags: ILTypeDefAdditionalFlags -> bool
1517+
1518+
val inline internal typeKindByNames: extendsName: string -> typeName: string -> ILTypeDefAdditionalFlags
15201519

15211520
/// Represents IL Type Definitions.
15221521
[<NoComparison; NoEquality>]
@@ -1529,7 +1528,7 @@ type ILTypeDef =
15291528
layout: ILTypeDefLayout *
15301529
implements: InterruptibleLazy<InterfaceImpl list> *
15311530
genericParams: ILGenericParameterDefs *
1532-
extends: ILType option *
1531+
extends: InterruptibleLazy<ILType option> *
15331532
methods: ILMethodDefs *
15341533
nestedTypes: ILTypeDefs *
15351534
fields: ILFieldDefs *
@@ -1542,14 +1541,14 @@ type ILTypeDef =
15421541
metadataIndex: int32 ->
15431542
ILTypeDef
15441543

1545-
/// Functional creation of a value, immediate
1544+
/// Functional creation of a value with lazy calculated data
15461545
new:
15471546
name: string *
15481547
attributes: TypeAttributes *
15491548
layout: ILTypeDefLayout *
15501549
implements: InterruptibleLazy<InterfaceImpl list> *
15511550
genericParams: ILGenericParameterDefs *
1552-
extends: ILType option *
1551+
extends: InterruptibleLazy<ILType option> *
15531552
methods: ILMethodDefs *
15541553
nestedTypes: ILTypeDefs *
15551554
fields: ILFieldDefs *
@@ -1561,13 +1560,31 @@ type ILTypeDef =
15611560
customAttrs: ILAttributesStored ->
15621561
ILTypeDef
15631562

1563+
/// Functional creation of a value, immediate
1564+
new:
1565+
name: string *
1566+
attributes: TypeAttributes *
1567+
layout: ILTypeDefLayout *
1568+
implements: InterfaceImpl list *
1569+
genericParams: ILGenericParameterDefs *
1570+
extends: ILType option *
1571+
methods: ILMethodDefs *
1572+
nestedTypes: ILTypeDefs *
1573+
fields: ILFieldDefs *
1574+
methodImpls: ILMethodImplDefs *
1575+
events: ILEventDefs *
1576+
properties: ILPropertyDefs *
1577+
securityDecls: ILSecurityDecls *
1578+
customAttrs: ILAttributesStored ->
1579+
ILTypeDef
1580+
15641581
member Name: string
15651582
member Attributes: TypeAttributes
15661583
member GenericParams: ILGenericParameterDefs
15671584
member Layout: ILTypeDefLayout
15681585
member NestedTypes: ILTypeDefs
15691586
member Implements: InterruptibleLazy<InterfaceImpl list>
1570-
member Extends: ILType option
1587+
member Extends: InterruptibleLazy<ILType option>
15711588
member Methods: ILMethodDefs
15721589
member SecurityDecls: ILSecurityDecls
15731590
member Fields: ILFieldDefs
@@ -1605,10 +1622,11 @@ type ILTypeDef =
16051622
member internal WithImport: bool -> ILTypeDef
16061623
member internal WithHasSecurity: bool -> ILTypeDef
16071624
member internal WithLayout: ILTypeDefLayout -> ILTypeDef
1608-
member internal WithKind: ILTypeDefKind -> ILTypeDef
1625+
member internal WithKind: ILTypeDefAdditionalFlags -> ILTypeDef
16091626
member internal WithEncoding: ILDefaultPInvokeEncoding -> ILTypeDef
16101627
member internal WithSpecialName: bool -> ILTypeDef
16111628
member internal WithInitSemantics: ILTypeInit -> ILTypeDef
1629+
member internal WithIsKnownToBeAttribute: unit -> ILTypeDef
16121630

16131631
/// Functional update
16141632
member With:
@@ -1617,7 +1635,7 @@ type ILTypeDef =
16171635
?layout: ILTypeDefLayout *
16181636
?implements: InterruptibleLazy<InterfaceImpl list> *
16191637
?genericParams: ILGenericParameterDefs *
1620-
?extends: ILType option *
1638+
?extends: InterruptibleLazy<ILType option> *
16211639
?methods: ILMethodDefs *
16221640
?nestedTypes: ILTypeDefs *
16231641
?fields: ILFieldDefs *
@@ -2257,6 +2275,8 @@ val internal mkILTypeForGlobalFunctions: ILScopeRef -> ILType
22572275

22582276
val emptyILInterfaceImpls: InterruptibleLazy<InterfaceImpl list>
22592277

2278+
val emptyILExtends: InterruptibleLazy<ILType option>
2279+
22602280
/// Making tables of custom attributes, etc.
22612281
val mkILCustomAttrs: ILAttribute list -> ILAttributes
22622282
val mkILCustomAttrsFromArray: ILAttribute[] -> ILAttributes

src/Compiler/AbstractIL/ilmorph.fs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,14 @@ let rec tdef_ty2ty_ilmbody2ilmbody_mdefs2mdefs isInKnownSet enc fs (tdef: ILType
371371
let implements =
372372
tdef.Implements.Value
373373
|> List.map (fun x -> { x with Type = fTyInCtxtR x.Type })
374-
|> InterruptibleLazy.FromValue
374+
|> notlazy
375+
376+
let extends = tdef.Extends.Value |> Option.map fTyInCtxtR |> notlazy
375377

376378
tdef.With(
377379
implements = implements,
378380
genericParams = gparams_ty2ty fTyInCtxtR tdef.GenericParams,
379-
extends = Option.map fTyInCtxtR tdef.Extends,
381+
extends = extends,
380382
methods = mdefsR,
381383
nestedTypes = tdefs_ty2ty_ilmbody2ilmbody_mdefs2mdefs isInKnownSet (enc @ [ tdef ]) fs tdef.NestedTypes,
382384
fields = fdefsR,

0 commit comments

Comments
 (0)