-
Notifications
You must be signed in to change notification settings - Fork 833
Description
This is a race condition in a very specific scenario when we have two or more type extensions of the same type in two independent (from graph checking pov) files:
fsharp/src/Compiler/Checking/CheckDeclarations.fs
Lines 4219 to 4228 in 12efe3b
| // Update resolved type parameters with the names from the source. | |
| let _, tcref, _ = res | |
| if tcref.TyparsNoRange.Length = synTypars.Length then | |
| (tcref.TyparsNoRange, synTypars) | |
| ||> List.zip | |
| |> List.iter (fun (typar, SynTyparDecl.SynTyparDecl (typar = tp)) -> | |
| let (SynTypar(ident = untypedIdent; staticReq = sr)) = tp | |
| if typar.StaticReq = sr then | |
| typar.SetIdent(untypedIdent) | |
| ) |
If each extension updates the type var name, we have a race during parallel checking. In effect some of the extensions will end up with a randomly wrong typar name.
This happens when compiling FCS.dll using graph based type checking because LexBuffer<_> has such multiple independent extensions: #19028 (comment)
Repro steps
dotnet build --no-incremental a few times.
observe the dumped sigdata or inspect dll:
correct with sequential checking:
wrong with graph based (Print<'X> instead of Print<'U>):

This is not very severe and rather an edge case, apart from the fact that it prevents graph based type checking from being deterministic.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status