diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs
index 7ee34cb5cd8..f2bc644fce9 100644
--- a/src/Compiler/Checking/CheckDeclarations.fs
+++ b/src/Compiler/Checking/CheckDeclarations.fs
@@ -5535,5 +5535,7 @@ let CheckOneSigFile (g, amap, thisCcu, checkForErrors, conditionalDefines, tcSin
FinalTypeDefinitionChecksAtEndOfInferenceScope(cenv.infoReader, tcEnv.NameEnv, cenv.tcSink, false, tcEnv.DisplayEnv, tycon))
with exn -> errorRecovery exn sigFile.QualifiedName.Range
+ UpdatePrettyTyparNames.updateModuleOrNamespaceType sigFileType
+
return (tcEnv, sigFileType, cenv.createsGeneratedProvidedTypes)
}
diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index bb833eebabd..145c7e0799c 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -116,9 +116,7 @@ let BindTypars g env (tps: Typar list) =
if isNil tps then env else
// Here we mutate to provide better names for generalized type parameters
let nms = PrettyTypes.PrettyTyparNames (fun _ -> true) env.boundTyparNames tps
- (tps, nms) ||> List.iter2 (fun tp nm ->
- if PrettyTypes.NeedsPrettyTyparName tp then
- tp.typar_id <- ident (nm, tp.Range))
+ PrettyTypes.AssignPrettyTyparNames tps nms
List.fold BindTypar env tps
/// Set the set of vals which are arguments in the active lambda. We are allowed to return
@@ -2597,6 +2595,7 @@ and CheckModuleSpec cenv env mbind =
let CheckImplFileContents cenv env implFileTy implFileContents =
let rpi, mhi = ComputeRemappingFromImplementationToSignature cenv.g implFileContents implFileTy
let env = { env with sigToImplRemapInfo = (mkRepackageRemapping rpi, mhi) :: env.sigToImplRemapInfo }
+ UpdatePrettyTyparNames.updateModuleOrNamespaceType implFileTy
CheckDefnInModule cenv env implFileContents
let CheckImplFile (g, amap, reportErrors, infoReader, internalsVisibleToPaths, viewCcu, tcValF, denv, implFileTy, implFileContents, extraAttribs, isLastCompiland: bool*bool, isInternalTestSpanStackReferring) =
diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs
index b011cc1971b..965505afbb2 100644
--- a/src/Compiler/Driver/ParseAndCheckInputs.fs
+++ b/src/Compiler/Driver/ParseAndCheckInputs.fs
@@ -1783,7 +1783,7 @@ let CheckClosedInputSet (ctok, checkForErrors, tcConfig: TcConfig, tcImports, tc
// tcEnvAtEndOfLastFile is the environment required by fsi.exe when incrementally adding definitions
let results, tcState =
match tcConfig.typeCheckingConfig.Mode with
- | TypeCheckingMode.Graph when (not tcConfig.isInteractive && not tcConfig.deterministic) ->
+ | TypeCheckingMode.Graph when (not tcConfig.isInteractive) ->
CheckMultipleInputsUsingGraphMode(
ctok,
checkForErrors,
diff --git a/src/Compiler/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj
index 537636de072..6025101e553 100644
--- a/src/Compiler/FSharp.Compiler.Service.fsproj
+++ b/src/Compiler/FSharp.Compiler.Service.fsproj
@@ -278,6 +278,8 @@
+
+
diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs
index 343d911aa4d..f1a92c4d132 100644
--- a/src/Compiler/Optimize/Optimizer.fs
+++ b/src/Compiler/Optimize/Optimizer.fs
@@ -604,9 +604,7 @@ let BindTyparsToUnknown (tps: Typar list) env =
// However here we mutate to provide better names for generalized type parameters
// The names chosen are 'a', 'b' etc. These are also the compiled names in the IL code
let nms = PrettyTypes.PrettyTyparNames (fun _ -> true) (env.typarInfos |> List.map (fun (tp, _) -> tp.Name) ) tps
- (tps, nms) ||> List.iter2 (fun tp nm ->
- if PrettyTypes.NeedsPrettyTyparName tp then
- tp.typar_id <- ident (nm, tp.Range))
+ PrettyTypes.AssignPrettyTyparNames tps nms
List.fold (fun sofar arg -> BindTypar arg UnknownTypeValue sofar) env tps
let BindCcu (ccu: CcuThunk) mval env (_g: TcGlobals) =
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs
index 7021a523e88..1bc7cdd4c99 100644
--- a/src/Compiler/TypedTree/TypedTreeOps.fs
+++ b/src/Compiler/TypedTree/TypedTreeOps.fs
@@ -2841,6 +2841,12 @@ module PrettyTypes =
choose tps (0, 0) []
+ let AssignPrettyTyparNames typars prettyNames =
+ (typars, prettyNames)
+ ||> List.iter2 (fun tp nm ->
+ if NeedsPrettyTyparName tp then
+ tp.typar_id <- ident (nm, tp.Range))
+
let PrettifyThings g foldTys mapTys things =
let ftps = foldTys (accFreeInTypeLeftToRight g true false) emptyFreeTyparsLeftToRight things
let ftps = List.rev ftps
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi
index c6cf1c303a8..8582edaa5fc 100755
--- a/src/Compiler/TypedTree/TypedTreeOps.fsi
+++ b/src/Compiler/TypedTree/TypedTreeOps.fsi
@@ -981,6 +981,9 @@ module PrettyTypes =
val PrettyTyparNames: (Typar -> bool) -> string list -> Typars -> string list
+ /// Assign previously generated pretty names to typars
+ val AssignPrettyTyparNames: Typars -> string list -> unit
+
val PrettifyType: TcGlobals -> TType -> TType * TyparConstraintsWithTypars
val PrettifyInstAndTyparsAndType:
diff --git a/src/Compiler/TypedTree/UpdatePrettyTyparNames.fs b/src/Compiler/TypedTree/UpdatePrettyTyparNames.fs
new file mode 100644
index 00000000000..614496a20d9
--- /dev/null
+++ b/src/Compiler/TypedTree/UpdatePrettyTyparNames.fs
@@ -0,0 +1,24 @@
+/// The Typars of a Val in the signature data should also be pretty named.
+/// This will happen for the implementation file contents, but not for the signature data.
+/// In this module some helpers will traverse the ModuleOrNamespaceType and update all the typars of each found Val.
+module internal FSharp.Compiler.UpdatePrettyTyparNames
+
+open Internal.Utilities.Library
+open FSharp.Compiler.TypedTree
+open FSharp.Compiler.TypedTreeOps
+
+let updateVal (v: Val) =
+ if not (List.isEmpty v.Typars) then
+ let nms = PrettyTypes.PrettyTyparNames (fun _ -> true) List.empty v.Typars
+ PrettyTypes.AssignPrettyTyparNames v.Typars nms
+
+let rec updateEntity (entity: Entity) =
+ for e in entity.ModuleOrNamespaceType.AllEntities do
+ updateEntity e
+
+ for v in entity.ModuleOrNamespaceType.AllValsAndMembers do
+ updateVal v
+
+let updateModuleOrNamespaceType (signatureData: ModuleOrNamespaceType) =
+ for e in signatureData.ModuleAndNamespaceDefinitions do
+ updateEntity e
diff --git a/src/Compiler/TypedTree/UpdatePrettyTyparNames.fsi b/src/Compiler/TypedTree/UpdatePrettyTyparNames.fsi
new file mode 100644
index 00000000000..8d2a6ffca10
--- /dev/null
+++ b/src/Compiler/TypedTree/UpdatePrettyTyparNames.fsi
@@ -0,0 +1,8 @@
+/// The Typars of a Val in the signature data should also be pretty named.
+/// This will happen for the implementation file contents, but not for the signature data.
+/// In this module some helpers will traverse the ModuleOrNamespaceType and update all the typars of each found Val.
+module internal FSharp.Compiler.UpdatePrettyTyparNames
+
+open FSharp.Compiler.TypedTree
+
+val updateModuleOrNamespaceType: signatureData: ModuleOrNamespaceType -> unit
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index f3f67a4020a..84f6273152c 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -206,6 +206,7 @@
+
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationTests.fs
index c1df009ffff..dc5f30df911 100644
--- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationTests.fs
@@ -13,7 +13,7 @@ type Method =
let methodOptions (method: Method) =
match method with
| Method.Sequential -> []
- | Method.Graph -> [ "--test:GraphBasedChecking"; "--test:DumpCheckingGraph"; "--deterministic-" ]
+ | Method.Graph -> [ "--test:GraphBasedChecking"; "--test:DumpCheckingGraph" ]
let withMethod (method: Method) (cu: CompilationUnit) : CompilationUnit =
match cu with
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TyparNameTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TyparNameTests.fs
new file mode 100644
index 00000000000..8b81bc0a312
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TyparNameTests.fs
@@ -0,0 +1,142 @@
+module FSharp.Compiler.ComponentTests.TypeChecks.TyparNameTests
+
+open FSharp.Compiler.Symbols
+open Xunit
+open FSharp.Test
+open FSharp.Test.Compiler
+
+let private getGenericParametersNamesFor
+ (cUnit: CompilationUnit)
+ (entityDisplayName: string)
+ (valueDisplayName: string)
+ (additionalFile: SourceCodeFileKind)
+ : string array =
+ let typeCheckResult =
+ cUnit |> withAdditionalSourceFile additionalFile |> typecheckProject
+
+ assert (Array.isEmpty typeCheckResult.Diagnostics)
+
+ typeCheckResult.AssemblySignature.Entities
+ |> Seq.tryPick (fun (entity: FSharpEntity) ->
+ if entity.DisplayName <> entityDisplayName then
+ None
+ else
+ entity.MembersFunctionsAndValues
+ |> Seq.tryFind (fun mfv -> mfv.DisplayName = valueDisplayName)
+ |> Option.map (fun (mfv: FSharpMemberOrFunctionOrValue) ->
+ mfv.GenericParameters |> Seq.map (fun gp -> gp.DisplayName) |> Seq.toArray))
+ |> Option.defaultValue Array.empty
+
+[]
+let ``The call site of a generic function should have no influence on the name of the type parameters`` () =
+ let definitionFile =
+ Fs
+ """
+module A
+
+let someGenericFunction _ = ()
+"""
+ |> withFileName "A.fs"
+
+ let usageFile =
+ ("""
+module B
+
+let otherGenericFunction _ _ _ =
+ A.someGenericFunction 1
+"""
+ |> FsSource)
+ .WithFileName("B.fs")
+
+ let namesForB =
+ getGenericParametersNamesFor definitionFile "A" "someGenericFunction" usageFile
+
+ let alternativeUsageFile =
+ ("""
+module C
+
+let alternateGenericFunction _ =
+ A.someGenericFunction 1
+"""
+ |> FsSource)
+ .WithFileName("C.fs")
+
+ let namesForC =
+ getGenericParametersNamesFor definitionFile "A" "someGenericFunction" alternativeUsageFile
+
+ Assert.Equal(namesForB, namesForC)
+
+[]
+let ``Fixed typar name in signature file is still respected`` () =
+ let signatureFile =
+ Fsi
+ """
+module A
+
+val someGenericFunction: 'x -> unit
+"""
+ |> withFileName "A.fsi"
+
+ let implementationFile =
+ ("""
+module A
+
+let someGenericFunction _ = ()
+"""
+ |> FsSource)
+ .WithFileName("A.fs")
+
+ let names =
+ getGenericParametersNamesFor signatureFile "A" "someGenericFunction" implementationFile
+
+ Assert.Equal([| "x" |], names)
+
+[]
+let ``Hash constraint typar in signature file gets pretty name`` () =
+ let signatureFile =
+ Fsi
+ """
+module A
+
+val someGenericFunction: #exn list -> unit
+"""
+ |> withFileName "A.fsi"
+
+ let implementationFile =
+ ("""
+module A
+
+let someGenericFunction (_ : #exn list) = ()
+"""
+ |> FsSource)
+ .WithFileName("A.fs")
+
+ let names =
+ getGenericParametersNamesFor signatureFile "A" "someGenericFunction" implementationFile
+
+ Assert.Equal([| "a" |], names)
+
+[]
+let ``Hash constraint with generic type parameter should have pretty name`` () =
+ let signatureFile =
+ Fsi
+ """
+module A
+
+val array2D: rows: seq<#seq<'T>> -> 'T[,]
+"""
+ |> withFileName "A.fsi"
+
+ let implementationFile =
+ ("""
+module A
+
+let array2D (rows: seq<#seq<'T>>) : 'T[,] = failwith "todo"
+"""
+ |> FsSource)
+ .WithFileName("A.fs")
+
+ let names =
+ getGenericParametersNamesFor signatureFile "A" "array2D" implementationFile
+
+ Assert.Equal([| "a"; "T" |], names)
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl
index 1924e0d7067..8d196f405f3 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl
@@ -42,7 +42,6 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, I
Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T)
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
-Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
@@ -662,6 +661,7 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken])
+Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose()
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg)
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Start()
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void add_Error(Microsoft.FSharp.Control.FSharpHandler`1[System.Exception])
@@ -987,7 +987,7 @@ Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToTextWriter[T](Syste
Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormat[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit])
Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceExpression[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T])
Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceUntypedExpression[T](Microsoft.FSharp.Quotations.FSharpExpr)
-Microsoft.FSharp.Core.ExtraTopLevelOperators: T[,] CreateArray2D[?,T](System.Collections.Generic.IEnumerable`1[?])
+Microsoft.FSharp.Core.ExtraTopLevelOperators: T[,] CreateArray2D[a,T](System.Collections.Generic.IEnumerable`1[a])
Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 Item
Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 get_Item()
Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: T2 Item
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl
index 4458119e921..8e493cc60ad 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl
@@ -40,12 +40,12 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32
Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]])
Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32)
Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T)
+Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
+Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
-Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
-Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
@@ -987,7 +987,7 @@ Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToTextWriter[T](Syste
Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormat[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit])
Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceExpression[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T])
Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceUntypedExpression[T](Microsoft.FSharp.Quotations.FSharpExpr)
-Microsoft.FSharp.Core.ExtraTopLevelOperators: T[,] CreateArray2D[?,T](System.Collections.Generic.IEnumerable`1[?])
+Microsoft.FSharp.Core.ExtraTopLevelOperators: T[,] CreateArray2D[a,T](System.Collections.Generic.IEnumerable`1[a])
Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 Item
Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 get_Item()
Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: T2 Item
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl
index efa567e9d49..2577f674bad 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl
@@ -661,6 +661,7 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken])
+Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose()
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg)
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Start()
Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void add_Error(Microsoft.FSharp.Control.FSharpHandler`1[System.Exception])
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl
index 3f24d58bbc1..55ebd5ff7bb 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl
@@ -42,11 +42,11 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, I
Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T)
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
-Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
+Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[])
@@ -988,7 +988,7 @@ Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToTextWriter[T](Syste
Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormat[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit])
Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceExpression[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T])
Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceUntypedExpression[T](Microsoft.FSharp.Quotations.FSharpExpr)
-Microsoft.FSharp.Core.ExtraTopLevelOperators: T[,] CreateArray2D[?,T](System.Collections.Generic.IEnumerable`1[?])
+Microsoft.FSharp.Core.ExtraTopLevelOperators: T[,] CreateArray2D[a,T](System.Collections.Generic.IEnumerable`1[a])
Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 Item
Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 get_Item()
Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: T2 Item
@@ -2525,4 +2525,4 @@ Microsoft.FSharp.Reflection.UnionCaseInfo: System.String Name
Microsoft.FSharp.Reflection.UnionCaseInfo: System.String ToString()
Microsoft.FSharp.Reflection.UnionCaseInfo: System.String get_Name()
Microsoft.FSharp.Reflection.UnionCaseInfo: System.Type DeclaringType
-Microsoft.FSharp.Reflection.UnionCaseInfo: System.Type get_DeclaringType()
+Microsoft.FSharp.Reflection.UnionCaseInfo: System.Type get_DeclaringType()
\ No newline at end of file
diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs
index 38352109215..c49e3f35a00 100644
--- a/tests/FSharp.Test.Utilities/Compiler.fs
+++ b/tests/FSharp.Test.Utilities/Compiler.fs
@@ -6,6 +6,7 @@ open FSharp.Compiler.Interactive.Shell
open FSharp.Compiler.IO
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.Symbols
+open FSharp.Compiler.Text
open FSharp.Test.Assert
open FSharp.Test.Utilities
open FSharp.Test.ScriptHelpers
@@ -347,6 +348,12 @@ module rec Compiler =
| CS src -> CS { src with Name = Some name }
| IL _ -> failwith "IL Compilation cannot be named."
+ let withFileName (name: string) (cUnit: CompilationUnit) : CompilationUnit =
+ match cUnit with
+ | FS compilationSource -> FS { compilationSource with Source = compilationSource.Source.WithFileName(name) }
+ | CS cSharpCompilationSource -> CS { cSharpCompilationSource with Source = cSharpCompilationSource.Source.WithFileName(name) }
+ | IL _ -> failwith "IL Compilation cannot be named."
+
let withReferenceFSharpCompilerService (cUnit: CompilationUnit) : CompilationUnit =
// Compute the location of the FSharp.Compiler.Service dll that matches the target framework used to build this test assembly
let compilerServiceAssemblyLocation =
@@ -816,6 +823,26 @@ module rec Compiler =
CompilerAssert.TypeCheck(options, fileName, source)
| _ -> failwith "Typecheck only supports F#"
+ let typecheckProject (cUnit: CompilationUnit) : FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults =
+ match cUnit with
+ | FS fsSource ->
+ let options = fsSource.Options |> Array.ofList
+ let sourceFiles =
+ [| yield (fsSource.Source.GetSourceFileName, fsSource.Source.GetSourceText)
+ yield!
+ fsSource.AdditionalSources
+ |> List.map (fun source -> source.GetSourceFileName, source.GetSourceText) |]
+
+ let getSourceText =
+ let project = Map.ofArray sourceFiles
+ fun (name: string) ->
+ Map.tryFind name project
+ |> Option.bind (Option.map SourceText.ofString)
+
+ let sourceFiles = Array.map fst sourceFiles
+ CompilerAssert.TypeCheckProject(options, sourceFiles, getSourceText)
+ | _ -> failwith "Typecheck only supports F#"
+
let run (result: CompilationResult) : CompilationResult =
match result with
| CompilationResult.Failure f -> failwith (sprintf "Compilation should be successful in order to run.\n Errors: %A" (f.Diagnostics))
diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs
index 68924870f76..742be80cf6e 100644
--- a/tests/FSharp.Test.Utilities/CompilerAssert.fs
+++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs
@@ -2,6 +2,8 @@
namespace FSharp.Test
+#nowarn "57"
+
open System
open System.IO
open System.Text
@@ -856,6 +858,14 @@ Updated automatically, please check diffs in your pull request, changes must be
static member TypeCheckSingleError (source: string) (expectedSeverity: FSharpDiagnosticSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) =
CompilerAssert.TypeCheckWithErrors source [| expectedSeverity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]
+ static member TypeCheckProject(options: string array, sourceFiles: string array, getSourceText: string -> ISourceText option) : FSharpCheckProjectResults =
+ let checker = FSharpChecker.Create(documentSource = DocumentSource.Custom getSourceText)
+ let defaultOptions = defaultProjectOptions TargetFramework.Current
+ let projectOptions = { defaultOptions with OtherOptions = Array.append options defaultOptions.OtherOptions; SourceFiles = sourceFiles }
+
+ checker.ParseAndCheckProject(projectOptions)
+ |> Async.RunImmediate
+
static member CompileExeWithOptions(options, (source: SourceCodeFileKind)) =
compile true options source (fun (errors, _, _) ->
if errors.Length > 0 then
diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs
index 12ca78b4aab..715ec77870b 100644
--- a/tests/service/ProjectAnalysisTests.fs
+++ b/tests/service/ProjectAnalysisTests.fs
@@ -4015,7 +4015,7 @@ let ``Test project28 all symbols in signature`` () =
("FSharpEntity", "Use", "T:M.Use");
("FSharpMemberOrFunctionOrValue", "``.ctor``", "M:M.Use.#ctor");
("FSharpMemberOrFunctionOrValue", "Test", "M:M.Use.Test``1(``0)");
- ("FSharpGenericParameter", "``?``", "")|]
+ ("FSharpGenericParameter", "a", "")|]
|> Array.iter (fun x ->
if xmlDocSigs |> Array.exists (fun y -> x = y) |> not then
failwithf "%A does not exist in the collection." x