Skip to content

Commit e19155e

Browse files
authored
Fix races in the ProvidedTypesContext (#11841)
1 parent 4f826ec commit e19155e

File tree

3 files changed

+12
-11
lines changed

3 files changed

+12
-11
lines changed

src/fsharp/CheckDeclarations.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3484,12 +3484,12 @@ module EstablishTypeDefinitionCores =
34843484
tycon.entity_tycon_repr <- repr
34853485
// Record the details so we can map System.Type --> TyconRef
34863486
let ilOrigRootTypeRef = GetOriginalILTypeRefOfProvidedType (theRootTypeWithRemapping, m)
3487-
theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupTyconRef.Remove(st)) ; lookupTyconRef.Add(st, tcref)), m)
3487+
theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupTyconRef.TryRemove(st)) ; ignore(lookupTyconRef.TryAdd(st, tcref))), m)
34883488

34893489
// Record the details so we can map System.Type --> ILTypeRef, including the relocation if any
34903490
if not isSuppressRelocate then
34913491
let ilTgtRootTyRef = tycon.CompiledRepresentationForNamedType
3492-
theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupILTypeRef.Remove(st)) ; lookupILTypeRef.Add(st, ilTgtRootTyRef)), m)
3492+
theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupILTypeRef.TryRemove(st)) ; ignore(lookupILTypeRef.TryAdd(st, ilTgtRootTyRef))), m)
34933493

34943494
// Iterate all nested types and force their embedding, to populate the mapping from System.Type --> TyconRef/ILTypeRef.
34953495
// This is only needed for generated types, because for other types the System.Type objects self-describe
@@ -3522,12 +3522,12 @@ module EstablishTypeDefinitionCores =
35223522
let ilOrigTypeRef = GetOriginalILTypeRefOfProvidedType (st, m)
35233523

35243524
// Record the details so we can map System.Type --> TyconRef
3525-
st.PUntaint ((fun st -> ignore(lookupTyconRef.Remove(st)) ; lookupTyconRef.Add(st, nestedTyRef)), m)
3525+
st.PUntaint ((fun st -> ignore(lookupTyconRef.TryRemove(st)) ; ignore(lookupTyconRef.TryAdd(st, nestedTyRef))), m)
35263526

35273527
if isGenerated then
35283528
let ilTgtTyRef = nestedTycon.CompiledRepresentationForNamedType
35293529
// Record the details so we can map System.Type --> ILTypeRef
3530-
st.PUntaint ((fun st -> ignore(lookupILTypeRef.Remove(st)) ; lookupILTypeRef.Add(st, ilTgtTyRef)), m)
3530+
st.PUntaint ((fun st -> ignore(lookupILTypeRef.TryRemove(st)) ; ignore(lookupILTypeRef.TryAdd(st, ilTgtTyRef))), m)
35313531

35323532
// Record the details so we can build correct ILTypeDefs during static linking rewriting
35333533
if not isSuppressRelocate then

src/fsharp/ExtensionTyping.fs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace FSharp.Compiler
77
#if !NO_EXTENSIONTYPING
88

99
open System
10+
open System.Collections.Concurrent
1011
open System.IO
1112
open System.Collections.Generic
1213
open System.Reflection
@@ -271,7 +272,7 @@ module internal ExtensionTyping =
271272
and ProvidedTypeContext =
272273
| NoEntries
273274
// The dictionaries are safe because the ProvidedType with the ProvidedTypeContext are only accessed one thread at a time during type-checking.
274-
| Entries of Dictionary<ProvidedType, ILTypeRef> * Lazy<Dictionary<ProvidedType, obj>>
275+
| Entries of ConcurrentDictionary<ProvidedType, ILTypeRef> * Lazy<ConcurrentDictionary<ProvidedType, obj>>
275276

276277
static member Empty = NoEntries
277278

@@ -280,7 +281,7 @@ module internal ExtensionTyping =
280281
member ctxt.GetDictionaries() =
281282
match ctxt with
282283
| NoEntries ->
283-
Dictionary<ProvidedType, ILTypeRef>(ProvidedTypeComparer.Instance), Dictionary<ProvidedType, obj>(ProvidedTypeComparer.Instance)
284+
ConcurrentDictionary<ProvidedType, ILTypeRef>(ProvidedTypeComparer.Instance), ConcurrentDictionary<ProvidedType, obj>(ProvidedTypeComparer.Instance)
284285
| Entries (lookupILTR, lookupILTCR) ->
285286
lookupILTR, lookupILTCR.Force()
286287

@@ -305,8 +306,8 @@ module internal ExtensionTyping =
305306
match ctxt with
306307
| NoEntries -> NoEntries
307308
| Entries(d1, d2) ->
308-
Entries(d1, lazy (let dict = Dictionary<ProvidedType, obj>(ProvidedTypeComparer.Instance)
309-
for KeyValue (st, tcref) in d2.Force() do dict.Add(st, f tcref)
309+
Entries(d1, lazy (let dict = ConcurrentDictionary<ProvidedType, obj>(ProvidedTypeComparer.Instance)
310+
for KeyValue (st, tcref) in d2.Force() do dict.TryAdd(st, f tcref) |> ignore
310311
dict))
311312

312313
and [<AllowNullLiteral; Sealed>]

src/fsharp/ExtensionTyping.fsi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace FSharp.Compiler
77
#if !NO_EXTENSIONTYPING
88

99
open System
10-
open System.Collections.Generic
10+
open System.Collections.Concurrent
1111
open FSharp.Core.CompilerServices
1212
open FSharp.Compiler.AbstractIL.IL
1313
open FSharp.Compiler.Text
@@ -78,9 +78,9 @@ module internal ExtensionTyping =
7878

7979
static member Empty : ProvidedTypeContext
8080

81-
static member Create : Dictionary<ProvidedType, ILTypeRef> * Dictionary<ProvidedType, obj (* TyconRef *) > -> ProvidedTypeContext
81+
static member Create : ConcurrentDictionary<ProvidedType, ILTypeRef> * ConcurrentDictionary<ProvidedType, obj (* TyconRef *) > -> ProvidedTypeContext
8282

83-
member GetDictionaries : unit -> Dictionary<ProvidedType, ILTypeRef> * Dictionary<ProvidedType, obj (* TyconRef *) >
83+
member GetDictionaries : unit -> ConcurrentDictionary<ProvidedType, ILTypeRef> * ConcurrentDictionary<ProvidedType, obj (* TyconRef *) >
8484

8585
/// Map the TyconRef objects, if any
8686
member RemapTyconRefs : (obj -> obj) -> ProvidedTypeContext

0 commit comments

Comments
 (0)