diff --git a/FSharp.Profiles.props b/FSharp.Profiles.props
index 534ba96c04f..b0c4c500b8a 100644
--- a/FSharp.Profiles.props
+++ b/FSharp.Profiles.props
@@ -1,6 +1,9 @@
+
+ BUILDING_WITH_LKG;$(DefineConstants)
+ $(DefineConstants);CROSS_PLATFORM_COMPILER
diff --git a/FSharpBuild.Directory.Build.props b/FSharpBuild.Directory.Build.props
index a1ba7ab156d..8d705695853 100644
--- a/FSharpBuild.Directory.Build.props
+++ b/FSharpBuild.Directory.Build.props
@@ -11,8 +11,7 @@
$(RepoRoot)src$(ArtifactsDir)\SymStore
- $(ArtifactsDir)\Bootstrap
- $(ArtifactsDir)/fsc/Proto/netcoreapp2.1
+ $(ArtifactsDir)\Bootstrap4.4.01182;0025;$(WarningsAsErrors)
@@ -92,14 +91,15 @@
fsfalsetrue
+ 4.6.2
- $(ProtoOutputPath)\Microsoft.FSharp.Targets
- $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.props
- $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.targets
- $(ProtoOutputPath)\Microsoft.FSharp.Overrides.NetSdk.targets
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.Targets
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.NetSdk.props
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.NetSdk.targets
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.Overrides.NetSdk.targets
diff --git a/FSharpTests.Directory.Build.props b/FSharpTests.Directory.Build.props
index 7c00805dda5..8a7a832a43e 100644
--- a/FSharpTests.Directory.Build.props
+++ b/FSharpTests.Directory.Build.props
@@ -32,9 +32,9 @@
- <_FSharpBuildTargetFramework Condition="'$(FSharpTestCompilerVersion)' == 'net40'">net472
- <_FSharpBuildTargetFramework Condition="'$(FSharpTestCompilerVersion)' == 'coreclr'">netcoreapp2.1
- <_FSharpBuildBinPath>$(MSBuildThisFileDirectory)artifacts\bin\FSharp.Build\$(Configuration)\$(_FSharpBuildTargetFramework)
+ <_FSharpBuildTargetFramework Condition="'$(MSBuildRuntimeType)'!='Core'">net472
+ <_FSharpBuildTargetFramework Condition="'$(MSBuildRuntimeType)'=='Core'">netcoreapp2.1
+ <_FSharpBuildBinPath>$(MSBuildThisFileDirectory)artifacts\bin\fsc\$(Configuration)\$(_FSharpBuildTargetFramework)
$(_FSharpBuildBinPath)\FSharp.Build.dll
diff --git a/eng/Build.ps1 b/eng/Build.ps1
index 6b85aaef9cf..158662e7a47 100644
--- a/eng/Build.ps1
+++ b/eng/Build.ps1
@@ -67,6 +67,7 @@ function Print-Usage() {
Write-Host ""
Write-Host "Actions:"
Write-Host " -restore Restore packages (short: -r)"
+ Write-Host " -norestore Don't restore packages"
Write-Host " -build Build main solution (short: -b)"
Write-Host " -rebuild Rebuild main solution"
Write-Host " -pack Build NuGet packages, VS insertion manifests and installer"
@@ -104,6 +105,7 @@ function Process-Arguments() {
Print-Usage
exit 0
}
+ $script:nodeReuse = $False;
if ($testAll) {
$script:testDesktop = $True
@@ -130,7 +132,7 @@ function Process-Arguments() {
}
function Update-Arguments() {
- if (-Not (Test-Path "$ArtifactsDir\Bootstrap\fsc.exe")) {
+ if (-Not (Test-Path "$ArtifactsDir\Bootstrap\fsc\fsc.exe")) {
$script:bootstrap = $True
}
}
@@ -164,7 +166,6 @@ function BuildSolution() {
/p:Publish=$publish `
/p:ContinuousIntegrationBuild=$ci `
/p:OfficialBuildId=$officialBuildId `
- /p:BootstrapBuildPath=$bootstrapDir `
/p:QuietRestore=$quietRestore `
/p:QuietRestoreBinaryLog=$binaryLog `
/p:TestTargetFrameworks=$testTargetFrameworks `
@@ -198,7 +199,7 @@ function UpdatePath() {
}
function VerifyAssemblyVersions() {
- $fsiPath = Join-Path $ArtifactsDir "bin\fsi\Proto\net472\fsi.exe"
+ $fsiPath = Join-Path $ArtifactsDir "bin\fsi\Proto\net472\publish\fsi.exe"
# Only verify versions on CI or official build
if ($ci -or $official) {
diff --git a/eng/build-utils.ps1 b/eng/build-utils.ps1
index d1e5dd85d55..335379b2f73 100644
--- a/eng/build-utils.ps1
+++ b/eng/build-utils.ps1
@@ -178,7 +178,7 @@ function Get-PackageDir([string]$name, [string]$version = "") {
return $p
}
-function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]$logFileName = "", [switch]$parallel = $true, [switch]$summary = $true, [switch]$warnAsError = $true, [string]$configuration = $script:configuration) {
+function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]$logFileName = "", [switch]$parallel = $true, [switch]$summary = $true, [switch]$warnAsError = $true, [string]$configuration = $script:configuration, [string]$verbosity = $script:verbosity) {
# Because we override the C#/VB toolset to build against our LKG package, it is important
# that we do not reuse MSBuild nodes from other jobs/builds on the machine. Otherwise,
# we'll run into issues such as https://github.com/dotnet/roslyn/issues/6211.
@@ -216,10 +216,6 @@ function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]
$args += " /p:ContinuousIntegrationBuild=true"
}
- if ($bootstrapDir -ne "") {
- $args += " /p:BootstrapBuildPath=$bootstrapDir"
- }
-
$args += " $buildArgs"
$args += " $projectFilePath"
$args += " $properties"
@@ -241,15 +237,15 @@ function Make-BootstrapBuild() {
Create-Directory $dir
# prepare FsLex and Fsyacc
- Run-MSBuild "$RepoRoot\src\buildtools\buildtools.proj" "/restore /t:Build" -logFileName "BuildTools" -configuration $bootstrapConfiguration
- Copy-Item "$ArtifactsDir\bin\fslex\$bootstrapConfiguration\netcoreapp2.1\*" -Destination $dir
- Copy-Item "$ArtifactsDir\bin\fsyacc\$bootstrapConfiguration\netcoreapp2.1\*" -Destination $dir
+ Run-MSBuild "$RepoRoot\src\buildtools\buildtools.proj" "/restore /t:Publish" -logFileName "BuildTools" -configuration $bootstrapConfiguration
+ Copy-Item "$ArtifactsDir\bin\fslex\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\fslex" -Force -Recurse
+ Copy-Item "$ArtifactsDir\bin\fsyacc\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\fsyacc" -Force -Recurse
# prepare compiler
$projectPath = "$RepoRoot\proto.proj"
- Run-MSBuild $projectPath "/restore /t:Build" -logFileName "Bootstrap" -configuration $bootstrapConfiguration
- Copy-Item "$ArtifactsDir\bin\fsc\$bootstrapConfiguration\$bootstrapTfm\*" -Destination $dir
- Copy-Item "$ArtifactsDir\bin\fsi\$bootstrapConfiguration\$bootstrapTfm\*" -Destination $dir
+ Run-MSBuild $projectPath "/restore /t:Publish" -logFileName "Bootstrap" -configuration $bootstrapConfiguration
+ Copy-Item "$ArtifactsDir\bin\fsc\$bootstrapConfiguration\$bootstrapTfm\publish" -Destination "$dir\fsc" -Force -Recurse
+ Copy-Item "$ArtifactsDir\bin\fsi\$bootstrapConfiguration\$bootstrapTfm\publish" -Destination "$dir\fsi" -Force -Recurse
return $dir
}
diff --git a/eng/build.sh b/eng/build.sh
index 58b283ff39b..0a7549c96f2 100755
--- a/eng/build.sh
+++ b/eng/build.sh
@@ -13,7 +13,9 @@ usage()
echo " --binaryLog Create MSBuild binary log (short: -bl)"
echo ""
echo "Actions:"
+ echo " --bootstrap Force the build of the bootstrap compiler"
echo " --restore Restore projects required to build (short: -r)"
+ echo " --norestore Don't restore projects required to build"
echo " --build Build all projects (short: -b)"
echo " --rebuild Rebuild all projects"
echo " --pack Build nuget packages"
@@ -54,6 +56,7 @@ test_core_clr=false
configuration="Debug"
verbosity='minimal'
binary_log=false
+force_bootstrap=false
ci=false
skip_analyzers=false
prepare_machine=false
@@ -88,6 +91,9 @@ while [[ $# > 0 ]]; do
--binarylog|-bl)
binary_log=true
;;
+ --bootstrap)
+ force_bootstrap=true
+ ;;
--restore|-r)
restore=true
;;
@@ -205,17 +211,33 @@ function BuildSolution {
quiet_restore=true
fi
+ # Node reuse fails because multiple different versions of FSharp.Build.dll get loaded into MSBuild nodes
+ node_reuse=false
+
# build bootstrap tools
bootstrap_config=Proto
- MSBuild "$repo_root/src/buildtools/buildtools.proj" \
- /restore \
- /p:Configuration=$bootstrap_config \
- /t:Build
-
bootstrap_dir=$artifacts_dir/Bootstrap
- mkdir -p "$bootstrap_dir"
- cp $artifacts_dir/bin/fslex/$bootstrap_config/netcoreapp2.1/* $bootstrap_dir
- cp $artifacts_dir/bin/fsyacc/$bootstrap_config/netcoreapp2.1/* $bootstrap_dir
+ if [[ "$force_bootstrap" == true ]]; then
+ rm -fr $bootstrap_dir
+ fi
+ if [ ! -f "$bootstrap_dir/fslex.dll" ]; then
+ MSBuild "$repo_root/src/buildtools/buildtools.proj" \
+ /restore \
+ /p:Configuration=$bootstrap_config \
+ /t:Publish
+
+ mkdir -p "$bootstrap_dir"
+ cp -pr $artifacts_dir/bin/fslex/$bootstrap_config/netcoreapp2.1/publish $bootstrap_dir/fslex
+ cp -pr $artifacts_dir/bin/fsyacc/$bootstrap_config/netcoreapp2.1/publish $bootstrap_dir/fsyacc
+ fi
+ if [ ! -f "$bootstrap_dir/fsc.exe" ]; then
+ MSBuild "$repo_root/proto.proj" \
+ /restore \
+ /p:Configuration=$bootstrap_config \
+ /t:Publish
+
+ cp -pr $artifacts_dir/bin/fsc/$bootstrap_config/netcoreapp2.1/publish $bootstrap_dir/fsc
+ fi
# do real build
MSBuild $toolset_build_proj \
diff --git a/fcs/Directory.Build.props b/fcs/Directory.Build.props
index 50e4c3e67b5..f901d93281c 100644
--- a/fcs/Directory.Build.props
+++ b/fcs/Directory.Build.props
@@ -31,7 +31,6 @@
$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.27\toolsfsi.exe
- $(ArtifactsBinDir)\FSharp.Build\Proto\net4724.6.2net461
diff --git a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
index 1f7ffbf6d55..9019c4f017a 100644
--- a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
+++ b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
@@ -10,6 +10,7 @@
falsetruetrue
+ $(DefineConstants);USES_FSHARP_CORE_45_PACKAGE$(DefineConstants);FX_NO_RUNTIMEENVIRONMENT
diff --git a/fcs/FSharp.Compiler.Service/AssemblyInfo.fs b/fcs/FSharp.Compiler.Service/AssemblyInfo.fs
index 90521fefd5a..20b5b909304 100644
--- a/fcs/FSharp.Compiler.Service/AssemblyInfo.fs
+++ b/fcs/FSharp.Compiler.Service/AssemblyInfo.fs
@@ -52,11 +52,4 @@ open System.Runtime.InteropServices
[]
[]
-// Until dotnet sdk can version assemblies, use this
-#if BUILD_FROM_SOURCE
-[]
-[]
-[]
-#endif
-
do()
\ No newline at end of file
diff --git a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
index ef30acc7efc..a13a5d5a27c 100644
--- a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
+++ b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
@@ -4,8 +4,8 @@
$(FcsTargetNetFxFramework);netstandard2.0true
- $(DefineConstants);COMPILER_SERVICE_AS_DLL$(DefineConstants);COMPILER
+ $(DefineConstants);BUILD_FROM_SOURCE$(DefineConstants);ENABLE_MONO_SUPPORT$(DefineConstants);NO_STRONG_NAMES$(TargetFramework)\
@@ -39,7 +39,7 @@
$(DefineConstants);FX_RESHAPED_REFEMIT
-
+
AssemblyInfo/AssemblyInfo.fs
diff --git a/proto.proj b/proto.proj
index 84103f6fdf8..b0ee288977f 100644
--- a/proto.proj
+++ b/proto.proj
@@ -28,6 +28,10 @@
+
+
+
+
diff --git a/src/absil/bytes.fs b/src/absil/bytes.fs
index a272b99a454..b0749e48713 100644
--- a/src/absil/bytes.fs
+++ b/src/absil/bytes.fs
@@ -36,6 +36,9 @@ type internal ByteStream =
{ bytes: byte[]
mutable pos: int
max: int }
+
+ member b.IsEOF = (b.pos >= b.max)
+
member b.ReadByte() =
if b.pos >= b.max then failwith "end of stream"
let res = b.bytes.[b.pos]
@@ -56,11 +59,6 @@ type internal ByteStream =
res
member b.Position = b.pos
-#if LAZY_UNPICKLE
- member b.CloneAndSeek = { bytes=b.bytes; pos=pos; max=b.max }
- member b.Skip = b.pos <- b.pos + n
-#endif
-
type internal ByteBuffer =
{ mutable bbArray: byte[]
diff --git a/src/absil/bytes.fsi b/src/absil/bytes.fsi
index c611e80c776..58fbb2ab280 100644
--- a/src/absil/bytes.fsi
+++ b/src/absil/bytes.fsi
@@ -43,13 +43,10 @@ type internal ByteBuffer =
[]
type internal ByteStream =
+ member IsEOF : bool
member ReadByte : unit -> byte
member ReadBytes : int -> byte[]
member ReadUtf8String : int -> string
member Position : int
static member FromBytes : byte[] * start:int * length:int -> ByteStream
-#if LAZY_UNPICKLE
- member CloneAndSeek : int -> ByteStream
- member Skip : int -> unit
-#endif
diff --git a/src/absil/illib.fs b/src/absil/illib.fs
index fea0fd92a97..9218627c74f 100644
--- a/src/absil/illib.fs
+++ b/src/absil/illib.fs
@@ -12,10 +12,6 @@ open System.Reflection
open System.Threading
open System.Runtime.CompilerServices
-#if FX_RESHAPED_REFLECTION
-open Microsoft.FSharp.Core.ReflectionAdapters
-#endif
-
// Logical shift right treating int32 as unsigned integer.
// Code that uses this should probably be adjusted to use unsigned integer types.
let (>>>&) (x: int32) (n: int32) = int32 (uint32 x >>> n)
@@ -24,6 +20,11 @@ let notlazy v = Lazy<_>.CreateFromValue v
let inline isNil l = List.isEmpty l
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+let inline (|NonNull|) x = match x with null -> raise (NullReferenceException()) | v -> v
+let inline nonNull<'T> (x: 'T) = x
+#endif
+
/// Returns true if the list has less than 2 elements. Otherwise false.
let inline isNilOrSingleton l =
match l with
@@ -38,9 +39,6 @@ let inline isSingleton l =
| _ -> false
let inline isNonNull x = not (isNull x)
-
-let inline nonNull msg x = if isNull x then failwith ("null: " + msg) else x
-
let inline (===) x y = LanguagePrimitives.PhysicalEquality x y
/// Per the docs the threshold for the Large Object Heap is 85000 bytes: https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/large-object-heap#how-an-object-ends-up-on-the-large-object-heap-and-how-gc-handles-them
@@ -70,14 +68,17 @@ let reportTime =
type InlineDelayInit<'T when 'T : not struct> =
new (f: unit -> 'T) = {store = Unchecked.defaultof<'T>; func = Func<_>(f) }
val mutable store : 'T
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
val mutable func : Func<'T>
-
+#else
+ val mutable func : Func<'T> ?
+#endif
member x.Value =
match x.func with
| null -> x.store
| _ ->
let res = LazyInitializer.EnsureInitialized(&x.store, x.func)
- x.func <- Unchecked.defaultof<_>
+ x.func <- null
res
//-------------------------------------------------------------------------
@@ -201,9 +202,7 @@ module Array =
/// ~0.8x slower for ints
let inline areEqual (xs: 'T []) (ys: 'T []) =
match xs, ys with
- | null, null -> true
| [||], [||] -> true
- | null, _ | _, null -> false
| _ when xs.Length <> ys.Length -> false
| _ ->
let mutable break' = false
@@ -227,8 +226,7 @@ module Array =
/// check if subArray is found in the wholeArray starting
/// at the provided index
let inline isSubArray (subArray: 'T []) (wholeArray:'T []) index =
- if isNull subArray || isNull wholeArray then false
- elif subArray.Length = 0 then true
+ if subArray.Length = 0 then true
elif subArray.Length > wholeArray.Length then false
elif subArray.Length = wholeArray.Length then areEqual subArray wholeArray else
let rec loop subidx idx =
@@ -258,12 +256,6 @@ module Option =
module List =
- //let item n xs = List.nth xs n
-#if FX_RESHAPED_REFLECTION
- open PrimReflectionAdapters
- open Microsoft.FSharp.Core.ReflectionAdapters
-#endif
-
let sortWithOrder (c: IComparer<'T>) elements = List.sortWith (Order.toFunction c) elements
let splitAfter n l =
@@ -546,9 +538,6 @@ module String =
String strArr
let extractTrailingIndex (str: string) =
- match str with
- | null -> null, None
- | _ ->
let charr = str.ToCharArray()
Array.revInPlace charr
let digits = Array.takeWhile Char.IsDigit charr
@@ -558,13 +547,9 @@ module String =
| "" -> str, None
| index -> str.Substring (0, str.Length - index.Length), Some (int index)
- /// Remove all trailing and leading whitespace from the string
- /// return null if the string is null
- let trim (value: string) = if isNull value then null else value.Trim()
-
/// Splits a string into substrings based on the strings in the array separators
let split options (separator: string []) (value: string) =
- if isNull value then null else value.Split(separator, options)
+ value.Split(separator, options)
let (|StartsWith|_|) pattern value =
if String.IsNullOrWhiteSpace value then
@@ -1018,7 +1003,7 @@ type LazyWithContext<'T, 'ctxt> =
/// This field holds either the function to run or a LazyWithContextFailure object recording the exception raised
/// from running the function. It is null if the thunk has been evaluated successfully.
- mutable funcOrException: obj
+ mutable funcOrException: obj
/// A helper to ensure we rethrow the "original" exception
findOriginalException : exn -> exn }
@@ -1051,9 +1036,11 @@ type LazyWithContext<'T, 'ctxt> =
member x.UnsynchronizedForce ctxt =
match x.funcOrException with
| null -> x.value
+
| :? LazyWithContextFailure as res ->
// Re-raise the original exception
raise (x.findOriginalException res.Exception)
+
| :? ('ctxt -> 'T) as f ->
x.funcOrException <- box(LazyWithContextFailure.Undefined)
try
@@ -1064,6 +1051,7 @@ type LazyWithContext<'T, 'ctxt> =
with e ->
x.funcOrException <- box(new LazyWithContextFailure(e))
reraise()
+
| _ ->
failwith "unreachable"
@@ -1272,11 +1260,6 @@ type LayeredMultiMap<'Key, 'Value when 'Key : equality and 'Key : comparison>(co
[]
module Shim =
-#if FX_RESHAPED_REFLECTION
- open PrimReflectionAdapters
- open Microsoft.FSharp.Core.ReflectionAdapters
-#endif
-
type IFileSystem =
/// A shim over File.ReadAllBytes
@@ -1346,14 +1329,32 @@ module Shim =
member __.IsPathRootedShim (path: string) = Path.IsPathRooted path
member __.IsInvalidPathShim(path: string) =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let isInvalidPath(p: string) =
- String.IsNullOrEmpty p || p.IndexOfAny(Path.GetInvalidPathChars()) <> -1
+#else
+ let isInvalidPath(p: string?) =
+#endif
+ match p with
+ | null | "" -> true
+ | NonNull p -> p.IndexOfAny(Path.GetInvalidPathChars()) <> -1
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let isInvalidFilename(p: string) =
- String.IsNullOrEmpty p || p.IndexOfAny(Path.GetInvalidFileNameChars()) <> -1
+#else
+ let isInvalidFilename(p: string?) =
+#endif
+ match p with
+ | null | "" -> true
+ | NonNull p -> p.IndexOfAny(Path.GetInvalidFileNameChars()) <> -1
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let isInvalidDirectory(d: string) =
- d=null || d.IndexOfAny(Path.GetInvalidPathChars()) <> -1
+#else
+ let isInvalidDirectory(d: string?) =
+#endif
+ match d with
+ | null -> true
+ | NonNull d -> d.IndexOfAny(Path.GetInvalidPathChars()) <> -1
isInvalidPath path ||
let directory = Path.GetDirectoryName path
diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs
index 280bbf0c384..88b0ef474f7 100644
--- a/src/absil/ilread.fs
+++ b/src/absil/ilread.fs
@@ -213,7 +213,11 @@ module MemoryMapping =
int _flProtect,
int _dwMaximumSizeLow,
int _dwMaximumSizeHigh,
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
string _lpName)
+#else
+ string? _lpName)
+#endif
[]
extern ADDR MapViewOfFile (HANDLE _hFileMappingObject,
@@ -892,7 +896,11 @@ type GenericParamsIdx = GenericParamsIdx of int * TypeOrMethodDefTag * int
let mkCacheInt32 lowMem _inbase _nm _sz =
if lowMem then (fun f x -> f x) else
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let cache = ref null
+#else
+ let cache : Dictionary<_,_>? ref = ref null // TODO NULLNESS: this explicit annotation should not be needed
+#endif
let count = ref 0
#if STATISTICS
addReport (fun oc -> if !count <> 0 then oc.WriteLine ((_inbase + string !count + " "+ _nm + " cache hits"): string))
@@ -900,9 +908,12 @@ let mkCacheInt32 lowMem _inbase _nm _sz =
fun f (idx: int32) ->
let cache =
match !cache with
- | null -> cache := new Dictionary(11)
- | _ -> ()
- !cache
+ | null ->
+ let c = new Dictionary(11)
+ cache := c
+ c
+ | NonNull c -> c
+
match cache.TryGetValue idx with
| true, res ->
incr count
@@ -914,7 +925,11 @@ let mkCacheInt32 lowMem _inbase _nm _sz =
let mkCacheGeneric lowMem _inbase _nm _sz =
if lowMem then (fun f x -> f x) else
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let cache = ref null
+#else
+ let cache : Dictionary<_,_>? ref = ref null // TODO NULLNESS: this explicit annotation should not be needed
+#endif
let count = ref 0
#if STATISTICS
addReport (fun oc -> if !count <> 0 then oc.WriteLine ((_inbase + string !count + " " + _nm + " cache hits"): string))
@@ -922,10 +937,13 @@ let mkCacheGeneric lowMem _inbase _nm _sz =
fun f (idx :'T) ->
let cache =
match !cache with
- | null -> cache := new Dictionary<_, _>(11 (* sz: int *) )
- | _ -> ()
- !cache
- match cache.TryGetValue idx with
+ | null ->
+ let c = new Dictionary<_, _>(11)
+ cache := c
+ c
+ | NonNull c -> c
+
+ match cache.TryGetValue(idx) with
| true, v ->
incr count
v
diff --git a/src/absil/ilreflect.fs b/src/absil/ilreflect.fs
index 404ebf81b0c..5a1151f2351 100644
--- a/src/absil/ilreflect.fs
+++ b/src/absil/ilreflect.fs
@@ -22,7 +22,6 @@ open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.ILAsciiWriter
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.Range
-open FSharp.Core.Printf
#if FX_RESHAPED_REFLECTION
open Microsoft.FSharp.Core.ReflectionAdapters
@@ -392,10 +391,15 @@ let emEnv0 =
emEntryPts = []
delayedFieldInits = [] }
-let envBindTypeRef emEnv (tref: ILTypeRef) (typT, typB, typeDef) =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+let envBindTypeRef emEnv (tref: ILTypeRef) (typT: System.Type, typB, typeDef)=
+#else
+let envBindTypeRef emEnv (tref: ILTypeRef) (typT: System.Type?, typB, typeDef)=
+#endif
match typT with
| null -> failwithf "binding null type in envBindTypeRef: %s\n" tref.Name
- | _ -> {emEnv with emTypMap = Zmap.add tref (typT, typB, typeDef, None) emEnv.emTypMap}
+ | NonNull typT ->
+ {emEnv with emTypMap = Zmap.add tref (typT, typB, typeDef, None) emEnv.emTypMap}
let envUpdateCreatedTypeRef emEnv (tref: ILTypeRef) =
// The tref's TypeBuilder has been created, so we have a Type proper.
@@ -424,14 +428,10 @@ let envUpdateCreatedTypeRef emEnv (tref: ILTypeRef) =
emEnv
let convTypeRef cenv emEnv preferCreated (tref: ILTypeRef) =
- let res =
- match Zmap.tryFind tref emEnv.emTypMap with
- | Some (_typT, _typB, _typeDef, Some createdTy) when preferCreated -> createdTy
- | Some (typT, _typB, _typeDef, _) -> typT
- | None -> convTypeRefAux cenv tref
- match res with
- | null -> error(Error(FSComp.SR.itemNotFoundDuringDynamicCodeGen ("type", tref.QualifiedName, tref.Scope.QualifiedName), range0))
- | _ -> res
+ match Zmap.tryFind tref emEnv.emTypMap with
+ | Some (_typT, _typB, _typeDef, Some createdTy) when preferCreated -> createdTy
+ | Some (typT, _typB, _typeDef, _) -> typT
+ | None -> convTypeRefAux cenv tref
let envBindConsRef emEnv (mref: ILMethodRef) consB =
{emEnv with emConsMap = Zmap.add mref consB emEnv.emConsMap}
@@ -533,7 +533,7 @@ let rec convTypeSpec cenv emEnv preferCreated (tspec: ILTypeSpec) =
| _, false -> null
match res with
| null -> error(Error(FSComp.SR.itemNotFoundDuringDynamicCodeGen ("type", tspec.TypeRef.QualifiedName, tspec.Scope.QualifiedName), range0))
- | _ -> res
+ | NonNull res -> res
and convTypeAux cenv emEnv preferCreated ty =
match ty with
@@ -675,7 +675,7 @@ let queryableTypeGetField _emEnv (parentT: Type) (fref: ILFieldRef) =
let res = parentT.GetField(fref.Name, BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance ||| BindingFlags.Static )
match res with
| null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("field", fref.Name, fref.DeclaringTypeRef.FullName, fref.DeclaringTypeRef.Scope.QualifiedName), range0))
- | _ -> res
+ | NonNull res -> res
let nonQueryableTypeGetField (parentTI: Type) (fieldInfo: FieldInfo) : FieldInfo =
let res =
@@ -683,10 +683,10 @@ let nonQueryableTypeGetField (parentTI: Type) (fieldInfo: FieldInfo) : FieldInfo
else fieldInfo
match res with
| null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("field", fieldInfo.Name, parentTI.AssemblyQualifiedName, parentTI.Assembly.FullName), range0))
- | _ -> res
+ | NonNull res -> res
-let convFieldSpec cenv emEnv fspec =
+let convFieldSpec cenv emEnv fspec : FieldInfo =
let fref = fspec.FieldRef
let tref = fref.DeclaringTypeRef
let parentTI = convType cenv emEnv fspec.DeclaringType
@@ -778,8 +778,8 @@ let queryableTypeGetMethodBySearch cenv emEnv parentT (mref: ILMethodRef) =
failwithf "convMethodRef: could not bind to method '%A' of type '%s'" (System.String.Join(", ", methNames)) parentT.AssemblyQualifiedName
| Some methInfo -> methInfo (* return MethodInfo for (generic) type's (generic) method *)
-let queryableTypeGetMethod cenv emEnv parentT (mref: ILMethodRef) =
- assert(not (typeIsNotQueryable parentT))
+let queryableTypeGetMethod cenv emEnv parentT (mref: ILMethodRef) : MethodInfo =
+ assert(not (typeIsNotQueryable(parentT)))
if mref.GenericArity = 0 then
let tyargTs = getGenericArgumentsOfType parentT
let argTs, resT =
@@ -794,12 +794,20 @@ let queryableTypeGetMethod cenv emEnv parentT (mref: ILMethodRef) =
parentT.GetMethod(mref.Name, cconv ||| BindingFlags.Public ||| BindingFlags.NonPublic,
null,
argTs,
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
#if FX_RESHAPED_REFLECTION
(null: obj[]))
#else
(null: ParameterModifier[]))
#endif
- // This can fail if there is an ambiguity w.r.t. return type
+#else
+#if FX_RESHAPED_REFLECTION
+ (null:obj[]?))
+#else
+ (null:ParameterModifier[]?))
+#endif
+#endif
+ // This can fail if there is an ambiguity w.r.t. return type
with _ -> null
if (isNonNull methInfo && equalTypes resT methInfo.ReturnType) then
methInfo
@@ -808,13 +816,17 @@ let queryableTypeGetMethod cenv emEnv parentT (mref: ILMethodRef) =
else
queryableTypeGetMethodBySearch cenv emEnv parentT mref
-let nonQueryableTypeGetMethod (parentTI: Type) (methInfo: MethodInfo) : MethodInfo =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+let nonQueryableTypeGetMethod (parentTI:Type) (methInfo : MethodInfo) : MethodInfo =
+#else
+let nonQueryableTypeGetMethod (parentTI:Type) (methInfo : MethodInfo) : MethodInfo? =
+#endif
if (parentTI.IsGenericType &&
not (equalTypes parentTI (getTypeConstructor parentTI)))
then TypeBuilder.GetMethod(parentTI, methInfo )
else methInfo
-let convMethodRef cenv emEnv (parentTI: Type) (mref: ILMethodRef) =
+let convMethodRef cenv emEnv (parentTI: Type) (mref: ILMethodRef) : MethodInfo =
let parent = mref.DeclaringTypeRef
let res =
if isEmittedTypeRef emEnv parent then
@@ -832,7 +844,7 @@ let convMethodRef cenv emEnv (parentTI: Type) (mref: ILMethodRef) =
queryableTypeGetMethod cenv emEnv parentTI mref
match res with
| null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("method", mref.Name, parentTI.FullName, parentTI.Assembly.FullName), range0))
- | _ -> res
+ | NonNull res -> res
//----------------------------------------------------------------------------
// convMethodSpec
@@ -850,19 +862,26 @@ let convMethodSpec cenv emEnv (mspec: ILMethodSpec) =
methInfo
methInfo
-/// Get a constructor on a non-TypeBuilder type
-let queryableTypeGetConstructor cenv emEnv (parentT: Type) (mref: ILMethodRef) =
- let tyargTs = getGenericArgumentsOfType parentT
- let reqArgTs =
+//----------------------------------------------------------------------------
+// - QueryableTypeGetConstructors: get a constructor on a non-TypeBuilder type
+//----------------------------------------------------------------------------
+
+let queryableTypeGetConstructor cenv emEnv (parentT: Type) (mref: ILMethodRef) : ConstructorInfo =
+ let tyargTs = getGenericArgumentsOfType parentT
+ let reqArgTs =
let emEnv = envPushTyvars emEnv tyargTs
convTypesToArray cenv emEnv mref.ArgTypes
let res = parentT.GetConstructor(BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance, null, reqArgTs, null)
match res with
| null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("constructor", mref.Name, parentT.FullName, parentT.Assembly.FullName), range0))
- | _ -> res
+ | NonNull res -> res
-let nonQueryableTypeGetConstructor (parentTI: Type) (consInfo: ConstructorInfo) : ConstructorInfo =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+let nonQueryableTypeGetConstructor (parentTI:Type) (consInfo : ConstructorInfo) : ConstructorInfo =
+#else
+let nonQueryableTypeGetConstructor (parentTI:Type) (consInfo : ConstructorInfo) : ConstructorInfo? =
+#endif
if parentTI.IsGenericType then TypeBuilder.GetConstructor(parentTI, consInfo) else consInfo
/// convConstructorSpec (like convMethodSpec)
@@ -883,7 +902,7 @@ let convConstructorSpec cenv emEnv (mspec: ILMethodSpec) =
queryableTypeGetConstructor cenv emEnv parentTI mref
match res with
| null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("constructor", "", parentTI.FullName, parentTI.Assembly.FullName), range0))
- | _ -> res
+ | NonNull res -> res
let emitLabelMark emEnv (ilG: ILGenerator) (label: ILCodeLabel) =
let lab = envGetLabel emEnv label
@@ -956,17 +975,17 @@ let getGenericMethodDefinition q (ty: Type) =
let getArrayMethInfo n ty =
match n with
- | 2 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.GetArray2D null 0 0 @@> ty
- | 3 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.GetArray3D null 0 0 0 @@> ty
- | 4 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.GetArray4D null 0 0 0 0 @@> ty
+ | 2 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.GetArray2D Unchecked.defaultof<_> 0 0 @@> ty
+ | 3 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.GetArray3D Unchecked.defaultof<_> 0 0 0 @@> ty
+ | 4 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.GetArray4D Unchecked.defaultof<_> 0 0 0 0 @@> ty
| _ -> invalidArg "n" "not expecting array dimension > 4"
let setArrayMethInfo n ty =
match n with
- | 2 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.SetArray2D null 0 0 0 @@> ty
- | 3 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.SetArray3D null 0 0 0 0 @@> ty
- | 4 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.SetArray4D null 0 0 0 0 0 @@> ty
- | _ -> invalidArg "n" "not expecting array dimension > 4"
+ | 2 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.SetArray2D Unchecked.defaultof<_> 0 0 0 @@> ty
+ | 3 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.SetArray3D Unchecked.defaultof<_> 0 0 0 0 @@> ty
+ | 4 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.SetArray4D Unchecked.defaultof<_> 0 0 0 0 0 @@> ty
+ | _ -> invalidArg "n" "not expecting array dimension > 4"
//----------------------------------------------------------------------------
@@ -1272,23 +1291,23 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr =
setArrayMethInfo shape.Rank ety
else
#endif
- modB.GetArrayMethodAndLog (aty, "Set", System.Reflection.CallingConventions.HasThis, (null: Type), Array.append (Array.create shape.Rank (typeof)) (Array.ofList [ ety ]))
- ilG.EmitAndLog (OpCodes.Call, meth)
+ modB.GetArrayMethodAndLog(aty, "Set", System.Reflection.CallingConventions.HasThis, null, Array.append (Array.create shape.Rank (typeof)) (Array.ofList [ ety ]))
+ ilG.EmitAndLog(OpCodes.Call, meth)
| I_newarr (shape, ty) ->
if (shape = ILArrayShape.SingleDimensional)
then ilG.EmitAndLog (OpCodes.Newarr, convType cenv emEnv ty)
else
- let aty = convType cenv emEnv (ILType.Array(shape, ty))
- let meth = modB.GetArrayMethodAndLog (aty, ".ctor", System.Reflection.CallingConventions.HasThis, (null: Type), Array.create shape.Rank (typeof))
- ilG.EmitAndLog (OpCodes.Newobj, meth)
-
- | I_ldlen -> ilG.EmitAndLog OpCodes.Ldlen
- | I_mkrefany ty -> ilG.EmitAndLog (OpCodes.Mkrefany, convType cenv emEnv ty)
- | I_refanytype -> ilG.EmitAndLog OpCodes.Refanytype
- | I_refanyval ty -> ilG.EmitAndLog (OpCodes.Refanyval, convType cenv emEnv ty)
- | I_rethrow -> ilG.EmitAndLog OpCodes.Rethrow
- | I_break -> ilG.EmitAndLog OpCodes.Break
+ let aty = convType cenv emEnv (ILType.Array(shape, ty))
+ let meth = modB.GetArrayMethodAndLog(aty, ".ctor", System.Reflection.CallingConventions.HasThis, null, Array.create shape.Rank (typeof))
+ ilG.EmitAndLog(OpCodes.Newobj, meth)
+
+ | I_ldlen -> ilG.EmitAndLog(OpCodes.Ldlen)
+ | I_mkrefany ty -> ilG.EmitAndLog(OpCodes.Mkrefany, convType cenv emEnv ty)
+ | I_refanytype -> ilG.EmitAndLog(OpCodes.Refanytype)
+ | I_refanyval ty -> ilG.EmitAndLog(OpCodes.Refanyval, convType cenv emEnv ty)
+ | I_rethrow -> ilG.EmitAndLog(OpCodes.Rethrow)
+ | I_break -> ilG.EmitAndLog(OpCodes.Break)
| I_seqpoint src ->
#if FX_RESHAPED_REFEMIT
ignore src
@@ -1411,10 +1430,7 @@ let emitMethodBody cenv modB emEnv ilG _name (mbody: ILLazyMethodBody) =
| MethodBody.NotAvailable -> failwith "emitMethodBody: metadata only"
let convCustomAttr cenv emEnv (cattr: ILAttribute) =
- let methInfo =
- match convConstructorSpec cenv emEnv cattr.Method with
- | null -> failwithf "convCustomAttr: %+A" cattr.Method
- | res -> res
+ let methInfo = convConstructorSpec cenv emEnv cattr.Method
let data = getCustomAttrData cenv.ilg cattr
(methInfo, data)
diff --git a/src/absil/ilsign.fs b/src/absil/ilsign.fs
index 6fbc1ca4525..1061f542c70 100644
--- a/src/absil/ilsign.fs
+++ b/src/absil/ilsign.fs
@@ -10,6 +10,7 @@ open System.Collections.Immutable
open System.Reflection.PortableExecutable
open System.Security.Cryptography
open System.Runtime.InteropServices
+open FSharp.Compiler.AbstractIL.Internal.Library
type KeyType =
| Public
@@ -141,10 +142,18 @@ open System.Runtime.InteropServices
key.D <- reader.ReadBigInteger byteLen
key
- let toCLRKeyBlob (rsaParameters:RSAParameters) (algId:int) : byte[] =
- let validateRSAField (field:byte[]) expected (name:string) =
- if field <> null && field.Length <> expected then
- raise (CryptographicException(String.Format(getResourceString(FSComp.SR.ilSignInvalidRSAParams()), name)))
+ let toCLRKeyBlob (rsaParameters: RSAParameters) (algId: int) : byte[] =
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ let validateRSAField (field: byte[]) expected (name: string) =
+#else
+ let validateRSAField (field: byte[]?) expected (name: string) =
+#endif
+ match field with
+ | null -> ()
+ | NonNull field ->
+ if field.Length <> expected then
+ raise (CryptographicException(String.Format(getResourceString(FSComp.SR.ilSignInvalidRSAParams()), name)))
// The original FCall this helper emulates supports other algId's - however, the only algid we need to support is CALG_RSA_KEYX. We will not port the codepaths dealing with other algid's.
if algId <> CALG_RSA_KEYX then raise (CryptographicException(getResourceString(FSComp.SR.ilSignInvalidAlgId())))
diff --git a/src/absil/ilsupp.fs b/src/absil/ilsupp.fs
index 97280194f74..b02eacb77c2 100644
--- a/src/absil/ilsupp.fs
+++ b/src/absil/ilsupp.fs
@@ -900,115 +900,119 @@ type ImageDebugDirectory =
[]
type ISymUnmanagedWriter2 =
abstract DefineDocument: [] url: string *
- language: System.Guid byref *
- languageVendor: System.Guid byref *
- documentType: System.Guid byref *
- [] RetVal: ISymUnmanagedDocumentWriter byref -> unit
- abstract SetUserEntryPoint: entryMethod: uint32 -> unit
- abstract OpenMethod: meth: int -> unit
- abstract CloseMethod: unit -> unit
- abstract OpenScope: startOffset: int * pRetVal: int byref -> unit
- abstract CloseScope: endOffset: int -> unit
- abstract SetScopeRange: scopeID: int * startOffset: int * endOffset: int -> unit
- abstract DefineLocalVariable: [] varname: string *
- attributes: int *
- cSig: int *
- []signature: byte[] *
- addressKind: int *
- addr1: int *
- addr2: int *
- addr3: int *
- startOffset: int *
- endOffset: int -> unit
- abstract DefineParameter: [] paramname: string *
- attributes: int *
- sequence: int *
- addressKind: int *
- addr1: int *
- addr2: int *
- addr3: int -> unit
- abstract DefineField: parent: int *
- [] fieldname: string *
- attributes: int *
- cSig: int *
- []signature: byte[] *
- addressKind: int *
- addr1: int *
- addr2: int *
- addr3: int -> unit
- abstract DefineGlobalVariable: [] globalvarname: string *
- attributes: int *
- cSig: int *
- []signature: byte[] *
- addressKind: int *
- addr1: int *
- addr2: int *
- addr3: int -> unit
- abstract Close: unit -> unit
- abstract SetSymAttribute: parent: int *
- [] attname: string *
- cData: int *
- []data: byte[] -> unit
- abstract OpenNamespace: [] nsname: string -> unit
- abstract CloseNamespace: unit -> unit
- abstract UsingNamespace: [] fullName: string -> unit
- abstract SetMethodSourceRange: startDoc: ISymUnmanagedDocumentWriter *
- startLine: int *
- startColumn: int *
- endDoc: ISymUnmanagedDocumentWriter *
- endLine: int *
- endColumn: int -> unit
- abstract Initialize: emitter: nativeint *
- [] filename: string *
- stream: IStream *
- fullBuild: bool -> unit
- abstract GetDebugInfo: iDD: ImageDebugDirectory byref *
- cData: int *
- pcData: int byref *
- []data: byte[] -> unit
- abstract DefineSequencePoints: document: ISymUnmanagedDocumentWriter *
- spCount: int *
- []offsets: int [] *
- []lines: int [] *
- []columns: int [] *
- []endLines: int [] *
- []endColumns: int [] -> unit
- abstract RemapToken: oldToken: int * newToken: int -> unit
- abstract Initialize2: emitter: nativeint *
- [] tempfilename: string *
- stream: IStream *
- fullBuild: bool *
- [] finalfilename: string -> unit
- abstract DefineConstant: [] constname: string *
- value: Object *
- cSig: int *
- []signature: byte[] -> unit
- abstract Abort: unit -> unit
- abstract DefineLocalVariable2: [] localvarname2: string *
- attributes: int *
- sigToken: int *
- addressKind: int *
- addr1: int *
- addr2: int *
- addr3: int *
- startOffset: int *
- endOffset: int -> unit
- abstract DefineGlobalVariable2: [] globalvarname2: string *
- attributes: int *
- sigToken: int *
- addressKind: int *
- addr1: int *
- addr2: int *
- addr3: int -> unit
- abstract DefineConstant2: [] constantname2: string *
- value: Object *
- sigToken: int -> unit
- abstract OpenMethod2: method2: int *
- isect: int *
- offset: int -> unit
-
-type PdbWriter = { symWriter: ISymUnmanagedWriter2 }
-type PdbDocumentWriter = { symDocWriter: ISymUnmanagedDocumentWriter } (* pointer to pDocumentWriter COM object *)
+ language: System.Guid byref *
+ languageVendor: System.Guid byref *
+ documentType: System.Guid byref *
+ [] RetVal: ISymUnmanagedDocumentWriter byref -> unit
+ abstract SetUserEntryPoint : entryMethod : uint32 -> unit
+ abstract OpenMethod : meth : int -> unit
+ abstract CloseMethod : unit -> unit
+ abstract OpenScope : startOffset : int * pRetVal : int byref -> unit
+ abstract CloseScope : endOffset : int -> unit
+ abstract SetScopeRange : scopeID : int * startOffset : int * endOffset : int -> unit
+ abstract DefineLocalVariable : [] varname : string *
+ attributes : int *
+ cSig : int *
+ []signature : byte[] *
+ addressKind : int *
+ addr1 : int *
+ addr2 : int *
+ addr3 : int *
+ startOffset : int *
+ endOffset : int -> unit
+ abstract DefineParameter : [] paramname : string *
+ attributes : int *
+ sequence : int *
+ addressKind : int *
+ addr1 : int *
+ addr2 : int *
+ addr3 : int -> unit
+ abstract DefineField : parent : int *
+ [] fieldname : string *
+ attributes : int *
+ cSig : int *
+ []signature : byte[] *
+ addressKind : int *
+ addr1 : int *
+ addr2 : int *
+ addr3 : int -> unit
+ abstract DefineGlobalVariable : [] globalvarname : string *
+ attributes : int *
+ cSig : int *
+ []signature : byte[] *
+ addressKind : int *
+ addr1 : int *
+ addr2 : int *
+ addr3 : int -> unit
+ abstract Close : unit -> unit
+ abstract SetSymAttribute : parent : int *
+ [] attname : string *
+ cData : int *
+ []data : byte[] -> unit
+ abstract OpenNamespace : [] nsname : string -> unit
+ abstract CloseNamespace : unit -> unit
+ abstract UsingNamespace : [] fullName : string -> unit
+ abstract SetMethodSourceRange : startDoc : ISymUnmanagedDocumentWriter *
+ startLine : int *
+ startColumn : int *
+ endDoc : ISymUnmanagedDocumentWriter *
+ endLine : int *
+ endColumn : int -> unit
+ abstract Initialize : emitter : nativeint *
+ [] filename : string *
+ stream : IStream *
+ fullBuild : bool -> unit
+ abstract GetDebugInfo : iDD : ImageDebugDirectory byref *
+ cData : int *
+ pcData : int byref *
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []data : byte[] -> unit
+#else
+ []data : byte[]? -> unit
+#endif
+ abstract DefineSequencePoints : document : ISymUnmanagedDocumentWriter *
+ spCount : int *
+ []offsets : int [] *
+ []lines : int [] *
+ []columns : int [] *
+ []endLines : int [] *
+ []endColumns : int [] -> unit
+ abstract RemapToken : oldToken : int * newToken : int -> unit
+ abstract Initialize2 : emitter : nativeint *
+ [] tempfilename : string *
+ stream : IStream *
+ fullBuild : bool *
+ [] finalfilename : string -> unit
+ abstract DefineConstant : [] constname : string *
+ value : Object *
+ cSig : int *
+ []signature : byte[] -> unit
+ abstract Abort : unit -> unit
+ abstract DefineLocalVariable2 : [] localvarname2 : string *
+ attributes : int *
+ sigToken : int *
+ addressKind : int *
+ addr1 : int *
+ addr2 : int *
+ addr3 : int *
+ startOffset : int *
+ endOffset : int -> unit
+ abstract DefineGlobalVariable2 : [] globalvarname2 : string *
+ attributes : int *
+ sigToken : int *
+ addressKind : int *
+ addr1 : int *
+ addr2 : int *
+ addr3 : int -> unit
+ abstract DefineConstant2 : [] constantname2 : string *
+ value : Object *
+ sigToken : int -> unit
+ abstract OpenMethod2 : method2 : int *
+ isect : int *
+ offset : int -> unit
+
+type PdbWriter = { symWriter : ISymUnmanagedWriter2 }
+type PdbDocumentWriter = { symDocWriter : ISymUnmanagedDocumentWriter } (* pointer to pDocumentWriter COM object *)
type idd =
{ iddCharacteristics: int32
iddMajorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *)
@@ -1177,17 +1181,14 @@ let pdbReadOpen (moduleName: string) (path: string) : PdbReader =
let importerPtr = Marshal.GetComInterfaceForObject(o, typeof)
try
#if ENABLE_MONO_SUPPORT
- // ISymWrapper.dll is not available as a compile-time dependency for the cross-platform compiler, since it is Windows-only
- // Access it via reflection instead.System.Diagnostics.SymbolStore.SymBinder
- try
- let isym = System.Reflection.Assembly.Load("ISymWrapper, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
- let symbolBinder = isym.CreateInstance("System.Diagnostics.SymbolStore.SymBinder")
- let symbolBinderTy = symbolBinder.GetType()
- let reader = symbolBinderTy.InvokeMember("GetReader", BindingFlags.Public ||| BindingFlags.InvokeMethod ||| BindingFlags.Instance, null, symbolBinder, [| box importerPtr; box moduleName; box path |])
- { symReader = reader :?> ISymbolReader }
- with _ ->
- { symReader = null }
-#else
+ // ISymWrapper.dll is not available as a compile-time dependency for the cross-platform compiler, since it is Windows-only
+ // Access it via reflection instead.System.Diagnostics.SymbolStore.SymBinder
+ let isym = System.Reflection.Assembly.Load("ISymWrapper, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
+ let symbolBinder = isym.CreateInstance("System.Diagnostics.SymbolStore.SymBinder")
+ let symbolBinderTy = symbolBinder.GetType()
+ let reader = symbolBinderTy.InvokeMember("GetReader",BindingFlags.Public ||| BindingFlags.InvokeMethod ||| BindingFlags.Instance, null,symbolBinder,[| box importerPtr; box moduleName; box path |])
+ { symReader = reader :?> ISymbolReader }
+#else
let symbolBinder = new System.Diagnostics.SymbolStore.SymBinder()
{ symReader = symbolBinder.GetReader(importerPtr, moduleName, path) }
#endif
diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs
index 5d6bfd3ee06..b5b82d89fbf 100644
--- a/src/absil/ilwrite.fs
+++ b/src/absil/ilwrite.fs
@@ -3035,9 +3035,7 @@ module FileSystemUtilites =
open System
open System.Reflection
open System.Globalization
-#if FX_RESHAPED_REFLECTION
- open Microsoft.FSharp.Core.ReflectionAdapters
-#endif
+
let progress = try System.Environment.GetEnvironmentVariable("FSharp_DebugSetFilePermissions") <> null with _ -> false
let setExecutablePermission (filename: string) =
diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs
index 260ccbe238e..c378baa936f 100644
--- a/src/absil/ilwritepdb.fs
+++ b/src/absil/ilwritepdb.fs
@@ -222,10 +222,7 @@ let getRowCounts tableRowCounts =
let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (sourceLink: string) showTimes (info: PdbData) isDeterministic (pathMap: PathMap) =
sortMethods showTimes info
let externalRowCounts = getRowCounts info.TableRowCounts
- let docs =
- match info.Documents with
- | null -> Array.empty
- | _ -> info.Documents
+ let docs = info.Documents
let metadata = MetadataBuilder()
let serializeDocumentName (name: string) =
@@ -324,12 +321,9 @@ let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (s
info.Methods |> Array.iter (fun minfo ->
let docHandle, sequencePointBlob =
let sps =
- match minfo.SequencePoints with
- | null -> Array.empty
- | _ ->
- match minfo.Range with
- | None -> Array.empty
- | Some (_,_) -> minfo.SequencePoints
+ match minfo.Range with
+ | None -> Array.empty
+ | Some (_,_) -> minfo.SequencePoints
let builder = new BlobBuilder()
builder.WriteCompressedInteger(minfo.LocalSignatureToken)
@@ -476,7 +470,11 @@ let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (s
| None -> MetadataTokens.MethodDefinitionHandle 0
| Some x -> MetadataTokens.MethodDefinitionHandle x
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let deterministicIdProvider isDeterministic : System.Func, BlobContentId> =
+#else
+ let deterministicIdProvider isDeterministic : System.Func, BlobContentId> ? =
+#endif
match isDeterministic with
| false -> null
| true ->
diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs
index a9a079598a3..813ad7d8b0f 100644
--- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs
+++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs
@@ -4393,12 +4393,48 @@ type internal SR private() =
/// The input to a copy-and-update expression that creates an anonymous record must be either an anonymous record or a record
/// (Originally from ..\FSComp.txt:1455)
static member tcCopyAndUpdateNeedsRecordType() = (3245, GetStringFunc("tcCopyAndUpdateNeedsRecordType",",,,") )
- /// The parameter '%s' has an invalid type '%s'. This is not permitted by the rules of Common IL.
+ /// The type '%s' does not support a nullness qualitification.
/// (Originally from ..\FSComp.txt:1456)
+ static member tcTypeDoesNotHaveAnyNull(a0 : System.String) = (3260, GetStringFunc("tcTypeDoesNotHaveAnyNull",",,,%s,,,") a0)
+ /// This language feature is not enabled, use /langversion:5.0 or greater to enable it
+ /// (Originally from ..\FSComp.txt:1461)
+ static member tcLangFeatureNotEnabled50() = (3265, GetStringFunc("tcLangFeatureNotEnabled50",",,,") )
+ /// Nullness warning. The default constructor of a struct type is required but one of the fields of struct type is non-nullable.
+ /// (Originally from ..\FSComp.txt:1462)
+ static member tcDefaultStructConstructorCallNulls() = (3266, GetStringFunc("tcDefaultStructConstructorCallNulls",",,,") )
+ /// Nullness warning. The 'DefaultValue' attribute is used but the type (or one of its fields if a struct) is non-nullable.
+ /// (Originally from ..\FSComp.txt:1463)
+ static member chkValueWithDefaultValueMustHaveDefaultValueNulls() = (3267, GetStringFunc("chkValueWithDefaultValueMustHaveDefaultValueNulls",",,,") )
+ /// The constraints 'null' and 'not null' are inconsistent
+ /// (Originally from ..\FSComp.txt:1464)
+ static member csNullNotNullConstraintInconsistent() = (3268, GetStringFunc("csNullNotNullConstraintInconsistent",",,,") )
+ /// The constraints 'struct' and 'null' are inconsistent
+ /// (Originally from ..\FSComp.txt:1465)
+ static member csStructNullConstraintInconsistent() = (3269, GetStringFunc("csStructNullConstraintInconsistent",",,,") )
+ /// The constraints 'delegate' and 'comparison' are inconsistent
+ /// (Originally from ..\FSComp.txt:1466)
+ static member csDelegateComparisonConstraintInconsistent() = (3270, GetStringFunc("csDelegateComparisonConstraintInconsistent",",,,") )
+ /// The /checknulls language feature is not enabled
+ /// (Originally from ..\FSComp.txt:1467)
+ static member tcNullnessCheckingNotEnabled() = (3271, GetStringFunc("tcNullnessCheckingNotEnabled",",,,") )
+ /// The type '%s' has 'null' as a true representation value but a constraint does not permit this
+ /// (Originally from ..\FSComp.txt:1468)
+ static member csTypeHasNullAsTrueValue(a0 : System.String) = (GetStringFunc("csTypeHasNullAsTrueValue",",,,%s,,,") a0)
+ /// The type '%s' has 'null' as an extra value but a constraint does not permit this
+ /// (Originally from ..\FSComp.txt:1469)
+ static member csTypeHasNullAsExtraValue(a0 : System.String) = (GetStringFunc("csTypeHasNullAsExtraValue",",,,%s,,,") a0)
+ /// The parameter '%s' has an invalid type '%s'. This is not permitted by the rules of Common IL.
+ /// (Originally from ..\FSComp.txt:1470)
static member chkInvalidFunctionParameterType(a0 : System.String, a1 : System.String) = (3300, GetStringFunc("chkInvalidFunctionParameterType",",,,%s,,,%s,,,") a0 a1)
/// The function or method has an invalid return type '%s'. This is not permitted by the rules of Common IL.
- /// (Originally from ..\FSComp.txt:1457)
+ /// (Originally from ..\FSComp.txt:1471)
static member chkInvalidFunctionReturnType(a0 : System.String) = (3301, GetStringFunc("chkInvalidFunctionReturnType",",,,%s,,,") a0)
+ /// Enable nullness declarations and checks
+ /// (Originally from ..\FSComp.txt:1472)
+ static member optsCheckNulls() = (GetStringFunc("optsCheckNulls",",,,") )
+ /// Specify the language version
+ /// (Originally from ..\FSComp.txt:1473)
+ static member optsLangVersion() = (GetStringFunc("optsLangVersion",",,,") )
/// Call this method once to validate that all known resources are valid; throws if not
static member RunStartupValidation() =
@@ -5828,6 +5864,18 @@ type internal SR private() =
ignore(GetString("parsInvalidAnonRecdExpr"))
ignore(GetString("parsInvalidAnonRecdType"))
ignore(GetString("tcCopyAndUpdateNeedsRecordType"))
+ ignore(GetString("tcTypeDoesNotHaveAnyNull"))
+ ignore(GetString("tcLangFeatureNotEnabled50"))
+ ignore(GetString("tcDefaultStructConstructorCallNulls"))
+ ignore(GetString("chkValueWithDefaultValueMustHaveDefaultValueNulls"))
+ ignore(GetString("csNullNotNullConstraintInconsistent"))
+ ignore(GetString("csStructNullConstraintInconsistent"))
+ ignore(GetString("csDelegateComparisonConstraintInconsistent"))
+ ignore(GetString("tcNullnessCheckingNotEnabled"))
+ ignore(GetString("csTypeHasNullAsTrueValue"))
+ ignore(GetString("csTypeHasNullAsExtraValue"))
ignore(GetString("chkInvalidFunctionParameterType"))
ignore(GetString("chkInvalidFunctionReturnType"))
+ ignore(GetString("optsCheckNulls"))
+ ignore(GetString("optsLangVersion"))
()
diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx
new file mode 100644
index 00000000000..8f130e8f0c9
--- /dev/null
+++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx
@@ -0,0 +1,4441 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ The namespace '{0}' is not defined.
+
+
+ The namespace or module '{0}' is not defined.
+
+
+ The field, constructor or member '{0}' is not defined.
+
+
+ The value, constructor, namespace or type '{0}' is not defined.
+
+
+ The value or constructor '{0}' is not defined.
+
+
+ The value, namespace, type or module '{0}' is not defined.
+
+
+ The constructor, module or namespace '{0}' is not defined.
+
+
+ The type '{0}' is not defined.
+
+
+ The type '{0}' is not defined in '{1}'.
+
+
+ The record label or namespace '{0}' is not defined.
+
+
+ The record label '{0}' is not defined.
+
+
+ Maybe you want one of the following:
+
+
+ The type parameter {0} is not defined.
+
+
+ The pattern discriminator '{0}' is not defined.
+
+
+ Replace with '{0}'
+
+
+ Add . for indexer access.
+
+
+ All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
+
+
+ All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
+
+
+ This 'if' expression is missing an 'else' branch. Because 'if' is an expression, and not a statement, add an 'else' branch which also returns a value of type '{0}'.
+
+
+ The 'if' expression needs to have type '{0}' to satisfy context type requirements. It currently has type '{1}'.
+
+
+ All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+
+
+ All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+
+
+ A pattern match guard must be of type 'bool', but this 'when' expression is of type '{0}'.
+
+
+ A ';' is used to separate field values in records. Consider replacing ',' with ';'.
+
+
+ The '!' operator is used to dereference a ref cell. Consider using 'not expr' here.
+
+
+ The non-generic type '{0}' does not expect any type arguments, but here is given {1} type argument(s)
+
+
+ Consider using 'return!' instead of 'return'.
+
+
+ Consider using 'yield!' instead of 'yield'.
+
+
+ \nA tuple type is required for one or more arguments. Consider wrapping the given arguments in additional parentheses or review the definition of the interface.
+
+
+ Invalid warning number '{0}'
+
+
+ Invalid version string '{0}'
+
+
+ Invalid version file '{0}'
+
+
+ Microsoft (R) F# Compiler version {0}
+
+
+ F# Compiler for F# {0}
+
+
+ Problem with filename '{0}': {1}
+
+
+ No inputs specified
+
+
+ The '--pdb' option requires the '--debug' option to be used
+
+
+ The search directory '{0}' is invalid
+
+
+ The search directory '{0}' could not be found
+
+
+ '{0}' is not a valid filename
+
+
+ '{0}' is not a valid assembly name
+
+
+ Unrecognized privacy setting '{0}' for managed resource, valid options are 'public' and 'private'
+
+
+ Multiple references to '{0}.dll' are not permitted
+
+
+ Could not read version from mscorlib.dll
+
+
+ Unable to read assembly '{0}'
+
+
+ Assembly resolution failure at or near this location
+
+
+ The declarations in this file will be placed in an implicit module '{0}' based on the file name '{1}'. However this is not a valid F# identifier, so the contents will not be accessible from other files. Consider renaming the file or adding a 'module' or 'namespace' declaration at the top of the file.
+
+
+ Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration.
+
+
+ Files in libraries or multiple-file applications must begin with a namespace or module declaration. When using a module declaration at the start of a file the '=' sign is not allowed. If this is a top-level module, consider removing the = to resolve this error.
+
+
+ This file contains multiple declarations of the form 'module SomeNamespace.SomeModule'. Only one declaration of this form is permitted in a file. Change your file to use an initial namespace declaration and/or use 'module ModuleName = ...' to define your modules.
+
+
+ Option requires parameter: {0}
+
+
+ Source file '{0}' could not be found
+
+
+ The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx, .fsscript, .ml or .mli.
+
+
+ Could not resolve assembly '{0}'
+
+
+ Could not resolve assembly '{0}' required by '{1}'
+
+
+ Error opening binary file '{0}': {1}
+
+
+ The F#-compiled DLL '{0}' needs to be recompiled to be used with this version of F#
+
+
+ Invalid directive. Expected '#I \"<path>\"'.
+
+
+ Invalid directive. Expected '#r \"<file-or-assembly>\"'.
+
+
+ Invalid directive. Expected '#load \"<file>\" ... \"<file>\"'.
+
+
+ Invalid directive. Expected '#time', '#time \"on\"' or '#time \"off\"'.
+
+
+ Directives inside modules are ignored
+
+
+ A signature for the file or module '{0}' has already been specified
+
+
+ An implementation of file or module '{0}' has already been given. Compilation order is significant in F# because of type inference. You may need to adjust the order of your files to place the signature file before the implementation. In Visual Studio files are type-checked in the order they appear in the project file, which can be edited manually or adjusted using the solution explorer.
+
+
+ An implementation of the file or module '{0}' has already been given
+
+
+ The signature file '{0}' does not have a corresponding implementation file. If an implementation file exists then check the 'module' and 'namespace' declarations in the signature and implementation files match.
+
+
+ '{0}' is not a valid integer argument
+
+
+ '{0}' is not a valid floating point argument
+
+
+ Unrecognized option: '{0}'
+
+
+ Invalid module or namespace name
+
+
+ Error reading/writing metadata for the F# compiled DLL '{0}'. Was the DLL compiled with an earlier version of the F# compiler? (error: '{1}').
+
+
+ The type/module '{0}' is not a concrete module or type
+
+
+ The type '{0}' has an inline assembly code representation
+
+
+ A namespace and a module named '{0}' both occur in two parts of this assembly
+
+
+ Two modules named '{0}' occur in two parts of this assembly
+
+
+ Two type definitions named '{0}' occur in namespace '{1}' in two parts of this assembly
+
+
+ A module and a type definition named '{0}' occur in namespace '{1}' in two parts of this assembly
+
+
+ Invalid member signature encountered because of an earlier error
+
+
+ This value does not have a valid property setter type
+
+
+ Invalid form for a property getter. At least one '()' argument is required when using the explicit syntax.
+
+
+ Invalid form for a property setter. At least one argument is required.
+
+
+ Unexpected use of a byref-typed variable
+
+
+ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'
+
+
+ Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.
+
+
+ The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed
+
+
+ Recursively defined values cannot appear directly as part of the construction of a tuple value within a recursive binding
+
+
+ Recursive values cannot appear directly as a construction of the type '{0}' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead.
+
+
+ Recursive values cannot be directly assigned to the non-mutable field '{0}' of the type '{1}' within a recursive binding. Consider using a mutable field instead.
+
+
+ Unexpected decode of AutoOpenAttribute
+
+
+ Unexpected decode of InternalsVisibleToAttribute
+
+
+ Unexpected decode of InterfaceDataVersionAttribute
+
+
+ Active patterns cannot return more than 7 possibilities
+
+
+ This is not a valid constant expression or custom attribute value
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe mutability attributes differ
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe names differ
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe compiled names differ
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe display names differ
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe accessibility specified in the signature is more than that specified in the implementation
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe inline flags differ
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe literal constant values and/or attributes differ
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nOne is a type function and the other is not. The signature requires explicit type parameters if they are present in the implementation.
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe respective type parameter counts differ
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nOne is an extension member and the other is not
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nAn arity was not inferred for this value
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe number of generic parameters in the signature and implementation differ (the signature declares {3} but the implementation declares {4}
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe generic parameters in the signature and implementation have different kinds. Perhaps there is a missing [<Measure>] attribute.
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe arities in the signature and implementation differ. The signature specifies that '{3}' is function definition or lambda expression accepting at least {4} argument(s), but the implementation is a computed function value. To declare that a computed function value is a permitted implementation simply parenthesize its type in the signature, e.g.\n\tval {5}: int -> (int -> int)\ninstead of\n\tval {6}: int -> int -> int.
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe CLI member names differ
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nOne is static and the other isn't
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nOne is virtual and the other isn't
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nOne is abstract and the other isn't
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nOne is final and the other isn't
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nOne is marked as an override and the other isn't
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nOne is a constructor/property and the other is not
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe compiled representation of this method is as a static member but the signature indicates its compiled representation is as an instance member
+
+
+ Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe compiled representation of this method is as an instance member, but the signature indicates its compiled representation is as a static member
+
+
+ The {0} definitions in the signature and implementation are not compatible because the names differ. The type is called '{1}' in the signature file but '{2}' in implementation.
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the respective type parameter counts differ
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the accessibility specified in the signature is more than that specified in the implementation
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the signature requires that the type supports the interface {2} but the interface has not been implemented
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the implementation says this type may use nulls as a representation but the signature does not
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the implementation says this type may use nulls as an extra value but the signature does not
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the signature says this type may use nulls as a representation but the implementation does not
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the signature says this type may use nulls as an extra value but the implementation does not
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the implementation type is sealed but the signature implies it is not. Consider adding the [<Sealed>] attribute to the signature.
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the implementation type is not sealed but signature implies it is. Consider adding the [<Sealed>] attribute to the implementation.
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the implementation is an abstract class but the signature is not. Consider adding the [<AbstractClass>] attribute to the signature.
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the signature is an abstract class but the implementation is not. Consider adding the [<AbstractClass>] attribute to the implementation.
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the types have different base types
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the number of {2}s differ
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the signature defines the {2} '{3}' but the implementation does not (or does, but not in the same order)
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the implementation defines the {2} '{3}' but the signature does not (or does, but not in the same order)
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the implementation defines a struct but the signature defines a type with a hidden representation
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because a CLI type representation is being hidden by a signature
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because a type representation is being hidden by a signature
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the types are of different kinds
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the IL representations differ
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the representations differ
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the field {2} was present in the implementation but not in the signature
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the order of the fields is different in the signature and implementation
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the field {2} was required by the signature but was not specified by the implementation
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the field '{2}' was present in the implementation but not in the signature. Struct types must now reveal their fields in the signature for the type, though the fields may still be labelled 'private' or 'internal'.
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the abstract member '{2}' was required by the signature but was not specified by the implementation
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the abstract member '{2}' was present in the implementation but not in the signature
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the signature declares a {2} while the implementation declares a {3}
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the abbreviations differ: {2} versus {3}
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because an abbreviation is being hidden by a signature. The abbreviation must be visible to other CLI languages. Consider making the abbreviation visible in the signature.
+
+
+ The {0} definitions for type '{1}' in the signature and implementation are not compatible because the signature has an abbreviation while the implementation does not
+
+
+ The module contains the constructor\n {0} \nbut its signature specifies\n {1} \nThe names differ
+
+
+ The module contains the constructor\n {0} \nbut its signature specifies\n {1} \nThe respective number of data fields differ
+
+
+ The module contains the constructor\n {0} \nbut its signature specifies\n {1} \nThe types of the fields differ
+
+
+ The module contains the constructor\n {0} \nbut its signature specifies\n {1} \nthe accessibility specified in the signature is more than that specified in the implementation
+
+
+ The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe names differ
+
+
+ The module contains the field\n {0} \nbut its signature specifies\n {1} \nthe accessibility specified in the signature is more than that specified in the implementation
+
+
+ The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe 'static' modifiers differ
+
+
+ The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe 'mutable' modifiers differ
+
+
+ The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe 'literal' modifiers differ
+
+
+ The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ
+
+
+ The implicit instantiation of a generic construct at or near this point could not be resolved because it could resolve to multiple unrelated types, e.g. '{0}' and '{1}'. Consider using type annotations to resolve the ambiguity
+
+
+ Could not resolve the ambiguity inherent in the use of a 'printf'-style format string
+
+
+ Could not resolve the ambiguity in the use of a generic construct with an 'enum' constraint at or near this position
+
+
+ Could not resolve the ambiguity in the use of a generic construct with a 'delegate' constraint at or near this position
+
+
+ Invalid value
+
+
+ The signature and implementation are not compatible because the respective type parameter counts differ
+
+
+ The signature and implementation are not compatible because the type parameter in the class/signature has a different compile-time requirement to the one in the member/implementation
+
+
+ The signature and implementation are not compatible because the declaration of the type parameter '{0}' requires a constraint of the form {1}
+
+
+ The signature and implementation are not compatible because the type parameter '{0}' has a constraint of the form {1} but the implementation does not. Either remove this constraint from the signature or add it to the implementation.
+
+
+ The type '{0}' implements 'System.IComparable'. Consider also adding an explicit override for 'Object.Equals'
+
+
+ The type '{0}' implements 'System.IComparable' explicitly but provides no corresponding override for 'Object.Equals'. An implementation of 'Object.Equals' has been automatically provided, implemented via 'System.IComparable'. Consider implementing the override 'Object.Equals' explicitly
+
+
+ The struct, record or union type '{0}' has an explicit implementation of 'Object.GetHashCode' or 'Object.Equals'. You must apply the 'CustomEquality' attribute to the type
+
+
+ The struct, record or union type '{0}' has an explicit implementation of 'Object.GetHashCode'. Consider implementing a matching override for 'Object.Equals(obj)'
+
+
+ The struct, record or union type '{0}' has an explicit implementation of 'Object.Equals'. Consider implementing a matching override for 'Object.GetHashCode()'
+
+
+ The exception definitions are not compatible because a CLI exception mapping is being hidden by a signature. The exception mapping must be visible to other modules. The module contains the exception definition\n {0} \nbut its signature specifies\n\t{1}
+
+
+ The exception definitions are not compatible because the CLI representations differ. The module contains the exception definition\n {0} \nbut its signature specifies\n\t{1}
+
+
+ The exception definitions are not compatible because the exception abbreviation is being hidden by the signature. The abbreviation must be visible to other CLI languages. Consider making the abbreviation visible in the signature. The module contains the exception definition\n {0} \nbut its signature specifies\n\t{1}.
+
+
+ The exception definitions are not compatible because the exception abbreviations in the signature and implementation differ. The module contains the exception definition\n {0} \nbut its signature specifies\n\t{1}.
+
+
+ The exception definitions are not compatible because the exception declarations differ. The module contains the exception definition\n {0} \nbut its signature specifies\n\t{1}.
+
+
+ The exception definitions are not compatible because the field '{0}' was required by the signature but was not specified by the implementation. The module contains the exception definition\n {1} \nbut its signature specifies\n\t{2}.
+
+
+ The exception definitions are not compatible because the field '{0}' was present in the implementation but not in the signature. The module contains the exception definition\n {1} \nbut its signature specifies\n\t{2}.
+
+
+ The exception definitions are not compatible because the order of the fields is different in the signature and implementation. The module contains the exception definition\n {0} \nbut its signature specifies\n\t{1}.
+
+
+ The namespace or module attributes differ between signature and implementation
+
+
+ This method is over-constrained in its type parameters
+
+
+ No implementations of '{0}' had the correct number of arguments and type parameters. The required signature is '{1}'.
+
+
+ The override for '{0}' was ambiguous
+
+
+ More than one override implements '{0}'
+
+
+ The method '{0}' is sealed and cannot be overridden
+
+
+ The override '{0}' implements more than one abstract slot, e.g. '{1}' and '{2}'
+
+
+ Duplicate or redundant interface
+
+
+ The interface '{0}' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface.
+
+
+ A named argument has been assigned more than one value
+
+
+ No implementation was given for '{0}'
+
+
+ No implementation was given for '{0}'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.
+
+
+ The member '{0}' does not have the correct number of arguments. The required signature is '{1}'.
+
+
+ The member '{0}' does not have the correct number of method type parameters. The required signature is '{1}'.
+
+
+ The member '{0}' does not have the correct kinds of generic parameters. The required signature is '{1}'.
+
+
+ The member '{0}' cannot be used to implement '{1}'. The required signature is '{2}'.
+
+
+ Error while parsing embedded IL
+
+
+ Error while parsing embedded IL type
+
+
+ This indexer notation has been removed from the F# language
+
+
+ Invalid expression on left of assignment
+
+
+ The 'ReferenceEquality' attribute cannot be used on structs. Consider using the 'StructuralEquality' attribute instead, or implement an override for 'System.Object.Equals(obj)'.
+
+
+ This type uses an invalid mix of the attributes 'NoEquality', 'ReferenceEquality', 'StructuralEquality', 'NoComparison' and 'StructuralComparison'
+
+
+ The 'NoEquality' attribute must be used in conjunction with the 'NoComparison' attribute
+
+
+ The 'StructuralComparison' attribute must be used in conjunction with the 'StructuralEquality' attribute
+
+
+ The 'StructuralEquality' attribute must be used in conjunction with the 'NoComparison' or 'StructuralComparison' attributes
+
+
+ A type cannot have both the 'ReferenceEquality' and 'StructuralEquality' or 'StructuralComparison' attributes
+
+
+ Only record, union, exception and struct types may be augmented with the 'ReferenceEquality', 'StructuralEquality' and 'StructuralComparison' attributes
+
+
+ A type with attribute 'ReferenceEquality' cannot have an explicit implementation of 'Object.Equals(obj)', 'System.IEquatable<_>' or 'System.Collections.IStructuralEquatable'
+
+
+ A type with attribute 'CustomEquality' must have an explicit implementation of at least one of 'Object.Equals(obj)', 'System.IEquatable<_>' or 'System.Collections.IStructuralEquatable'
+
+
+ A type with attribute 'CustomComparison' must have an explicit implementation of at least one of 'System.IComparable' or 'System.Collections.IStructuralComparable'
+
+
+ A type with attribute 'NoEquality' should not usually have an explicit implementation of 'Object.Equals(obj)'. Disable this warning if this is intentional for interoperability purposes
+
+
+ A type with attribute 'NoComparison' should not usually have an explicit implementation of 'System.IComparable', 'System.IComparable<_>' or 'System.Collections.IStructuralComparable'. Disable this warning if this is intentional for interoperability purposes
+
+
+ The 'CustomEquality' attribute must be used in conjunction with the 'NoComparison' or 'CustomComparison' attributes
+
+
+ Positional specifiers are not permitted in format strings
+
+
+ Missing format specifier
+
+
+ '{0}' flag set twice
+
+
+ Prefix flag (' ' or '+') set twice
+
+
+ The # formatting modifier is invalid in F#
+
+
+ Bad precision in format specifier
+
+
+ Bad width in format specifier
+
+
+ '{0}' format does not support '0' flag
+
+
+ Precision missing after the '.'
+
+
+ '{0}' format does not support precision
+
+
+ Bad format specifier (after l or L): Expected ld,li,lo,lu,lx or lX. In F# code you can use %d, %x, %o or %u instead, which are overloaded to work with all basic integer types.
+
+
+ The 'l' or 'L' in this format specifier is unnecessary. In F# code you can use %d, %x, %o or %u instead, which are overloaded to work with all basic integer types.
+
+
+ The 'h' or 'H' in this format specifier is unnecessary. You can use %d, %x, %o or %u instead, which are overloaded to work with all basic integer types.
+
+
+ '{0}' does not support prefix '{1}' flag
+
+
+ Bad format specifier: '{0}'
+
+
+ System.Environment.Exit did not exit
+
+
+ The treatment of this operator is now handled directly by the F# compiler and its meaning cannot be redefined
+
+
+ A protected member is called or 'base' is being used. This is only allowed in the direct implementation of members since they could escape their object scope.
+
+
+ The byref-typed variable '{0}' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+
+
+ The 'base' keyword is used in an invalid way. Base calls cannot be used in closures. Consider using a private member to make base calls.
+
+
+ The variable '{0}' is used in an invalid way
+
+
+ The type '{0}' is less accessible than the value, member or type '{1}' it is used in.
+
+
+ 'System.Void' can only be used as 'typeof<System.Void>' in F#
+
+
+ A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+
+
+ Calls to 'reraise' may only occur directly in a handler of a try-with
+
+
+ Expression-splicing operators may only be used within quotations
+
+
+ First-class uses of the expression-splicing operator are not permitted
+
+
+ First-class uses of the address-of operators are not permitted
+
+
+ First-class uses of the 'reraise' function is not permitted
+
+
+ The byref typed value '{0}' cannot be used at this point
+
+
+ 'base' values may only be used to make direct calls to the base implementations of overridden members
+
+
+ Object constructors cannot directly use try/with and try/finally prior to the initialization of the object. This includes constructs such as 'for x in ...' that may elaborate to uses of these constructs. This is a limitation imposed by Common IL.
+
+
+ The address of the variable '{0}' cannot be used at this point
+
+
+ The address of the static field '{0}' cannot be used at this point
+
+
+ The address of the field '{0}' cannot be used at this point
+
+
+ The address of an array element cannot be used at this point
+
+
+ The type of a first-class function cannot contain byrefs
+
+
+ A method return type would contain byrefs which is not permitted
+
+
+ Invalid custom attribute value (not a constant or literal)
+
+
+ The attribute type '{0}' has 'AllowMultiple=false'. Multiple instances of this attribute cannot be attached to a single language element.
+
+
+ The member '{0}' is used in an invalid way. A use of '{1}' has been inferred prior to its definition at or near '{2}'. This is an invalid forward reference.
+
+
+ A byref typed value would be stored here. Top-level let-bound byref values are not permitted.
+
+
+ [<ReflectedDefinition>] terms cannot contain uses of the prefix splice operator '%'
+
+
+ A function labeled with the 'EntryPointAttribute' attribute must be the last declaration in the last file in the compilation sequence.
+
+
+ compiled form of the union case
+
+
+ default augmentation of the union case
+
+
+ The property '{0}' has the same name as a method in type '{1}'.
+
+
+ The property '{0}' of type '{1}' has a getter and a setter that do not match. If one is abstract then the other must be as well.
+
+
+ The property '{0}' has the same name as another property in type '{1}', but one takes indexer arguments and the other does not. You may be missing an indexer argument to one of your properties.
+
+
+ A type would store a byref typed value. This is not permitted by Common IL.
+
+
+ Duplicate method. The method '{0}' has the same name and signature as another method in type '{1}'.
+
+
+ Duplicate method. The method '{0}' has the same name and signature as another method in type '{1}' once tuples, functions, units of measure and/or provided types are erased.
+
+
+ The method '{0}' has curried arguments but has the same name as another method in type '{1}'. Methods with curried arguments cannot be overloaded. Consider using a method taking tupled arguments.
+
+
+ Methods with curried arguments cannot declare 'out', 'ParamArray', 'optional', 'ReflectedDefinition', 'byref', 'CallerLineNumber', 'CallerMemberName', or 'CallerFilePath' arguments
+
+
+ Duplicate property. The property '{0}' has the same name and signature as another property in type '{1}'.
+
+
+ Duplicate property. The property '{0}' has the same name and signature as another property in type '{1}' once tuples, functions, units of measure and/or provided types are erased.
+
+
+ Duplicate method. The abstract method '{0}' has the same name and signature as an abstract method in an inherited type.
+
+
+ Duplicate method. The abstract method '{0}' has the same name and signature as an abstract method in an inherited type once tuples, functions, units of measure and/or provided types are erased.
+
+
+ This type implements the same interface at different generic instantiations '{0}' and '{1}'. This is not permitted in this version of F#.
+
+
+ The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check
+
+
+ The type abbreviation contains byrefs. This is not permitted by F#.
+
+
+ The variable '{0}' is bound in a quotation but is used as part of a spliced expression. This is not permitted since it may escape its scope.
+
+
+ Quotations cannot contain uses of generic expressions
+
+
+ Quotations cannot contain function definitions that are inferred or declared to be generic. Consider adding some type constraints to make this a valid quoted expression.
+
+
+ Quotations cannot contain object expressions
+
+
+ Quotations cannot contain expressions that take the address of a field
+
+
+ Quotations cannot contain expressions that fetch static fields
+
+
+ Quotations cannot contain inline assembly code or pattern matching on arrays
+
+
+ Quotations cannot contain descending for loops
+
+
+ Quotations cannot contain expressions that fetch union case indexes
+
+
+ Quotations cannot contain expressions that set union case fields
+
+
+ Quotations cannot contain expressions that set fields in exception values
+
+
+ Quotations cannot contain expressions that require byref pointers
+
+
+ Quotations cannot contain expressions that make member constraint calls, or uses of operators that implicitly resolve to a member constraint call
+
+
+ Quotations cannot contain this kind of constant
+
+
+ Quotations cannot contain this kind of pattern match
+
+
+ Quotations cannot contain array pattern matching
+
+
+ Quotations cannot contain this kind of type
+
+
+ The declared type parameter '{0}' cannot be used here since the type parameter cannot be resolved at compile time
+
+
+ This code is less generic than indicated by its annotations. A unit-of-measure specified using '_' has been determined to be '1', i.e. dimensionless. Consider making the code generic, or removing the use of '_'.
+
+
+ Type inference problem too complicated (maximum iteration depth reached). Consider adding further type annotations.
+
+
+ Expected arguments to an instance member
+
+
+ This indexer expects {0} arguments but is here given {1}
+
+
+ Expecting a type supporting the operator '{0}' but given a function type. You may be missing an argument to a function.
+
+
+ Expecting a type supporting the operator '{0}' but given a tuple type
+
+
+ None of the types '{0}' support the operator '{1}'
+
+
+ The type '{0}' does not support the operator '{1}'
+
+
+ None of the types '{0}' support the operator '{1}'. Consider opening the module 'Microsoft.FSharp.Linq.NullableOperators'.
+
+
+ The type '{0}' does not support the operator '{1}'. Consider opening the module 'Microsoft.FSharp.Linq.NullableOperators'.
+
+
+ The type '{0}' does not support a conversion to the type '{1}'
+
+
+ The type '{0}' has a method '{1}' (full name '{2}'), but the method is static
+
+
+ The type '{0}' has a method '{1}' (full name '{2}'), but the method is not static
+
+
+ The constraints 'struct' and 'not struct' are inconsistent
+
+
+ The type '{0}' does not have 'null' as a proper value
+
+
+ The type '{0}' does not have 'null' as a proper value. To create a null value for a Nullable type use 'System.Nullable()'.
+
+
+ The type '{0}' does not support the 'comparison' constraint because it has the 'NoComparison' attribute
+
+
+ The type '{0}' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface
+
+
+ The type '{0}' does not support the 'comparison' constraint because it is a record, union or struct with one or more structural element types which do not support the 'comparison' constraint. Either avoid the use of comparison with this type, or add the 'StructuralComparison' attribute to the type to determine which field type does not support comparison
+
+
+ The type '{0}' does not support the 'equality' constraint because it has the 'NoEquality' attribute
+
+
+ The type '{0}' does not support the 'equality' constraint because it is a function type
+
+
+ The type '{0}' does not support the 'equality' constraint because it is a record, union or struct with one or more structural element types which do not support the 'equality' constraint. Either avoid the use of equality with this type, or add the 'StructuralEquality' attribute to the type to determine which field type does not support equality
+
+
+ The type '{0}' is not a CLI enum type
+
+
+ The type '{0}' has a non-standard delegate type
+
+
+ The type '{0}' is not a CLI delegate type
+
+
+ This type parameter cannot be instantiated to 'Nullable'. This is a restriction imposed in order to ensure the meaning of 'null' in some CLI languages is not confusing when used in conjunction with 'Nullable' values.
+
+
+ A generic construct requires that the type '{0}' is a CLI or F# struct type
+
+
+ A generic construct requires that the type '{0}' is an unmanaged type
+
+
+ The type '{0}' is not compatible with any of the types {1}, arising from the use of a printf-style format string
+
+
+ A generic construct requires that the type '{0}' have reference semantics, but it does not, i.e. it is a struct
+
+
+ A generic construct requires that the type '{0}' be non-abstract
+
+
+ A generic construct requires that the type '{0}' have a public default constructor
+
+
+ Type instantiation length mismatch
+
+
+ Optional arguments not permitted here
+
+
+ {0} is not a static member
+
+
+ {0} is not an instance member
+
+
+ Argument length mismatch
+
+
+ The argument types don't match
+
+
+ This method expects a CLI 'params' parameter in this position. 'params' is a way of passing a variable number of arguments to a method in languages such as C#. Consider passing an array for this argument
+
+
+ The member or object constructor '{0}' is not {1}
+
+
+ The member or object constructor '{0}' is not {1}. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.
+
+
+ {0} is not a static method
+
+
+ {0} is not an instance method
+
+
+ The member or object constructor '{0}' has no argument or settable return property '{1}'. {2}.
+
+
+ The object constructor '{0}' has no argument or settable return property '{1}'. {2}.
+
+
+ The required signature is {0}
+
+
+ The member or object constructor '{0}' requires {1} argument(s). The required signature is '{2}'.
+
+
+ The member or object constructor '{0}' requires {1} additional argument(s). The required signature is '{2}'.
+
+
+ The member or object constructor '{0}' requires {1} argument(s). The required signature is '{2}'. Some names for missing arguments are {3}.
+
+
+ The member or object constructor '{0}' requires {1} additional argument(s). The required signature is '{2}'. Some names for missing arguments are {3}.
+
+
+ The member or object constructor '{0}' requires {1} argument(s) but is here given {2} unnamed and {3} named argument(s). The required signature is '{4}'.
+
+
+ The member or object constructor '{0}' takes {1} argument(s) but is here given {2}. The required signature is '{3}'.
+
+
+ The object constructor '{0}' takes {1} argument(s) but is here given {2}. The required signature is '{3}'.
+
+
+ The object constructor '{0}' takes {1} argument(s) but is here given {2}. The required signature is '{3}'. If some of the arguments are meant to assign values to properties, consider separating those arguments with a comma (',').
+
+
+ The member or object constructor '{0}' takes {1} type argument(s) but is here given {2}. The required signature is '{3}'.
+
+
+ A member or object constructor '{0}' taking {1} arguments is not accessible from this code location. All accessible versions of method '{2}' take {3} arguments.
+
+
+ Incorrect generic instantiation. No {0} member named '{1}' takes {2} generic arguments.
+
+
+ The member or object constructor '{0}' does not take {1} argument(s). An overload was found taking {2} arguments.
+
+
+ No {0} member or object constructor named '{1}' takes {2} arguments
+
+
+ No {0} member or object constructor named '{1}' takes {2} arguments. Note the call to this member also provides {3} named arguments.
+
+
+ No {0} member or object constructor named '{1}' takes {2} arguments. The named argument '{3}' doesn't correspond to any argument or settable return property for any overload.
+
+
+ Method or object constructor '{0}' not found
+
+
+ No overloads match for method '{0}'.
+
+
+ A unique overload for method '{0}' could not be determined based on type information prior to this program point. A type annotation may be needed.
+
+
+ Candidates: {0}
+
+
+ The available overloads are shown below.
+
+
+ Accessibility modifiers are not permitted on 'do' bindings, but '{0}' was given.
+
+
+ End of file in #if section begun at or after here
+
+
+ End of file in string begun at or before here
+
+
+ End of file in verbatim string begun at or before here
+
+
+ End of file in comment begun at or before here
+
+
+ End of file in string embedded in comment begun at or before here
+
+
+ End of file in verbatim string embedded in comment begun at or before here
+
+
+ End of file in IF-OCAML section begun at or before here
+
+
+ End of file in directive begun at or before here
+
+
+ No #endif found for #if or #else
+
+
+ Attributes have been ignored in this construct
+
+
+ 'use' bindings are not permitted in primary constructors
+
+
+ 'use' bindings are not permitted in modules and are treated as 'let' bindings
+
+
+ An integer for loop must use a simple identifier
+
+
+ At most one 'with' augmentation is permitted
+
+
+ A semicolon is not expected at this point
+
+
+ Unexpected end of input
+
+
+ Accessibility modifiers are not permitted here, but '{0}' was given.
+
+
+ Only '#' compiler directives may occur prior to the first 'namespace' declaration
+
+
+ Accessibility modifiers should come immediately prior to the identifier naming a construct
+
+
+ Files should begin with either a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule', but not both. To define a module within a namespace use 'module SomeModule = ...'
+
+
+ A module abbreviation must be a simple name, not a path
+
+
+ Ignoring attributes on module abbreviation
+
+
+ The '{0}' accessibility attribute is not allowed on module abbreviation. Module abbreviations are always private.
+
+
+ The '{0}' visibility attribute is not allowed on module abbreviation. Module abbreviations are always private.
+
+
+ Unclosed block
+
+
+ Unmatched 'begin' or 'struct'
+
+
+ A module name must be a simple name, not a path
+
+
+ Unexpected empty type moduleDefn list
+
+
+ Attributes should be placed before 'val'
+
+
+ Attributes are not permitted on interface implementations
+
+
+ Syntax error
+
+
+ Augmentations are not permitted on delegate type moduleDefns
+
+
+ Unmatched 'class', 'interface' or 'struct'
+
+
+ A type definition requires one or more members or other declarations. If you intend to define an empty class, struct or interface, then use 'type ... = class end', 'interface end' or 'struct end'.
+
+
+ Unmatched 'with' or badly formatted 'with' block
+
+
+ 'get', 'set' or 'get,set' required
+
+
+ Only class types may take value arguments
+
+
+ Unmatched 'begin'
+
+
+ Invalid declaration syntax
+
+
+ 'get' and/or 'set' required
+
+
+ Type annotations on property getters and setters must be given after the 'get()' or 'set(v)', e.g. 'with get() : string = ...'
+
+
+ A getter property is expected to be a function, e.g. 'get() = ...' or 'get(index) = ...'
+
+
+ Multiple accessibilities given for property getter or setter
+
+
+ Property setters must be defined using 'set value = ', 'set idx value = ' or 'set (idx1,...,idxN) value = ... '
+
+
+ Interfaces always have the same visibility as the enclosing type
+
+
+ Accessibility modifiers are not allowed on this member. Abstract slots always have the same visibility as the enclosing type.
+
+
+ Attributes are not permitted on 'inherit' declarations
+
+
+ Accessibility modifiers are not permitted on an 'inherits' declaration
+
+
+ 'inherit' declarations cannot have 'as' bindings. To access members of the base class when overriding a method, the syntax 'base.SomeMember' may be used; 'base' is a keyword. Remove this 'as' binding.
+
+
+ Attributes are not allowed here
+
+
+ Accessibility modifiers are not permitted in this position for type abbreviations
+
+
+ Accessibility modifiers are not permitted in this position for enum types
+
+
+ All enum fields must be given values
+
+
+ Accessibility modifiers are not permitted on inline assembly code types
+
+
+ Unexpected identifier: '{0}'
+
+
+ Accessibility modifiers are not permitted on union cases. Use 'type U = internal ...' or 'type U = private ...' to give an accessibility to the whole representation.
+
+
+ Accessibility modifiers are not permitted on enumeration fields
+
+
+ Consider using a separate record type instead
+
+
+ Accessibility modifiers are not permitted on record fields. Use 'type R = internal ...' or 'type R = private ...' to give an accessibility to the whole representation.
+
+
+ The declaration form 'let ... and ...' for non-recursive bindings is not used in F# code. Consider using a sequence of 'let' bindings
+
+
+ Unmatched '('
+
+
+ Successive patterns should be separated by spaces or tupled
+
+
+ No matching 'in' found for this 'let'
+
+
+ Error in the return expression for this 'let'. Possible incorrect indentation.
+
+
+ The block following this '{0}' is unfinished. Every code block is an expression and must have a result. '{1}' cannot be the final code element in a block. Consider giving this block an explicit result.
+
+
+ Incomplete conditional. Expected 'if <expr> then <expr>' or 'if <expr> then <expr> else <expr>'.
+
+
+ 'assert' may not be used as a first class value. Use 'assert <expr>' instead.
+
+
+ Identifier expected
+
+
+ 'in' or '=' expected
+
+
+ The use of '->' in sequence and computation expressions is limited to the form 'for pat in expr -> expr'. Use the syntax 'for ... in ... do ... yield...' to generate elements in more complex sequence expressions.
+
+
+ Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized
+
+
+ Unmatched '['
+
+
+ Missing qualification after '.'
+
+
+ In F# code you may use 'expr.[expr]'. A type annotation may be required to indicate the first expression is an array
+
+
+ Mismatched quotation, beginning with '{0}'
+
+
+ Unmatched '{0}'
+
+
+ Unmatched '[|'
+
+
+ Unmatched '{{'
+
+
+ Unmatched '{{|'
+
+
+ Field bindings must have the form 'id = expr;'
+
+
+ This member is not permitted in an object implementation
+
+
+ Missing function body
+
+
+ Syntax error in labelled type argument
+
+
+ Unexpected infix operator in type expression
+
+
+ The syntax '(typ,...,typ) ident' is not used in F# code. Consider using 'ident<typ,...,typ>' instead
+
+
+ Invalid literal in type
+
+
+ Unexpected infix operator in unit-of-measure expression. Legal operators are '*', '/' and '^'.
+
+
+ Unexpected integer literal in unit-of-measure expression
+
+
+ Syntax error: unexpected type parameter specification
+
+
+ Mismatched quotation operator name, beginning with '{0}'
+
+
+ Active pattern case identifiers must begin with an uppercase letter
+
+
+ The '|' character is not permitted in active pattern case identifiers
+
+
+ Denominator must not be 0 in unit-of-measure exponent
+
+
+ No '=' symbol should follow a 'namespace' declaration
+
+
+ The syntax 'module ... = struct .. end' is not used in F# code. Consider using 'module ... = begin .. end'
+
+
+ The syntax 'module ... : sig .. end' is not used in F# code. Consider using 'module ... = begin .. end'
+
+
+ A static field was used where an instance field is expected
+
+
+ Method '{0}' is not accessible from this code location
+
+
+ Implicit product of measures following /
+
+
+ Unexpected SynMeasure.Anon
+
+
+ Non-zero constants cannot have generic units. For generic zero, write 0.0<_>.
+
+
+ In sequence expressions, results are generated using 'yield'
+
+
+ Unexpected big rational constant
+
+
+ Units-of-measure supported only on float, float32, decimal and signed integer types
+
+
+ Unexpected Const_uint16array
+
+
+ Unexpected Const_bytearray
+
+
+ A parameter with attributes must also be given a name, e.g. '[<Attribute>] Name : Type'
+
+
+ Return values cannot have names
+
+
+ MemberKind.PropertyGetSet only expected in parse trees
+
+
+ Namespaces cannot contain values. Consider using a module to hold your value declarations.
+
+
+ Namespaces cannot contain extension members except in the same file and namespace declaration group where the type is defined. Consider using a module to hold declarations of extension members.
+
+
+ Multiple visibility attributes have been specified for this identifier
+
+
+ Multiple visibility attributes have been specified for this identifier. 'let' bindings in classes are always private, as are any 'let' bindings inside expressions.
+
+
+ The name '({0})' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name '{1}' instead.
+
+
+ The name '({0})' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name '{1}' instead.
+
+
+ The name '({0})' should not be used as a member name. If defining a static member for use from other CLI languages then use the name '{1}' instead.
+
+
+ The name '({0})' should not be used as a member name because it is given a standard definition in the F# library over fixed types
+
+
+ The '{0}' operator should not normally be redefined. To define overloaded comparison semantics for a particular type, implement the 'System.IComparable' interface in the definition of that type.
+
+
+ The '{0}' operator should not normally be redefined. To define equality semantics for a type, override the 'Object.Equals' member in the definition of that type.
+
+
+ The '{0}' operator should not normally be redefined. Consider using a different operator name
+
+
+ The '{0}' operator cannot be redefined. Consider using a different operator name
+
+
+ Expected module or namespace parent {0}
+
+
+ The struct, record or union type '{0}' implements the interface 'System.IComparable' explicitly. You must apply the 'CustomComparison' attribute to the type.
+
+
+ The struct, record or union type '{0}' implements the interface 'System.IComparable<_>' explicitly. You must apply the 'CustomComparison' attribute to the type, and should also provide a consistent implementation of the non-generic interface System.IComparable.
+
+
+ The struct, record or union type '{0}' implements the interface 'System.IStructuralComparable' explicitly. Apply the 'CustomComparison' attribute to the type.
+
+
+ This record contains fields from inconsistent types
+
+
+ DLLImport stubs cannot be inlined
+
+
+ Structs may only bind a 'this' parameter at member declarations
+
+
+ Unexpected expression at recursive inference point
+
+
+ This code is less generic than required by its annotations because the explicit type variable '{0}' could not be generalized. It was constrained to be '{1}'.
+
+
+ One or more of the explicit class or function type variables for this binding could not be generalized, because they were constrained to other types
+
+
+ A generic type parameter has been used in a way that constrains it to always be '{0}'
+
+
+ This type parameter has been used in a way that constrains it to always be '{0}'
+
+
+ The type parameters inferred for this value are not stable under the erasure of type abbreviations. This is due to the use of type abbreviations which drop or reorder type parameters, e.g. \n\ttype taggedInt<'a> = int or\n\ttype swap<'a,'b> = 'b * 'a.\nConsider declaring the type parameters for this value explicitly, e.g.\n\tlet f<'a,'b> ((x,y) : swap<'b,'a>) : swap<'a,'b> = (y,x).
+
+
+ Explicit type parameters may only be used on module or member bindings
+
+
+ You must explicitly declare either all or no type parameters when overriding a generic abstract method
+
+
+ The field labels and expected type of this record expression or pattern do not uniquely determine a corresponding record type
+
+
+ The field '{0}' appears twice in this record expression or pattern
+
+
+ Unknown union case
+
+
+ This code is not sufficiently generic. The type variable {0} could not be generalized because it would escape its scope.
+
+
+ A property cannot have explicit type parameters. Consider using a method instead.
+
+
+ A constructor cannot have explicit type parameters. Consider using a static construction method instead.
+
+
+ This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args) = ...'.
+
+
+ Unexpected source-level property specification in syntax tree
+
+
+ A static initializer requires an argument
+
+
+ An object constructor requires an argument
+
+
+ This static member should not have a 'this' parameter. Consider using the notation 'member Member(args) = ...'.
+
+
+ An explicit static initializer should use the syntax 'static new(args) = expr'
+
+
+ An explicit object constructor should use the syntax 'new(args) = expr'
+
+
+ Unexpected source-level property specification
+
+
+ This form of object expression is not used in F#. Use 'member this.MemberName ... = ...' to define member implementations in object expressions.
+
+
+ Invalid declaration
+
+
+ Attributes are not allowed within patterns
+
+
+ The generic function '{0}' must be given explicit type argument(s)
+
+
+ The method or function '{0}' should not be given explicit type argument(s) because it does not declare its type parameters explicitly
+
+
+ This value, type or method expects {0} type parameter(s) but was given {1}
+
+
+ The default, zero-initializing constructor of a struct type may only be used if all the fields of the struct type admit default initialization
+
+
+ Couldn't find Dispose on IDisposable, or it was overloaded
+
+
+ This value is not a literal and cannot be used in a pattern
+
+
+ This field is readonly
+
+
+ Named arguments must appear after all other arguments
+
+
+ This function value is being used to construct a delegate type whose signature includes a byref argument. You must use an explicit lambda expression taking {0} arguments.
+
+
+ The type '{0}' is not a type whose values can be enumerated with this syntax, i.e. is not compatible with either seq<_>, IEnumerable<_> or IEnumerable and does not have a GetEnumerator method
+
+
+ This recursive binding uses an invalid mixture of recursive forms
+
+
+ This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor.
+
+
+ Invalid constraint
+
+
+ Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution
+
+
+ An 'enum' constraint must be of the form 'enum<type>'
+
+
+ 'new' constraints must take one argument of type 'unit' and return the constructed type
+
+
+ This property has an invalid type. Properties taking multiple indexer arguments should have types of the form 'ty1 * ty2 -> ty3'. Properties returning functions should have types of the form '(ty1 -> ty2)'.
+
+
+ Expected unit-of-measure parameter, not type parameter. Explicit unit-of-measure parameters must be marked with the [<Measure>] attribute.
+
+
+ Expected type parameter, not unit-of-measure parameter
+
+
+ Expected type, not unit-of-measure
+
+
+ Expected unit-of-measure, not type
+
+
+ Units-of-measure cannot be used as prefix arguments to a type. Rewrite as postfix arguments in angle brackets.
+
+
+ Unit-of-measure cannot be used in type constructor application
+
+
+ This control construct may only be used if the computation expression builder defines a '{0}' method
+
+
+ This type has no nested types
+
+
+ Unexpected {0} in type expression
+
+
+ Type parameter cannot be used as type constructor
+
+
+ Illegal syntax in type expression
+
+
+ Anonymous unit-of-measure cannot be nested inside another unit-of-measure expression
+
+
+ Anonymous type variables are not permitted in this declaration
+
+
+ Unexpected / in type
+
+
+ Unexpected type arguments
+
+
+ Optional arguments are only permitted on type members
+
+
+ Name '{0}' not bound in pattern context
+
+
+ Non-primitive numeric literal constants cannot be used in pattern matches because they can be mapped to multiple different types through the use of a NumericLiteral module. Consider using replacing with a variable, and use 'when <variable> = <constant>' at the end of the match clause.
+
+
+ Type arguments cannot be specified here
+
+
+ Only active patterns returning exactly one result may accept arguments
+
+
+ Invalid argument to parameterized pattern label
+
+
+ Internal error. Invalid index into active pattern array
+
+
+ This union case does not take arguments
+
+
+ This union case takes one argument
+
+
+ This union case expects {0} arguments in tupled form
+
+
+ Field '{0}' is not static
+
+
+ This field is not a literal and cannot be used in a pattern
+
+
+ This is not a variable, constant, active recognizer or literal
+
+
+ This is not a valid pattern
+
+
+ Character range matches have been removed in F#. Consider using a 'when' pattern guard instead.
+
+
+ Illegal pattern
+
+
+ Syntax error - unexpected '?' symbol
+
+
+ Expected {0} expressions, got {1}
+
+
+ TcExprUndelayed: delayed
+
+
+ This expression form may only be used in sequence and computation expressions
+
+
+ Invalid object expression. Objects without overrides or interfaces should use the expression form 'new Type(args)' without braces.
+
+
+ Invalid object, sequence or record expression
+
+
+ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}'
+
+
+ This list or array expression includes an element of the form 'if ... then ... else'. Parenthesize this expression to indicate it is an individual element of the list or array, to disambiguate this from a list generated using a sequence expression
+
+
+ Unable to parse format string '{0}'
+
+
+ This list expression exceeds the maximum size for list literals. Use an array for larger literals and call Array.ToList.
+
+
+ The expression form 'expr then expr' may only be used as part of an explicit object constructor
+
+
+ Named arguments cannot be given to member trait calls
+
+
+ This is not a valid name for an enumeration case
+
+
+ This field is not mutable
+
+
+ This construct may only be used within list, array and sequence expressions, e.g. expressions of the form 'seq {{ ... }}', '[ ... ]' or '[| ... |]'. These use the syntax 'for ... in ... do ... yield...' to generate elements
+
+
+ This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'.
+
+
+ This construct may only be used within sequence or computation expressions
+
+
+ This construct may only be used within computation expressions
+
+
+ Invalid indexer expression
+
+
+ The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints
+
+
+ Cannot inherit from a variable type
+
+
+ Calls to object constructors on type parameters cannot be given arguments
+
+
+ The 'CompiledName' attribute cannot be used with this language element
+
+
+ '{0}' may only be used with named types
+
+
+ 'inherit' cannot be used on interface types. Consider implementing the interface by using 'interface ... with ... end' instead.
+
+
+ 'new' cannot be used on interface types. Consider using an object expression '{{ new ... with ... }}' instead.
+
+
+ Instances of this type cannot be created since it has been marked abstract or not all methods have been given implementations. Consider using an object expression '{{ new ... with ... }}' instead.
+
+
+ It is recommended that objects supporting the IDisposable interface are created using the syntax 'new Type(args)', rather than 'Type(args)' or 'Type' as a function value representing the constructor, to indicate that resources may be owned by the generated value
+
+
+ '{0}' may only be used to construct object types
+
+
+ Constructors for the type '{0}' must directly or indirectly call its implicit object constructor. Use a call to the implicit object constructor instead of a record expression.
+
+
+ The field '{0}' has been given a value, but is not present in the type '{1}'
+
+
+ No assignment given for field '{0}' of type '{1}'
+
+
+ Extraneous fields have been given values
+
+
+ Only overrides of abstract and virtual members may be specified in object expressions
+
+
+ The member '{0}' does not correspond to any abstract or virtual method available to override or implement.
+
+
+ The type {0} contains the member '{1}' but it is not a virtual or abstract method that is available to override or implement.
+
+
+ The member '{0}' does not accept the correct number of arguments. {1} argument(s) are expected, but {2} were given. The required signature is '{3}'.{4}
+
+
+ The member '{0}' does not accept the correct number of arguments. One overload accepts {1} arguments, but {2} were given. The required signature is '{3}'.{4}
+
+
+ A simple method name is required here
+
+
+ The types System.ValueType, System.Enum, System.Delegate, System.MulticastDelegate and System.Array cannot be used as super types in an object expression or class
+
+
+ 'new' must be used with a named type
+
+
+ Cannot create an extension of a sealed type
+
+
+ No arguments may be given when constructing a record value
+
+
+ Interface implementations cannot be given on construction expressions
+
+
+ Object construction expressions may only be used to implement constructors in class types
+
+
+ Only simple bindings of the form 'id = expr' can be used in construction expressions
+
+
+ Objects must be initialized by an object construction expression that calls an inherited object constructor and assigns a value to each field
+
+
+ Expected an interface type
+
+
+ Constructor expressions for interfaces do not take arguments
+
+
+ This object constructor requires arguments
+
+
+ 'new' may only be used with object constructors
+
+
+ At least one override did not correctly implement its corresponding abstract member
+
+
+ This numeric literal requires that a module '{0}' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope
+
+
+ Invalid record construction
+
+
+ The expression form {{ expr with ... }} may only be used with record types. To build object types use {{ new Type(...) with ... }}
+
+
+ The inherited type is not an object model type
+
+
+ Object construction expressions (i.e. record expressions with inheritance specifications) may only be used to implement constructors in object model types. Use 'new ObjectType(args)' to construct instances of object model types outside of constructors
+
+
+ '{{ }}' is not a valid expression. Records must include at least one field. Empty sequences are specified by using Seq.empty or an empty list '[]'.
+
+
+ This type is not a record type. Values of class and struct types must be created using calls to object constructors.
+
+
+ This type is not a record type
+
+
+ This construct is ambiguous as part of a computation expression. Nested expressions may be written using 'let _ = (...)' and nested computations using 'let! res = builder {{ ... }}'.
+
+
+ This construct is ambiguous as part of a sequence expression. Nested expressions may be written using 'let _ = (...)' and nested sequences using 'yield! seq {{... }}'.
+
+
+ 'do!' cannot be used within sequence expressions
+
+
+ The use of 'let! x = coll' in sequence expressions is not permitted. Use 'for x in coll' instead.
+
+
+ 'try'/'with' cannot be used within sequence expressions
+
+
+ In sequence expressions, multiple results are generated using 'yield!'
+
+
+ Invalid assignment
+
+
+ Invalid use of a type name
+
+
+ This type has no accessible object constructors
+
+
+ Invalid use of an interface type
+
+
+ Invalid use of a delegate constructor. Use the syntax 'new Type(args)' or just 'Type(args)'.
+
+
+ Property '{0}' is not static
+
+
+ Property '{0}' is not readable
+
+
+ This lookup cannot be used here
+
+
+ Property '{0}' is static
+
+
+ Property '{0}' cannot be set
+
+
+ Constructors must be applied to arguments and cannot be used as first-class values. If necessary use an anonymous function '(fun arg1 ... argN -> new Type(arg1,...,argN))'.
+
+
+ The syntax 'expr.id' may only be used with record labels, properties and fields
+
+
+ Event '{0}' is static
+
+
+ Event '{0}' is not static
+
+
+ The named argument '{0}' did not match any argument or mutable property
+
+
+ One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form.
+
+
+ The unnamed arguments do not form a prefix of the arguments of the method called
+
+
+ Static optimization conditionals are only for use within the F# library
+
+
+ The corresponding formal argument is not optional
+
+
+ Invalid optional assignment to a property or field
+
+
+ A delegate constructor must be passed a single function value
+
+
+ A binding cannot be marked both 'use' and 'rec'
+
+
+ The 'VolatileField' attribute may only be used on 'let' bindings in classes
+
+
+ Attributes are not permitted on 'let' bindings in expressions
+
+
+ The 'DefaultValue' attribute may only be used on 'val' declarations
+
+
+ The 'ConditionalAttribute' attribute may only be used on members
+
+
+ This is not a valid name for an active pattern
+
+
+ The 'EntryPointAttribute' attribute may only be used on function definitions in modules
+
+
+ Mutable values cannot be marked 'inline'
+
+
+ Mutable values cannot have generic parameters
+
+
+ Mutable function values should be written 'let mutable f = (fun args -> ...)'
+
+
+ Only functions may be marked 'inline'
+
+
+ A literal value cannot be given the [<ThreadStatic>] or [<ContextStatic>] attributes
+
+
+ A literal value cannot be marked 'mutable'
+
+
+ A literal value cannot be marked 'inline'
+
+
+ Literal values cannot have generic parameters
+
+
+ This is not a valid constant expression
+
+
+ This type is not accessible from this code location
+
+
+ Unexpected condition in imported assembly: failed to decode AttributeUsage attribute
+
+
+ Unrecognized attribute target. Valid attribute targets are 'assembly', 'module', 'type', 'method', 'property', 'return', 'param', 'field', 'event', 'constructor'.
+
+
+ This attribute is not valid for use on this language element. Assembly attributes should be attached to a 'do ()' declaration, if necessary within an F# module.
+
+
+ This attribute is not valid for use on this language element
+
+
+ Optional arguments cannot be used in custom attributes
+
+
+ This property cannot be set
+
+
+ This property or field was not found on this custom attribute type
+
+
+ A custom attribute must be a reference type
+
+
+ The number of args for a custom attribute does not match the expected number of args for the attribute constructor
+
+
+ A custom attribute must invoke an object constructor
+
+
+ Attribute expressions must be calls to object constructors
+
+
+ This attribute cannot be used in this version of F#
+
+
+ Invalid inline specification
+
+
+ 'use' bindings must be of the form 'use <var> = <expr>'
+
+
+ Abstract members are not permitted in an augmentation - they must be defined as part of the type itself
+
+
+ Method overrides and interface implementations are not permitted here
+
+
+ No abstract or interface member was found that corresponds to this override
+
+
+ This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:{0}
+
+
+ This method already has a default implementation
+
+
+ The method implemented by this default is ambiguous
+
+
+ No abstract property was found that corresponds to this override
+
+
+ This property overrides or implements an abstract property but the abstract property doesn't have a corresponding {0}
+
+
+ Invalid signature for set member
+
+
+ This new member hides the abstract member '{0}'. Rename the member or use 'override' instead.
+
+
+ This new member hides the abstract member '{0}' once tuples, functions, units of measure and/or provided types are erased. Rename the member or use 'override' instead.
+
+
+ Interfaces cannot contain definitions of static initializers
+
+
+ Interfaces cannot contain definitions of object constructors
+
+
+ Interfaces cannot contain definitions of member overrides
+
+
+ Interfaces cannot contain definitions of concrete members. You may need to define a constructor on your type to indicate that the type is a class.
+
+
+ Constructors cannot be specified in exception augmentations
+
+
+ Structs cannot have an object constructor with no arguments. This is a restriction imposed on all CLI languages as structs automatically support a default constructor.
+
+
+ Constructors cannot be defined for this type
+
+
+ Recursive bindings that include member specifications can only occur as a direct augmentation of a type
+
+
+ Only simple variable patterns can be bound in 'let rec' constructs
+
+
+ Only record fields and simple, non-recursive 'let' bindings may be marked mutable
+
+
+ This member is not sufficiently generic
+
+
+ A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
+
+
+ A declaration may only be given a value in a signature if the declaration has the [<Literal>] attribute
+
+
+ Thread-static and context-static variables must be static and given the [<DefaultValue>] attribute to indicate that the value is initialized to the default value on each new thread
+
+
+ Volatile fields must be marked 'mutable' and cannot be thread-static
+
+
+ Uninitialized 'val' fields must be mutable and marked with the '[<DefaultValue>]' attribute. Consider using a 'let' binding instead of a 'val' field.
+
+
+ Static 'val' fields in types must be mutable, private and marked with the '[<DefaultValue>]' attribute. They are initialized to the 'null' or 'zero' value for their type. Consider also using a 'static let mutable' binding in a class type.
+
+
+ This field requires a name
+
+
+ Invalid namespace, module, type or union case name
+
+
+ Explicit type declarations for constructors must be of the form 'ty1 * ... * tyN -> resTy'. Parentheses may be required around 'resTy'
+
+
+ Return types of union cases must be identical to the type being defined, up to abbreviations
+
+
+ This is not a valid value for an enumeration literal
+
+
+ The type '{0}' is not an interface type
+
+
+ Duplicate specification of an interface
+
+
+ A field/val declaration is not permitted here
+
+
+ A inheritance declaration is not permitted here
+
+
+ This declaration opens the module '{0}', which is marked as 'RequireQualifiedAccess'. Adjust your code to use qualified references to the elements of the module instead, e.g. 'List.map' instead of 'map'. This change will ensure that your code is robust as new constructs are added to libraries.
+
+
+ This declaration opens the namespace or module '{0}' through a partially qualified path. Adjust this code to use the full path of the namespace. This change will make your code more robust as new constructs are added to the F# and CLI libraries.
+
+
+ Local class bindings cannot be marked inline. Consider lifting the definition out of the class or else do not mark it as inline.
+
+
+ Type abbreviations cannot have members
+
+
+ As of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors.
+
+
+ Enumerations cannot have members
+
+
+ Measure declarations may have only static members
+
+
+ Structs cannot contain 'do' bindings because the default constructor for structs would not execute these bindings
+
+
+ Structs cannot contain value definitions because the default constructor for structs will not execute these bindings. Consider adding additional arguments to the primary constructor for the type.
+
+
+ Static value definitions may only be used in types with a primary constructor. Consider adding arguments to the type definition, e.g. 'type X(args) = ...'.
+
+
+ Measure declarations may have only static members: constructors are not available
+
+
+ A member and a local class binding both have the name '{0}'
+
+
+ Type abbreviations cannot have interface declarations
+
+
+ Enumerations cannot have interface declarations
+
+
+ This type is not an interface type
+
+
+ All implemented interfaces should be declared on the initial declaration of the type
+
+
+ A default implementation of this interface has already been added because the explicit implementation of the interface was not specified at the definition of the type
+
+
+ This member is not permitted in an interface implementation
+
+
+ This declaration element is not permitted in an augmentation
+
+
+ Types cannot contain nested type definitions
+
+
+ type, exception or module
+
+
+ type or module
+
+
+ The struct, record or union type '{0}' implements the interface 'System.IStructuralEquatable' explicitly. Apply the 'CustomEquality' attribute to the type.
+
+
+ The struct, record or union type '{0}' implements the interface 'System.IEquatable<_>' explicitly. Apply the 'CustomEquality' attribute to the type and provide a consistent implementation of the non-generic override 'System.Object.Equals(obj)'.
+
+
+ Explicit type specifications cannot be used for exception constructors
+
+
+ Exception abbreviations should not have argument lists
+
+
+ Abbreviations for Common IL exceptions cannot take arguments
+
+
+ Exception abbreviations must refer to existing exceptions or F# types deriving from System.Exception
+
+
+ Abbreviations for Common IL exception types must have a matching object constructor
+
+
+ Not an exception
+
+
+ Invalid module name
+
+
+ Invalid type extension
+
+
+ The attributes of this type specify multiple kinds for the type
+
+
+ The kind of the type specified by its attributes does not match the kind implied by its definition
+
+
+ Measure definitions cannot have type parameters
+
+
+ This type requires a definition
+
+
+ This type abbreviation has one or more declared type parameters that do not appear in the type being abbreviated. Type abbreviations must use all declared type parameters in the type being abbreviated. Consider removing one or more type parameters, or use a concrete type definition that wraps an underlying type, such as 'type C<'a> = C of ...'.
+
+
+ Structs, interfaces, enums and delegates cannot inherit from other types
+
+
+ Types cannot inherit from multiple concrete types
+
+
+ Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute
+
+
+ Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal
+
+
+ Generic types cannot be given the 'StructLayout' attribute
+
+
+ Only structs and classes without primary constructors may be given the 'StructLayout' attribute
+
+
+ The representation of this type is hidden by the signature. It must be given an attribute such as [<Sealed>], [<Class>] or [<Interface>] to indicate the characteristics of the type.
+
+
+ Only classes may be given the 'AbstractClass' attribute
+
+
+ Only types representing units-of-measure may be given the 'Measure' attribute
+
+
+ Accessibility modifiers are not permitted on overrides or interface implementations
+
+
+ Discriminated union types are always sealed
+
+
+ Record types are always sealed
+
+
+ Assembly code types are always sealed
+
+
+ Struct types are always sealed
+
+
+ Delegate types are always sealed
+
+
+ Enum types are always sealed
+
+
+ Interface types and delegate types cannot contain fields
+
+
+ Abbreviated types cannot be given the 'Sealed' attribute
+
+
+ Cannot inherit a sealed type
+
+
+ Cannot inherit from interface type. Use interface ... with instead.
+
+
+ Struct types cannot contain abstract members
+
+
+ Interface types cannot be sealed
+
+
+ Delegate specifications must be of the form 'typ -> typ'
+
+
+ Delegate specifications must not be curried types. Use 'typ * ... * typ -> typ' for multi-argument delegates, and 'typ -> (typ -> typ)' for delegates returning function values.
+
+
+ Literal enumerations must have type int, uint, int16, uint16, int64, uint64, byte, sbyte or char
+
+
+ This type definition involves an immediate cyclic reference through an abbreviation
+
+
+ This type definition involves an immediate cyclic reference through a struct field or inheritance relation
+
+
+ The syntax 'type X with ...' is reserved for augmentations. Types whose representations are hidden but which have members are now declared in signatures using 'type X = ...'. You may also need to add the '[<Sealed>] attribute to the type definition in the signature
+
+
+ Members that extend interface, delegate or enum types must be placed in a module separate to the definition of the type. This module must either have the AutoOpen attribute or be opened explicitly by client code to bring the extension members into scope.
+
+
+ One or more of the declared type parameters for this type extension have a missing or wrong type constraint not matching the original type constraints on '{0}'
+
+
+ Type definitions may only have one 'inherit' specification and it must be the first declaration
+
+
+ 'let' and 'do' bindings must come before member and interface definitions in type definitions
+
+
+ This 'inherit' declaration specifies the inherited type but no arguments. Consider supplying arguments, e.g. 'inherit BaseType(args)'.
+
+
+ This 'inherit' declaration has arguments, but is not in a type with a primary constructor. Consider adding arguments to your type definition, e.g. 'type X(args) = ...'.
+
+
+ This definition may only be used in a type with a primary constructor. Consider adding arguments to your type definition, e.g. 'type X(args) = ...'.
+
+
+ Type abbreviations cannot have augmentations
+
+
+ The path '{0}' is a namespace. A module abbreviation may not abbreviate a namespace.
+
+
+ The type '{0}' is used in an invalid way. A value prior to '{1}' has an inferred type involving '{2}', which is an invalid forward reference.
+
+
+ The member '{0}' is used in an invalid way. A use of '{1}' has been inferred prior to the definition of '{2}', which is an invalid forward reference.
+
+
+ The attribute 'AutoOpen(\"{0}\")' in the assembly '{1}' did not refer to a valid module or namespace in that assembly and has been ignored
+
+
+ Undefined value '{0}'
+
+
+ Label {0} not found
+
+
+ Incorrect number of type arguments to local call
+
+
+ Dynamic invocation of {0} is not supported
+
+
+ Taking the address of a literal field is invalid
+
+
+ This operation involves taking the address of a value '{0}' represented using a local variable or other special representation. This is invalid.
+
+
+ Custom marshallers cannot be specified in F# code. Consider using a C# helper function.
+
+
+ The MarshalAs attribute could not be decoded
+
+
+ The signature for this external function contains type parameters. Constrain the argument and return types to indicate the types of the corresponding C function.
+
+
+ The DllImport attribute could not be decoded
+
+
+ Literal fields cannot be set
+
+
+ GenSetStorage: {0} was represented as a static method but was not an appropriate lambda expression
+
+
+ Mutable variables cannot escape their method
+
+
+ Compiler error: unexpected unrealized value
+
+
+ Main module of program is empty: nothing will happen when it is run
+
+
+ This type cannot be used for a literal field
+
+
+ Unexpected GetSet annotation on a property
+
+
+ The FieldOffset attribute could not be decoded
+
+
+ The StructLayout attribute could not be decoded
+
+
+ The DefaultAugmentation attribute could not be decoded
+
+
+ Reflected definitions cannot contain uses of the prefix splice operator '%'
+
+
+ Problem with codepage '{0}': {1}
+
+
+ Copyright (c) Microsoft Corporation. All Rights Reserved.
+
+
+ Freely distributed under the MIT Open Source License. https://github.com/Microsoft/visualfsharp/blob/master/License.txt
+
+
+ Name of the output file (Short form: -o)
+
+
+ Build a console executable
+
+
+ Build a Windows executable
+
+
+ Build a library (Short form: -a)
+
+
+ Build a module that can be added to another assembly
+
+
+ Delay-sign the assembly using only the public portion of the strong name key
+
+
+ Public-sign the assembly using only the public portion of the strong name key, and mark the assembly as signed
+
+
+ Write the xmldoc of the assembly to the given file
+
+
+ Specify a strong name key file
+
+
+ Specify a strong name key container
+
+
+ Limit which platforms this code can run on: x86, Itanium, x64, anycpu32bitpreferred, or anycpu. The default is anycpu.
+
+
+ Only include optimization information essential for implementing inlined constructs. Inhibits cross-module inlining but improves binary compatibility.
+
+
+ Don't add a resource to the generated assembly containing F#-specific metadata
+
+
+ Print the inferred interface of the assembly to a file
+
+
+ Reference an assembly (Short form: -r)
+
+
+ Specify a Win32 resource file (.res)
+
+
+ Specify a Win32 manifest file
+
+
+ Do not include the default Win32 manifest
+
+
+ Embed all source files in the portable PDB file
+
+
+ Embed specific source files in the portable PDB file
+
+
+ Source link information file to embed in the portable PDB file
+
+
+ --embed switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)
+
+
+ --sourcelink switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)
+
+
+ Source file is too large to embed in a portable PDB
+
+
+ Embed the specified managed resource
+
+
+ Link the specified resource to this assembly where the resinfo format is <file>[,<string name>[,public|private]]
+
+
+ Emit debug information (Short form: -g)
+
+
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debuggging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
+
+
+ Enable optimizations (Short form: -O)
+
+
+ Enable or disable tailcalls
+
+
+ Produce a deterministic assembly (including module version GUID and timestamp)
+
+
+ Enable or disable cross-module optimizations
+
+
+ Report all warnings as errors
+
+
+ Report specific warnings as errors
+
+
+ Set a warning level (0-5)
+
+
+ Disable specific warning messages
+
+
+ Enable specific warnings that may be off by default
+
+
+ Generate overflow checks
+
+
+ Define conditional compilation symbols (Short form: -d)
+
+
+ Ignore ML compatibility warnings
+
+
+ Suppress compiler copyright message
+
+
+ Display this usage message (Short form: -?)
+
+
+ Read response file for more options
+
+
+ Specify the codepage used to read source files
+
+
+ Output messages in UTF-8 encoding
+
+
+ Output messages with fully qualified paths
+
+
+ Specify a directory for the include path which is used to resolve source files and assemblies (Short form: -I)
+
+
+ Base address for the library to be built
+
+
+ Do not reference the default CLI assemblies by default
+
+
+ Statically link the F# library and all referenced DLLs that depend on it into the assembly being generated
+
+
+ Statically link the given assembly and all referenced DLLs that depend on this assembly. Use an assembly name e.g. mylib, not a DLL name.
+
+
+ Use a resident background compilation service to improve compiler startup times.
+
+
+ Name the output debug file
+
+
+ Resolve assembly references using directory-based rules rather than MSBuild resolution
+
+
+ Unrecognized target '{0}', expected 'exe', 'winexe', 'library' or 'module'
+
+
+ Unrecognized debug type '{0}', expected 'pdbonly' or 'full'
+
+
+ Invalid warning level '{0}'
+
+
+ Short form of '{0}'
+
+
+ The command-line option '--cliroot' has been deprecated. Use an explicit reference to a specific copy of mscorlib.dll instead.
+
+
+ Use to override where the compiler looks for mscorlib.dll and framework components
+
+
+ - OUTPUT FILES -
+
+
+ - INPUT FILES -
+
+
+ - RESOURCES -
+
+
+ - CODE GENERATION -
+
+
+ - ADVANCED -
+
+
+ - MISCELLANEOUS -
+
+
+ - LANGUAGE -
+
+
+ - ERRORS AND WARNINGS -
+
+
+ Unknown --test argument: '{0}'
+
+
+ Unrecognized platform '{0}', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'
+
+
+ The command-line option '{0}' is for test purposes only
+
+
+ The command-line option '{0}' has been deprecated
+
+
+ The command-line option '{0}' has been deprecated. Use '{1}' instead.
+
+
+ The command-line option '{0}' has been deprecated. HTML document generation is now part of the F# Power Pack, via the tool FsHtmlDoc.exe.
+
+
+ Output warning and error messages in color
+
+
+ Enable high-entropy ASLR
+
+
+ Specify subsystem version of this assembly
+
+
+ Specify target framework profile of this assembly. Valid values are mscorlib, netcore or netstandard. Default - mscorlib
+
+
+ Emit debug information in quotations
+
+
+ Specify the preferred output language culture name (e.g. es-ES, ja-JP)
+
+
+ Don't copy FSharp.Core.dll along the produced binaries
+
+
+ Invalid version '{0}' for '--subsystemversion'. The version must be 4.00 or greater.
+
+
+ Invalid value '{0}' for '--targetprofile', valid values are 'mscorlib', 'netcore' or 'netstandard'.
+
+
+ Full name
+
+
+ and {0} other overloads
+
+
+ union case
+
+
+ active pattern result
+
+
+ active recognizer
+
+
+ field
+
+
+ event
+
+
+ property
+
+
+ extension
+
+
+ custom operation
+
+
+ argument
+
+
+ anonymous record field
+
+
+ patvar
+
+
+ namespace
+
+
+ module
+
+
+ namespace/module
+
+
+ from {0}
+
+
+ also from {0}
+
+
+ generated property
+
+
+ generated type
+
+
+ Found by AssemblyFolders registry key
+
+
+ Found by AssemblyFoldersEx registry key
+
+
+ .NET Framework
+
+
+ Global Assembly Cache
+
+
+ Recursive class hierarchy in type '{0}'
+
+
+ Invalid recursive reference to an abstract slot
+
+
+ The event '{0}' has a non-standard type. If this event is declared in another CLI language, you may need to access this event using the explicit {1} and {2} methods for the event. If this event is declared in F#, make the type of the event an instantiation of either 'IDelegateEvent<_>' or 'IEvent<_,_>'.
+
+
+ The type '{0}' is not accessible from this code location
+
+
+ The union cases or fields of the type '{0}' are not accessible from this code location
+
+
+ The value '{0}' is not accessible from this code location
+
+
+ The union case '{0}' is not accessible from this code location
+
+
+ The record, struct or class field '{0}' is not accessible from this code location
+
+
+ The struct or class field '{0}' is not accessible from this code location
+
+
+ This construct is experimental
+
+
+ No Invoke methods found for delegate type
+
+
+ More than one Invoke method found for delegate type
+
+
+ Delegates are not allowed to have curried signatures
+
+
+ Unexpected Expr.TyChoose
+
+
+ Note: Lambda-lifting optimizations have not been applied because of the use of this local constrained generic function as a first class value. Adding type constraints may resolve this condition.
+
+
+ Identifiers containing '@' are reserved for use in F# code generation
+
+
+ The identifier '{0}' is reserved for future use by F#
+
+
+ Missing variable '{0}'
+
+
+ Partial active patterns may only generate one result
+
+
+ The type '{0}' is required here and is unavailable. You must add a reference to assembly '{1}'.
+
+
+ A reference to the type '{0}' in assembly '{1}' was found, but the type could not be found in that assembly
+
+
+ Internal error or badly formed metadata: not enough type parameters were in scope while importing
+
+
+ A reference to the DLL {0} is required by assembly {1}. The imported type {2} is located in the first assembly and could not be resolved.
+
+
+ An imported assembly uses the type '{0}' but that type is not public
+
+
+ The value '{0}' was marked inline but its implementation makes use of an internal or private function which is not sufficiently accessible
+
+
+ The value '{0}' was marked inline but was not bound in the optimization environment
+
+
+ Local value {0} not found during optimization
+
+
+ A value marked as 'inline' has an unexpected value
+
+
+ A value marked as 'inline' could not be inlined
+
+
+ Failed to inline the value '{0}' marked 'inline', perhaps because a recursive value was marked 'inline'
+
+
+ Recursive ValValue {0}
+
+
+ The indentation of this 'in' token is incorrect with respect to the corresponding 'let'
+
+
+ Possible incorrect indentation: this token is offside of context started at position {0}. Try indenting this token further or using standard formatting conventions.
+
+
+ The '|' tokens separating rules of this pattern match are misaligned by one column. Consider realigning your code or using further indentation.
+
+
+ Invalid module/expression/type
+
+
+ Multiple types exist called '{0}', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. '{1}'.
+
+
+ The instantiation of the generic type '{0}' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. '{1}'.
+
+
+ 'global' may only be used as the first name in a qualified path
+
+
+ This is not a constructor or literal, or a constructor is being used incorrectly
+
+
+ Unexpected empty long identifier
+
+
+ The record type '{0}' does not contain a label '{1}'.
+
+
+ Invalid field label
+
+
+ Invalid expression '{0}'
+
+
+ No constructors are available for the type '{0}'
+
+
+ The union type for union case '{0}' was defined with the RequireQualifiedAccessAttribute. Include the name of the union type ('{1}') in the name you are using.
+
+
+ The record type for the record field '{0}' was defined with the RequireQualifiedAccessAttribute. Include the name of the record type ('{1}') in the name you are using.
+
+
+ Unexpected error creating debug information file '{0}'
+
+
+ This number is outside the allowable range for this integer type
+
+
+ '{0}' is not permitted as a character in operator names and is reserved for future use
+
+
+ Unexpected character '{0}'
+
+
+ This byte array literal contains characters that do not encode as a single byte
+
+
+ Identifiers followed by '{0}' are reserved for future use
+
+
+ This number is outside the allowable range for 8-bit signed integers
+
+
+ This number is outside the allowable range for hexadecimal 8-bit signed integers
+
+
+ This number is outside the allowable range for 8-bit unsigned integers
+
+
+ This number is outside the allowable range for 16-bit signed integers
+
+
+ This number is outside the allowable range for 16-bit unsigned integers
+
+
+ This number is outside the allowable range for 32-bit signed integers
+
+
+ This number is outside the allowable range for 32-bit unsigned integers
+
+
+ This number is outside the allowable range for 64-bit signed integers
+
+
+ This number is outside the allowable range for 64-bit unsigned integers
+
+
+ This number is outside the allowable range for signed native integers
+
+
+ This number is outside the allowable range for unsigned native integers
+
+
+ Invalid floating point number
+
+
+ This number is outside the allowable range for decimal literals
+
+
+ This number is outside the allowable range for 32-bit floats
+
+
+ This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+
+
+ This is not a valid byte literal
+
+
+ This is not a valid character literal
+
+
+ This Unicode encoding is only valid in string literals
+
+
+ This token is reserved for future use
+
+
+ TABs are not allowed in F# code unless the #indent \"off\" option is used
+
+
+ Invalid line number: '{0}'
+
+
+ #if directive must appear as the first non-whitespace character on a line
+
+
+ #else has no matching #if
+
+
+ #endif required for #else
+
+
+ #else directive must appear as the first non-whitespace character on a line
+
+
+ #endif has no matching #if
+
+
+ #endif directive must appear as the first non-whitespace character on a line
+
+
+ #if directive should be immediately followed by an identifier
+
+
+ Syntax error. Wrong nested #endif, unexpected tokens before it.
+
+
+ #! may only appear as the first line at the start of a file.
+
+
+ Expected single line comment or end of line
+
+
+ Infix operator member '{0}' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ...
+
+
+ Infix operator member '{0}' has {1} initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ...
+
+
+ Infix operator member '{0}' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ...
+
+
+ All record, union and struct types in FSharp.Core.dll must be explicitly labelled with 'StructuralComparison' or 'NoComparison'
+
+
+ The struct, record or union type '{0}' has the 'StructuralComparison' attribute but the type parameter '{1}' does not satisfy the 'comparison' constraint. Consider adding the 'comparison' constraint to the type parameter
+
+
+ The struct, record or union type '{0}' has the 'StructuralComparison' attribute but the component type '{1}' does not satisfy the 'comparison' constraint
+
+
+ The struct, record or union type '{0}' is not structurally comparable because the type parameter {1} does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type '{2}' to clarify that the type is not comparable
+
+
+ The struct, record or union type '{0}' is not structurally comparable because the type '{1}' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type '{2}' to clarify that the type is not comparable
+
+
+ The struct, record or union type '{0}' does not support structural equality because the type parameter {1} does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type '{2}' to clarify that the type does not support structural equality
+
+
+ The struct, record or union type '{0}' does not support structural equality because the type '{1}' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type '{2}' to clarify that the type does not support structural equality
+
+
+ The struct, record or union type '{0}' has the 'StructuralEquality' attribute but the type parameter '{1}' does not satisfy the 'equality' constraint. Consider adding the 'equality' constraint to the type parameter
+
+
+ The struct, record or union type '{0}' has the 'StructuralEquality' attribute but the component type '{1}' does not satisfy the 'equality' constraint
+
+
+ Each argument of the primary constructor for a struct must be given a type, for example 'type S(x1:int, x2: int) = ...'. These arguments determine the fields of the struct.
+
+
+ The value '{0}' is unused
+
+
+ The recursive object reference '{0}' is unused. The presence of a recursive object reference adds runtime initialization checks to members in this and derived types. Consider removing this recursive object reference.
+
+
+ A getter property may have at most one argument group
+
+
+ A setter property may have at most two argument groups
+
+
+ Invalid property getter or setter
+
+
+ An indexer property must be given at least one argument
+
+
+ This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation
+
+
+ Remove spaces between the type name and type parameter, e.g. \"type C<'T>\", not type \"C <'T>\". Type parameters must be placed directly adjacent to the type name.
+
+
+ Remove spaces between the type name and type parameter, e.g. \"C<'T>\", not \"C <'T>\". Type parameters must be placed directly adjacent to the type name.
+
+
+ The use of the type syntax 'int C' and 'C <int>' is not permitted here. Consider adjusting this type to be written in the form 'C<int>'
+
+
+ The module/namespace '{0}' from compilation unit '{1}' did not contain the module/namespace '{2}'
+
+
+ The module/namespace '{0}' from compilation unit '{1}' did not contain the val '{2}'
+
+
+ The module/namespace '{0}' from compilation unit '{1}' did not contain the namespace, module or type '{2}'
+
+
+ The 'UseNullAsTrueValue' attribute flag may only be used with union types that have one nullary case and at least one non-nullary case
+
+
+ The parameter '{0}' was inferred to have byref type. Parameters of byref type must be given an explicit type annotation, e.g. 'x1: byref<int>'. When used, a byref parameter is implicitly dereferenced.
+
+
+ The generic member '{0}' has been used at a non-uniform instantiation prior to this program point. Consider reordering the members so this member occurs first. Alternatively, specify the full type of the member explicitly, including argument types, return type and any additional generic parameters and constraints.
+
+
+ The attribute '{0}' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
+
+
+ Cannot call an abstract base member: '{0}'
+
+
+ Could not resolve the ambiguity in the use of a generic construct with an 'unmanaged' constraint at or near this position
+
+
+ This construct is for ML compatibility. {0}. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'.
+
+
+ The type '{0}' has been marked as having an Explicit layout, but the field '{1}' has not been marked with the 'FieldOffset' attribute
+
+
+ Interfaces inherited by other interfaces should be declared using 'inherit ...' instead of 'interface ...'
+
+
+ Invalid prefix operator
+
+
+ Invalid operator definition. Prefix operator definitions must use a valid prefix operator name.
+
+
+ The file extensions '.ml' and '.mli' are for ML compatibility
+
+
+ Consider using a file with extension '.ml' or '.mli' instead
+
+
+ Active pattern '{0}' is not a function
+
+
+ Active pattern '{0}' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice<int,unit> = A x'
+
+
+ The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)
+
+
+ Optional arguments must come at the end of the argument list, after any non-optional arguments
+
+
+ Attribute 'System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes
+
+
+ Extension members cannot provide operator overloads. Consider defining the operator as part of the type definition instead.
+
+
+ The name of the MDB file must be <assembly-file-name>.mdb. The --pdb option will be ignored.
+
+
+ MDB generation failed. Could not find compatible member {0}
+
+
+ Cannot generate MDB debug information. Failed to load the 'MonoSymbolWriter' type from the 'Mono.CompilerServices.SymbolWriter.dll' assembly.
+
+
+ The union case named '{0}' conflicts with the generated type '{1}'
+
+
+ ReflectedDefinitionAttribute may not be applied to an instance member on a struct type, because the instance member takes an implicit 'this' byref parameter
+
+
+ DLLImport bindings must be static members in a class or function definitions in a module
+
+
+ When mscorlib.dll or FSharp.Core.dll is explicitly referenced the {0} option must also be passed
+
+
+ FSharp.Core.sigdata not found alongside FSharp.Core. File expected in {0}. Consider upgrading to a more recent version of FSharp.Core, where this file is no longer be required.
+
+
+ File '{0}' not found alongside FSharp.Core. File expected in {1}. Consider upgrading to a more recent version of FSharp.Core, where this file is no longer be required.
+
+
+ Filename '{0}' contains invalid character '{1}'
+
+
+ 'use!' bindings must be of the form 'use! <var> = <expr>'
+
+
+ Inner generic functions are not permitted in quoted expressions. Consider adding some type constraints until this function is no longer generic.
+
+
+ The type '{0}' is not a valid enumerator type , i.e. does not have a 'MoveNext()' method returning a bool, and a 'Current' property
+
+
+ End of file in triple-quote string begun at or before here
+
+
+ End of file in triple-quote string embedded in comment begun at or before here
+
+
+ This type test or downcast will ignore the unit-of-measure '{0}'
+
+
+ Expected type argument or static argument
+
+
+ Unmatched '<'. Expected closing '>'
+
+
+ Unexpected quotation operator '<@' in type definition. If you intend to pass a verbatim string as a static argument to a type provider, put a space between the '<' and '@' characters.
+
+
+ Attempted to parse this as an operator name, but failed
+
+
+ \U{0} is not a valid Unicode character escape sequence
+
+
+ '{0}' must be applied to an argument of type '{1}', but has been applied to an argument of type '{2}'
+
+
+ '{0}' can only be applied to optional arguments
+
+
+ The specified .NET Framework version '{0}' is not supported. Please specify a value from the enumeration Microsoft.Build.Utilities.TargetDotNetFrameworkVersion.
+
+
+ Invalid Magic value in CLR Header
+
+
+ Bad image format
+
+
+ Private key expected
+
+
+ RSA key expected
+
+
+ Invalid bit Length
+
+
+ Invalid RSAParameters structure - '{{0}}' expected
+
+
+ Invalid algId - 'Exponent' expected
+
+
+ Invalid signature size
+
+
+ No signature directory
+
+
+ Invalid Public Key blob
+
+
+ Exiting - too many errors
+
+
+ The documentation file has no .xml suffix
+
+
+ No implementation files specified
+
+
+ The attribute {0} specified version '{1}', but this value is invalid and has been ignored
+
+
+ Conflicting options specified: 'win32manifest' and 'win32res'. Only one of these can be used.
+
+
+ The code in assembly '{0}' makes uses of quotation literals. Static linking may not include components that make use of quotation literals unless all assemblies are compiled with at least F# 4.0.
+
+
+ Code in this assembly makes uses of quotation literals. Static linking may not include components that make use of quotation literals unless all assemblies are compiled with at least F# 4.0.
+
+
+ Static linking may not include a .EXE
+
+
+ Static linking may not include a mixed managed/unmanaged DLL
+
+
+ Ignoring mixed managed/unmanaged assembly '{0}' during static linking
+
+
+ Assembly '{0}' was referenced transitively and the assembly could not be resolved automatically. Static linking will assume this DLL has no dependencies on the F# library or other statically linked DLLs. Consider adding an explicit reference to this DLL.
+
+
+ Assembly '{0}' not found in dependency set of target binary. Statically linked roots should be specified using an assembly name, without a DLL or EXE extension. If this assembly was referenced explicitly then it is possible the assembly was not actually required by the generated binary, in which case it should not be statically linked.
+
+
+ The key file '{0}' could not be opened
+
+
+ A problem occurred writing the binary '{0}': {1}
+
+
+ The 'AssemblyVersionAttribute' has been ignored because a version was given using a command line option
+
+
+ Error emitting 'System.Reflection.AssemblyCultureAttribute' attribute -- 'Executables cannot be satellite assemblies, Culture should always be empty'
+
+
+ Option '--delaysign' overrides attribute 'System.Reflection.AssemblyDelaySignAttribute' given in a source file or added module
+
+
+ Option '--keyfile' overrides attribute 'System.Reflection.AssemblyKeyFileAttribute' given in a source file or added module
+
+
+ Option '--keycontainer' overrides attribute 'System.Reflection.AssemblyNameAttribute' given in a source file or added module
+
+
+ The assembly '{0}' is listed on the command line. Assemblies should be referenced using a command line flag such as '-r'.
+
+
+ The resident compilation service was not used because a problem occured in communicating with the server.
+
+
+ Problem with filename '{0}': Illegal characters in path.
+
+
+ Passing a .resx file ({0}) as a source file to the compiler is deprecated. Use resgen.exe to transform the .resx file into a .resources file to pass as a --resource option. If you are using MSBuild, this can be done via an <EmbeddedResource> item in the .fsproj project file.
+
+
+ Static linking may not be used on an assembly referencing mscorlib (e.g. a .NET Framework assembly) when generating an assembly that references System.Runtime (e.g. a .NET Core or Portable assembly).
+
+
+ An {0} specified version '{1}', but this value is a wildcard, and you have requested a deterministic build, these are in conflict.
+
+
+ Determinstic builds only support portable PDBs (--debug:portable or --debug:embedded)
+
+
+ Character '{0}' is not allowed in provided namespace name '{1}'
+
+
+ The provided type '{0}' returned a member with a null or empty member name
+
+
+ The provided type '{0}' returned a null member
+
+
+ The provided type '{0}' member info '{1}' has null declaring type
+
+
+ The provided type '{0}' has member '{1}' which has declaring type '{2}'. Expected declaring type to be the same as provided type.
+
+
+ Referenced assembly '{0}' has assembly level attribute '{1}' but no public type provider classes were found
+
+
+ Type '{0}' from type provider '{1}' has an empty namespace. Use 'null' for the global namespace.
+
+
+ Empty namespace found from the type provider '{0}'. Use 'null' for the global namespace.
+
+
+ Provided type '{0}' has 'IsGenericType' as true, but generic types are not supported.
+
+
+ Provided type '{0}' has 'IsArray' as true, but array types are not supported.
+
+
+ Invalid member '{0}' on provided type '{1}'. Provided type members must be public, and not be generic, virtual, or abstract.
+
+
+ Invalid member '{0}' on provided type '{1}'. Only properties, methods and constructors are allowed
+
+
+ Property '{0}' on provided type '{1}' has CanRead=true but there was no value from GetGetMethod()
+
+
+ Property '{0}' on provided type '{1}' has CanRead=false but GetGetMethod() returned a method
+
+
+ Property '{0}' on provided type '{1}' has CanWrite=true but there was no value from GetSetMethod()
+
+
+ Property '{0}' on provided type '{1}' has CanWrite=false but GetSetMethod() returned a method
+
+
+ One or more errors seen during provided type setup
+
+
+ Unexpected exception from provided type '{0}' member '{1}': {2}
+
+
+ Unsupported constant type '{0}'. Quotations provided by type providers can only contain simple constants. The implementation of the type provider may need to be adjusted by moving a value declared outside a provided quotation literal to be a 'let' binding inside the quotation literal.
+
+
+ Unsupported expression '{0}' from type provider. If you are the author of this type provider, consider adjusting it to provide a different provided expression.
+
+
+ Expected provided type named '{0}' but provided type has 'Name' with value '{1}'
+
+
+ Event '{0}' on provided type '{1}' has no value from GetAddMethod()
+
+
+ Event '{0}' on provided type '{1}' has no value from GetRemoveMethod()
+
+
+ Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
+
+
+ The type provider does not have a valid constructor. A constructor taking either no arguments or one argument of type 'TypeProviderConfig' was expected.
+
+
+ The type provider '{0}' reported an error: {1}
+
+
+ The type provider '{0}' used an invalid parameter in the ParameterExpression: {1}
+
+
+ The type provider '{0}' provided a method with a name '{1}' and metadata token '{2}', which is not reported among its methods of its declaring type '{3}'
+
+
+ The type provider '{0}' provided a constructor which is not reported among the constructors of its declaring type '{1}'
+
+
+ A direct reference to the generated type '{0}' is not permitted. Instead, use a type definition, e.g. 'type TypeAlias = <path>'. This indicates that a type provider adds generated types to your assembly.
+
+
+ Expected provided type with path '{0}' but provided type has path '{1}'
+
+
+ Unexpected 'null' return value from provided type '{0}' member '{1}'
+
+
+ Unexpected exception from member '{0}' of provided type '{1}' member '{2}': {3}
+
+
+ Nested provided types do not take static arguments or generic parameters
+
+
+ Invalid static argument to provided type. Expected an argument of kind '{0}'.
+
+
+ An error occured applying the static arguments to a provided type
+
+
+ Unknown static argument kind '{0}' when resolving a reference to a provided type or method '{1}'
+
+
+ invalid namespace for provided type
+
+
+ invalid full name for provided type
+
+
+ The type provider returned 'null', which is not a valid return value from '{0}'
+
+
+ The type provider constructor has thrown an exception: {0}
+
+
+ Type provider '{0}' returned null from GetInvokerExpression.
+
+
+ The type provider '{0}' returned an invalid type from 'ApplyStaticArguments'. A type with name '{1}' was expected, but a type with name '{2}' was returned.
+
+
+ The type provider '{0}' returned an invalid method from 'ApplyStaticArgumentsForMethod'. A method with name '{1}' was expected, but a method with name '{2}' was returned.
+
+
+ This type test or downcast will erase the provided type '{0}' to the type '{1}'
+
+
+ This downcast will erase the provided type '{0}' to the type '{1}'.
+
+
+ This type test with a provided type '{0}' is not allowed because this provided type will be erased to '{1}' at runtime.
+
+
+ Cannot inherit from erased provided type
+
+
+ Assembly '{0}' hase TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
+
+
+ Invalid member name. Members may not have name '.ctor' or '.cctor'
+
+
+ The function or member '{0}' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is '{1}'.
+
+
+ The number of type arguments did not match: '{0}' given, '{1}' expected. This may be related to a previously reported error.
+
+
+ Cannot override inherited member '{0}' because it is sealed
+
+
+ The type provider '{0}' reported an error in the context of provided type '{1}', member '{2}'. The error: {3}
+
+
+ An exception occurred when accessing the '{0}' of a provided type: {1}
+
+
+ The '{0}' of a provided type was null or empty.
+
+
+ Character '{0}' is not allowed in provided type name '{1}'
+
+
+ In queries, '{0}' must use a simple pattern
+
+
+ A custom query operation for '{0}' is required but not specified
+
+
+ Named static arguments must come after all unnamed static arguments
+
+
+ The static parameter '{0}' of the provided type or method '{1}' requires a value. Static parameters to type providers may be optionally specified using named arguments, e.g. '{2}<{3}=...>'.
+
+
+ No static parameter exists with name '{0}'
+
+
+ The static parameter '{0}' has already been given a value
+
+
+ Multiple static parameters exist with name '{0}'
+
+
+ A custom operation may not be used in conjunction with a non-value or recursive 'let' binding in another part of this computation expression
+
+
+ A custom operation may not be used in conjunction with 'use', 'try/with', 'try/finally', 'if/then/else' or 'match' operators within this computation expression
+
+
+ The custom operation '{0}' refers to a method which is overloaded. The implementations of custom operations may not be overloaded.
+
+
+ An if/then/else expression may not be used within queries. Consider using either an if/then expression, or use a sequence expression instead.
+
+
+ Invalid argument to 'methodhandleof' during codegen
+
+
+ A reference to a provided type was missing a value for the static parameter '{0}'. You may need to recompile one or more referenced assemblies.
+
+
+ A reference to a provided type had an invalid value '{0}' for a static parameter. You may need to recompile one or more referenced assemblies.
+
+
+ '{0}' is not used correctly. This is a custom operation in this query or computation expression.
+
+
+ '{0}' is not used correctly. Usage: {1}. This is a custom operation in this query or computation expression.
+
+
+ {0} var in collection {1} (outerKey = innerKey). Note that parentheses are required after '{2}'
+
+
+ {0} var in collection {1} (outerKey = innerKey) into group. Note that parentheses are required after '{2}'
+
+
+ {0} var in collection
+
+
+ '{0}' must be followed by a variable name. Usage: {1}.
+
+
+ Incorrect syntax for '{0}'. Usage: {1}.
+
+
+ '{0}' must come after a 'for' selection clause and be followed by the rest of the query. Syntax: ... {1} ...
+
+
+ '{0}' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected {1} argument(s), but given {2}.
+
+
+ Expected an expression after this point
+
+
+ Expected a type after this point
+
+
+ Unmatched '[<'. Expected closing '>]'
+
+
+ Unexpected end of input in 'match' expression. Expected 'match <expr> with | <pat> -> <expr> | <pat> -> <expr> ...'.
+
+
+ Unexpected end of input in 'try' expression. Expected 'try <expr> with <rules>' or 'try <expr> finally <expr>'.
+
+
+ Unexpected end of input in 'while' expression. Expected 'while <expr> do <expr>'.
+
+
+ Unexpected end of input in 'for' expression. Expected 'for <pat> in <expr> do <expr>'.
+
+
+ Unexpected end of input in 'match' or 'try' expression
+
+
+ Unexpected end of input in 'then' branch of conditional expression. Expected 'if <expr> then <expr>' or 'if <expr> then <expr> else <expr>'.
+
+
+ Unexpected end of input in 'else' branch of conditional expression. Expected 'if <expr> then <expr>' or 'if <expr> then <expr> else <expr>'.
+
+
+ Unexpected end of input in body of lambda expression. Expected 'fun <pat> ... <pat> -> <expr>'.
+
+
+ Unexpected end of input in type arguments
+
+
+ Unexpected end of input in type signature
+
+
+ Unexpected end of input in type definition
+
+
+ Unexpected end of input in object members
+
+
+ Unexpected end of input in value, function or member definition
+
+
+ Unexpected end of input in expression
+
+
+ Unexpected end of type. Expected a name after this point.
+
+
+ Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword.
+
+
+ Incomplete value definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let!' keyword.
+
+
+ Incomplete value definition. If this is in an expression, the body of the expression must be indented to the same column as the 'use!' keyword.
+
+
+ Incomplete value definition. If this is in an expression, the body of the expression must be indented to the same column as the 'use' keyword.
+
+
+ Missing 'do' in 'while' expression. Expected 'while <expr> do <expr>'.
+
+
+ Missing 'do' in 'for' expression. Expected 'for <pat> in <expr> do <expr>'.
+
+
+ Invalid join relation in '{0}'. Expected 'expr <op> expr', where <op> is =, =?, ?= or ?=?.
+
+
+ Calls
+
+
+ Invalid number of generic arguments to type '{0}' in provided type. Expected '{1}' arguments, given '{2}'.
+
+
+ Invalid value '{0}' for unit-of-measure parameter '{1}'
+
+
+ Invalid value unit-of-measure parameter '{0}'
+
+
+ Property '{0}' on provided type '{1}' is neither readable nor writable as it has CanRead=false and CanWrite=false
+
+
+ A use of 'into' must be followed by the remainder of the computation
+
+
+ The operator '{0}' does not accept the use of 'into'
+
+
+ The definition of the custom operator '{0}' does not use a valid combination of attribute flags
+
+
+ This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute.
+
+
+ 'member val' definitions are only permitted in types with a primary constructor. Consider adding arguments to your type definition, e.g. 'type X(args) = ...'.
+
+
+ Property definitions may not be declared mutable. To indicate that this property can be set, use 'member val PropertyName = expr with get,set'.
+
+
+ To indicate that this property can be set, use 'member val PropertyName = expr with get,set'.
+
+
+ Type '{0}' is illegal because in byref<T>, T cannot contain byref types.
+
+
+ F# supports array ranks between 1 and 32. The value {0} is not allowed.
+
+
+ In queries, use the form 'for x in n .. m do ...' for ranging over integers
+
+
+ 'while' expressions may not be used in queries
+
+
+ 'try/finally' expressions may not be used in queries
+
+
+ 'use' expressions may not be used in queries
+
+
+ 'let!', 'use!' and 'do!' expressions may not be used in queries
+
+
+ 'return' and 'return!' may not be used in queries
+
+
+ This is not a known query operator. Query operators are identifiers such as 'select', 'where', 'sortBy', 'thenBy', 'groupBy', 'groupValBy', 'join', 'groupJoin', 'sumBy' and 'averageBy', defined using corresponding methods on the 'QueryBuilder' type.
+
+
+ 'try/with' expressions may not be used in queries
+
+
+ This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.
+
+
+ Too many static parameters. Expected at most {0} parameters, but got {1} unnamed and {2} named parameters.
+
+
+ Invalid provided literal value '{0}'
+
+
+ The 'anycpu32bitpreferred' platform can only be used with EXE targets. You must use 'anycpu' instead.
+
+
+ This member, function or value declaration may not be declared 'inline'
+
+
+ The provider '{0}' returned a non-generated type '{1}' in the context of a set of generated types. Consider adjusting the type provider to only return generated types.
+
+
+ Arguments to query operators may require parentheses, e.g. 'where (x > y)' or 'groupBy (x.Length / 10)'
+
+
+ A quotation may not involve an assignment to or taking the address of a captured local variable
+
+
+ + 1 overload
+
+
+ + {0} overloads
+
+
+ Erased to
+
+
+ Unexpected token '{0}' or incomplete expression
+
+
+ Cannot find code target for this attribute, possibly because the code after the attribute is incomplete.
+
+
+ Type name cannot be empty.
+
+
+ Problem reading assembly '{0}': {1}
+
+
+ Invalid provided field. Provided fields of erased provided types must be literals.
+
+
+ (loading description...)
+
+
+ (description unavailable...)
+
+
+ A type variable has been constrained by multiple different class types. A type variable may only have one class constraint.
+
+
+ 'match' expressions may not be used in queries
+
+
+ Infix operator member '{0}' has {1} initial argument(s). Expected a tuple of 3 arguments
+
+
+ The operator '{0}' cannot be resolved. Consider opening the module 'Microsoft.FSharp.Linq.NullableOperators'.
+
+
+ '{0}' must be followed by 'in'. Usage: {1}.
+
+
+ Neither 'member val' nor 'override val' definitions are permitted in object expressions.
+
+
+ Copy-and-update record expressions must include at least one field.
+
+
+ '_' cannot be used as field name
+
+
+ The provided types generated by this use of a type provider may not be used from other F# assemblies and should be marked internal or private. Consider using 'type internal TypeName = ...' or 'type private TypeName = ...'.
+
+
+ A property's getter and setter must have the same type. Property '{0}' has getter of type '{1}' but setter of type '{2}'.
+
+
+ Array method '{0}' is supplied by the runtime and cannot be directly used in code. For operations with array elements consider using family of GetArray/SetArray functions from LanguagePrimitives.IntrinsicFunctions module.
+
+
+ The union case '{0}' does not have a field named '{1}'.
+
+
+ The exception '{0}' does not have a field named '{1}'.
+
+
+ Active patterns do not have fields. This syntax is invalid.
+
+
+ The constructor does not have a field named '{0}'.
+
+
+ Union case/exception field '{0}' cannot be used more than once.
+
+
+ Named field '{0}' is used more than once.
+
+
+ Named field '{0}' conflicts with autogenerated name for anonymous field.
+
+
+ This literal expression or attribute argument results in an arithmetic overflow.
+
+
+ This is not valid literal expression. The [<Literal>] attribute will be ignored.
+
+
+ System.Runtime.InteropServices assembly is required to use UnknownWrapper\DispatchWrapper classes.
+
+
+ The mutable local '{0}' is implicitly allocated as a reference cell because it has been captured by a closure. This warning is for informational purposes only to indicate where implicit allocations are performed.
+
+
+ A type provider implemented GetStaticParametersForMethod, but ApplyStaticArgumentsForMethod was not implemented or invalid
+
+
+ An error occured applying the static arguments to a provided method
+
+
+ Unexpected character '{0}' in preprocessor expression
+
+
+ Unexpected token '{0}' in preprocessor expression
+
+
+ Incomplete preprocessor expression
+
+
+ Missing token '{0}' in preprocessor expression
+
+
+ An error occurred while reading the F# metadata node at position {0} in table '{1}' of assembly '{2}'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using.
+
+
+ Type inference caused the type variable {0} to escape its scope. Consider adding an explicit type parameter declaration or adjusting your code to be less generic.
+
+
+ Type inference caused an inference type variable to escape its scope. Consider adding type annotations to make your code less generic.
+
+
+ Redundant arguments are being ignored in function '{0}'. Expected {1} but got {2} arguments.
+
+
+ Lowercase literal '{0}' is being shadowed by a new pattern with the same name. Only uppercase and module-prefixed literals can be used as named patterns.
+
+
+ This literal pattern does not take arguments
+
+
+ Constructors are not permitted as extension members - they must be defined as part of the original definition of the type
+
+
+ Invalid response file '{0}' ( '{1}' )
+
+
+ Response file '{0}' not found in '{1}'
+
+
+ Response file name '{0}' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long
+
+
+ Cannot find FSharp.Core.dll in compiler's directory
+
+
+ One tuple type is a struct tuple, the other is a reference tuple
+
+
+ This provided method requires static parameters
+
+
+ The conversion from {0} to {1} is a compile-time safe upcast, not a downcast. Consider using 'upcast' instead of 'downcast'.
+
+
+ The conversion from {0} to {1} is a compile-time safe upcast, not a downcast. Consider using the :> (upcast) operator instead of the :?> (downcast) operator.
+
+
+ The 'rec' on this module is implied by an outer 'rec' declaration and is being ignored
+
+
+ In a recursive declaration group, 'open' declarations must come first in each module
+
+
+ In a recursive declaration group, module abbreviations must come after all 'open' declarations and before other declarations
+
+
+ This declaration is not supported in recursive declaration groups
+
+
+ Invalid use of 'rec' keyword
+
+
+ If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.
+
+
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
+
+
+ Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'
+
+
+ Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression.
+
+
+ The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.
+
+
+ {0} is an active pattern and cannot be treated as a discriminated union case with named fields.
+
+
+ The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'.
+
+
+ The system type '{0}' was required but no referenced system DLL contained this type
+
+
+ The member '{0}' matches multiple overloads of the same method.\nPlease restrict it to one of the following:{1}.
+
+
+ Method or object constructor '{0}' is not static
+
+
+ Unexpected symbol '=' in expression. Did you intend to use 'for x in y .. z do' instead?
+
+
+ Two anonymous record types are from different assemblies '{0}' and '{1}'
+
+
+ Two anonymous record types have mismatched sets of field names '{0}' and '{1}'
+
+
+ Indicates a method that either has no implementation in the type in which it is declared or that is virtual and has a default implementation.
+
+
+ Used in mutually recursive bindings, in property declarations, and with multiple constraints on generic parameters.
+
+
+ Used to give the current class object an object name. Also used to give a name to a whole pattern within a pattern match.
+
+
+ Used to verify code during debugging.
+
+
+ Used as the name of the base class object.
+
+
+ In verbose syntax, indicates the start of a code block.
+
+
+ In verbose syntax, indicates the start of a class definition.
+
+
+ Indicates an implementation of an abstract method; used together with an abstract method declaration to create a virtual method.
+
+
+ Used to declare a delegate.
+
+
+ Used in looping constructs or to execute imperative code.
+
+
+ In verbose syntax, indicates the end of a block of code in a looping expression.
+
+
+ Used to convert to a type that is lower in the inheritance chain.
+
+
+ In a for expression, used when counting in reverse.
+
+
+ Used in conditional branching. A short form of else if.
+
+
+ Used in conditional branching.
+
+
+ In type definitions and type extensions, indicates the end of a section of member definitions. In verbose syntax, used to specify the end of a code block that starts with the begin keyword.
+
+
+ Used to declare an exception type.
+
+
+ Indicates that a declared program element is defined in another binary or assembly.
+
+
+ Used as a Boolean literal.
+
+
+ Used together with try to introduce a block of code that executes regardless of whether an exception occurs.
+
+
+ Used in looping constructs.
+
+
+ Used in lambda expressions, also known as anonymous functions.
+
+
+ Used as a shorter alternative to the fun keyword and a match expression in a lambda expression that has pattern matching on a single argument.
+
+
+ Used to reference the top-level .NET namespace.
+
+
+ Used in conditional branching constructs.
+
+
+ Used for sequence expressions and, in verbose syntax, to separate expressions from bindings.
+
+
+ Used to specify a base class or base interface.
+
+
+ Used to indicate a function that should be integrated directly into the caller's code.
+
+
+ Used to declare and implement interfaces.
+
+
+ Used to specify that a member is visible inside an assembly but not outside it.
+
+
+ Used to specify a computation that is to be performed only when a result is needed.
+
+
+ Used to associate, or bind, a name to a value or function.
+
+
+ Used in computation expressions to bind a name to the result of another computation expression.
+
+
+ Used to branch by comparing a value to a pattern.
+
+
+ Used in computation expressions to pattern match directly over the result of another computation expression.
+
+
+ Used to declare a property or method in an object type.
+
+
+ Used to associate a name with a group of related types, values, and functions, to logically separate it from other code.
+
+
+ Used to declare a variable, that is, a value that can be changed.
+
+
+ Used to associate a name with a group of related types and modules, to logically separate it from other code.
+
+
+ Used to declare, define, or invoke a constructor that creates or that can create an object. Also used in generic parameter constraints to indicate that a type must have a certain constructor.
+
+
+ Not actually a keyword. However, not struct in combination is used as a generic parameter constraint.
+
+
+ Indicates the absence of an object. Also used in generic parameter constraints.
+
+
+ Used in discriminated unions to indicate the type of categories of values, and in delegate and exception declarations.
+
+
+ Used to make the contents of a namespace or module available without qualification.
+
+
+ Used with Boolean conditions as a Boolean or operator. Equivalent to ||. Also used in member constraints.
+
+
+ Used to implement a version of an abstract or virtual method that differs from the base version.
+
+
+ Restricts access to a member to code in the same type or module.
+
+
+ Allows access to a member from outside the type.
+
+
+ Used to indicate that a function is recursive.
+
+
+ Used to provide a value for the result of the containing computation expression.
+
+
+ Used to provide a value for the result of the containing computation expression, where that value itself comes from the result another computation expression.
+
+
+ Used in query expressions to specify what fields or columns to extract. Note that this is a contextual keyword, which means that it is not actually a reserved word and it only acts like a keyword in appropriate context.
+
+
+ Used to indicate a method or property that can be called without an instance of a type, or a value member that is shared among all instances of a type.
+
+
+ Used to declare a structure type. Also used in generic parameter constraints. Used for OCaml compatibility in module definitions.
+
+
+ Used in conditional expressions. Also used to perform side effects after object construction.
+
+
+ Used in for loops to indicate a range.
+
+
+ Used to introduce a block of code that might generate an exception. Used together with with or finally.
+
+
+ Used to declare a class, record, structure, discriminated union, enumeration type, unit of measure, or type abbreviation.
+
+
+ Used to convert to a type that is higher in the inheritance chain.
+
+
+ Used instead of let for values that implement IDisposable"
+
+
+ Used instead of let! in computation expressions for computation expression results that implement IDisposable.
+
+
+ Used in a signature to indicate a value, or in a type to declare a member, in limited situations.
+
+
+ Indicates the .NET void type. Used when interoperating with other .NET languages.
+
+
+ Used for Boolean conditions (when guards) on pattern matches and to introduce a constraint clause for a generic type parameter.
+
+
+ Introduces a looping construct.
+
+
+ Used together with the match keyword in pattern matching expressions. Also used in object expressions, record copying expressions, and type extensions to introduce member definitions, and to introduce exception handlers.
+
+
+ Used in a sequence expression to produce a value for a sequence.
+
+
+ Used in a computation expression to append the result of a given computation expression to a collection of results for the containing computation expression.
+
+
+ In function types, delimits arguments and return values. Yields an expression (in sequence expressions); equivalent to the yield keyword. Used in match expressions
+
+
+ Assigns a value to a variable.
+
+
+ Converts a type to type that is higher in the hierarchy.
+
+
+ Converts a type to a type that is lower in the hierarchy.
+
+
+ Delimits a typed code quotation.
+
+
+ Delimits a untyped code quotation.
+
+
+ {0} '{1}' not found in assembly '{2}'. A possible cause may be a version incompatibility. You may need to explicitly reference the correct version of this assembly to allow all referenced components to use the correct version.
+
+
+ {0} '{1}' not found in type '{2}' from assembly '{3}'. A possible cause may be a version incompatibility. You may need to explicitly reference the correct version of this assembly to allow all referenced components to use the correct version.
+
+
+ is
+
+
+ This value is not a function and cannot be applied.
+
+
+ This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
+
+
+ This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
+
+
+
+
+
+
+ This value is not a function and cannot be applied. Did you forget to terminate a declaration?
+
+
+ The argument names in the signature '{0}' and implementation '{1}' do not match. The argument name from the signature file will be used. This may cause problems when debugging or profiling.
+
+
+ An error occurred while reading the F# metadata of assembly '{0}'. A reserved construct was utilized. You may need to upgrade your F# compiler or use an earlier version of the assembly that doesn't make use of a specific construct.
+
+
+ This method or property is not normally used from F# code, use an explicit tuple pattern for deconstruction instead.
+
+
+ This expression returns a value of type '{0}' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield'.
+
+
+ This expression returns a value of type '{0}' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield!'.
+
+
+ The file '{0}' changed on disk unexpectedly, please reload.
+
+
+ The byref pointer is readonly, so this write is not permitted.
+
+
+ A ReadOnly attribute has been applied to a struct type with a mutable field.
+
+
+ A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'.
+
+
+ A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type.
+
+
+ The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.
+
+
+ This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.
+
+
+ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'
+
+
+ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type.
+
+
+ Struct members cannot return the address of fields of the struct by reference
+
+
+ The function or method call cannot be used at this point, because one argument that is a byref of a non-stack-local Span or IsByRefLike type is used with another argument that is a stack-local Span or IsByRefLike type. This is to ensure the address of the local value does not escape its scope.
+
+
+ The Span or IsByRefLike variable '{0}' cannot be used at this point. This is to ensure the address of the local value does not escape its scope.
+
+
+ A Span or IsByRefLike value returned from the expression cannot be used at ths point. This is to ensure the address of the local value does not escape its scope.
+
+
+ Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address.
+
+
+ Cannot call the byref extension method '{0}. The first parameter requires the value to be mutable or a non-readonly byref type.
+
+
+ Byref types are not allowed to have optional type extensions.
+
+
+ Cannot partially apply the extension method '{0}' because the first parameter is a byref type.
+
+
+ This type does not inherit Attribute, it will not work correctly with other .NET languages.
+
+
+ Invalid anonymous record expression
+
+
+ Invalid anonymous record type
+
+
+ The input to a copy-and-update expression that creates an anonymous record must be either an anonymous record or a record
+
+
+ The type '{0}' does not support a nullness qualitification.
+
+
+ This language feature is not enabled, use /langversion:5.0 or greater to enable it
+
+
+ Nullness warning. The default constructor of a struct type is required but one of the fields of struct type is non-nullable.
+
+
+ Nullness warning. The 'DefaultValue' attribute is used but the type (or one of its fields if a struct) is non-nullable.
+
+
+ The constraints 'null' and 'not null' are inconsistent
+
+
+ The constraints 'struct' and 'null' are inconsistent
+
+
+ The constraints 'delegate' and 'comparison' are inconsistent
+
+
+ The /checknulls language feature is not enabled
+
+
+ The type '{0}' has 'null' as a true representation value but a constraint does not permit this
+
+
+ The type '{0}' has 'null' as an extra value but a constraint does not permit this
+
+
+ The parameter '{0}' has an invalid type '{1}'. This is not permitted by the rules of Common IL.
+
+
+ The function or method has an invalid return type '{0}'. This is not permitted by the rules of Common IL.
+
+
+ Enable nullness declarations and checks
+
+
+ Specify the language version
+
+
\ No newline at end of file
diff --git a/src/buildtools/buildtools.proj b/src/buildtools/buildtools.proj
index 593f086dd07..630bb678561 100644
--- a/src/buildtools/buildtools.proj
+++ b/src/buildtools/buildtools.proj
@@ -2,7 +2,8 @@
Debug
-
+ true
+
@@ -10,23 +11,23 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/src/buildtools/buildtools.targets b/src/buildtools/buildtools.targets
index 303ab00825d..185fd4d0599 100644
--- a/src/buildtools/buildtools.targets
+++ b/src/buildtools/buildtools.targets
@@ -20,7 +20,7 @@
BeforeTargets="CoreCompile">
- $(ArtifactsDir)\Bootstrap\fslex.dll
+ $(ArtifactsDir)\Bootstrap\fslex\fslex.dll
@@ -43,7 +43,7 @@
BeforeTargets="CoreCompile">
- $(ArtifactsDir)\Bootstrap\fsyacc.dll
+ $(ArtifactsDir)\Bootstrap\fsyacc\fsyacc.dll
diff --git a/src/fsharp/AccessibilityLogic.fs b/src/fsharp/AccessibilityLogic.fs
index 4070ea9b402..5881e2ae9bc 100644
--- a/src/fsharp/AccessibilityLogic.fs
+++ b/src/fsharp/AccessibilityLogic.fs
@@ -10,6 +10,7 @@ open FSharp.Compiler.Infos
open FSharp.Compiler.Tast
open FSharp.Compiler.Tastops
open FSharp.Compiler.TcGlobals
+open FSharp.Compiler.AbstractIL.Internal.Library
#if !NO_EXTENSIONTYPING
open FSharp.Compiler.ExtensionTyping
@@ -81,7 +82,7 @@ let private IsILMemberAccessible g amap m (tcrefOfViewedItem : TyconRef) ad acce
match tcrefViewedFromOption with
| None -> false
| Some tcrefViewedFrom ->
- ExistsHeadTypeInEntireHierarchy g amap m (generalizedTyconRef tcrefViewedFrom) tcrefOfViewedItem)
+ ExistsHeadTypeInEntireHierarchy g amap m (generalizedTyOfTyconRef g tcrefViewedFrom) tcrefOfViewedItem)
let accessibleByInternalsVisibleTo =
(access = ILMemberAccess.Assembly || access = ILMemberAccess.FamilyOrAssembly) &&
@@ -93,7 +94,7 @@ let private IsILMemberAccessible g amap m (tcrefOfViewedItem : TyconRef) ad acce
match tcrefViewedFromOption with
| None -> false
| Some tcrefViewedFrom ->
- ExistsHeadTypeInEntireHierarchy g amap m (generalizedTyconRef tcrefViewedFrom) tcrefOfViewedItem
+ ExistsHeadTypeInEntireHierarchy g amap m (generalizedTyOfTyconRef g tcrefViewedFrom) tcrefOfViewedItem
(access = ILMemberAccess.Public) || accessibleByFamily || accessibleByInternalsVisibleTo || accessibleByFamilyAndAssembly
@@ -327,10 +328,16 @@ let IsPropInfoAccessible g amap m ad = function
| ProvidedProp (amap, tppi, m) as pp->
let access =
let a = tppi.PUntaint((fun ppi ->
- let tryGetILAccessForProvidedMethodBase (mi : ProvidedMethodBase) =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ let tryGetILAccessForProvidedMethodBase (mi : ProvidedMethodInfo) =
+#else
+ let tryGetILAccessForProvidedMethodBase (mi : ProvidedMethodInfo?) = // TODO NULLNESS: using ProvidedMethodBase? gives a nullness warning
+#endif
match mi with
| null -> None
- | mi -> Some(ComputeILAccess mi.IsPublic mi.IsFamily mi.IsFamilyOrAssembly mi.IsFamilyAndAssembly)
+ | NonNull mi ->
+ Some(ComputeILAccess mi.IsPublic mi.IsFamily mi.IsFamilyOrAssembly mi.IsFamilyAndAssembly)
+
match tryGetILAccessForProvidedMethodBase(ppi.GetGetMethod()) with
| None -> tryGetILAccessForProvidedMethodBase(ppi.GetSetMethod())
| x -> x), m)
diff --git a/src/fsharp/AugmentWithHashCompare.fs b/src/fsharp/AugmentWithHashCompare.fs
index ce562dedaa4..562218f93b2 100644
--- a/src/fsharp/AugmentWithHashCompare.fs
+++ b/src/fsharp/AugmentWithHashCompare.fs
@@ -43,21 +43,21 @@ let mkEqualsSlotSig (g: TcGlobals) =
let mkThisTy g ty = if isStructTy g ty then mkByrefTy g ty else ty
-let mkCompareObjTy g ty = (mkThisTy g ty) --> (g.obj_ty --> g.int_ty)
+let mkCompareObjTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty g.int_ty)
-let mkCompareTy g ty = (mkThisTy g ty) --> (ty --> g.int_ty)
+let mkCompareTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g ty g.int_ty)
-let mkCompareWithComparerTy g ty = (mkThisTy g ty) --> ((mkRefTupledTy g [g.obj_ty ; g.IComparer_ty]) --> g.int_ty)
+let mkCompareWithComparerTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [g.obj_ty ; g.IComparer_ty]) g.int_ty)
-let mkEqualsObjTy g ty = (mkThisTy g ty) --> (g.obj_ty --> g.bool_ty)
+let mkEqualsObjTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty g.bool_ty)
-let mkEqualsTy g ty = (mkThisTy g ty) --> (ty --> g.bool_ty)
+let mkEqualsTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g ty g.bool_ty)
-let mkEqualsWithComparerTy g ty = (mkThisTy g ty) --> ((mkRefTupledTy g [g.obj_ty ; g.IEqualityComparer_ty]) --> g.bool_ty)
+let mkEqualsWithComparerTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [g.obj_ty ; g.IEqualityComparer_ty]) g.bool_ty)
-let mkHashTy g ty = (mkThisTy g ty) --> (g.unit_ty --> g.int_ty)
+let mkHashTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g g.unit_ty g.int_ty)
-let mkHashWithComparerTy g ty = (mkThisTy g ty) --> (g.IEqualityComparer_ty --> g.int_ty)
+let mkHashWithComparerTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g g.IEqualityComparer_ty g.int_ty)
//-------------------------------------------------------------------------
// Polymorphic comparison
@@ -174,7 +174,7 @@ let mkEqualsTestConjuncts g m exprs =
let mkMinimalTy (g: TcGlobals) (tcref: TyconRef) =
if tcref.Deref.IsExceptionDecl then [], g.exn_ty
- else generalizeTyconRef tcref
+ else generalizeTyconRef g tcref
// check for nulls
let mkBindNullComparison g m thise thate expr =
@@ -783,7 +783,7 @@ let CheckAugmentationAttribs isImplementation g amap (tycon: Tycon) =
errorR(Error(FSComp.SR.augInvalidAttrs(), m))
let hasNominalInterface tcref =
- let ty = generalizedTyconRef (mkLocalTyconRef tycon)
+ let ty = generalizedTyOfTyconRef g (mkLocalTyconRef tycon)
ExistsHeadTypeInEntireHierarchy g amap tycon.Range ty tcref
let hasExplicitICompare =
@@ -950,10 +950,10 @@ let MakeBindingsForCompareAugmentation g (tycon: Tycon) =
mkApps g ((exprForValRef m vref2, vref2.Type), (if isNil tinst then [] else [tinst]), [thise;thate], m)
- mkLambdas m tps [thisv;thatobjv] (comparee, g.int_ty)
+ mkLambdas g m tps [thisv; thatobjv] (comparee, g.int_ty)
let rhs2 =
let thisv, thatv, comparee = comparef g tcref tycon
- mkLambdas m tps [thisv;thatv] (comparee, g.int_ty)
+ mkLambdas g m tps [thisv; thatv] (comparee, g.int_ty)
[ // This one must come first because it may be inlined into the second
mkCompGenBind vspec2 rhs2
mkCompGenBind vspec1 rhs1; ]
@@ -981,7 +981,7 @@ let MakeBindingsForCompareWithComparerAugmentation g (tycon: Tycon) =
let rhs =
let comparee = comparef g tcref tycon (thisv, thise) (thatobjv, thate) compe
let comparee = if isUnitTy g ty then mkZero g m else comparee
- mkMultiLambdas m tps [[thisv];[thatobjv;compv]] (comparee, g.int_ty)
+ mkMultiLambdas g m tps [[thisv]; [thatobjv; compv]] (comparee, g.int_ty)
[mkCompGenBind vspec rhs]
if tycon.IsUnionTycon then mkCompare mkUnionCompareWithComparer
elif tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then mkCompare mkRecdCompareWithComparer
@@ -1000,18 +1000,17 @@ let MakeBindingsForEqualityWithComparerAugmentation (g: TcGlobals) (tycon: Tycon
let withcGetHashCodeExpr =
let compv, compe = mkCompGenLocal m "comp" g.IEqualityComparer_ty
let thisv, hashe = hashf g tcref tycon compe
- mkLambdas m tps [thisv;compv] (hashe, g.int_ty)
+ mkLambdas g m tps [thisv; compv] (hashe, g.int_ty)
// build the equals rhs
let withcEqualsExpr =
- let _tinst, ty = mkMinimalTy g tcref
- let thisv, thise = mkThisVar g m ty
- let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty
- let thatv, thate = mkCompGenLocal m "that" ty
- let compv, compe = mkCompGenLocal m "comp" g.IEqualityComparer_ty
- let equalse = equalsf g tcref tycon (thisv, thise) thatobje (thatv, thate) compe
- mkMultiLambdas m tps [[thisv];[thatobjv;compv]] (equalse, g.bool_ty)
-
+ let _tinst,ty = mkMinimalTy g tcref
+ let thisv,thise = mkThisVar g m ty
+ let thatobjv,thatobje = mkCompGenLocal m "obj" g.obj_ty
+ let thatv,thate = mkCompGenLocal m "that" ty
+ let compv,compe = mkCompGenLocal m "comp" g.IEqualityComparer_ty
+ let equalse = equalsf g tcref tycon (thisv, thise) thatobje (thatv,thate) compe
+ mkMultiLambdas g m tps [[thisv];[thatobjv;compv]] (equalse,g.bool_ty)
let objGetHashCodeExpr =
let tinst, ty = mkMinimalTy g tcref
@@ -1024,7 +1023,7 @@ let MakeBindingsForEqualityWithComparerAugmentation (g: TcGlobals) (tycon: Tycon
let compe = mkILCallGetEqualityComparer g m
mkApps g ((exprForValRef m withcGetHashCodeVal, withcGetHashCodeVal.Type), (if isNil tinst then [] else [tinst]), [thise; compe], m)
- mkLambdas m tps [thisv; unitv] (hashe, g.int_ty)
+ mkLambdas g m tps [thisv; unitv] (hashe, g.int_ty)
[(mkCompGenBind withcGetHashCodeVal.Deref withcGetHashCodeExpr)
(mkCompGenBind objGetHashCodeVal.Deref objGetHashCodeExpr)
@@ -1044,8 +1043,8 @@ let MakeBindingsForEqualsAugmentation (g: TcGlobals) (tycon: Tycon) =
| Some (objEqualsVal, nocEqualsVal) ->
// this is the body of the real strongly typed implementation
let nocEqualsExpr =
- let thisv, thatv, equalse = equalsf g tcref tycon
- mkLambdas m tps [thisv;thatv] (equalse, g.bool_ty)
+ let thisv,thatv,equalse = equalsf g tcref tycon
+ mkLambdas g m tps [thisv;thatv] (equalse, g.bool_ty)
// this is the body of the override
let objEqualsExpr =
@@ -1061,7 +1060,7 @@ let MakeBindingsForEqualsAugmentation (g: TcGlobals) (tycon: Tycon) =
(mkApps g ((exprForValRef m nocEqualsVal, nocEqualsVal.Type), (if isNil tinst then [] else [tinst]), [thise;thate], m))
(mkFalse g m)
- mkLambdas m tps [thisv;thatobjv] (equalse, g.bool_ty)
+ mkLambdas g m tps [thisv;thatobjv] (equalse, g.bool_ty)
[ mkCompGenBind nocEqualsVal.Deref nocEqualsExpr
diff --git a/src/fsharp/CheckFormatStrings.fs b/src/fsharp/CheckFormatStrings.fs
index 1622a61351c..4b791ab0241 100644
--- a/src/fsharp/CheckFormatStrings.fs
+++ b/src/fsharp/CheckFormatStrings.fs
@@ -257,27 +257,27 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringChe
| 'O' ->
checkOtherFlags ch
collectSpecifierLocation relLine relCol 1
- parseLoop ((posi, NewInferenceType ()) :: acc) (i+1, relLine, relCol+1)
+ parseLoop ((posi, NewInferenceType g) :: acc) (i+1, relLine, relCol+1)
| 'A' ->
match info.numPrefixIfPos with
| None // %A has BindingFlags=Public, %+A has BindingFlags=Public | NonPublic
| Some '+' ->
collectSpecifierLocation relLine relCol 1
- parseLoop ((posi, NewInferenceType ()) :: acc) (i+1, relLine, relCol+1)
+ parseLoop ((posi, NewInferenceType g) :: acc) (i+1, relLine, relCol+1)
| Some _ -> failwithf "%s" <| FSComp.SR.forDoesNotSupportPrefixFlag(ch.ToString(), (Option.get info.numPrefixIfPos).ToString())
| 'a' ->
checkOtherFlags ch
- let xty = NewInferenceType ()
- let fty = bty --> (xty --> cty)
+ let xty = NewInferenceType g
+ let fty = mkFunTy g bty (mkFunTy g xty cty)
collectSpecifierLocation relLine relCol 2
parseLoop ((Option.map ((+)1) posi, xty) :: (posi, fty) :: acc) (i+1, relLine, relCol+1)
| 't' ->
checkOtherFlags ch
collectSpecifierLocation relLine relCol 1
- parseLoop ((posi, bty --> cty) :: acc) (i+1, relLine, relCol+1)
+ parseLoop ((posi, mkFunTy g bty cty) :: acc) (i+1, relLine, relCol+1)
| c -> failwithf "%s" <| FSComp.SR.forBadFormatSpecifierGeneral(String.make 1 c)
@@ -289,7 +289,7 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringChe
let ParseFormatString m g formatStringCheckContext fmt bty cty dty =
let argtys, specifierLocations = parseFormatStringInternal m g formatStringCheckContext fmt bty cty
- let aty = List.foldBack (-->) argtys dty
+ let aty = List.foldBack (mkFunTy g) argtys dty
let ety = mkRefTupledTy g argtys
(aty, ety), specifierLocations
diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs
index 237b6ae70dd..b51cb081a32 100644
--- a/src/fsharp/CompileOps.fs
+++ b/src/fsharp/CompileOps.fs
@@ -192,7 +192,11 @@ let GetRangeOfDiagnostic(err: PhasedDiagnostic) =
| NonRigidTypar(_, _, _, _, _, m)
| ConstraintSolverTupleDiffLengths(_, _, _, m, _)
| ConstraintSolverInfiniteTypes(_, _, _, _, m, _)
- | ConstraintSolverMissingConstraint(_, _, _, m, _)
+ | ConstraintSolverMissingConstraint(_, _, _, m, _)
+ | ConstraintSolverNullnessWarningEquivWithTypes(_, _, _, _, _, m, _)
+ | ConstraintSolverNullnessWarningWithTypes(_, _, _, _, _, m, _)
+ | ConstraintSolverNullnessWarningWithType(_, _, _, m, _)
+ | ConstraintSolverNonNullnessWarningWithType(_, _, _, m, _)
| ConstraintSolverTypesNotInEqualityRelation(_, _, _, m, _, _)
| ConstraintSolverError(_, m, _)
| ConstraintSolverTypesNotInSubsumptionRelation(_, _, _, m, _)
@@ -370,6 +374,10 @@ let GetDiagnosticNumber(err: PhasedDiagnostic) =
| :? TypeProviderError as e -> e.Number
#endif
| ErrorsFromAddingSubsumptionConstraint (_, _, _, _, _, ContextInfo.DowncastUsedInsteadOfUpcast _, _) -> fst (FSComp.SR.considerUpcast("", ""))
+ | ConstraintSolverNullnessWarningEquivWithTypes _ -> 3261
+ | ConstraintSolverNullnessWarningWithTypes _ -> 3262
+ | ConstraintSolverNullnessWarningWithType _ -> 3263
+ | ConstraintSolverNonNullnessWarningWithType _ -> 3264
| _ -> 193
GetFromException err.Exception
@@ -441,6 +449,10 @@ let ConstraintSolverTupleDiffLengthsE() = DeclareResourceString("ConstraintSolve
let ConstraintSolverInfiniteTypesE() = DeclareResourceString("ConstraintSolverInfiniteTypes", "%s%s")
let ConstraintSolverMissingConstraintE() = DeclareResourceString("ConstraintSolverMissingConstraint", "%s")
let ConstraintSolverTypesNotInEqualityRelation1E() = DeclareResourceString("ConstraintSolverTypesNotInEqualityRelation1", "%s%s")
+let ConstraintSolverNullnessWarningEquivWithTypesE() = DeclareResourceString("ConstraintSolverNullnessWarningEquivWithTypes", "%s%s%s%s")
+let ConstraintSolverNullnessWarningWithTypesE() = DeclareResourceString("ConstraintSolverNullnessWarningWithTypes", "%s%s%s%s")
+let ConstraintSolverNullnessWarningWithTypeE() = DeclareResourceString("ConstraintSolverNullnessWarningWithType", "%s")
+let ConstraintSolverNonNullnessWarningWithTypeE() = DeclareResourceString("ConstraintSolverNonNullnessWarningWithType", "%s")
let ConstraintSolverTypesNotInEqualityRelation2E() = DeclareResourceString("ConstraintSolverTypesNotInEqualityRelation2", "%s%s")
let ConstraintSolverTypesNotInSubsumptionRelationE() = DeclareResourceString("ConstraintSolverTypesNotInSubsumptionRelation", "%s%s%s")
let ErrorFromAddingTypeEquation1E() = DeclareResourceString("ErrorFromAddingTypeEquation1", "%s%s%s")
@@ -630,11 +642,45 @@ let OutputPhasedErrorR (os: StringBuilder) (err: PhasedDiagnostic) (suggestNames
if m.StartLine <> m2.StartLine then
os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore
+ | ConstraintSolverNullnessWarningEquivWithTypes(denv, ty1, ty2, nullness1, nullness2, m, m2) ->
+
+ let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2
+
+ os.Append(ConstraintSolverNullnessWarningEquivWithTypesE().Format t1 t2 (nullness1.ToString()) (nullness2.ToString())) |> ignore
+
+ if m.StartLine <> m2.StartLine then
+ os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore
+
+ | ConstraintSolverNullnessWarningWithTypes(denv, ty1, ty2, nullness1, nullness2, m, m2) ->
+
+ let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2
+
+ os.Append(ConstraintSolverNullnessWarningWithTypesE().Format t1 t2 (nullness1.ToString()) (nullness2.ToString())) |> ignore
+
+ if m.StartLine <> m2.StartLine then
+ os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore
+
+ | ConstraintSolverNullnessWarningWithType(denv, ty, _nullness, m, m2) ->
+
+ let t = NicePrint.minimalStringOfType denv ty
+ os.Append(ConstraintSolverNullnessWarningWithTypeE().Format (t)) |> ignore
+
+ if m.StartLine <> m2.StartLine then
+ os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore
+
+ | ConstraintSolverNonNullnessWarningWithType(denv, ty, _nullness, m, m2) ->
+
+ let t = NicePrint.minimalStringOfType denv ty
+ os.Append(ConstraintSolverNonNullnessWarningWithTypeE().Format (t)) |> ignore
+
+ if m.StartLine <> m2.StartLine then
+ os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore
+
| ConstraintSolverTypesNotInEqualityRelation(denv, (TType_measure _ as t1), (TType_measure _ as t2), m, m2, _) ->
// REVIEW: consider if we need to show _cxs (the type parameter constraints)
let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2
- os.Append(ConstraintSolverTypesNotInEqualityRelation1E().Format t1 t2 ) |> ignore
+ os.Append(ConstraintSolverTypesNotInEqualityRelation1E().Format t1 t2) |> ignore
if m.StartLine <> m2.StartLine then
os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore
@@ -1244,7 +1290,7 @@ let OutputPhasedErrorR (os: StringBuilder) (err: PhasedDiagnostic) (suggestNames
// we need to check if unit was used as a type argument
let rec hasUnitTType_app (types: TType list) =
match types with
- | TType_app (maybeUnit, []) :: ts ->
+ | TType_app (maybeUnit, [], _) :: ts ->
match maybeUnit.TypeAbbrev with
| Some ttype when Tastops.isUnitTy g ttype -> true
| _ -> hasUnitTType_app ts
@@ -1252,7 +1298,7 @@ let OutputPhasedErrorR (os: StringBuilder) (err: PhasedDiagnostic) (suggestNames
| [] -> false
match minfoVirt.ApparentEnclosingType with
- | TType_app (t, types) when t.IsFSharpInterfaceTycon && hasUnitTType_app types ->
+ | TType_app (t, types, _) when t.IsFSharpInterfaceTycon && hasUnitTType_app types ->
// match abstract member with 'unit' passed as generic argument
os.Append(OverrideDoesntOverride4E().Format sig1) |> ignore
| _ ->
@@ -1880,24 +1926,35 @@ type VersionFlag =
/// Represents a reference to an assembly. May be backed by a real assembly on disk, or a cross-project
/// reference backed by information generated by the the compiler service.
type IRawFSharpAssemblyData =
+
/// The raw list AutoOpenAttribute attributes in the assembly
abstract GetAutoOpenAttributes: ILGlobals -> string list
+
/// The raw list InternalsVisibleToAttribute attributes in the assembly
- abstract GetInternalsVisibleToAttributes: ILGlobals -> string list
+ abstract GetInternalsVisibleToAttributes: ILGlobals -> string list
+
/// The raw IL module definition in the assembly, if any. This is not present for cross-project references
/// in the language service
abstract TryGetILModuleDef: unit -> ILModuleDef option
+
/// The raw F# signature data in the assembly, if any
- abstract GetRawFSharpSignatureData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> byte[])) list
+ abstract GetRawFSharpSignatureData: range * ilShortAssemName: string * fileName: string -> (string * ((unit -> byte[]) * (unit -> byte[]) option)) list
+
/// The raw F# optimization data in the assembly, if any
- abstract GetRawFSharpOptimizationData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> byte[])) list
+ abstract GetRawFSharpOptimizationData: range * ilShortAssemName: string * fileName: string -> (string * ((unit -> byte[]) * (unit -> byte[]) option)) list
+
/// The table of type forwarders in the assembly
abstract GetRawTypeForwarders: unit -> ILExportedTypesAndForwarders
+
/// The identity of the module
abstract ILScopeRef: ILScopeRef
+
abstract ILAssemblyRefs: ILAssemblyRef list
+
abstract ShortAssemblyName: string
+
abstract HasAnyFSharpSignatureDataAttribute: bool
+
abstract HasMatchingFSharpSignatureDataAttribute: ILGlobals -> bool
/// Cache of time stamps as we traverse a project description
@@ -2026,6 +2083,9 @@ type TcConfigBuilder =
mutable embedResources: string list
mutable errorSeverityOptions: FSharpErrorSeverityOptions
mutable mlCompatibility: bool
+ mutable assumeNullOnImport: bool
+ mutable checkNullness: bool
+ mutable langVersion: double
mutable checkOverflow: bool
mutable showReferenceResolutions: bool
mutable outputFile: string option
@@ -2079,7 +2139,7 @@ type TcConfigBuilder =
mutable win32manifest: string
mutable includewin32manifest: bool
mutable linkResources: string list
- mutable legacyReferenceResolver: ReferenceResolver.Resolver
+ mutable legacyReferenceResolver: ReferenceResolver.Resolver
mutable showFullPaths: bool
mutable errorStyle: ErrorStyle
@@ -2154,7 +2214,7 @@ type TcConfigBuilder =
mutable pathMap: PathMap
}
- static member Initial =
+ static member Initial(legacyReferenceResolver) =
{
primaryAssembly = PrimaryAssembly.Mscorlib // defaut value, can be overridden using the command line switch
light = None
@@ -2187,6 +2247,9 @@ type TcConfigBuilder =
subsystemVersion = 4, 0 // per spec for 357994
useHighEntropyVA = false
mlCompatibility = false
+ assumeNullOnImport = false
+ checkNullness = false
+ langVersion = 5.0
checkOverflow = false
showReferenceResolutions = false
outputFile = None
@@ -2243,7 +2306,7 @@ type TcConfigBuilder =
win32manifest = ""
includewin32manifest = true
linkResources = []
- legacyReferenceResolver = null
+ legacyReferenceResolver = legacyReferenceResolver
showFullPaths = false
errorStyle = ErrorStyle.DefaultErrors
@@ -2298,7 +2361,7 @@ type TcConfigBuilder =
if (String.IsNullOrEmpty defaultFSharpBinariesDir) then
failwith "Expected a valid defaultFSharpBinariesDir"
- { TcConfigBuilder.Initial with
+ { TcConfigBuilder.Initial(legacyReferenceResolver) with
implicitIncludeDir = implicitIncludeDir
defaultFSharpBinariesDir = defaultFSharpBinariesDir
reduceMemoryUsage = reduceMemoryUsage
@@ -2670,6 +2733,9 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member x.embedResources = data.embedResources
member x.errorSeverityOptions = data.errorSeverityOptions
member x.mlCompatibility = data.mlCompatibility
+ member x.assumeNullOnImport = data.assumeNullOnImport
+ member x.checkNullness = data.checkNullness
+ member x.langVersion = data.langVersion
member x.checkOverflow = data.checkOverflow
member x.showReferenceResolutions = data.showReferenceResolutions
member x.outputFile = data.outputFile
@@ -3586,13 +3652,21 @@ let IsSignatureDataResource (r: ILResource) =
r.Name.StartsWithOrdinal FSharpSignatureDataResourceName ||
r.Name.StartsWithOrdinal FSharpSignatureDataResourceName2
+let IsSignatureDataResourceB (r: ILResource) =
+ r.Name.StartsWithOrdinal FSharpSignatureDataResourceNameB
+
let IsOptimizationDataResource (r: ILResource) =
- r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName||
+ r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName ||
r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName2
+let IsOptimizationDataResourceB (r: ILResource) =
+ r.Name.StartsWithOrdinal FSharpOptimizationDataResourceNameB
+
let GetSignatureDataResourceName (r: ILResource) =
if r.Name.StartsWithOrdinal FSharpSignatureDataResourceName then
String.dropPrefix r.Name FSharpSignatureDataResourceName
+ elif r.Name.StartsWithOrdinal FSharpSignatureDataResourceNameB then
+ String.dropPrefix r.Name FSharpSignatureDataResourceNameB
elif r.Name.StartsWithOrdinal FSharpSignatureDataResourceName2 then
String.dropPrefix r.Name FSharpSignatureDataResourceName2
else failwith "GetSignatureDataResourceName"
@@ -3600,12 +3674,14 @@ let GetSignatureDataResourceName (r: ILResource) =
let GetOptimizationDataResourceName (r: ILResource) =
if r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName then
String.dropPrefix r.Name FSharpOptimizationDataResourceName
+ elif r.Name.StartsWithOrdinal FSharpOptimizationDataResourceNameB then
+ String.dropPrefix r.Name FSharpOptimizationDataResourceNameB
elif r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName2 then
String.dropPrefix r.Name FSharpOptimizationDataResourceName2
else failwith "GetOptimizationDataResourceName"
let IsReflectedDefinitionsResource (r: ILResource) =
- r.Name.StartsWithOrdinal(QuotationPickler.SerializedReflectedDefinitionsResourceNameBase)
+ r.Name.StartsWithOrdinal QuotationPickler.SerializedReflectedDefinitionsResourceNameBase
let MakeILResource rname bytes =
{ Name = rname
@@ -3614,25 +3690,30 @@ let MakeILResource rname bytes =
CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs
MetadataIndex = NoMetadataIdx }
-let PickleToResource inMem file (g: TcGlobals) scope rname p x =
+let PickleToResource inMem file (g: TcGlobals) scope rname rnameB p x =
let file = PathMap.apply g.pathMap file
-
+ let bytes, bytesB = pickleObjWithDanglingCcus inMem file g scope p x
{ Name = rname
- Location = (let bytes = pickleObjWithDanglingCcus inMem file g scope p x in ILResourceLocation.LocalOut bytes)
+ Location = ILResourceLocation.LocalOut bytes
+ Access = ILResourceAccess.Public
+ CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs
+ MetadataIndex = NoMetadataIdx },
+ { Name = rnameB
+ Location = ILResourceLocation.LocalOut bytesB
Access = ILResourceAccess.Public
CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs
MetadataIndex = NoMetadataIdx }
-let GetSignatureData (file, ilScopeRef, ilModule, byteReader) : PickledDataWithReferences =
- unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleCcuInfo (byteReader())
+let GetSignatureData (file, ilScopeRef, ilModule, byteReader, byteReaderB) : PickledDataWithReferences =
+ unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleCcuInfo (byteReader()) (match byteReaderB with None -> [| |] | Some br -> br())
-let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: CcuThunk, file, inMem) : ILResource =
+let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: CcuThunk, file, inMem) : ILResource * ILResource =
let mspec = ccu.Contents
let mspec = ApplyExportRemappingToEntity tcGlobals exportRemapping mspec
// For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers
// don't complain when they see the resource.
- let rname = if ccu.AssemblyName = getFSharpCoreLibraryName then FSharpSignatureDataResourceName2 else FSharpSignatureDataResourceName
-
+ let rname = if ccu.AssemblyName = getFSharpCoreLibraryName then FSharpSignatureDataResourceName2 else FSharpSignatureDataResourceName
+ let rnameB = FSharpSignatureDataResourceNameB
let includeDir =
if String.IsNullOrEmpty tcConfig.implicitIncludeDir then ""
else
@@ -3640,19 +3721,20 @@ let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: Ccu
|> System.IO.Path.GetFullPath
|> PathMap.applyDir tcGlobals.pathMap
- PickleToResource inMem file tcGlobals ccu (rname+ccu.AssemblyName) pickleCcuInfo
+ PickleToResource inMem file tcGlobals ccu (rname+ccu.AssemblyName) (rnameB+ccu.AssemblyName) pickleCcuInfo
{ mspec=mspec
compileTimeWorkingDir=includeDir
usesQuotations = ccu.UsesFSharp20PlusQuotations }
-let GetOptimizationData (file, ilScopeRef, ilModule, byteReader) =
- unpickleObjWithDanglingCcus file ilScopeRef ilModule Optimizer.u_CcuOptimizationInfo (byteReader())
+let GetOptimizationData (file, ilScopeRef, ilModule, byteReader, byteReaderB) =
+ unpickleObjWithDanglingCcus file ilScopeRef ilModule Optimizer.u_CcuOptimizationInfo (byteReader()) (match byteReaderB with None -> [| |] | Some br -> br())
let WriteOptimizationData (tcGlobals, file, inMem, ccu: CcuThunk, modulInfo) =
// For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers
// don't complain when they see the resource.
let rname = if ccu.AssemblyName = getFSharpCoreLibraryName then FSharpOptimizationDataResourceName2 else FSharpOptimizationDataResourceName
- PickleToResource inMem file tcGlobals ccu (rname+ccu.AssemblyName) Optimizer.p_CcuOptimizationInfo modulInfo
+ let rnameB = FSharpOptimizationDataResourceNameB
+ PickleToResource inMem file tcGlobals ccu (rname+ccu.AssemblyName) (rnameB+ccu.AssemblyName) Optimizer.p_CcuOptimizationInfo modulInfo
//----------------------------------------------------------------------------
// Abstraction for project reference
@@ -3660,30 +3742,60 @@ let WriteOptimizationData (tcGlobals, file, inMem, ccu: CcuThunk, modulInfo) =
type RawFSharpAssemblyDataBackedByFileOnDisk (ilModule: ILModuleDef, ilAssemblyRefs) =
let externalSigAndOptData = ["FSharp.Core"]
interface IRawFSharpAssemblyData with
+
member __.GetAutoOpenAttributes ilg = GetAutoOpenAttributes ilg ilModule
+
member __.GetInternalsVisibleToAttributes ilg = GetInternalsVisibleToAttributes ilg ilModule
+
member __.TryGetILModuleDef() = Some ilModule
+
member __.GetRawFSharpSignatureData(m, ilShortAssemName, filename) =
let resources = ilModule.Resources.AsList
+
let sigDataReaders =
[ for iresource in resources do
if IsSignatureDataResource iresource then
let ccuName = GetSignatureDataResourceName iresource
- yield (ccuName, fun () -> iresource.GetBytes()) ]
-
+ let readerA = fun () -> iresource.GetBytes()
+ let readerB =
+ resources |> List.tryPick (fun iresourceB ->
+ if IsSignatureDataResourceB iresourceB then
+ let ccuNameB = GetSignatureDataResourceName iresourceB
+ if ccuName = ccuNameB then
+ Some (fun () -> iresourceB.GetBytes() )
+ else None
+ else None)
+ yield (ccuName, (readerA, readerB)) ]
+
let sigDataReaders =
if sigDataReaders.IsEmpty && List.contains ilShortAssemName externalSigAndOptData then
let sigFileName = Path.ChangeExtension(filename, "sigdata")
if not (FileSystem.SafeExists sigFileName) then
error(Error(FSComp.SR.buildExpectedSigdataFile (FileSystem.GetFullPathShim sigFileName), m))
- [ (ilShortAssemName, fun () -> FileSystem.ReadAllBytesShim sigFileName)]
+ [ (ilShortAssemName, ((fun () -> FileSystem.ReadAllBytesShim sigFileName), None))]
else
sigDataReaders
sigDataReaders
+
member __.GetRawFSharpOptimizationData(m, ilShortAssemName, filename) =
+ let resources = ilModule.Resources.AsList
let optDataReaders =
- ilModule.Resources.AsList
- |> List.choose (fun r -> if IsOptimizationDataResource r then Some(GetOptimizationDataResourceName r, (fun () -> r.GetBytes())) else None)
+ resources
+ |> List.choose (fun r ->
+ if IsOptimizationDataResource r then
+ let ccuName = GetOptimizationDataResourceName r
+ let readerA = (fun () -> r.GetBytes())
+ let readerB =
+ resources |> List.tryPick (fun iresourceB ->
+ if IsOptimizationDataResourceB iresourceB then
+ let ccuNameB = GetOptimizationDataResourceName iresourceB
+ if ccuName = ccuNameB then
+ Some (fun () -> iresourceB.GetBytes() )
+ else None
+ else None)
+ Some(ccuName, (readerA, readerB))
+ else
+ None)
// Look for optimization data in a file
let optDataReaders =
@@ -3691,14 +3803,16 @@ type RawFSharpAssemblyDataBackedByFileOnDisk (ilModule: ILModuleDef, ilAssemblyR
let optDataFile = Path.ChangeExtension(filename, "optdata")
if not (FileSystem.SafeExists optDataFile) then
error(Error(FSComp.SR.buildExpectedFileAlongSideFSharpCore(optDataFile, FileSystem.GetFullPathShim optDataFile), m))
- [ (ilShortAssemName, (fun () -> FileSystem.ReadAllBytesShim optDataFile))]
+ [ (ilShortAssemName, ((fun () -> FileSystem.ReadAllBytesShim optDataFile), None))]
else
optDataReaders
optDataReaders
+
member __.GetRawTypeForwarders() =
match ilModule.Manifest with
| Some manifest -> manifest.ExportedTypes
| None -> mkILExportedTypes []
+
member __.ShortAssemblyName = GetNameOfILModule ilModule
member __.ILScopeRef = MakeScopeRefForILModule ilModule
member __.ILAssemblyRefs = ilAssemblyRefs
@@ -3882,11 +3996,19 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu
#if !NO_EXTENSIONTYPING
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
member tcImports.GetProvidedAssemblyInfo(ctok, m, assembly: Tainted) =
- let anameOpt = assembly.PUntaint((fun assembly -> match assembly with null -> None | a -> Some (a.GetName())), m)
- match anameOpt with
- | None -> false, None
- | Some aname ->
+#else
+ member tcImports.GetProvidedAssemblyInfo(ctok, m, assembly: Tainted) =
+#endif
+ match assembly with
+ | Tainted.Null -> false,None
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ | assembly ->
+#else
+ | Tainted.NonNull assembly ->
+#endif
+ let aname = assembly.PUntaint((fun a -> a.GetName()), m)
let ilShortAssemName = aname.Name
match tcImports.FindCcu (ctok, m, ilShortAssemName, lookupOnly=true) with
| ResolvedCcu ccu ->
@@ -4121,7 +4243,7 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu
member tcImports.ImportTypeProviderExtensions
(ctok, tcConfig: TcConfig,
- fileNameOfRuntimeAssembly,
+ fileNameOfRuntimeAssembly: string,
ilScopeRefOfRuntimeAssembly,
runtimeAssemblyAttributes: ILAttribute list,
entityToInjectInto, invalidateCcu: Event<_>, m) =
@@ -4134,7 +4256,7 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu
runtimeAssemblyAttributes
|> List.choose (TryDecodeTypeProviderAssemblyAttr (defaultArg ilGlobalsOpt EcmaMscorlibILGlobals))
// If no design-time assembly is specified, use the runtime assembly
- |> List.map (function null -> fileNameOfRuntimeAssembly | s -> s)
+ |> List.map (function null -> fileNameOfRuntimeAssembly | NonNull s -> s)
// For each simple name of a design-time assembly, we take the first matching one in the order they are
// specified in the attributes
|> List.distinctBy (fun s -> try Path.GetFileNameWithoutExtension s with _ -> s)
@@ -4316,8 +4438,8 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu
let ccuRawDataAndInfos =
ilModule.GetRawFSharpSignatureData(m, ilShortAssemName, filename)
- |> List.map (fun (ccuName, sigDataReader) ->
- let data = GetSignatureData (filename, ilScopeRef, ilModule.TryGetILModuleDef(), sigDataReader)
+ |> List.map (fun (ccuName, (sigDataReader, sigDataReaderB)) ->
+ let data = GetSignatureData (filename, ilScopeRef, ilModule.TryGetILModuleDef(), sigDataReader, sigDataReaderB)
let optDatas = Map.ofList optDataReaders
@@ -4355,8 +4477,8 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu
| None ->
if verbose then dprintf "*** no optimization data for CCU %s, was DLL compiled with --no-optimization-data??\n" ccuName
None
- | Some info ->
- let data = GetOptimizationData (filename, ilScopeRef, ilModule.TryGetILModuleDef(), info)
+ | Some (readerA, readerB) ->
+ let data = GetOptimizationData (filename, ilScopeRef, ilModule.TryGetILModuleDef(), readerA, readerB)
let res = data.OptionalFixup(fun nm -> availableToOptionalCcu(tcImports.FindCcu(ctok, m, nm, lookupOnly=false)))
if verbose then dprintf "found optimization data for CCU %s\n" ccuName
Some res)
@@ -4643,9 +4765,10 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu
// OK, now we have both mscorlib.dll and FSharp.Core.dll we can create TcGlobals
let tcGlobals = TcGlobals(tcConfig.compilingFslib, ilGlobals, fslibCcu,
- tcConfig.implicitIncludeDir, tcConfig.mlCompatibility,
- tcConfig.isInteractive, tryFindSysTypeCcu, tcConfig.emitDebugInfoInQuotations,
- tcConfig.noDebugData, tcConfig.pathMap)
+ tcConfig.implicitIncludeDir, tcConfig.mlCompatibility,
+ tcConfig.isInteractive, tcConfig.assumeNullOnImport, tcConfig.checkNullness, tcConfig.langVersion,
+ tryFindSysTypeCcu, tcConfig.emitDebugInfoInQuotations,
+ tcConfig.noDebugData, tcConfig.pathMap)
#if DEBUG
// the global_g reference cell is used only for debug printing
diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi
index 94d9bf53713..e50b5fa15c0 100644
--- a/src/fsharp/CompileOps.fsi
+++ b/src/fsharp/CompileOps.fsi
@@ -142,24 +142,35 @@ exception HashLoadedScriptConsideredSource of range
/// Represents a reference to an F# assembly. May be backed by a real assembly on disk (read by Abstract IL), or a cross-project
/// reference in FSharp.Compiler.Service.
type IRawFSharpAssemblyData =
+
/// The raw list AutoOpenAttribute attributes in the assembly
abstract GetAutoOpenAttributes: ILGlobals -> string list
+
/// The raw list InternalsVisibleToAttribute attributes in the assembly
abstract GetInternalsVisibleToAttributes: ILGlobals -> string list
+
/// The raw IL module definition in the assembly, if any. This is not present for cross-project references
/// in the language service
abstract TryGetILModuleDef: unit -> ILModuleDef option
+
abstract HasAnyFSharpSignatureDataAttribute: bool
+
abstract HasMatchingFSharpSignatureDataAttribute: ILGlobals -> bool
+
/// The raw F# signature data in the assembly, if any
- abstract GetRawFSharpSignatureData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> byte[])) list
+ abstract GetRawFSharpSignatureData : range * ilShortAssemName: string * fileName: string -> (string * ((unit -> byte[]) * (unit -> byte[]) option)) list
+
/// The raw F# optimization data in the assembly, if any
- abstract GetRawFSharpOptimizationData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> byte[])) list
+ abstract GetRawFSharpOptimizationData : range * ilShortAssemName: string * fileName: string -> (string * ((unit -> byte[]) * (unit -> byte[]) option)) list
+
/// The table of type forwarders in the assembly
abstract GetRawTypeForwarders: unit -> ILExportedTypesAndForwarders
+
/// The identity of the module
abstract ILScopeRef: ILScopeRef
+
abstract ILAssemblyRefs: ILAssemblyRef list
+
abstract ShortAssemblyName: string
type TimeStampCache =
@@ -273,6 +284,9 @@ type TcConfigBuilder =
mutable embedResources: string list
mutable errorSeverityOptions: FSharpErrorSeverityOptions
mutable mlCompatibility:bool
+ mutable assumeNullOnImport: bool
+ mutable checkNullness: bool
+ mutable langVersion: double
mutable checkOverflow:bool
mutable showReferenceResolutions:bool
mutable outputFile: string option
@@ -377,7 +391,7 @@ type TcConfigBuilder =
mutable pathMap : PathMap
}
- static member Initial: TcConfigBuilder
+ static member Initial: ReferenceResolver.Resolver -> TcConfigBuilder
static member CreateNew:
legacyReferenceResolver: ReferenceResolver.Resolver *
@@ -433,6 +447,9 @@ type TcConfig =
member embedResources: string list
member errorSeverityOptions: FSharpErrorSeverityOptions
member mlCompatibility:bool
+ member assumeNullOnImport: bool
+ member checkNullness: bool
+ member langVersion: double
member checkOverflow:bool
member showReferenceResolutions:bool
member outputFile: string option
@@ -640,6 +657,9 @@ type TcImports =
/// Determine if an IL resource attached to an F# assembly is an F# signature data resource
val IsSignatureDataResource: ILResource -> bool
+/// Determine if an IL resource attached to an F# assembly is an F# signature data resource (data stream B)
+val IsSignatureDataResourceB: ILResource -> bool
+
/// Determine if an IL resource attached to an F# assembly is an F# optimization data resource
val IsOptimizationDataResource: ILResource -> bool
@@ -648,14 +668,10 @@ val IsReflectedDefinitionsResource: ILResource -> bool
val GetSignatureDataResourceName: ILResource -> string
/// Write F# signature data as an IL resource
-val WriteSignatureData: TcConfig * TcGlobals * Tastops.Remap * CcuThunk * filename: string * inMem: bool -> ILResource
+val WriteSignatureData: TcConfig * TcGlobals * Tastops.Remap * CcuThunk * filename: string * inMem: bool -> ILResource * ILResource
/// Write F# optimization data as an IL resource
-val WriteOptimizationData: TcGlobals * filename: string * inMem: bool * CcuThunk * Optimizer.LazyModuleInfo -> ILResource
-
-//----------------------------------------------------------------------------
-// #r and other directives
-//--------------------------------------------------------------------------
+val WriteOptimizationData: TcGlobals * filename: string * inMem: bool * CcuThunk * Optimizer.LazyModuleInfo -> ILResource * ILResource
//----------------------------------------------------------------------------
// #r and other directives
diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs
index 3a30ed50077..e5b042e3928 100644
--- a/src/fsharp/CompileOptions.fs
+++ b/src/fsharp/CompileOptions.fs
@@ -615,6 +615,10 @@ let errorsAndWarningsFlags (tcConfigB: TcConfigBuilder) =
CompilerOption("warnon", tagWarnList, OptionStringList (fun n ->
tcConfigB.TurnWarningOn(rangeCmdArgs, trimFS n)), None, Some (FSComp.SR.optsWarnOn()))
+ CompilerOption("checknulls", tagNone, OptionSwitch (fun switch -> tcConfigB.checkNullness <- (switch = OptionSwitch.On)), None, Some (FSComp.SR.optsCheckNulls()))
+
+ CompilerOption("langversion", tagNone, OptionString (fun switch -> tcConfigB.langVersion <- double switch), None, Some (FSComp.SR.optsLangVersion()))
+
CompilerOption("consolecolors", tagNone, OptionSwitch (fun switch ->
enableConsoleColoring <- switch = OptionSwitch.On), None, Some (FSComp.SR.optsConsoleColors()))
]
@@ -986,6 +990,7 @@ let testFlag tcConfigB =
("test", tagString,
OptionString (fun s ->
match s with
+ | "AssumeNullOnImport" -> tcConfigB.assumeNullOnImport <- true
| "StackSpan" -> tcConfigB.internalTestSpanStackReferring <- true
| "ErrorRanges" -> tcConfigB.errorStyle <- ErrorStyle.TestErrors
| "Tracking" -> Lib.tracking := true (* general purpose on/off diagnostics flag *)
diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs
index 74036e1687c..2e86194cdb7 100644
--- a/src/fsharp/ConstraintSolver.fs
+++ b/src/fsharp/ConstraintSolver.fs
@@ -53,6 +53,10 @@ open FSharp.Compiler.Tastops
open FSharp.Compiler.TcGlobals
open FSharp.Compiler.TypeRelations
+#if !NO_EXTENSIONTYPING
+open FSharp.Compiler.ExtensionTyping
+#endif
+
//-------------------------------------------------------------------------
// Generate type variables and record them in within the scope of the
// compilation environment, which currently corresponds to the scope
@@ -72,25 +76,33 @@ let NewAnonTypar (kind, m, rigid, var, dyn) =
let NewNamedInferenceMeasureVar (_m, rigid, var, id) =
NewTypar(TyparKind.Measure, rigid, Typar(id, var, false), false, TyparDynamicReq.No, [], false, false)
-let NewInferenceMeasurePar () = NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, NoStaticReq, TyparDynamicReq.No, false)
+let NewInferenceMeasurePar () =
+ NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, NoStaticReq, TyparDynamicReq.No, false)
-let NewErrorTypar () = NewCompGenTypar (TyparKind.Type, TyparRigidity.Flexible, NoStaticReq, TyparDynamicReq.No, true)
+let NewErrorTypar () =
+ NewCompGenTypar (TyparKind.Type, TyparRigidity.Flexible, NoStaticReq, TyparDynamicReq.No, true)
-let NewErrorMeasureVar () = NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, NoStaticReq, TyparDynamicReq.No, true)
+let NewErrorMeasureVar () =
+ NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, NoStaticReq, TyparDynamicReq.No, true)
-let NewInferenceType () = mkTyparTy (NewTypar (TyparKind.Type, TyparRigidity.Flexible, Typar(compgenId, NoStaticReq, true), false, TyparDynamicReq.No, [], false, false))
-
-let NewErrorType () = mkTyparTy (NewErrorTypar ())
+let NewInferenceType (g: TcGlobals) =
+ let tp = NewTypar (TyparKind.Type, TyparRigidity.Flexible, Typar(compgenId, NoStaticReq, true), false, TyparDynamicReq.No, [], false, false)
+ let nullness = if g.langFeatureNullness then NewNullnessVar() else KnownAmbivalentToNull
+ TType_var (tp, nullness)
+
+let NewErrorType () =
+ mkTyparTy (NewErrorTypar ())
-let NewErrorMeasure () = Measure.Var (NewErrorMeasureVar ())
+let NewErrorMeasure () =
+ Measure.Var (NewErrorMeasureVar ())
let NewByRefKindInferenceType (g: TcGlobals) m =
let tp = NewTypar (TyparKind.Type, TyparRigidity.Flexible, Typar(compgenId, HeadTypeStaticReq, true), false, TyparDynamicReq.No, [], false, false)
if g.byrefkind_InOut_tcr.CanDeref then
- tp.SetConstraints [TyparConstraint.DefaultsTo(10, TType_app(g.byrefkind_InOut_tcr, []), m)]
+ tp.SetConstraints [TyparConstraint.DefaultsTo(10, TType_app(g.byrefkind_InOut_tcr, [], g.knownWithoutNull), m)]
mkTyparTy tp
-let NewInferenceTypes l = l |> List.map (fun _ -> NewInferenceType ())
+let NewInferenceTypes g l = l |> List.map (fun _ -> NewInferenceType g)
// QUERY: should 'rigid' ever really be 'true'? We set this when we know
// we are going to have to generalize a typar, e.g. when implementing a
@@ -103,8 +115,11 @@ let FreshenAndFixupTypars m rigid fctps tinst tpsorig =
let renaming, tinst = FixupNewTypars m fctps tinst tpsorig tps
tps, renaming, tinst
-let FreshenTypeInst m tpsorig = FreshenAndFixupTypars m TyparRigidity.Flexible [] [] tpsorig
-let FreshMethInst m fctps tinst tpsorig = FreshenAndFixupTypars m TyparRigidity.Flexible fctps tinst tpsorig
+let FreshenTypeInst m tpsorig =
+ FreshenAndFixupTypars m TyparRigidity.Flexible [] [] tpsorig
+
+let FreshMethInst m fctps tinst tpsorig =
+ FreshenAndFixupTypars m TyparRigidity.Flexible fctps tinst tpsorig
let FreshenTypars m tpsorig =
match tpsorig with
@@ -160,6 +175,10 @@ exception ConstraintSolverInfiniteTypes of displayEnv: DisplayEn
exception ConstraintSolverTypesNotInEqualityRelation of displayEnv: DisplayEnv * TType * TType * range * range * ContextInfo
exception ConstraintSolverTypesNotInSubsumptionRelation of displayEnv: DisplayEnv * TType * TType * range * range
exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Tast.Typar * Tast.TyparConstraint * range * range
+exception ConstraintSolverNullnessWarningEquivWithTypes of DisplayEnv * TType * TType * NullnessInfo * NullnessInfo * range * range
+exception ConstraintSolverNullnessWarningWithTypes of DisplayEnv * TType * TType * NullnessInfo * NullnessInfo * range * range
+exception ConstraintSolverNullnessWarningWithType of DisplayEnv * TType * NullnessInfo * range * range
+exception ConstraintSolverNonNullnessWarningWithType of DisplayEnv * TType * NullnessInfo * range * range
exception ConstraintSolverError of string * range * range
exception ConstraintSolverRelatedInformation of string option * range * exn
@@ -230,11 +249,11 @@ let MakeConstraintSolverEnv contextInfo css m denv =
let rec occursCheck g un ty =
match stripTyEqns g ty with
| TType_ucase(_, l)
- | TType_app (_, l)
+ | TType_app (_, l, _)
| TType_anon(_, l)
| TType_tuple (_, l) -> List.exists (occursCheck g un) l
- | TType_fun (d, r) -> occursCheck g un d || occursCheck g un r
- | TType_var r -> typarEq un r
+ | TType_fun (d, r, _nullness) -> occursCheck g un d || occursCheck g un r
+ | TType_var (r, _) -> typarEq un r
| TType_forall (_, tau) -> occursCheck g un tau
| _ -> false
@@ -586,11 +605,11 @@ let SimplifyMeasure g vars ms =
let rec SimplifyMeasuresInType g resultFirst ((generalizable, generalized) as param) ty =
match stripTyparEqns ty with
| TType_ucase(_, l)
- | TType_app (_, l)
- | TType_anon (_,l)
+ | TType_app (_, l, _)
+ | TType_anon (_, l)
| TType_tuple (_, l) -> SimplifyMeasuresInTypes g param l
- | TType_fun (d, r) -> if resultFirst then SimplifyMeasuresInTypes g param [r;d] else SimplifyMeasuresInTypes g param [d;r]
+ | TType_fun (d, r, _nullness) -> if resultFirst then SimplifyMeasuresInTypes g param [r;d] else SimplifyMeasuresInTypes g param [d;r]
| TType_var _ -> param
| TType_forall (_, tau) -> SimplifyMeasuresInType g resultFirst param tau
| TType_measure unt ->
@@ -624,11 +643,11 @@ let rec SimplifyMeasuresInConstraints g param cs =
let rec GetMeasureVarGcdInType v ty =
match stripTyparEqns ty with
| TType_ucase(_, l)
- | TType_app (_, l)
- | TType_anon (_,l)
+ | TType_app (_, l, _)
+ | TType_anon (_, l)
| TType_tuple (_, l) -> GetMeasureVarGcdInTypes v l
- | TType_fun (d, r) -> GcdRational (GetMeasureVarGcdInType v d) (GetMeasureVarGcdInType v r)
+ | TType_fun (d, r, _nullness) -> GcdRational (GetMeasureVarGcdInType v d) (GetMeasureVarGcdInType v r)
| TType_var _ -> ZeroRational
| TType_forall (_, tau) -> GetMeasureVarGcdInType v tau
| TType_measure unt -> MeasureVarExponent v unt
@@ -720,7 +739,7 @@ let rec SolveTyparEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optio
let m = csenv.m
do! DepthCheck ndeep m
match ty1 with
- | TType_var r | TType_measure (Measure.Var r) ->
+ | TType_var (r, _) | TType_measure (Measure.Var r) ->
// The types may still be equivalent due to abbreviations, which we are trying not to eliminate
if typeEquiv csenv.g ty1 ty then () else
// The famous 'occursCheck' check to catch "infinite types" like 'a = list<'a> - see also https://github.com/Microsoft/visualfsharp/issues/1170
@@ -770,7 +789,8 @@ and solveTypMeetsTyparConstraints (csenv: ConstraintSolverEnv) ndeep m2 trace ty
| ValueSome destTypar ->
AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.DefaultsTo(priority, dty, m))
- | TyparConstraint.SupportsNull m2 -> SolveTypeSupportsNull csenv ndeep m2 trace ty
+ | TyparConstraint.NotSupportsNull m2 -> SolveTypeDefnNotSupportsNull csenv ndeep m2 trace ty
+ | TyparConstraint.SupportsNull m2 -> SolveTypeDefnSupportsNull csenv ndeep m2 trace ty
| TyparConstraint.IsEnum(underlying, m2) -> SolveTypeIsEnum csenv ndeep m2 trace ty underlying
| TyparConstraint.SupportsComparison(m2) -> SolveTypeSupportsComparison csenv ndeep m2 trace ty
| TyparConstraint.SupportsEquality(m2) -> SolveTypeSupportsEquality csenv ndeep m2 trace ty
@@ -785,6 +805,73 @@ and solveTypMeetsTyparConstraints (csenv: ConstraintSolverEnv) ndeep m2 trace ty
SolveMemberConstraint csenv false false ndeep m2 trace traitInfo |> OperationResult.ignore
}
+// nullness1: actual
+// nullness2: expected
+and SolveNullnessEquiv (csenv:ConstraintSolverEnv) m2 (trace: OptionalTrace) ty1 ty2 nullness1 nullness2 =
+ match nullness1, nullness2 with
+ | Nullness.Variable nv1, Nullness.Variable nv2 when nv1 === nv2 ->
+ CompleteD
+ | Nullness.Variable nv1, _ when nv1.IsSolved ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nv1.Solution nullness2
+ | _, Nullness.Variable nv2 when nv2.IsSolved ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nv2.Solution
+ | Nullness.Variable nv1, _ ->
+ trace.Exec (fun () -> nv1.Set nullness2) (fun () -> nv1.Unset())
+ CompleteD
+ | _, Nullness.Variable nv2 ->
+ trace.Exec (fun () -> nv2.Set nullness1) (fun () -> nv2.Unset())
+ CompleteD
+ | Nullness.Known n1, Nullness.Known n2 ->
+ match n1, n2 with
+ | NullnessInfo.AmbivalentToNull, _ -> CompleteD
+ | _, NullnessInfo.AmbivalentToNull -> CompleteD
+ | NullnessInfo.WithNull, NullnessInfo.WithNull -> CompleteD
+ | NullnessInfo.WithoutNull, NullnessInfo.WithoutNull -> CompleteD
+ // Allow expected of WithNull and actual of WithoutNull
+ // TODO NULLNESS: this is not sound in contravariant cases etc.
+ | NullnessInfo.WithNull, NullnessInfo.WithoutNull -> CompleteD
+ | _ ->
+ // NOTE: we never give nullness warnings for the 'obj' type
+ if csenv.g.checkNullness then
+ if not (isObjTy csenv.g ty1) && not (isObjTy csenv.g ty2) then
+ WarnD(ConstraintSolverNullnessWarningEquivWithTypes(csenv.DisplayEnv, ty1, ty2, n1, n2, csenv.m, m2))
+ else
+ CompleteD
+ else
+ CompleteD
+
+// nullness1: target
+// nullness2: source
+and SolveNullnessSubsumesNullness (csenv:ConstraintSolverEnv) m2 (trace: OptionalTrace) ty1 ty2 nullness1 nullness2 =
+ match nullness1, nullness2 with
+ | Nullness.Variable nv1, Nullness.Variable nv2 when nv1 === nv2 ->
+ CompleteD
+ | Nullness.Variable nv1, _ when nv1.IsSolved ->
+ SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nv1.Solution nullness2
+ | _, Nullness.Variable nv2 when nv2.IsSolved ->
+ SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nv2.Solution
+ | Nullness.Variable nv1, _ ->
+ trace.Exec (fun () -> nv1.Set nullness2) (fun () -> nv1.Unset())
+ CompleteD
+ | _, Nullness.Variable nv2 ->
+ trace.Exec (fun () -> nv2.Set nullness1) (fun () -> nv2.Unset())
+ CompleteD
+ | Nullness.Known n1, Nullness.Known n2 ->
+ match n1, n2 with
+ | NullnessInfo.AmbivalentToNull, _ -> CompleteD
+ | _, NullnessInfo.AmbivalentToNull -> CompleteD
+ | NullnessInfo.WithNull, NullnessInfo.WithNull -> CompleteD
+ | NullnessInfo.WithoutNull, NullnessInfo.WithoutNull -> CompleteD
+ // Allow target of WithNull and actual of WithoutNull
+ | NullnessInfo.WithNull, NullnessInfo.WithoutNull -> CompleteD
+ | NullnessInfo.WithoutNull, NullnessInfo.WithNull ->
+ if csenv.g.checkNullness then
+ if not (isObjTy csenv.g ty1) && not (isObjTy csenv.g ty2) then
+ WarnD(ConstraintSolverNullnessWarningWithTypes(csenv.DisplayEnv, ty1, ty2, n1, n2, csenv.m, m2))
+ else
+ CompleteD
+ else
+ CompleteD
and SolveAnonInfoEqualsAnonInfo (csenv: ConstraintSolverEnv) m2 (anonInfo1: AnonRecdTypeInfo) (anonInfo2: AnonRecdTypeInfo) =
if evalTupInfoIsStruct anonInfo1.TupInfo <> evalTupInfoIsStruct anonInfo2.TupInfo then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m,m2)) else
@@ -800,7 +887,7 @@ and SolveAnonInfoEqualsAnonInfo (csenv: ConstraintSolverEnv) m2 (anonInfo1: Anon
/// Add the constraint "ty1 = ty2" to the constraint problem.
/// Propagate all effects of adding this constraint, e.g. to solve type variables
-and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) (cxsln:(TraitConstraintInfo * TraitConstraintSln) option) ty1 ty2 =
+and SolveTypeEqualsType (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) (cxsln:(TraitConstraintInfo * TraitConstraintSln) option) ty1 ty2 =
let ndeep = ndeep + 1
let aenv = csenv.EquivEnv
let g = csenv.g
@@ -819,30 +906,100 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr
match sty1, sty2 with
// type vars inside forall-types may be alpha-equivalent
- | TType_var tp1, TType_var tp2 when typarEq tp1 tp2 || (match aenv.EquivTypars.TryFind tp1 with | Some v when typeEquiv g v ty2 -> true | _ -> false) -> CompleteD
+ | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when typarEq tp1 tp2 || (match aenv.EquivTypars.TryFind tp1 with | Some v when typeEquiv g v ty2 -> true | _ -> false) ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
+
+ | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when PreferUnifyTypar tp1 tp2 ->
+ match nullness1.TryEvaluate(), nullness2.TryEvaluate() with
+ // Unifying 'T1? and 'T2?
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty1 (TType_var (tp2, g.knownWithoutNull))
+ //// Unifying 'T1 % and 'T2 %
+ //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
+ // SolveTyparEqualsType csenv ndeep m2 trace sty1 (TType_var (tp2, g.knownWithoutNull))
+ | _ ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 ++ (fun () ->
+ let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 nullness2
+ )
+
+ | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when not csenv.MatchingOnly && PreferUnifyTypar tp2 tp1 ->
+ match nullness1.TryEvaluate(), nullness2.TryEvaluate() with
+ // Unifying 'T1? and 'T2?
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty2 (TType_var (tp1, g.knownWithoutNull))
+ //// Unifying 'T1 % and 'T2 %
+ //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
+ // SolveTyparEqualsType csenv ndeep m2 trace sty2 (TType_var (tp1, g.knownWithoutNull))
+ | _ ->
+ // Unifying 'T1 ? and 'T2 %
+ // Unifying 'T1 % and 'T2 ?
+ SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 ++ (fun () ->
+ let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2
+ )
+
+ | TType_var (tp1, nullness1), _ when (tp1.Rigidity <> TyparRigidity.Rigid) ->
+ match nullness1.TryEvaluate(), (nullnessOfTy g sty2).TryEvaluate() with
+ // Unifying 'T1? and 'T2?
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2)
+ //// Unifying 'T1 % and 'T2 %
+ //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
+ // SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2)
+ | _ ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 ++ (fun () ->
+ let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 (nullnessOfTy g sty2)
+ )
+
+ | _, TType_var (tp2, nullness2) when (tp2.Rigidity <> TyparRigidity.Rigid) && not csenv.MatchingOnly ->
+ match (nullnessOfTy g sty1).TryEvaluate(), nullness2.TryEvaluate() with
+ // Unifying 'T1? and 'T2?
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty2 (replaceNullnessOfTy g.knownWithoutNull sty1)
+ //// Unifying 'T1 % and 'T2 %
+ //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
+ // SolveTyparEqualsType csenv ndeep m2 trace sty2 (replaceNullnessOfTy g.knownWithoutNull sty1)
+ | _ ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 ++ (fun () ->
+ let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2
+ )
- | TType_var tp1, TType_var tp2 when PreferUnifyTypar tp1 tp2 -> SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2
- | TType_var tp1, TType_var tp2 when not csenv.MatchingOnly && PreferUnifyTypar tp2 tp1 -> SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1
+ // Catch float<_>=float<1>, float32<_>=float32<1> and decimal<_>=decimal<1>
+ | (_, TType_app (tc2, [ms2], nullness2)) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2])) ->
+ SolveTypeEqualsType csenv ndeep m2 trace None (TType_measure Measure.One) ms2 ++ (fun () ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullness2
+ )
- | TType_var r, _ when (r.Rigidity <> TyparRigidity.Rigid) -> SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2
- | _, TType_var r when (r.Rigidity <> TyparRigidity.Rigid) && not csenv.MatchingOnly -> SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1
+ | (TType_app (tc1, [ms1], nullness1), _) when (tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1])) ->
+ SolveTypeEqualsType csenv ndeep m2 trace None ms1 (TType_measure Measure.One) ++ (fun () ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 (nullnessOfTy g sty2)
+ )
- // Catch float<_>=float<1>, float32<_>=float32<1> and decimal<_>=decimal<1>
- | (_, TType_app (tc2, [ms])) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms]))
- -> SolveTypeEqualsType csenv ndeep m2 trace None ms (TType_measure Measure.One)
- | (TType_app (tc2, [ms]), _) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms]))
- -> SolveTypeEqualsType csenv ndeep m2 trace None ms (TType_measure Measure.One)
+ | TType_app (tc1, l1, nullness1), TType_app (tc2, l2, nullness2) when tyconRefEq g tc1 tc2 ->
+ SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 ++ (fun () ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
+ )
- | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
- | TType_app (_, _), TType_app (_, _) -> localAbortD
- | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) ->
+ | TType_app _, TType_app _ -> localAbortD
+
+ | TType_tuple (tupInfo1, l1) , TType_tuple (tupInfo2, l2) ->
if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else
SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
+
+ | TType_fun (d1, r1, nullness1) , TType_fun (d2, r2, nullness2) ->
+ SolveFunTypeEqn csenv ndeep m2 trace None d1 d2 r1 r2 ++ (fun () ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
+ )
+
+ | TType_measure ms1 , TType_measure ms2 ->
+ UnifyMeasures csenv trace ms1 ms2
+
| TType_anon (anonInfo1, l1),TType_anon (anonInfo2, l2) ->
SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2 ++ (fun () ->
SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2)
- | TType_fun (d1, r1), TType_fun (d2, r2) -> SolveFunTypeEqn csenv ndeep m2 trace None d1 d2 r1 r2
- | TType_measure ms1, TType_measure ms2 -> UnifyMeasures csenv trace ms1 ms2
| TType_forall(tps1, rty1), TType_forall(tps2, rty2) ->
if tps1.Length <> tps2.Length then localAbortD else
let aenv = aenv.BindEquivTypars tps1 tps2
@@ -850,11 +1007,14 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr
if not (typarsAEquiv g aenv tps1 tps2) then localAbortD else
SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty1 rty2
- | TType_ucase (uc1, l1), TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
+ | TType_ucase (uc1, l1) , TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 ->
+ SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
+
| _ -> localAbortD
-and SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1 ty2 = SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace None ty1 ty2
+and SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1 ty2 =
+ SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace None ty1 ty2
and private SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1 ty2 =
// Back out of expansions of type abbreviations to give improved error messages.
@@ -878,7 +1038,9 @@ and SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln origl1 origl2 =
loop origl1 origl2
and SolveFunTypeEqn csenv ndeep m2 trace cxsln d1 d2 r1 r2 = trackErrors {
- do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln d1 d2
+ // TODO NULLNESS: consider whether flipping the actual and expected in argument position
+ // causes other problems, e.g. better/worse diagnostics
+ do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln d2 d1
return! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln r1 r2
}
@@ -900,47 +1062,69 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional
let aenv = csenv.EquivEnv
let denv = csenv.DisplayEnv
match sty1, sty2 with
- | TType_var tp1, _ ->
+ | TType_var (tp1, nullness1) , _ ->
match aenv.EquivTypars.TryFind tp1 with
| Some v -> SolveTypeSubsumesType csenv ndeep m2 trace cxsln v ty2
| _ ->
match sty2 with
- | TType_var r2 when typarEq tp1 r2 -> CompleteD
- | TType_var r when not csenv.MatchingOnly -> SolveTyparSubtypeOfType csenv ndeep m2 trace r ty1
+ | TType_var (r2, nullness2) when typarEq tp1 r2 ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
+ | TType_var (r2, nullness2) when not csenv.MatchingOnly ->
+ SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1 ++ (fun () ->
+ let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
+ SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2
+ )
| _ -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1 ty2
- | _, TType_var r when not csenv.MatchingOnly -> SolveTyparSubtypeOfType csenv ndeep m2 trace r ty1
+ | _, TType_var (r2, nullness2) when not csenv.MatchingOnly ->
+ SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1 ++ (fun () ->
+ let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
+ SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2
+ )
| TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) ->
if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else
SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *)
+
+ | TType_fun (d1, r1, nullness1) , TType_fun (d2, r2, nullness2) ->
+ (* nb. can unify since no variance *)
+ SolveFunTypeEqn csenv ndeep m2 trace cxsln d1 d2 r1 r2 ++ (fun () ->
+ SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullness2
+ )
+
| TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) ->
SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2 ++ (fun () ->
SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2) (* nb. can unify since no variance *)
- | TType_fun (d1, r1), TType_fun (d2, r2) -> SolveFunTypeEqn csenv ndeep m2 trace cxsln d1 d2 r1 r2 (* nb. can unify since no variance *)
| TType_measure ms1, TType_measure ms2 -> UnifyMeasures csenv trace ms1 ms2
// Enforce the identities float=float<1>, float32=float32<1> and decimal=decimal<1>
- | (_, TType_app (tc2, [ms])) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms]))
- -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One)
- | (TType_app (tc2, [ms]), _) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms]))
- -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One)
+ | (_, TType_app (tc2, [ms2], nullness2)) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2])) ->
+ SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms2 (TType_measure Measure.One) ++ (fun () ->
+ SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullness2
+ )
+
+ | (TType_app (tc1, [ms1], nullness1), _) when (tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1])) ->
+ SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms1 (TType_measure Measure.One) ++ (fun () ->
+ SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 (nullnessOfTy g sty2)
+ )
// Special subsumption rule for byref tags
- | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 && g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tc1 ->
+ | TType_app (tc1, l1, _nullness1) , TType_app (tc2, l2, _nullness2) when tyconRefEq g tc1 tc2 && g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tc1 ->
match l1, l2 with
| [ h1; tag1 ], [ h2; tag2 ] -> trackErrors {
do! SolveTypeEqualsType csenv ndeep m2 trace None h1 h2
match stripTyEqnsA csenv.g canShortcut tag1, stripTyEqnsA csenv.g canShortcut tag2 with
- | TType_app(tagc1, []), TType_app(tagc2, [])
+ | TType_app(tagc1, [], _), TType_app(tagc2, [], _)
when (tyconRefEq g tagc2 g.byrefkind_InOut_tcr &&
(tyconRefEq g tagc1 g.byrefkind_In_tcr || tyconRefEq g tagc1 g.byrefkind_Out_tcr) ) -> ()
| _ -> return! SolveTypeEqualsType csenv ndeep m2 trace cxsln tag1 tag2
}
| _ -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2
- | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 ->
- SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2
+ | TType_app (tc1, l1, nullness1) , TType_app (tc2, l2, nullness2) when tyconRefEq g tc1 tc2 ->
+ SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 ++ (fun () ->
+ SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullness2
+ )
| TType_ucase (uc1, l1), TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 ->
SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2
@@ -992,7 +1176,8 @@ and SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m2 trace cxsln ty1 ty2 =
//-------------------------------------------------------------------------
-and SolveTyparSubtypeOfType (csenv: ConstraintSolverEnv) ndeep m2 trace tp ty1 =
+// 'T :> ty
+and SolveTyparSubtypeOfType (csenv:ConstraintSolverEnv) ndeep m2 trace tp ty1 =
let g = csenv.g
if isObjTy g ty1 then CompleteD
elif typeEquiv g ty1 (mkTyparTy tp) then CompleteD
@@ -1475,14 +1660,14 @@ and MemberConstraintSolutionOfMethInfo css m minfo minst =
let allArgVars, allArgs = minfo.GetParamTypes(amap, m, minst) |> List.concat |> List.mapi (fun i ty -> mkLocal m ("arg"+string i) ty) |> List.unzip
let objArgVars, objArgs = (if minfo.IsInstance then [mkLocal m "this" minfo.ApparentEnclosingType] else []) |> List.unzip
let callMethInfoOpt, callExpr, callExprTy = ProvidedMethodCalls.BuildInvokerExpressionForProvidedMethodCall css.TcVal (g, amap, mi, objArgs, NeverMutates, false, ValUseFlag.NormalValUse, allArgs, m)
- let closedExprSln = ClosedExprSln (mkLambdas m [] (objArgVars@allArgVars) (callExpr, callExprTy) )
+ let closedExprSln = ClosedExprSln (mkLambdas g m [] (objArgVars@allArgVars) (callExpr, callExprTy) )
// If the call is a simple call to an IL method with all the arguments in the natural order, then revert to use ILMethSln.
// This is important for calls to operators on generated provided types. There is an (unchecked) condition
// that generative providers do not re=order arguments or insert any more information into operator calls.
match callMethInfoOpt, callExpr with
| Some methInfo, Expr.Op (TOp.ILCall (_useCallVirt, _isProtected, _, _isNewObj, NormalValUse, _isProp, _noTailCall, ilMethRef, _actualTypeInst, actualMethInst, _ilReturnTys), [], args, m)
- when (args, (objArgVars@allArgVars)) ||> List.lengthsEqAndForall2 (fun a b -> match a with Expr.Val (v, _, _) -> valEq v.Deref b | _ -> false) ->
- let declaringType = Import.ImportProvidedType amap m (methInfo.PApply((fun x -> x.DeclaringType), m))
+ when (args, (objArgVars@allArgVars)) ||> List.lengthsEqAndForall2 (fun a b -> match a with Expr.Val(v, _, _) -> valEq v.Deref b | _ -> false) ->
+ let declaringType = Import.ImportProvidedType amap m (methInfo.PApply((fun x -> nonNull x.DeclaringType), m))
if isILAppTy g declaringType then
let extOpt = None // EXTENSION METHODS FROM TYPE PROVIDERS: for extension methods coming from the type providers we would have something here.
ILMethSln(declaringType, extOpt, ilMethRef, actualMethInst)
@@ -1680,12 +1865,21 @@ and AddConstraint (csenv: ConstraintSolverEnv) ndeep m2 trace tp newConstraint
}
| TyparConstraint.SupportsComparison _, TyparConstraint.IsDelegate _
- | TyparConstraint.IsDelegate _, TyparConstraint.SupportsComparison _
+ | TyparConstraint.IsDelegate _ , TyparConstraint.SupportsComparison _ ->
+ ErrorD (Error(FSComp.SR.csDelegateComparisonConstraintInconsistent(), m))
+
+ | TyparConstraint.NotSupportsNull _, TyparConstraint.SupportsNull _
+ | TyparConstraint.SupportsNull _, TyparConstraint.NotSupportsNull _ ->
+ ErrorD (Error(FSComp.SR.csNullNotNullConstraintInconsistent(), m))
+
+ | TyparConstraint.SupportsNull _, TyparConstraint.IsNonNullableStruct _
+ | TyparConstraint.IsNonNullableStruct _, TyparConstraint.SupportsNull _ ->
+ ErrorD (Error(FSComp.SR.csStructNullConstraintInconsistent(), m))
+
| TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsReferenceType _
| TyparConstraint.IsReferenceType _, TyparConstraint.IsNonNullableStruct _ ->
ErrorD (Error(FSComp.SR.csStructConstraintInconsistent(), m))
-
| TyparConstraint.SupportsComparison _, TyparConstraint.SupportsComparison _
| TyparConstraint.SupportsEquality _, TyparConstraint.SupportsEquality _
| TyparConstraint.SupportsNull _, TyparConstraint.SupportsNull _
@@ -1721,6 +1915,7 @@ and AddConstraint (csenv: ConstraintSolverEnv) ndeep m2 trace tp newConstraint
// comparison implies equality
| TyparConstraint.SupportsComparison _, TyparConstraint.SupportsEquality _
| TyparConstraint.SupportsNull _, TyparConstraint.SupportsNull _
+ | TyparConstraint.NotSupportsNull _, TyparConstraint.NotSupportsNull _
| TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _
| TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _
| TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _
@@ -1788,20 +1983,129 @@ and AddConstraint (csenv: ConstraintSolverEnv) ndeep m2 trace tp newConstraint
}
-and SolveTypeSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 trace ty =
+and SolveNullnessSupportsNull (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) ty nullness = trackErrors {
let g = csenv.g
let m = csenv.m
let denv = csenv.DisplayEnv
- match tryDestTyparTy g ty with
- | ValueSome destTypar ->
- AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.SupportsNull m)
- | ValueNone ->
- if TypeSatisfiesNullConstraint g m ty then CompleteD else
+ match nullness with
+ | Nullness.Variable nv ->
+ if nv.IsSolved then
+ do! SolveNullnessSupportsNull csenv ndeep m2 trace ty nv.Solution
+ else
+ trace.Exec (fun () -> nv.Set KnownWithNull) (fun () -> nv.Unset())
+ | Nullness.Known n1 ->
+ match n1 with
+ | NullnessInfo.AmbivalentToNull -> ()
+ | NullnessInfo.WithNull -> ()
+ | NullnessInfo.WithoutNull ->
+ if g.checkNullness then
+ if not (isObjTy g ty) then
+ return! WarnD(ConstraintSolverNullnessWarningWithType(denv, ty, n1, m, m2))
+ }
+
+and SolveTypeSupportsNullCore (csenv:ConstraintSolverEnv) ndeep m2 trace ty = trackErrors {
+ let g = csenv.g
+ let m = csenv.m
+ let denv = csenv.DisplayEnv
+ if TypeNullIsExtraValueNew g m ty then
+ ()
+ else
match ty with
| NullableTy g _ ->
- ErrorD (ConstraintSolverError(FSComp.SR.csNullableTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2))
+ return! ErrorD (ConstraintSolverError(FSComp.SR.csNullableTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2))
| _ ->
- ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2))
+ // If langFeatureNullness is on then solve, maybe give warnings
+ if g.langFeatureNullness then
+ let nullness = nullnessOfTy g ty
+ do! SolveNullnessSupportsNull csenv ndeep m2 trace ty nullness
+
+ // If langFeatureNullness or checkNullness are off give the same errors as F# 4.5
+ if not g.langFeatureNullness || not g.checkNullness then
+ if not (TypeNullIsExtraValueOld g m ty) then
+ return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2))
+ }
+
+// This version prefers to constrain a type parameter definiton
+and SolveTypeDefnSupportsNull (csenv:ConstraintSolverEnv) ndeep m2 trace ty =
+ let g = csenv.g
+ let m = csenv.m
+ match stripTyparEqns ty with
+ // If you set a type variable constrained with a T: null to U? then you don't induce an inference constraint
+ // of U: null.
+ // TODO: what about Obsolete?
+ | TType_var(_, nullness) when nullness.Evaluate() = NullnessInfo.WithNull -> CompleteD
+ | _ ->
+ match tryDestTyparTy g ty with
+ | ValueSome tp ->
+ AddConstraint csenv ndeep m2 trace tp (TyparConstraint.SupportsNull m)
+ | ValueNone ->
+ SolveTypeSupportsNullCore csenv ndeep m2 trace ty
+
+// This version prefers to constrain the nullness annotation
+and SolveTypeUseSupportsNull (csenv:ConstraintSolverEnv) ndeep m2 trace ty =
+ let m = csenv.m
+ match stripTyparEqns ty with
+ | TType_var(tp, nullness) ->
+ AddConstraint csenv ndeep m2 trace tp (TyparConstraint.IsReferenceType m) ++ (fun () ->
+ SolveNullnessSupportsNull csenv ndeep m2 trace ty nullness)
+ | _ ->
+ SolveTypeSupportsNullCore csenv ndeep m2 trace ty
+
+and SolveNullnessNotSupportsNull (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) ty nullness = trackErrors {
+ let g = csenv.g
+ let m = csenv.m
+ let denv = csenv.DisplayEnv
+ match nullness with
+ | Nullness.Variable nv ->
+ if nv.IsSolved then
+ do! SolveNullnessNotSupportsNull csenv ndeep m2 trace ty nv.Solution
+ else
+ trace.Exec (fun () -> nv.Set KnownWithoutNull) (fun () -> nv.Unset())
+ | Nullness.Known n1 ->
+ match n1 with
+ | NullnessInfo.AmbivalentToNull -> ()
+ | NullnessInfo.WithoutNull -> ()
+ | NullnessInfo.WithNull ->
+ if g.checkNullness then
+ if not (isObjTy g ty) then
+ return! WarnD(ConstraintSolverNonNullnessWarningWithType(denv, ty, n1, m, m2))
+ else
+ if TypeNullIsExtraValueOld g m ty then
+ return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeHasNullAsExtraValue(NicePrint.minimalStringOfType denv ty), m, m2))
+ }
+
+and SolveTypeNotSupportsNullCore (csenv:ConstraintSolverEnv) ndeep m2 trace ty = trackErrors {
+ let g = csenv.g
+ let m = csenv.m
+ let denv = csenv.DisplayEnv
+ if TypeNullIsTrueValue g ty then
+ // We can only give warnings here as F# 5.0 introduces these constraints into existing
+ // code via Option.ofObj and Option.toObj
+ do! WarnD (ConstraintSolverError(FSComp.SR.csTypeHasNullAsTrueValue(NicePrint.minimalStringOfType denv ty), m, m2))
+ elif TypeNullIsExtraValueNew g m ty then
+ if g.checkNullness || TypeNullIsExtraValueOld g m ty then
+ do! WarnD (ConstraintSolverError(FSComp.SR.csTypeHasNullAsExtraValue(NicePrint.minimalStringOfType denv ty), m, m2))
+ else
+ if g.checkNullness then
+ let nullness = nullnessOfTy g ty
+ do! SolveNullnessNotSupportsNull csenv ndeep m2 trace ty nullness
+ }
+
+// This version prefers to constrain a type parameter definiton
+and SolveTypeDefnNotSupportsNull (csenv:ConstraintSolverEnv) ndeep m2 trace ty =
+ let g = csenv.g
+ let m = csenv.m
+ //match stripTyparEqns ty with
+ //// If you set a type variable constrained with a T: not null to U then you don't induce an inference constraint
+ //// of U: not null.
+ //// TODO: what about Obsolete?
+ //| TType_var(_, nullness) when nullness.TryEvaluate() = Some NullnessInfo.WithoutNull || nullness.TryEvaluate() = Some NullnessInfo.AmbivalentToNull -> CompleteD
+ //| _ ->
+ match tryDestTyparTy g ty with
+ | ValueSome tp ->
+ AddConstraint csenv ndeep m2 trace tp (TyparConstraint.NotSupportsNull m)
+ | ValueNone ->
+ SolveTypeNotSupportsNullCore csenv ndeep m2 trace ty
and SolveTypeSupportsComparison (csenv: ConstraintSolverEnv) ndeep m2 trace ty =
let g = csenv.g
@@ -1984,7 +2288,7 @@ and SolveTypeRequiresDefaultConstructor (csenv: ConstraintSolverEnv) ndeep m2 tr
| ValueSome destTypar ->
AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.RequiresDefaultConstructor m)
| _ ->
- if isStructTy g ty && TypeHasDefaultValue g m ty then
+ if isStructTy g ty && TypeHasDefaultValueOld g m ty then
CompleteD
else
if GetIntrinsicConstructorInfosOfType csenv.InfoReader m ty
@@ -2047,12 +2351,16 @@ and CanMemberSigsMatchUpToCheck
else
return! ErrorD(Error (FSComp.SR.csMemberIsNotInstance(minfo.LogicalName), m))
else
- do! Iterate2D subsumeTypes calledObjArgTys callerObjArgTys
+ // The object types must be non-null
+ let nonNullCalledObjArgTys = calledObjArgTys |> List.map (replaceNullnessOfTy g.knownWithoutNull)
+ do! Iterate2D subsumeTypes nonNullCalledObjArgTys callerObjArgTys
+
for argSet in calledMeth.ArgSets do
if argSet.UnnamedCalledArgs.Length <> argSet.UnnamedCallerArgs.Length then
return! ErrorD(Error(FSComp.SR.csArgumentLengthMismatch(), m))
else
do! Iterate2D subsumeArg argSet.UnnamedCalledArgs argSet.UnnamedCallerArgs
+
match calledMeth.ParamArrayCalledArgOpt with
| Some calledArg ->
if isArray1DTy g calledArg.CalledArgumentType then
@@ -2707,8 +3015,18 @@ let AddCxMethodConstraint denv css m trace traitInfo =
(fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m)))
|> RaiseOperationResult
-let AddCxTypeMustSupportNull denv css m trace ty =
- TryD (fun () -> SolveTypeSupportsNull (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty)
+let AddCxTypeDefnSupportsNull denv css m trace ty =
+ TryD (fun () -> SolveTypeDefnSupportsNull (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty)
+ (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m)))
+ |> RaiseOperationResult
+
+let AddCxTypeDefnNotSupportsNull denv css m trace ty =
+ TryD (fun () -> SolveTypeDefnNotSupportsNull (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty)
+ (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m)))
+ |> RaiseOperationResult
+
+let AddCxTypeUseSupportsNull denv css m trace ty =
+ TryD (fun () -> SolveTypeUseSupportsNull (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty)
(fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m)))
|> RaiseOperationResult
diff --git a/src/fsharp/ConstraintSolver.fsi b/src/fsharp/ConstraintSolver.fsi
index 59c271b126b..b78af7fdf41 100644
--- a/src/fsharp/ConstraintSolver.fsi
+++ b/src/fsharp/ConstraintSolver.fsi
@@ -1,3 +1,4 @@
+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
/// Solves constraints using a mutable constraint-solver state
@@ -20,7 +21,7 @@ open FSharp.Compiler.InfoReader
val NewAnonTypar : TyparKind * range * TyparRigidity * TyparStaticReq * TyparDynamicReq -> Typar
/// Create an inference type variable
-val NewInferenceType : unit -> TType
+val NewInferenceType : TcGlobals -> TType
/// Create an inference type variable for the kind of a byref pointer
val NewByRefKindInferenceType : TcGlobals -> range -> TType
@@ -32,7 +33,7 @@ val NewErrorType : unit -> TType
val NewErrorMeasure : unit -> Measure
/// Create a list of inference type variables, one for each element in the input list
-val NewInferenceTypes : 'a list -> TType list
+val NewInferenceTypes : TcGlobals -> 'a list -> TType list
/// Given a set of formal type parameters and their constraints, make new inference type variables for
/// each and ensure that the constraints on the new type variables are adjusted to refer to these.
@@ -81,6 +82,10 @@ exception ConstraintSolverInfiniteTypes of displayEnv: DisplayEn
exception ConstraintSolverTypesNotInEqualityRelation of displayEnv: DisplayEnv * TType * TType * range * range * ContextInfo
exception ConstraintSolverTypesNotInSubsumptionRelation of displayEnv: DisplayEnv * TType * TType * range * range
exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Typar * TyparConstraint * range * range
+exception ConstraintSolverNullnessWarningEquivWithTypes of DisplayEnv * TType * TType * NullnessInfo * NullnessInfo * range * range
+exception ConstraintSolverNullnessWarningWithTypes of DisplayEnv * TType * TType * NullnessInfo * NullnessInfo * range * range
+exception ConstraintSolverNullnessWarningWithType of DisplayEnv * TType * NullnessInfo * range * range
+exception ConstraintSolverNonNullnessWarningWithType of DisplayEnv * TType * NullnessInfo * range * range
exception ConstraintSolverError of string * range * range
exception ConstraintSolverRelatedInformation of string option * range * exn
@@ -131,7 +136,9 @@ val AddCxTypeMustSubsumeType : ContextInfo -> DisplayEnv -> Con
val AddCxTypeMustSubsumeTypeUndoIfFailed : DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool
val AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed : DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool
val AddCxMethodConstraint : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TraitConstraintInfo -> unit
-val AddCxTypeMustSupportNull : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit
+val AddCxTypeDefnNotSupportsNull : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit
+val AddCxTypeDefnSupportsNull : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit
+val AddCxTypeUseSupportsNull : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit
val AddCxTypeMustSupportComparison : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit
val AddCxTypeMustSupportEquality : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit
val AddCxTypeMustSupportDefaultCtor : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit
diff --git a/src/fsharp/DetupleArgs.fs b/src/fsharp/DetupleArgs.fs
index 9af6d4f32ac..271e00f5ccd 100644
--- a/src/fsharp/DetupleArgs.fs
+++ b/src/fsharp/DetupleArgs.fs
@@ -484,7 +484,7 @@ let mkTransform g (f: Val) m tps x1Ntys rty (callPattern, tyfringes: (TType list
let tys1r = List.collect fst tyfringes (* types for collapsed initial r args *)
let tysrN = List.drop tyfringes.Length x1Ntys (* types for remaining args *)
let argtys = tys1r @ tysrN
- let fCty = mkLambdaTy tps argtys rty
+ let fCty = mkLambdaTy g tps argtys rty
let transformedVal = mkLocalVal f.Range (globalNng.FreshCompilerGeneratedName (f.LogicalName, f.Range)) fCty topValInfo
{ transformCallPattern = callPattern
transformedFormals = transformedFormals
@@ -800,8 +800,8 @@ let passBind penv (TBind(fOrig, repr, letSeqPtOpt) as bind) =
let rebinds = List.concat (List.map2 transRebind transformedFormals x1ps)
// fCBody - rebuild
// fCBody = TLambda tps. Lam formals. let rebinds in body
- let rbody, rt = mkLetsBind m rebinds body, rty
- let bind = mkMultiLambdaBind transformedVal letSeqPtOpt m tps formals (rbody, rt)
+ let rbody, rt = mkLetsBind m rebinds body, rty
+ let bind = mkMultiLambdaBind penv.g transformedVal letSeqPtOpt m tps formals (rbody, rt)
// result
bind
diff --git a/src/fsharp/ErrorLogger.fs b/src/fsharp/ErrorLogger.fs
index e84b5c69e4b..c7c4f961e82 100755
--- a/src/fsharp/ErrorLogger.fs
+++ b/src/fsharp/ErrorLogger.fs
@@ -231,7 +231,6 @@ type PhasedDiagnostic =
| BuildPhaseSubcategory.Parameter
| BuildPhaseSubcategory.Parse
| BuildPhaseSubcategory.TypeCheck -> true
- | null
| BuildPhaseSubcategory.DefaultPhase
| BuildPhaseSubcategory.CodeGen
| BuildPhaseSubcategory.Optimize
@@ -634,8 +633,14 @@ let NewlineifyErrorString (message:string) = message.Replace(stringThatIsAProxyF
/// fixes given string by replacing all control chars with spaces.
/// NOTE: newlines are recognized and replaced with stringThatIsAProxyForANewlineInFlatErrors (ASCII 29, the 'group separator'),
/// which is decoded by the IDE with 'NewlineifyErrorString' back into newlines, so that multi-line errors can be displayed in QuickInfo
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let NormalizeErrorString (text : string) =
if isNull text then nullArg "text"
+#else
+let NormalizeErrorString (text : string?) =
+ let text = nullArgCheck "text" text
+#endif
+
let text = text.Trim()
let buf = System.Text.StringBuilder()
diff --git a/src/fsharp/ExtensionTyping.fs b/src/fsharp/ExtensionTyping.fs
index 9f58399d333..77afc04505e 100755
--- a/src/fsharp/ExtensionTyping.fs
+++ b/src/fsharp/ExtensionTyping.fs
@@ -45,9 +45,9 @@ module internal ExtensionTyping =
// Detect the host tooling context
let toolingCompatibleVersions() =
if typeof.Assembly.GetName().Name = "mscorlib" then
- [ "net461"; "net452"; "net451"; "net45"; "netstandard2.0"]
+ [ "net471"; "net47"; "net462"; "net461"; "net452"; "net451"; "net45"; "netstandard2.0"]
elif typeof.Assembly.GetName().Name = "System.Private.CoreLib" then
- [ "netcoreapp2.0"; "netstandard2.0"]
+ [ "netcoreapp2.1"; "netcoreapp2.0"; "netstandard2.0"]
else
System.Diagnostics.Debug.Assert(false, "Couldn't determine runtime tooling context, assuming it supports at least .NET Standard 2.0")
[ "netstandard2.0"]
@@ -131,8 +131,11 @@ module internal ExtensionTyping =
let filtered =
[ for t in exportedTypes do
let ca = t.GetCustomAttributes(typeof, true)
- if ca <> null && ca.Length > 0 then
- yield t ]
+ match ca with
+ | null -> ()
+ | NonNull ca ->
+ if ca.Length > 0 then
+ yield t ]
filtered
with e ->
raiseError e
@@ -235,7 +238,7 @@ module internal ExtensionTyping =
let unmarshal (t: Tainted<_>) = t.PUntaintNoFailure id
/// Try to access a member on a provided type, catching and reporting errors
- let TryTypeMember(st: Tainted<_>, fullName, memberName, m, recover, f) =
+ let TryTypeMember<'T,'U>(st: Tainted<'T>, fullName, memberName, m, recover, f: 'T -> 'U) =
try
st.PApply (f, m)
with :? TypeProviderError as tpe ->
@@ -244,16 +247,11 @@ module internal ExtensionTyping =
/// Try to access a member on a provided type, where the result is an array of values, catching and reporting errors
let TryTypeMemberArray (st: Tainted<_>, fullName, memberName, m, f) =
- let result =
- try
- st.PApplyArray(f, memberName, m)
- with :? TypeProviderError as tpe ->
- tpe.Iter (fun e -> error(Error(FSComp.SR.etUnexpectedExceptionFromProvidedTypeMember(fullName, memberName, e.ContextualErrorMessage), m)))
- [||]
-
- match result with
- | null -> error(Error(FSComp.SR.etUnexpectedNullFromProvidedTypeMember(fullName, memberName), m)); [||]
- | r -> r
+ try
+ st.PApplyArray(f, memberName, m)
+ with :? TypeProviderError as tpe ->
+ tpe.Iter (fun e -> error(Error(FSComp.SR.etUnexpectedExceptionFromProvidedTypeMember(fullName, memberName, e.ContextualErrorMessage), m)))
+ [||]
/// Try to access a member on a provided type, catching and reporting errors and checking the result is non-null,
let TryTypeMemberNonNull (st: Tainted<_>, fullName, memberName, m, recover, f) =
@@ -261,7 +259,7 @@ module internal ExtensionTyping =
| Tainted.Null ->
errorR(Error(FSComp.SR.etUnexpectedNullFromProvidedTypeMember(fullName, memberName), m));
st.PApplyNoFailure(fun _ -> recover)
- | r -> r
+ | Tainted.NonNull r -> r
/// Try to access a property or method on a provided member, catching and reporting errors
let TryMemberMember (mi: Tainted<_>, typeName, memberName, memberMemberName, m, recover, f) =
@@ -276,8 +274,14 @@ module internal ExtensionTyping =
resolver.PUntaint((fun tp -> tp.GetType().Name), m)
/// Validate a provided namespace name
- let ValidateNamespaceName(name, typeProvider: Tainted, m, nsp: string) =
- if nsp<>null then // Null namespace designates the global namespace.
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ let ValidateNamespaceName(name, typeProvider: Tainted, m, nsp:string) =
+#else
+ let ValidateNamespaceName(name, typeProvider: Tainted, m, nsp:string?) =
+#endif
+ match nsp with
+ | null -> ()
+ | NonNull nsp ->
if String.IsNullOrWhiteSpace nsp then
// Empty namespace is not allowed
errorR(Error(FSComp.SR.etEmptyNamespaceOfTypeNotAllowed(name, typeProvider.PUntaint((fun tp -> tp.GetType().Name), m)), m))
@@ -361,7 +365,10 @@ module internal ExtensionTyping =
type CustomAttributeNamedArgument = System.Reflection.CustomAttributeNamedArgument
type CustomAttributeTypedArgument = System.Reflection.CustomAttributeTypedArgument
- []
+ []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
type ProvidedType (x: System.Type, ctxt: ProvidedTypeContext) =
inherit ProvidedMemberInfo(x, ctxt)
let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.CustomAttributes)
@@ -380,7 +387,11 @@ module internal ExtensionTyping =
member __.IsSuppressRelocate = (x.Attributes &&& enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) <> enum 0
member __.IsErased = (x.Attributes &&& enum (int32 TypeProviderTypeAttributes.IsErased)) <> enum 0
member __.IsGenericType = x.IsGenericType
- member __.Namespace = x.Namespace
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ member __.Namespace : string = x.Namespace
+#else
+ member __.Namespace : string? = x.Namespace
+#endif
member __.FullName = x.FullName
member __.IsArray = x.IsArray
member __.Assembly = x.Assembly |> ProvidedAssembly.Create ctxt
@@ -421,16 +432,39 @@ module internal ExtensionTyping =
member __.GetArrayRank() = x.GetArrayRank()
member __.GenericParameterPosition = x.GenericParameterPosition
member __.RawSystemType = x
+
/// Type.GetEnumUnderlyingType either returns type or raises exception, null is not permitted
member __.GetEnumUnderlyingType() =
x.GetEnumUnderlyingType()
|> ProvidedType.CreateWithNullCheck ctxt "EnumUnderlyingType"
- static member Create ctxt x = match x with null -> null | t -> ProvidedType (t, ctxt)
- static member CreateWithNullCheck ctxt name x = match x with null -> nullArg name | t -> ProvidedType (t, ctxt)
- static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedType.Create ctxt)
- static member CreateNoContext (x: Type) = ProvidedType.Create ProvidedTypeContext.Empty x
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ static member Create ctxt x : ProvidedType =
+#else
+ static member Create ctxt x : ProvidedType? =
+#endif
+ match x with
+ | null -> null
+ | NonNull t -> ProvidedType (t, ctxt)
+
+ static member CreateNonNull ctxt x = ProvidedType (x, ctxt)
+
+ static member CreateWithNullCheck ctxt name x =
+ match x with
+ | null -> nullArg name
+ | t -> ProvidedType (t, ctxt)
+
+ static member CreateArray ctxt xs =
+ match box xs with
+ | null -> [| |]
+ | _ -> xs |> Array.map (ProvidedType.CreateNonNull ctxt)
+
+ static member CreateNoContext (x:Type) = ProvidedType.Create ProvidedTypeContext.Empty x
+
static member Void = ProvidedType.CreateNoContext typeof
+
member __.Handle = x
+
override __.Equals y = assert false; match y with :? ProvidedType as y -> x.Equals y.Handle | _ -> false
override __.GetHashCode() = assert false; x.GetHashCode()
member __.TryGetILTypeRef() = ctxt.TryGetILTypeRef x
@@ -440,12 +474,22 @@ module internal ExtensionTyping =
static member TaintedEquals (pt1: Tainted, pt2: Tainted) =
Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle))
- and []
+ and
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
IProvidedCustomAttributeProvider =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
abstract GetDefinitionLocationAttribute : provider: ITypeProvider -> (string * int * int) option
+#else
+ abstract GetDefinitionLocationAttribute : provider: ITypeProvider -> (string? * int * int) option
+#endif
+
abstract GetXmlDocAttributes : provider: ITypeProvider -> string[]
- abstract GetHasTypeProviderEditorHideMethodsAttribute : provider: ITypeProvider -> bool
- abstract GetAttributeConstructorArgs: provider: ITypeProvider * attribName: string -> (obj option list * (string * obj option) list) option
+
+ abstract GetHasTypeProviderEditorHideMethodsAttribute : provider:ITypeProvider -> bool
+
+ abstract GetAttributeConstructorArgs: provider:ITypeProvider * attribName:string -> (obj option list * (string * obj option) list) option
and ProvidedCustomAttributeProvider =
static member Create (attributes :(ITypeProvider -> seq)) : IProvidedCustomAttributeProvider =
@@ -491,7 +535,10 @@ module internal ExtensionTyping =
None)
|> Seq.toArray }
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedMemberInfo (x: System.Reflection.MemberInfo, ctxt) =
let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.CustomAttributes)
member __.Name = x.Name
@@ -503,39 +550,72 @@ module internal ExtensionTyping =
member __.GetXmlDocAttributes provider = provide().GetXmlDocAttributes provider
member __.GetAttributeConstructorArgs (provider, attribName) = provide().GetAttributeConstructorArgs (provider, attribName)
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedParameterInfo (x: System.Reflection.ParameterInfo, ctxt) =
let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.CustomAttributes)
- member __.Name = x.Name
+ member __.Name = let nm = x.Name in match box nm with null -> "" | _ -> nm
member __.IsOut = x.IsOut
member __.IsIn = x.IsIn
member __.IsOptional = x.IsOptional
member __.RawDefaultValue = x.RawDefaultValue
member __.HasDefaultValue = x.Attributes.HasFlag(System.Reflection.ParameterAttributes.HasDefault)
/// ParameterInfo.ParameterType cannot be null
- member __.ParameterType = ProvidedType.CreateWithNullCheck ctxt "ParameterType" x.ParameterType
- static member Create ctxt x = match x with null -> null | t -> ProvidedParameterInfo (t, ctxt)
- static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedParameterInfo.Create ctxt) // TODO null wrong?
+ member __.ParameterType = ProvidedType.CreateWithNullCheck ctxt "ParameterType" x.ParameterType
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ static member Create ctxt (x: ParameterInfo) : ProvidedParameterInfo =
+#else
+ static member Create ctxt (x: ParameterInfo?) : ProvidedParameterInfo? =
+#endif
+ match x with
+ | null -> null
+ | NonNull x -> ProvidedParameterInfo (x, ctxt)
+
+ static member CreateNonNull ctxt x = ProvidedParameterInfo (x, ctxt)
+
+ static member CreateArray ctxt (xs: ParameterInfo[]) : ProvidedParameterInfo[] =
+ match box xs with
+ | null -> [| |]
+ | _ -> xs |> Array.map (ProvidedParameterInfo.CreateNonNull ctxt)
+
interface IProvidedCustomAttributeProvider with
member __.GetHasTypeProviderEditorHideMethodsAttribute provider = provide().GetHasTypeProviderEditorHideMethodsAttribute provider
member __.GetDefinitionLocationAttribute provider = provide().GetDefinitionLocationAttribute provider
member __.GetXmlDocAttributes provider = provide().GetXmlDocAttributes provider
member __.GetAttributeConstructorArgs (provider, attribName) = provide().GetAttributeConstructorArgs (provider, attribName)
+
member __.Handle = x
override __.Equals y = assert false; match y with :? ProvidedParameterInfo as y -> x.Equals y.Handle | _ -> false
override __.GetHashCode() = assert false; x.GetHashCode()
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedAssembly (x: System.Reflection.Assembly, _ctxt) =
member __.GetName() = x.GetName()
member __.FullName = x.FullName
- member __.GetManifestModuleContents(provider: ITypeProvider) = provider.GetGeneratedAssemblyContents x
- static member Create ctxt x = match x with null -> null | t -> ProvidedAssembly (t, ctxt)
+ member __.GetManifestModuleContents (provider: ITypeProvider) = provider.GetGeneratedAssemblyContents x
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ static member Create ctxt x : ProvidedAssembly = match x with null -> null | t -> ProvidedAssembly (t, ctxt)
+#else
+ static member Create ctxt x : ProvidedAssembly? = match x with null -> null | t -> ProvidedAssembly (t, ctxt)
+#endif
+
member __.Handle = x
+
override __.Equals y = assert false; match y with :? ProvidedAssembly as y -> x.Equals y.Handle | _ -> false
+
override __.GetHashCode() = assert false; x.GetHashCode()
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedMethodBase (x: System.Reflection.MethodBase, ctxt) =
inherit ProvidedMemberInfo(x, ctxt)
member __.Context = ctxt
@@ -553,8 +633,12 @@ module internal ExtensionTyping =
member __.GetParameters() = x.GetParameters() |> ProvidedParameterInfo.CreateArray ctxt
member __.GetGenericArguments() = x.GetGenericArguments() |> ProvidedType.CreateArray ctxt
member __.Handle = x
+
static member TaintedGetHashCode (x: Tainted) =
- Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName)))
+ Tainted.GetHashCodeTainted
+ (x.PApplyNoFailure(fun st -> (st.Name, (nonNull (nonNull st.DeclaringType).Assembly).FullName,
+ (nonNull st.DeclaringType).FullName)))
+
static member TaintedEquals (pt1: Tainted, pt2: Tainted) =
Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle))
@@ -597,16 +681,34 @@ module internal ExtensionTyping =
| :? System.Reflection.MethodBase as mb -> mb
| _ -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented())
match mb with
- | :? System.Reflection.MethodInfo as mi -> (mi |> ProvidedMethodInfo.Create ctxt : ProvidedMethodInfo) :> ProvidedMethodBase
- | :? System.Reflection.ConstructorInfo as ci -> (ci |> ProvidedConstructorInfo.Create ctxt : ProvidedConstructorInfo) :> ProvidedMethodBase
+ | :? System.Reflection.MethodInfo as mi -> (mi |> ProvidedMethodInfo.CreateNonNull ctxt : ProvidedMethodInfo) :> ProvidedMethodBase
+ | :? System.Reflection.ConstructorInfo as ci -> (ci |> ProvidedConstructorInfo.CreateNonNull ctxt : ProvidedConstructorInfo) :> ProvidedMethodBase
| _ -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented())
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedFieldInfo (x: System.Reflection.FieldInfo, ctxt) =
inherit ProvidedMemberInfo(x, ctxt)
- static member Create ctxt x = match x with null -> null | t -> ProvidedFieldInfo (t, ctxt)
- static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedFieldInfo.Create ctxt)
+
+ static member CreateNonNull ctxt x = ProvidedFieldInfo (x, ctxt)
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ static member Create ctxt x : ProvidedFieldInfo =
+#else
+ static member Create ctxt x : ProvidedFieldInfo? =
+#endif
+ match x with
+ | null -> null
+ | NonNull x -> ProvidedFieldInfo (x, ctxt)
+
+ static member CreateArray ctxt xs : ProvidedFieldInfo[] =
+ match box xs with
+ | null -> [| |]
+ | _ -> xs |> Array.map (ProvidedFieldInfo.CreateNonNull ctxt)
+
member __.IsInitOnly = x.IsInitOnly
member __.IsStatic = x.IsStatic
member __.IsSpecialName = x.IsSpecialName
@@ -627,15 +729,32 @@ module internal ExtensionTyping =
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedMethodInfo (x: System.Reflection.MethodInfo, ctxt) =
inherit ProvidedMethodBase(x, ctxt)
member __.ReturnType = x.ReturnType |> ProvidedType.CreateWithNullCheck ctxt "ReturnType"
- static member Create ctxt x = match x with null -> null | t -> ProvidedMethodInfo (t, ctxt)
+ static member CreateNonNull ctxt (x: MethodInfo) : ProvidedMethodInfo =
+ ProvidedMethodInfo (x, ctxt)
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ static member Create ctxt (x: MethodInfo) : ProvidedMethodInfo =
+#else
+ static member Create ctxt (x: MethodInfo?) : ProvidedMethodInfo? =
+#endif
+ match x with
+ | null -> null
+ | NonNull x -> ProvidedMethodInfo (x, ctxt)
+
+ static member CreateArray ctxt (xs: MethodInfo[]) : ProvidedMethodInfo[] =
+ match box xs with
+ | null -> [| |]
+ | _ -> xs |> Array.map (ProvidedMethodInfo.CreateNonNull ctxt)
- static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedMethodInfo.Create ctxt)
member __.Handle = x
#if !FX_NO_REFLECTION_METADATA_TOKENS
member __.MetadataToken = x.MetadataToken
@@ -643,7 +762,10 @@ module internal ExtensionTyping =
override __.Equals y = assert false; match y with :? ProvidedMethodInfo as y -> x.Equals y.Handle | _ -> false
override __.GetHashCode() = assert false; x.GetHashCode()
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedPropertyInfo (x: System.Reflection.PropertyInfo, ctxt) =
inherit ProvidedMemberInfo(x, ctxt)
member __.GetGetMethod() = x.GetGetMethod() |> ProvidedMethodInfo.Create ctxt
@@ -653,64 +775,160 @@ module internal ExtensionTyping =
member __.GetIndexParameters() = x.GetIndexParameters() |> ProvidedParameterInfo.CreateArray ctxt
/// PropertyInfo.PropertyType cannot be null
member __.PropertyType = x.PropertyType |> ProvidedType.CreateWithNullCheck ctxt "PropertyType"
- static member Create ctxt x = match x with null -> null | t -> ProvidedPropertyInfo (t, ctxt)
- static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedPropertyInfo.Create ctxt)
+
+ static member CreateNonNull ctxt x = ProvidedPropertyInfo (x, ctxt)
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ static member Create ctxt x : ProvidedPropertyInfo =
+#else
+ static member Create ctxt x : ProvidedPropertyInfo? =
+#endif
+ match x with
+ | null -> null
+ | NonNull x -> ProvidedPropertyInfo (x, ctxt)
+
+ static member CreateArray ctxt xs : ProvidedPropertyInfo[] =
+ match box xs with
+ | null -> [| |]
+ | _ -> xs |> Array.map (ProvidedPropertyInfo.CreateNonNull ctxt)
+
member __.Handle = x
+
override __.Equals y = assert false; match y with :? ProvidedPropertyInfo as y -> x.Equals y.Handle | _ -> false
+
override __.GetHashCode() = assert false; x.GetHashCode()
+
static member TaintedGetHashCode (x: Tainted) =
- Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName)))
+ Tainted.GetHashCodeTainted
+ (x.PApplyNoFailure(fun st -> (st.Name, (nonNull (nonNull st.DeclaringType).Assembly).FullName,
+ (nonNull st.DeclaringType).FullName)))
+
static member TaintedEquals (pt1: Tainted, pt2: Tainted) =
Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle))
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedEventInfo (x: System.Reflection.EventInfo, ctxt) =
inherit ProvidedMemberInfo(x, ctxt)
member __.GetAddMethod() = x.GetAddMethod() |> ProvidedMethodInfo.Create ctxt
member __.GetRemoveMethod() = x.GetRemoveMethod() |> ProvidedMethodInfo.Create ctxt
/// EventInfo.EventHandlerType cannot be null
member __.EventHandlerType = x.EventHandlerType |> ProvidedType.CreateWithNullCheck ctxt "EventHandlerType"
- static member Create ctxt x = match x with null -> null | t -> ProvidedEventInfo (t, ctxt)
- static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedEventInfo.Create ctxt)
+
+ static member CreateNonNull ctxt x = ProvidedEventInfo (x, ctxt)
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ static member Create ctxt x : ProvidedEventInfo =
+#else
+ static member Create ctxt x : ProvidedEventInfo? =
+#endif
+ match x with
+ | null -> null
+ | NonNull x -> ProvidedEventInfo (x, ctxt)
+
+ static member CreateArray ctxt xs : ProvidedEventInfo[] =
+ match box xs with
+ | null -> [| |]
+ | _ -> xs |> Array.map (ProvidedEventInfo.CreateNonNull ctxt)
+
member __.Handle = x
+
override __.Equals y = assert false; match y with :? ProvidedEventInfo as y -> x.Equals y.Handle | _ -> false
+
override __.GetHashCode() = assert false; x.GetHashCode()
+
static member TaintedGetHashCode (x: Tainted) =
- Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName)))
+ Tainted.GetHashCodeTainted
+ (x.PApplyNoFailure(fun st -> (st.Name, (nonNull (nonNull st.DeclaringType).Assembly).FullName,
+ (nonNull st.DeclaringType).FullName)))
+
static member TaintedEquals (pt1: Tainted, pt2: Tainted) =
Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle))
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedConstructorInfo (x: System.Reflection.ConstructorInfo, ctxt) =
inherit ProvidedMethodBase(x, ctxt)
- static member Create ctxt x = match x with null -> null | t -> ProvidedConstructorInfo (t, ctxt)
- static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedConstructorInfo.Create ctxt)
+
+ static member CreateNonNull ctxt x = ProvidedConstructorInfo (x, ctxt)
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ static member Create ctxt (x: ConstructorInfo) : ProvidedConstructorInfo =
+#else
+ static member Create ctxt (x: ConstructorInfo?) : ProvidedConstructorInfo? =
+#endif
+ match x with
+ | null -> null
+ | NonNull x -> ProvidedConstructorInfo (x, ctxt)
+
+ static member CreateArray ctxt xs : ProvidedConstructorInfo[] =
+ match box xs with
+ | null -> [| |]
+ | _ -> xs |> Array.map (ProvidedConstructorInfo.CreateNonNull ctxt)
+
member __.Handle = x
override __.Equals y = assert false; match y with :? ProvidedConstructorInfo as y -> x.Equals y.Handle | _ -> false
override __.GetHashCode() = assert false; x.GetHashCode()
- []
+ []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
type ProvidedExpr (x: Quotations.Expr, ctxt) =
member __.Type = x.Type |> ProvidedType.Create ctxt
member __.Handle = x
member __.Context = ctxt
member __.UnderlyingExpressionString = x.ToString()
- static member Create ctxt t = match box t with null -> null | _ -> ProvidedExpr (t, ctxt)
- static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedExpr.Create ctxt)
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ static member Create ctxt t : ProvidedExpr =
+#else
+ static member Create ctxt t : ProvidedExpr? =
+#endif
+ match box t with
+ | null -> null
+ | _ -> ProvidedExpr (t, ctxt)
+
+ static member CreateNonNull ctxt t : ProvidedExpr =
+ ProvidedExpr (t, ctxt)
+
+ static member CreateArray ctxt xs : ProvidedExpr[] =
+ match box xs with
+ | null -> [| |]
+ | _ -> xs |> Array.map (ProvidedExpr.CreateNonNull ctxt)
+
override __.Equals y = match y with :? ProvidedExpr as y -> x.Equals y.Handle | _ -> false
+
override __.GetHashCode() = x.GetHashCode()
- []
+ []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
type ProvidedVar (x: Quotations.Var, ctxt) =
member __.Type = x.Type |> ProvidedType.Create ctxt
member __.Name = x.Name
member __.IsMutable = x.IsMutable
member __.Handle = x
member __.Context = ctxt
- static member Create ctxt t = match box t with null -> null | _ -> ProvidedVar (t, ctxt)
- static member Fresh (nm, ty: ProvidedType) = ProvidedVar.Create ty.Context (new Quotations.Var(nm, ty.Handle))
- static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedVar.Create ctxt)
+
+ static member CreateNonNull ctxt t =
+ ProvidedVar (t, ctxt)
+
+ static member Fresh (nm, ty: ProvidedType) =
+ ProvidedVar.CreateNonNull ty.Context (new Quotations.Var(nm, ty.Handle))
+
+ static member CreateArray ctxt xs =
+ match box xs with
+ | null -> [| |]
+ | _ -> xs |> Array.map (ProvidedVar.CreateNonNull ctxt)
+
override __.Equals y = match y with :? ProvidedVar as y -> x.Equals y.Handle | _ -> false
+
override __.GetHashCode() = x.GetHashCode()
@@ -789,7 +1007,7 @@ module internal ExtensionTyping =
/// Detect a provided lambda expression
let (|ProvidedLambdaExpr|_|) (x: ProvidedExpr) =
match x.Handle with
- | Quotations.Patterns.Lambda(v, body) -> Some (ProvidedVar.Create x.Context v, ProvidedExpr.Create x.Context body)
+ | Quotations.Patterns.Lambda(v, body) -> Some (ProvidedVar.CreateNonNull x.Context v, ProvidedExpr.Create x.Context body)
| _ -> None
/// Detect a provided try/finally expression
@@ -801,7 +1019,7 @@ module internal ExtensionTyping =
/// Detect a provided try/with expression
let (|ProvidedTryWithExpr|_|) (x: ProvidedExpr) =
match x.Handle with
- | Quotations.Patterns.TryWith(b, v1, e1, v2, e2) -> Some (ProvidedExpr.Create x.Context b, ProvidedVar.Create x.Context v1, ProvidedExpr.Create x.Context e1, ProvidedVar.Create x.Context v2, ProvidedExpr.Create x.Context e2)
+ | Quotations.Patterns.TryWith(b, v1, e1, v2, e2) -> Some (ProvidedExpr.Create x.Context b, ProvidedVar.CreateNonNull x.Context v1, ProvidedExpr.Create x.Context e1, ProvidedVar.CreateNonNull x.Context v2, ProvidedExpr.Create x.Context e2)
| _ -> None
#if PROVIDED_ADDRESS_OF
@@ -820,7 +1038,7 @@ module internal ExtensionTyping =
/// Detect a provided 'let' expression
let (|ProvidedLetExpr|_|) (x: ProvidedExpr) =
match x.Handle with
- | Quotations.Patterns.Let(v, e, b) -> Some (ProvidedVar.Create x.Context v, ProvidedExpr.Create x.Context e, ProvidedExpr.Create x.Context b)
+ | Quotations.Patterns.Let(v, e, b) -> Some (ProvidedVar.CreateNonNull x.Context v, ProvidedExpr.Create x.Context e, ProvidedExpr.Create x.Context b)
| _ -> None
@@ -828,7 +1046,7 @@ module internal ExtensionTyping =
let (|ProvidedForIntegerRangeLoopExpr|_|) (x: ProvidedExpr) =
match x.Handle with
| Quotations.Patterns.ForIntegerRangeLoop (v, e1, e2, e3) ->
- Some (ProvidedVar.Create x.Context v,
+ Some (ProvidedVar.CreateNonNull x.Context v,
ProvidedExpr.Create x.Context e1,
ProvidedExpr.Create x.Context e2,
ProvidedExpr.Create x.Context e3)
@@ -837,7 +1055,7 @@ module internal ExtensionTyping =
/// Detect a provided 'set variable' expression
let (|ProvidedVarSetExpr|_|) (x: ProvidedExpr) =
match x.Handle with
- | Quotations.Patterns.VarSet(v, e) -> Some (ProvidedVar.Create x.Context v, ProvidedExpr.Create x.Context e)
+ | Quotations.Patterns.VarSet(v, e) -> Some (ProvidedVar.CreateNonNull x.Context v, ProvidedExpr.Create x.Context e)
| _ -> None
/// Detect a provided 'IfThenElse' expression
@@ -849,7 +1067,7 @@ module internal ExtensionTyping =
/// Detect a provided 'Var' expression
let (|ProvidedVarExpr|_|) (x: ProvidedExpr) =
match x.Handle with
- | Quotations.Patterns.Var v -> Some (ProvidedVar.Create x.Context v)
+ | Quotations.Patterns.Var v -> Some (ProvidedVar.CreateNonNull x.Context v)
| _ -> None
/// Get the provided invoker expression for a particular use of a method.
@@ -874,7 +1092,7 @@ module internal ExtensionTyping =
errorR(Error(FSComp.SR.etMustNotBeGeneric fullName, m))
if TryTypeMember(st, fullName, "IsArray", m, false, fun st->st.IsArray) |> unmarshal then
errorR(Error(FSComp.SR.etMustNotBeAnArray fullName, m))
- TryTypeMemberNonNull(st, fullName, "GetInterfaces", m, [||], fun st -> st.GetInterfaces()) |> ignore
+ TryTypeMember(st, fullName, "GetInterfaces", m, [||], fun st -> st.GetInterfaces()) |> ignore
/// Verify that a provided type has the expected name
@@ -883,15 +1101,21 @@ module internal ExtensionTyping =
if name <> expectedName then
raise (TypeProviderError(FSComp.SR.etProvidedTypeHasUnexpectedName(expectedName, name), st.TypeProviderDesignation, m))
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let namespaceName = TryTypeMember(st, name, "Namespace", m, "", fun st -> st.Namespace) |> unmarshal
+#else
+ let namespaceName = TryTypeMember<_, string?>(st, name, "Namespace", m, "", fun st -> st.Namespace) |> unmarshal // TODO NULLNESS: why is this explicit instantiation needed?
+#endif
+
let rec declaringTypes (st: Tainted) accu =
match TryTypeMember(st, name, "DeclaringType", m, null, fun st -> st.DeclaringType) with
- | Tainted.Null -> accu
- | dt -> declaringTypes dt (CheckAndComputeProvidedNameProperty(m, dt, (fun dt -> dt.Name), "Name") :: accu)
+ | Tainted.Null -> accu
+ | Tainted.NonNull dt -> declaringTypes dt (CheckAndComputeProvidedNameProperty(m, dt, (fun dt -> dt.Name), "Name") :: accu)
+
let path =
[| match namespaceName with
| null -> ()
- | _ -> yield! namespaceName.Split([|'.'|])
+ | NonNull namespaceName -> yield! namespaceName.Split([|'.'|])
yield! declaringTypes st [] |]
if path <> expectedPath then
@@ -904,7 +1128,11 @@ module internal ExtensionTyping =
// Do all the calling into st up front with recovery
let fullName, namespaceName, usedMembers =
let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name")
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let namespaceName = TryTypeMember(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal
+#else
+ let namespaceName = TryTypeMember<_, string?>(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal
+#endif
let fullName = TryTypeMemberNonNull(st, name, "FullName", m, FSComp.SR.invalidFullNameForProvidedType(), fun st -> st.FullName) |> unmarshal
ValidateExpectedName m expectedPath expectedName st
// Must be able to call (GetMethods|GetEvents|GetPropeties|GetNestedTypes|GetConstructors)(bindingFlags).
@@ -929,7 +1157,7 @@ module internal ExtensionTyping =
for mi in usedMembers do
match mi with
| Tainted.Null -> errorR(Error(FSComp.SR.etNullMember fullName, m))
- | _ ->
+ | Tainted.NonNull _ ->
let memberName = TryMemberMember(mi, fullName, "Name", "Name", m, "invalid provided type member name", fun mi -> mi.Name) |> unmarshal
if String.IsNullOrEmpty memberName then
errorR(Error(FSComp.SR.etNullOrEmptyMemberName fullName, m))
@@ -940,7 +1168,7 @@ module internal ExtensionTyping =
| Tainted.Null when (mi.OfType().IsSome) -> ()
| Tainted.Null ->
errorR(Error(FSComp.SR.etNullMemberDeclaringType(fullName, memberName), m))
- | _ ->
+ | Tainted.NonNull miDeclaringType ->
let miDeclaringTypeFullName =
TryMemberMember(miDeclaringType, fullName, memberName, "FullName", m, "invalid declaring type full name", fun miDeclaringType -> miDeclaringType.FullName)
|> unmarshal
@@ -1006,7 +1234,11 @@ module internal ExtensionTyping =
// Validate the Name, Namespace and FullName properties
let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name")
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let _namespaceName = TryTypeMember(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal
+#else
+ let _namespaceName = TryTypeMember<_, (string?)>(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal
+#endif
let _fullname = TryTypeMemberNonNull(st, name, "FullName", m, FSComp.SR.invalidFullNameForProvidedType(), fun st -> st.FullName) |> unmarshal
ValidateExpectedName m expectedPath expectedName st
@@ -1025,7 +1257,11 @@ module internal ExtensionTyping =
/// Resolve a (non-nested) provided type given a full namespace name and a type name.
/// May throw an exception which will be turned into an error message by one of the 'Try' function below.
/// If resolution is successful the type is then validated.
- let ResolveProvidedType (resolver: Tainted, m, moduleOrNamespace: string[], typeName) =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ let ResolveProvidedType (resolver: Tainted, m, moduleOrNamespace: string[], typeName) : Tainted =
+#else
+ let ResolveProvidedType (resolver: Tainted, m, moduleOrNamespace: string[], typeName) : Tainted =
+#endif
let displayName = String.Join(".", moduleOrNamespace)
// Try to find the type in the given provided namespace
@@ -1038,8 +1274,8 @@ module internal ExtensionTyping =
if displayName = providedNamespaceName then
let resolvedType = providedNamespace.PApply((fun providedNamespace -> ProvidedType.CreateNoContext(providedNamespace.ResolveTypeName typeName)), range=m)
match resolvedType with
- | Tainted.Null -> None
- | result ->
+ | Tainted.Null -> None
+ | Tainted.NonNull result ->
ValidateProvidedTypeDefinition(m, result, moduleOrNamespace, typeName)
Some result
else
@@ -1061,7 +1297,7 @@ module internal ExtensionTyping =
try
match ResolveProvidedType(resolver, m, moduleOrNamespace, typeName) with
| Tainted.Null -> None
- | ty -> Some ty
+ | Tainted.NonNull ty -> Some ty
with e ->
errorRecovery e m
None
@@ -1073,13 +1309,13 @@ module internal ExtensionTyping =
| Tainted.Null ->
match st.PUntaint((fun st -> st.Namespace), m) with
| null -> typeName
- | ns -> ns + "." + typeName
+ | NonNull ns -> ns + "." + typeName
| _ -> typeName
let rec encContrib (st: Tainted) =
match st.PApply((fun st ->st.DeclaringType), m) with
| Tainted.Null -> []
- | enc -> encContrib enc @ [ nameContrib enc ]
+ | Tainted.NonNull enc -> encContrib enc @ [ nameContrib enc ]
encContrib st, nameContrib st
@@ -1103,7 +1339,7 @@ module internal ExtensionTyping =
match methBeforeArgs.PApplyWithProvider((fun (mb, provider) -> mb.ApplyStaticArgumentsForMethod(provider, mangledName, staticArgs)), range=m) with
| Tainted.Null -> None
- | methWithArguments ->
+ | Tainted.NonNull methWithArguments ->
let actualName = methWithArguments.PUntaint((fun x -> x.Name), m)
if actualName <> mangledName then
error(Error(FSComp.SR.etProvidedAppliedMethodHadWrongName(methWithArguments.TypeProviderDesignation, mangledName, actualName), m))
@@ -1130,7 +1366,7 @@ module internal ExtensionTyping =
match typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, provider) -> typeBeforeArguments.ApplyStaticArguments(provider, Array.ofList fullTypePathAfterArguments, staticArgs)), range=m) with
| Tainted.Null -> None
- | typeWithArguments ->
+ | Tainted.NonNull typeWithArguments ->
let actualName = typeWithArguments.PUntaint((fun x -> x.Name), m)
let checkTypeName() =
let expectedTypeNameAfterArguments = fullTypePathAfterArguments.[fullTypePathAfterArguments.Length-1]
@@ -1154,7 +1390,7 @@ module internal ExtensionTyping =
match typeBeforeArguments with
| Tainted.Null -> None
- | _ ->
+ | Tainted.NonNull typeBeforeArguments ->
// Take the static arguments (as strings, taken from the text in the reference we're relinking),
// and convert them to objects of the appropriate type, based on the expected kind.
let staticParameters = typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, resolver) -> typeBeforeArguments.GetStaticParameters resolver), range=range0)
@@ -1208,27 +1444,43 @@ module internal ExtensionTyping =
| None -> None
/// Get the parts of a .NET namespace. Special rules: null means global, empty is not allowed.
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let GetPartsOfNamespaceRecover(namespaceName: string) =
- if namespaceName=null then []
- elif namespaceName.Length = 0 then [""]
- else splitNamespace namespaceName
+#else
+ let GetPartsOfNamespaceRecover(namespaceName: string?) =
+#endif
+ match namespaceName with
+ | null -> []
+ | NonNull namespaceName ->
+ if namespaceName.Length = 0 then [""]
+ else splitNamespace (nonNull namespaceName)
/// Get the parts of a .NET namespace. Special rules: null means global, empty is not allowed.
- let GetProvidedNamespaceAsPath (m, resolver: Tainted, namespaceName: string) =
- if namespaceName<>null && namespaceName.Length = 0 then
- errorR(Error(FSComp.SR.etEmptyNamespaceNotAllowed(DisplayNameOfTypeProvider(resolver.TypeProvider, m)), m))
-
- GetPartsOfNamespaceRecover namespaceName
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ let GetProvidedNamespaceAsPath (m, resolver:Tainted, namespaceName:string) =
+#else
+ let GetProvidedNamespaceAsPath (m, resolver:Tainted, namespaceName:string?) =
+#endif
+ match namespaceName with
+ | null -> []
+ | NonNull namespaceName ->
+ if namespaceName.Length = 0 then
+ errorR(Error(FSComp.SR.etEmptyNamespaceNotAllowed(DisplayNameOfTypeProvider(resolver.TypeProvider, m)), m))
+ GetPartsOfNamespaceRecover namespaceName
/// Get the parts of the name that encloses the .NET type including nested types.
let GetFSharpPathToProvidedType (st: Tainted, m) =
// Can't use st.Fullname because it may be like IEnumerable
// We want [System;Collections;Generic]
let namespaceParts = GetPartsOfNamespaceRecover(st.PUntaint((fun st -> st.Namespace), m))
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let rec walkUpNestedClasses(st: Tainted, soFar) =
+#else
+ let rec walkUpNestedClasses(st: Tainted, soFar) =
+#endif
match st with
| Tainted.Null -> soFar
- | st -> walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), m), soFar) @ [st.PUntaint((fun st -> st.Name), m)]
+ | Tainted.NonNull st -> walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), m), soFar) @ [st.PUntaint((fun st -> st.Name), m)]
walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), m), namespaceParts)
@@ -1243,7 +1495,7 @@ module internal ExtensionTyping =
/// any type relocations or static linking for generated types.
let GetOriginalILTypeRefOfProvidedType (st: Tainted, m) =
- let aref = GetOriginalILAssemblyRefOfProvidedAssembly (st.PApply((fun st -> st.Assembly), m), m)
+ let aref = GetOriginalILAssemblyRefOfProvidedAssembly (st.PApply((fun st -> nonNull st.Assembly), m), m) // TODO: why is explicit instantiation needed here
let scoperef = ILScopeRef.Assembly aref
let enc, nm = ILPathToProvidedType (st, m)
let tref = ILTypeRef.Create(scoperef, enc, nm)
diff --git a/src/fsharp/ExtensionTyping.fsi b/src/fsharp/ExtensionTyping.fsi
index d4b58be8cb0..2e6cba85d6f 100755
--- a/src/fsharp/ExtensionTyping.fsi
+++ b/src/fsharp/ExtensionTyping.fsi
@@ -86,18 +86,29 @@ module internal ExtensionTyping =
/// Map the TyconRef objects, if any
member RemapTyconRefs : (obj -> obj) -> ProvidedTypeContext
- type []
+ type []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedType =
inherit ProvidedMemberInfo
member IsSuppressRelocate : bool
member IsErased : bool
member IsGenericType : bool
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
member Namespace : string
+#else
+ member Namespace : string?
+#endif
member FullName : string
member IsArray : bool
member GetInterfaces : unit -> ProvidedType[]
member Assembly : ProvidedAssembly
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
member BaseType : ProvidedType
+#else
+ member BaseType : ProvidedType?
+#endif
member GetNestedType : string -> ProvidedType
member GetNestedTypes : unit -> ProvidedType[]
member GetAllNestedTypes : unit -> ProvidedType[]
@@ -137,27 +148,47 @@ module internal ExtensionTyping =
interface IProvidedCustomAttributeProvider
static member TaintedEquals : Tainted * Tainted -> bool
- and []
+ and
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
IProvidedCustomAttributeProvider =
abstract GetHasTypeProviderEditorHideMethodsAttribute : provider:ITypeProvider -> bool
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
abstract GetDefinitionLocationAttribute : provider:ITypeProvider -> (string * int * int) option
+#else
+ abstract GetDefinitionLocationAttribute : provider:ITypeProvider -> (string? * int * int) option
+#endif
abstract GetXmlDocAttributes : provider:ITypeProvider -> string[]
abstract GetAttributeConstructorArgs: provider:ITypeProvider * attribName:string -> (obj option list * (string * obj option) list) option
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedAssembly =
member GetName : unit -> System.Reflection.AssemblyName
member FullName : string
member GetManifestModuleContents : ITypeProvider -> byte[]
member Handle : System.Reflection.Assembly
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedMemberInfo =
member Name :string
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
member DeclaringType : ProvidedType
+#else
+ member DeclaringType : ProvidedType?
+#endif
interface IProvidedCustomAttributeProvider
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedMethodBase =
inherit ProvidedMemberInfo
member IsGenericMethod : bool
@@ -177,7 +208,10 @@ module internal ExtensionTyping =
static member TaintedGetHashCode : Tainted -> int
static member TaintedEquals : Tainted * Tainted -> bool
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedMethodInfo =
inherit ProvidedMethodBase
member ReturnType : ProvidedType
@@ -185,9 +219,12 @@ module internal ExtensionTyping =
member MetadataToken : int
#endif
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedParameterInfo =
- member Name :string
+ member Name : string
member ParameterType : ProvidedType
member IsIn : bool
member IsOut : bool
@@ -196,7 +233,10 @@ module internal ExtensionTyping =
member HasDefaultValue : bool
interface IProvidedCustomAttributeProvider
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedFieldInfo =
inherit ProvidedMemberInfo
member IsInitOnly : bool
@@ -212,19 +252,39 @@ module internal ExtensionTyping =
member IsPrivate : bool
static member TaintedEquals : Tainted * Tainted -> bool
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedPropertyInfo =
inherit ProvidedMemberInfo
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
member GetGetMethod : unit -> ProvidedMethodInfo
+
member GetSetMethod : unit -> ProvidedMethodInfo
+#else
+ member GetGetMethod : unit -> ProvidedMethodInfo?
+
+ member GetSetMethod : unit -> ProvidedMethodInfo?
+#endif
+
member GetIndexParameters : unit -> ProvidedParameterInfo[]
+
member CanRead : bool
+
member CanWrite : bool
+
member PropertyType : ProvidedType
+
static member TaintedGetHashCode : Tainted -> int
+
static member TaintedEquals : Tainted * Tainted -> bool
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedEventInfo =
inherit ProvidedMemberInfo
member GetAddMethod : unit -> ProvidedMethodInfo
@@ -233,17 +293,26 @@ module internal ExtensionTyping =
static member TaintedGetHashCode : Tainted -> int
static member TaintedEquals : Tainted * Tainted -> bool
- and []
+ and []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
ProvidedConstructorInfo =
inherit ProvidedMethodBase
- []
+ []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
type ProvidedExpr =
member Type : ProvidedType
/// Convert the expression to a string for diagnostics
member UnderlyingExpressionString : string
- []
+ []
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ []
+#endif
type ProvidedVar =
member Type : ProvidedType
member Name : string
diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt
index c28343c01bc..498a619db5b 100644
--- a/src/fsharp/FSComp.txt
+++ b/src/fsharp/FSComp.txt
@@ -1459,6 +1459,22 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl
3243,parsInvalidAnonRecdExpr,"Invalid anonymous record expression"
3244,parsInvalidAnonRecdType,"Invalid anonymous record type"
3245,tcCopyAndUpdateNeedsRecordType,"The input to a copy-and-update expression that creates an anonymous record must be either an anonymous record or a record"
+3260,tcTypeDoesNotHaveAnyNull,"The type '%s' does not support a nullness qualitification."
+#3261 reserved for ConstraintSolverNullnessWarningEquivWithTypes
+#3262 reserved for ConstraintSolverNullnessWarningWithTypes
+#3263 reserved for ConstraintSolverNullnessWarningWithType
+#3264 reserved for ConstraintSolverNonNullnessWarningWithType
+3265,tcLangFeatureNotEnabled50,"This language feature is not enabled, use /langversion:5.0 or greater to enable it"
+3266,tcDefaultStructConstructorCallNulls,"Nullness warning. The default constructor of a struct type is required but one of the fields of struct type is non-nullable."
+3267,chkValueWithDefaultValueMustHaveDefaultValueNulls,"Nullness warning. The 'DefaultValue' attribute is used but the type (or one of its fields if a struct) is non-nullable."
+3268,csNullNotNullConstraintInconsistent,"The constraints 'null' and 'not null' are inconsistent"
+3269,csStructNullConstraintInconsistent,"The constraints 'struct' and 'null' are inconsistent"
+3270,csDelegateComparisonConstraintInconsistent,"The constraints 'delegate' and 'comparison' are inconsistent"
+3271,tcNullnessCheckingNotEnabled,"The /checknulls language feature is not enabled"
+csTypeHasNullAsTrueValue,"The type '%s' has 'null' as a true representation value but a constraint does not permit this"
+csTypeHasNullAsExtraValue,"The type '%s' has 'null' as an extra value but a constraint does not permit this"
3300,chkInvalidFunctionParameterType,"The parameter '%s' has an invalid type '%s'. This is not permitted by the rules of Common IL."
3301,chkInvalidFunctionReturnType,"The function or method has an invalid return type '%s'. This is not permitted by the rules of Common IL."
useSdkRefs,"Use reference assemblies for .NET framework references when available (Enabled by default)."
+optsCheckNulls,"Enable nullness declarations and checks"
+optsLangVersion,"Specify the language version"
diff --git a/src/fsharp/FSStrings.resx b/src/fsharp/FSStrings.resx
index 05cd75cc669..ca37d5395f1 100644
--- a/src/fsharp/FSStrings.resx
+++ b/src/fsharp/FSStrings.resx
@@ -129,6 +129,18 @@
A type parameter is missing a constraint '{0}'
+
+ Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability '{2}' and '{3}'.
+
+
+ Nullness warning: The types '{0}' and '{1}' do not have compatible nullability '{2}' and '{3}'.
+
+
+ Nullness warning: The type '{0}' does not support nullness.
+
+
+ Nullness warning: The type '{0}' supports a null value but a constraint requires the type to be non-null.
+
The unit of measure '{0}' does not match the unit of measure '{1}'
diff --git a/src/fsharp/FSharp.Build/FSharp.Build.fsproj b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
index 0dad55058b0..47f627a73bf 100644
--- a/src/fsharp/FSharp.Build/FSharp.Build.fsproj
+++ b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
@@ -9,6 +9,7 @@
FSharp.Build$(NoWarn);45;55;62;75;1204true
+ $(OtherFlags) --checknulls$(OtherFlags) --maxerrors:20 --extraoptimizationloops:1true
@@ -33,7 +34,9 @@
-
+
+
+
diff --git a/src/fsharp/FSharp.Build/FSharpCommandLineBuilder.fs b/src/fsharp/FSharp.Build/FSharpCommandLineBuilder.fs
index 0ea056694c6..c4f33c0e922 100644
--- a/src/fsharp/FSharp.Build/FSharpCommandLineBuilder.fs
+++ b/src/fsharp/FSharp.Build/FSharpCommandLineBuilder.fs
@@ -32,7 +32,7 @@ type FSharpCommandLineBuilder () =
/// Return a full command line (with quoting for the cmd.exe shell)
override x.ToString() = builder.ToString()
- member x.AppendFileNamesIfNotNull(filenames:ITaskItem array, sep:string) =
+ member x.AppendFileNamesIfNotNull(filenames:ITaskItem[], sep:string) =
builder.AppendFileNamesIfNotNull(filenames, sep)
// do not update "args", not used
for item in filenames do
@@ -42,7 +42,7 @@ type FSharpCommandLineBuilder () =
if s <> String.Empty then
srcs <- tmp.ToString() :: srcs
- member x.AppendSwitchIfNotNull(switch:string, values:string array, sep:string) =
+ member x.AppendSwitchesIfNotNull(switch:string, values:string[], sep:string) =
builder.AppendSwitchIfNotNull(switch, values, sep)
let tmp = new CommandLineBuilder()
tmp.AppendSwitchUnquotedIfNotNull(switch, values, sep)
@@ -50,7 +50,11 @@ type FSharpCommandLineBuilder () =
if s <> String.Empty then
args <- s :: args
- member x.AppendSwitchIfNotNull(switch:string, value:string, ?metadataNames:string array) =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ member x.AppendSwitchIfNotNull(switch:string, value:string, ?metadataNames:string[]) =
+#else
+ member x.AppendSwitchIfNotNull(switch:string, value:string?, ?metadataNames:string[]) =
+#endif
let metadataNames = defaultArg metadataNames [||]
builder.AppendSwitchIfNotNull(switch, value)
let tmp = new CommandLineBuilder()
@@ -65,7 +69,11 @@ type FSharpCommandLineBuilder () =
if s <> String.Empty then
args <- s :: args
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
member x.AppendSwitchUnquotedIfNotNull(switch:string, value:string) =
+#else
+ member x.AppendSwitchUnquotedIfNotNull(switch:string, value:string?) =
+#endif
assert(switch = "") // we only call this method for "OtherFlags"
// Unfortunately we still need to mimic what cmd.exe does, but only for "OtherFlags".
let ParseCommandLineArgs(commandLine:string) = // returns list in reverse order
diff --git a/src/fsharp/FSharp.Build/FSharpEmbedResXSource.fs b/src/fsharp/FSharp.Build/FSharpEmbedResXSource.fs
index 80ab03249f0..fe0e3862b3e 100644
--- a/src/fsharp/FSharp.Build/FSharpEmbedResXSource.fs
+++ b/src/fsharp/FSharp.Build/FSharpEmbedResXSource.fs
@@ -13,8 +13,13 @@ open Microsoft.Build.Framework
open Microsoft.Build.Utilities
type FSharpEmbedResXSource() =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let mutable _buildEngine : IBuildEngine = null
let mutable _hostObject : ITaskHost = null
+#else
+ let mutable _buildEngine : IBuildEngine? = null
+ let mutable _hostObject : ITaskHost? = null
+#endif
let mutable _embeddedText : ITaskItem[] = [||]
let mutable _generatedSource : ITaskItem[] = [||]
let mutable _outputPath : string = ""
@@ -27,9 +32,9 @@ namespace {0}
open System.Reflection
module internal {1} =
- type private C (_dummy:System.Object) = class end
+ type private C (_dummy:System.Int32) = class end
let mutable Culture = System.Globalization.CultureInfo.CurrentUICulture
- let ResourceManager = new System.Resources.ResourceManager(""{2}"", C(null).GetType().GetTypeInfo().Assembly)
+ let ResourceManager = new System.Resources.ResourceManager(""{2}"", C(0).GetType().GetTypeInfo().Assembly)
let GetString(name:System.String) : System.String = ResourceManager.GetString(name, Culture)"
let boilerplateGetObject = " let GetObject(name:System.String) : System.Object = ResourceManager.GetObject(name, Culture)"
diff --git a/src/fsharp/FSharp.Build/FSharpEmbedResourceText.fs b/src/fsharp/FSharp.Build/FSharpEmbedResourceText.fs
index a40017edf5d..10a43cdc903 100644
--- a/src/fsharp/FSharp.Build/FSharpEmbedResourceText.fs
+++ b/src/fsharp/FSharp.Build/FSharpEmbedResourceText.fs
@@ -8,8 +8,13 @@ open Microsoft.Build.Framework
open Microsoft.Build.Utilities
type FSharpEmbedResourceText() =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let mutable _buildEngine : IBuildEngine = null
let mutable _hostObject : ITaskHost = null
+#else
+ let mutable _buildEngine : IBuildEngine? = null
+ let mutable _hostObject : ITaskHost? = null
+#endif
let mutable _embeddedText : ITaskItem[] = [||]
let mutable _generatedSource : ITaskItem[] = [||]
let mutable _generatedResx : ITaskItem[] = [||]
diff --git a/src/fsharp/FSharp.Build/Fsc.fs b/src/fsharp/FSharp.Build/Fsc.fs
index 19d8cd171fa..f06b03c81a1 100644
--- a/src/fsharp/FSharp.Build/Fsc.fs
+++ b/src/fsharp/FSharp.Build/Fsc.fs
@@ -11,6 +11,12 @@ open Microsoft.Build.Framework
open Microsoft.Build.Utilities
open Internal.Utilities
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+[]
+module Utils =
+ let inline (|NonNull|) x = match x with null -> raise (NullReferenceException()) | v -> v
+#endif
+
//There are a lot of flags on fsc.exe.
//For now, not all of them are represented in the "Fsc class" object model.
//The goal is to have the most common/important flags available via the Fsc class, and the
@@ -21,65 +27,95 @@ type public Fsc () as this =
inherit ToolTask ()
- let mutable baseAddress : string = null
let mutable capturedArguments : string list = [] // list of individual args, to pass to HostObject Compile()
let mutable capturedFilenames : string list = [] // list of individual source filenames, to pass to HostObject Compile()
- let mutable codePage : string = null
let mutable commandLineArgs : ITaskItem list = []
let mutable debugSymbols = false
- let mutable debugType : string = null
let mutable defineConstants : ITaskItem[] = [||]
let mutable delaySign : bool = false
let mutable deterministic : bool = false
- let mutable disabledWarnings : string = null
- let mutable documentationFile : string = null
- let mutable dotnetFscCompilerPath : string = null
let mutable embedAllSources = false
let mutable embeddedFiles : ITaskItem[] = [||]
- let mutable generateInterfaceFile : string = null
let mutable highEntropyVA : bool = false
- let mutable keyFile : string = null
let mutable noFramework = false
let mutable optimize : bool = true
- let mutable otherFlags : string = null
- let mutable outputAssembly : string = null
- let mutable pathMap : string = null
- let mutable pdbFile : string = null
- let mutable platform : string = null
let mutable prefer32bit : bool = false
- let mutable preferredUILang : string = null
let mutable publicSign : bool = false
let mutable provideCommandLineArgs : bool = false
let mutable references : ITaskItem[] = [||]
- let mutable referencePath : string = null
let mutable resources : ITaskItem[] = [||]
let mutable skipCompilerExecution : bool = false
let mutable sources : ITaskItem[] = [||]
- let mutable sourceLink : string = null
- let mutable subsystemVersion : string = null
let mutable tailcalls : bool = true
- let mutable targetProfile : string = null
- let mutable targetType : string = null
let mutable toolExe : string = "fsc.exe"
- let mutable toolPath : string =
- let locationOfThisDll =
- try Some(Path.GetDirectoryName(typeof.Assembly.Location))
- with _ -> None
- match FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(locationOfThisDll) with
- | Some s -> s
- | None -> ""
let mutable treatWarningsAsErrors : bool = false
let mutable useStandardResourceNames : bool = false
+ let mutable vserrors : bool = false
+ let mutable utf8output : bool = false
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ let mutable baseAddress : string = null
+ let mutable codePage : string = null
+ let mutable debugType : string = null
+ let mutable disabledWarnings : string = null
+ let mutable documentationFile : string = null
+ let mutable dotnetFscCompilerPath : string = null
+ let mutable generateInterfaceFile : string = null
+ let mutable keyFile : string = null
+ let mutable otherFlags : string = null
+ let mutable outputAssembly : string = null
+ let mutable pathMap : string = null
+ let mutable pdbFile : string = null
+ let mutable platform : string = null
+ let mutable preferredUILang : string = null
+ let mutable referencePath : string = null
+ let mutable sourceLink : string = null
+ let mutable subsystemVersion : string = null
+ let mutable targetProfile : string = null
+ let mutable targetType : string = null
let mutable warningsAsErrors : string = null
let mutable warningsNotAsErrors : string = null
let mutable versionFile : string = null
let mutable warningLevel : string = null
let mutable win32res : string = null
let mutable win32manifest : string = null
- let mutable vserrors : bool = false
let mutable vslcid : string = null
- let mutable utf8output : bool = false
+#else
+ let mutable baseAddress : string? = null
+ let mutable codePage : string? = null
+ let mutable debugType : string? = null
+ let mutable disabledWarnings : string? = null
+ let mutable documentationFile : string? = null
+ let mutable dotnetFscCompilerPath : string? = null
+ let mutable generateInterfaceFile : string? = null
+ let mutable keyFile : string? = null
+ let mutable otherFlags : string? = null
+ let mutable outputAssembly : string? = null
+ let mutable pathMap : string? = null
+ let mutable pdbFile : string? = null
+ let mutable platform : string? = null
+ let mutable preferredUILang : string? = null
+ let mutable referencePath : string? = null
+ let mutable sourceLink : string? = null
+ let mutable subsystemVersion : string? = null
+ let mutable targetProfile : string? = null
+ let mutable targetType : string? = null
+ let mutable warningsAsErrors : string? = null
+ let mutable warningsNotAsErrors : string? = null
+ let mutable versionFile : string? = null
+ let mutable warningLevel : string? = null
+ let mutable win32res : string? = null
+ let mutable win32manifest : string? = null
+ let mutable vslcid : string? = null
+#endif
+ let mutable toolPath : string =
+ let locationOfThisDll =
+ try Some(Path.GetDirectoryName(typeof.Assembly.Location))
+ with _ -> None
+ match FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(locationOfThisDll) with
+ | Some s -> s
+ | None -> ""
// See bug 6483; this makes parallel build faster, and is fine to set unconditionally
do this.YieldDuringToolExecution <- true
@@ -94,7 +130,9 @@ type public Fsc () as this =
builder.AppendSwitch("-g")
// DebugType
builder.AppendSwitchIfNotNull("--debug:",
- if debugType = null then null else
+ match debugType with
+ | null -> null
+ | NonNull debugType ->
match debugType.ToUpperInvariant() with
| "NONE" -> null
| "PORTABLE" -> "portable"
@@ -104,9 +142,8 @@ type public Fsc () as this =
| _ -> null)
if embedAllSources then
builder.AppendSwitch("--embed+")
- if embeddedFiles <> null then
- for item in embeddedFiles do
- builder.AppendSwitchIfNotNull("--embed:", item.ItemSpec)
+ for item in embeddedFiles do
+ builder.AppendSwitchIfNotNull("--embed:", item.ItemSpec)
builder.AppendSwitchIfNotNull("--sourcelink:", sourceLink)
// NoFramework
if noFramework then
@@ -114,9 +151,8 @@ type public Fsc () as this =
// BaseAddress
builder.AppendSwitchIfNotNull("--baseaddress:", baseAddress)
// DefineConstants
- if defineConstants <> null then
- for item in defineConstants do
- builder.AppendSwitchIfNotNull("--define:", item.ItemSpec)
+ for item in defineConstants do
+ builder.AppendSwitchIfNotNull("--define:", item.ItemSpec)
// DocumentationFile
builder.AppendSwitchIfNotNull("--doc:", documentationFile)
@@ -137,7 +173,12 @@ type public Fsc () as this =
builder.AppendSwitchIfNotNull("--pdb:", pdbFile)
// Platform
builder.AppendSwitchIfNotNull("--platform:",
- let ToUpperInvariant (s:string) = if s = null then null else s.ToUpperInvariant()
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ let ToUpperInvariant (s:string) =
+#else
+ let ToUpperInvariant (s:string?) =
+#endif
+ match s with null -> null | NonNull s -> s.ToUpperInvariant()
match ToUpperInvariant(platform), prefer32bit, ToUpperInvariant(targetType) with
| "ANYCPU", true, "EXE"
| "ANYCPU", true, "WINEXE" -> "anycpu32bitpreferred"
@@ -145,29 +186,34 @@ type public Fsc () as this =
| "X86", _, _ -> "x86"
| "X64", _, _ -> "x64"
| _ -> null)
+
// Resources
- if resources <> null then
- for item in resources do
- match useStandardResourceNames with
- | true -> builder.AppendSwitchIfNotNull("--resource:", item.ItemSpec, [|item.GetMetadata("LogicalName"); item.GetMetadata("Access")|])
- | false -> builder.AppendSwitchIfNotNull("--resource:", item.ItemSpec)
+ for item in resources do
+ match useStandardResourceNames with
+ | true -> builder.AppendSwitchIfNotNull("--resource:", item.ItemSpec, [|item.GetMetadata("LogicalName"); item.GetMetadata("Access")|])
+ | false -> builder.AppendSwitchIfNotNull("--resource:", item.ItemSpec)
// VersionFile
builder.AppendSwitchIfNotNull("--versionfile:", versionFile)
+
// References
- if references <> null then
- for item in references do
- builder.AppendSwitchIfNotNull("-r:", item.ItemSpec)
+ for item in references do
+ builder.AppendSwitchIfNotNull("-r:", item.ItemSpec)
+
// ReferencePath
let referencePathArray = // create a array of strings
match referencePath with
| null -> null
- | _ -> referencePath.Split([|';'; ','|], StringSplitOptions.RemoveEmptyEntries)
+ | NonNull referencePath ->
+ referencePath.Split([|';'; ','|], StringSplitOptions.RemoveEmptyEntries)
+
+ builder.AppendSwitchesIfNotNull("--lib:", referencePathArray, ",")
- builder.AppendSwitchIfNotNull("--lib:", referencePathArray, ",")
// TargetType
builder.AppendSwitchIfNotNull("--target:",
- if targetType = null then null else
+ match targetType with
+ | null -> null
+ | NonNull targetType ->
match targetType.ToUpperInvariant() with
| "LIBRARY" -> "library"
| "EXE" -> "exe"
@@ -178,7 +224,8 @@ type public Fsc () as this =
// NoWarn
match disabledWarnings with
| null -> ()
- | _ -> builder.AppendSwitchIfNotNull("--nowarn:", disabledWarnings.Split([|' '; ';'; ','; '\r'; '\n'|], StringSplitOptions.RemoveEmptyEntries), ",")
+ | NonNull disabledWarnings ->
+ builder.AppendSwitchesIfNotNull("--nowarn:", disabledWarnings.Split([|' '; ';'; ','; '\r'; '\n'|], StringSplitOptions.RemoveEmptyEntries), ",")
// WarningLevel
builder.AppendSwitchIfNotNull("--warn:", warningLevel)
@@ -193,14 +240,15 @@ type public Fsc () as this =
let warningsAsErrorsArray =
match warningsAsErrors with
| null -> [|"76"|]
- | _ -> (warningsAsErrors + " 76 ").Split([|' '; ';'; ','|], StringSplitOptions.RemoveEmptyEntries)
+ | NonNull warningsAsErrors -> (warningsAsErrors + " 76 ").Split([|' '; ';'; ','|], StringSplitOptions.RemoveEmptyEntries)
- builder.AppendSwitchIfNotNull("--warnaserror:", warningsAsErrorsArray, ",")
+ builder.AppendSwitchesIfNotNull("--warnaserror:", warningsAsErrorsArray, ",")
// WarningsNotAsErrors
match warningsNotAsErrors with
| null -> ()
- | _ -> builder.AppendSwitchIfNotNull("--warnaserror-:", warningsNotAsErrors.Split([|' '; ';'; ','|], StringSplitOptions.RemoveEmptyEntries), ",")
+ | NonNull warningsNotAsErrors ->
+ builder.AppendSwitchesIfNotNull("--warnaserror-:", warningsNotAsErrors.Split([|' '; ';'; ','|], StringSplitOptions.RemoveEmptyEntries), ",")
// Win32ResourceFile
builder.AppendSwitchIfNotNull("--win32res:", win32res)
@@ -236,9 +284,13 @@ type public Fsc () as this =
builder.AppendSwitch("--nocopyfsharpcore")
- match pathMap with
- | null -> ()
- | _ -> builder.AppendSwitchIfNotNull("--pathmap:", pathMap.Split([|';'; ','|], StringSplitOptions.RemoveEmptyEntries), ",")
+ let pathMapArray = // create a array of strings
+ match pathMap with
+ | null -> null
+ | NonNull pathMap ->
+ pathMap.Split([|';'; ','|], StringSplitOptions.RemoveEmptyEntries)
+
+ builder.AppendSwitchesIfNotNull("--pathmap:", pathMapArray, ",")
if deterministic then
builder.AppendSwitch("--deterministic+")
@@ -555,7 +607,10 @@ type public Fsc () as this =
override fsc.GenerateCommandLineCommands() =
let builder = new FSharpCommandLineBuilder()
- if not (String.IsNullOrEmpty(dotnetFscCompilerPath)) then builder.AppendSwitch(dotnetFscCompilerPath)
+ match dotnetFscCompilerPath with
+ | null | "" -> ()
+ | NonNull dotnetFscCompilerPath ->
+ builder.AppendSwitch(dotnetFscCompilerPath)
builder.ToString()
override fsc.GenerateResponseFileCommands() =
diff --git a/src/fsharp/FSharp.Build/Fsi.fs b/src/fsharp/FSharp.Build/Fsi.fs
index 93d8fc66590..1be1a8ec9ee 100644
--- a/src/fsharp/FSharp.Build/Fsi.fs
+++ b/src/fsharp/FSharp.Build/Fsi.fs
@@ -11,6 +11,12 @@ open Microsoft.Build.Framework
open Microsoft.Build.Utilities
open Internal.Utilities
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+[]
+module UtilsFsi =
+ let inline (|NonNull|) x = match x with null -> raise (NullReferenceException()) | v -> v
+#endif
+
//There are a lot of flags on fsi.exe.
//For now, not all of them are represented in the "Fsi class" object model.
//The goal is to have the most common/important flags available via the Fsi class, and the
@@ -23,27 +29,19 @@ type public Fsi () as this =
let mutable capturedArguments : string list = [] // list of individual args, to pass to HostObject Compile()
let mutable capturedFilenames : string list = [] // list of individual source filenames, to pass to HostObject Compile()
- let mutable codePage : string = null
let mutable commandLineArgs : ITaskItem list = []
let mutable defineConstants : ITaskItem[] = [||]
- let mutable disabledWarnings : string = null
- let mutable dotnetFsiCompilerPath : string = null
let mutable fsiExec = false
let mutable noFramework = false
let mutable optimize = true
- let mutable otherFlags : string = null
- let mutable preferredUILang = null
let mutable provideCommandLineArgs = false
let mutable references : ITaskItem[] = [||]
- let mutable referencePath : string = null
let mutable resources : ITaskItem[] = [||]
let mutable skipCompilerExecution = false
let mutable sources : ITaskItem[] = [||]
let mutable loadSources : ITaskItem[] = [||]
let mutable useSources : ITaskItem[] = [||]
let mutable tailcalls : bool = true
- let mutable targetProfile : string = null
- let mutable targetType : string = null
let mutable toolExe : string = "fsi.exe"
let mutable toolPath : string =
let locationOfThisDll =
@@ -53,11 +51,35 @@ type public Fsi () as this =
| Some s -> s
| None -> ""
let mutable treatWarningsAsErrors : bool = false
+ let mutable utf8output : bool = false
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+ let mutable codePage : string = null
+ let mutable disabledWarnings : string = null
+ let mutable dotnetFsiCompilerPath : string = null
+ let mutable otherFlags : string = null
+ let mutable preferredUILang : string = null
+ let mutable targetProfile : string = null
+ let mutable targetType : string = null
+ let mutable referencePath : string = null
let mutable warningsAsErrors : string = null
let mutable warningsNotAsErrors : string = null
let mutable warningLevel : string = null
let mutable vslcid : string = null
- let mutable utf8output : bool = false
+#else
+ let mutable codePage : string? = null
+ let mutable disabledWarnings : string? = null
+ let mutable dotnetFsiCompilerPath : string? = null
+ let mutable otherFlags : string? = null
+ let mutable preferredUILang : string? = null
+ let mutable targetProfile : string? = null
+ let mutable targetType : string? = null
+ let mutable referencePath : string? = null
+ let mutable warningsAsErrors : string? = null
+ let mutable warningsNotAsErrors : string? = null
+ let mutable warningLevel : string? = null
+ let mutable vslcid : string? = null
+#endif
// See bug 6483; this makes parallel build faster, and is fine to set unconditionally
do this.YieldDuringToolExecution <- true
@@ -69,9 +91,8 @@ type public Fsi () as this =
if noFramework then builder.AppendSwitch("--noframework")
- if defineConstants <> null then
- for item in defineConstants do
- builder.AppendSwitchIfNotNull("--define:", item.ItemSpec)
+ for item in defineConstants do
+ builder.AppendSwitchIfNotNull("--define:", item.ItemSpec)
if optimize then builder.AppendSwitch("--optimize+")
else builder.AppendSwitch("--optimize-")
@@ -79,19 +100,18 @@ type public Fsi () as this =
if not tailcalls then
builder.AppendSwitch("--tailcalls-")
- if references <> null then
- for item in references do
- builder.AppendSwitchIfNotNull("-r:", item.ItemSpec)
+ for item in references do
+ builder.AppendSwitchIfNotNull("-r:", item.ItemSpec)
let referencePathArray = // create a array of strings
match referencePath with
| null -> null
- | _ -> referencePath.Split([|';'; ','|], StringSplitOptions.RemoveEmptyEntries)
+ | NonNull referencePath -> referencePath.Split([|';'; ','|], StringSplitOptions.RemoveEmptyEntries)
// NoWarn
match disabledWarnings with
| null -> ()
- | _ -> builder.AppendSwitchIfNotNull("--nowarn:", disabledWarnings.Split([|' '; ';'; ','; '\r'; '\n'|], StringSplitOptions.RemoveEmptyEntries), ",")
+ | NonNull disabledWarnings -> builder.AppendSwitchesIfNotNull("--nowarn:", disabledWarnings.Split([|' '; ';'; ','; '\r'; '\n'|], StringSplitOptions.RemoveEmptyEntries), ",")
builder.AppendSwitchIfNotNull("--warn:", warningLevel)
@@ -101,13 +121,13 @@ type public Fsi () as this =
let warningsAsErrorsArray =
match warningsAsErrors with
| null -> [| "76" |]
- | _ -> (warningsAsErrors + " 76 ").Split([|' '; ';'; ','|], StringSplitOptions.RemoveEmptyEntries)
+ | NonNull warningsAsErrors -> (warningsAsErrors + " 76 ").Split([|' '; ';'; ','|], StringSplitOptions.RemoveEmptyEntries)
- builder.AppendSwitchIfNotNull("--warnaserror:", warningsAsErrorsArray, ",")
+ builder.AppendSwitchesIfNotNull("--warnaserror:", warningsAsErrorsArray, ",")
match warningsNotAsErrors with
| null -> ()
- | _ -> builder.AppendSwitchIfNotNull("--warnaserror-:", warningsNotAsErrors.Split([|' '; ';'; ','|], StringSplitOptions.RemoveEmptyEntries), ",")
+ | NonNull warningsNotAsErrors -> builder.AppendSwitchesIfNotNull("--warnaserror-:", warningsNotAsErrors.Split([|' '; ';'; ','|], StringSplitOptions.RemoveEmptyEntries), ",")
builder.AppendSwitchIfNotNull("--LCID:", vslcid)
@@ -120,13 +140,11 @@ type public Fsi () as this =
builder.AppendSwitchIfNotNull("--targetprofile:", targetProfile)
- if loadSources <> null then
- for item in loadSources do
- builder.AppendSwitchIfNotNull("--load:", item.ItemSpec)
+ for item in loadSources do
+ builder.AppendSwitchIfNotNull("--load:", item.ItemSpec)
- if useSources <> null then
- for item in useSources do
- builder.AppendSwitchIfNotNull("--use:", item.ItemSpec)
+ for item in useSources do
+ builder.AppendSwitchIfNotNull("--use:", item.ItemSpec)
// OtherFlags - must be second-to-last
builder.AppendSwitchUnquotedIfNotNull("", otherFlags)
@@ -260,15 +278,20 @@ type public Fsi () as this =
// ToolTask methods
override fsi.ToolName = "fsi.exe"
+
override fsi.StandardErrorEncoding = if utf8output then System.Text.Encoding.UTF8 else base.StandardErrorEncoding
+
override fsi.StandardOutputEncoding = if utf8output then System.Text.Encoding.UTF8 else base.StandardOutputEncoding
+
override fsi.GenerateFullPathToTool() =
if toolPath = "" then raise (new System.InvalidOperationException(FSBuild.SR.toolpathUnknown()))
System.IO.Path.Combine(toolPath, fsi.ToolExe)
+
override fsi.LogToolCommand (message:string) =
fsi.Log.LogMessageFromText(message, MessageImportance.Normal) |>ignore
member internal fsi.InternalGenerateFullPathToTool() = fsi.GenerateFullPathToTool() // expose for unit testing
+
member internal fsi.BaseExecuteTool(pathToTool, responseFileCommands, commandLineCommands) = // F# does not allow protected members to be captured by lambdas, this is the standard workaround
base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)
@@ -311,7 +334,10 @@ type public Fsi () as this =
override fsi.GenerateCommandLineCommands() =
let builder = new FSharpCommandLineBuilder()
- if not (String.IsNullOrEmpty(dotnetFsiCompilerPath)) then builder.AppendSwitch(dotnetFsiCompilerPath)
+ match dotnetFsiCompilerPath with
+ | null | "" -> ()
+ | NonNull dotnetFsiCompilerPath ->
+ builder.AppendSwitch(dotnetFsiCompilerPath)
builder.ToString()
override fsi.GenerateResponseFileCommands() =
diff --git a/src/fsharp/FSharp.Build/WriteCodeFragment.fs b/src/fsharp/FSharp.Build/WriteCodeFragment.fs
index b878dadaba0..10fde48de20 100644
--- a/src/fsharp/FSharp.Build/WriteCodeFragment.fs
+++ b/src/fsharp/FSharp.Build/WriteCodeFragment.fs
@@ -12,13 +12,26 @@ open System.Text
open Microsoft.Build.Framework
open Microsoft.Build.Utilities
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+[]
+module UtilsWriteCodeFragment =
+ let inline (|NonNull|) x = match x with null -> raise (NullReferenceException()) | v -> v
+#endif
+
type WriteCodeFragment() =
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let mutable _buildEngine : IBuildEngine = null
let mutable _hostObject : ITaskHost = null
- let mutable _language : string = ""
- let mutable _assemblyAttributes : ITaskItem[] = [||]
let mutable _outputDirectory : ITaskItem = null
let mutable _outputFile : ITaskItem = null
+#else
+ let mutable _buildEngine : IBuildEngine? = null
+ let mutable _hostObject : ITaskHost? = null
+ let mutable _outputDirectory : ITaskItem? = null
+ let mutable _outputFile : ITaskItem? = null
+#endif
+ let mutable _language : string = ""
+ let mutable _assemblyAttributes : ITaskItem[] = [||]
static let escapeString (str:string) =
let sb = str.ToCharArray() |> Seq.fold (fun (sb:StringBuilder) (c:char) ->
@@ -109,7 +122,10 @@ type WriteCodeFragment() =
member this.Execute() =
try
- if isNull _outputFile && isNull _outputDirectory then failwith "Output location must be specified"
+ match _outputFile with
+ | null -> failwith "Output location must be specified"
+ | NonNull outputFile ->
+
let boilerplate =
match _language.ToLowerInvariant() with
| "f#" -> "// \n// Generated by the FSharp WriteCodeFragment class.\n// \nnamespace FSharp\n\nopen System\nopen System.Reflection\n"
@@ -121,16 +137,27 @@ type WriteCodeFragment() =
let code = Array.fold (fun (sb:StringBuilder) (item:ITaskItem) -> sb.AppendLine(WriteCodeFragment.GenerateAttribute (item, _language.ToLowerInvariant()))) sb _assemblyAttributes
if _language.ToLowerInvariant() = "f#" then code.AppendLine("do()") |> ignore
+
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let fileName = _outputFile.ItemSpec
let outputFileItem =
if not (isNull _outputFile) && not (isNull _outputDirectory) && not (Path.IsPathRooted(fileName)) then
TaskItem(Path.Combine(_outputDirectory.ItemSpec, fileName)) :> ITaskItem
- elif isNull _outputFile then
- let tempFile = Path.Combine(Path.GetTempPath(), sprintf "tmp%s.fs" (Guid.NewGuid().ToString("N")))
- TaskItem(tempFile) :> ITaskItem
else
_outputFile
+#else
+ let fileName = outputFile.ItemSpec
+
+ let outputFileItem =
+ match _outputDirectory with
+ | null -> outputFile
+ | NonNull outputDirectory ->
+ if Path.IsPathRooted(fileName) then
+ outputFile
+ else
+ TaskItem(Path.Combine(outputDirectory.ItemSpec, fileName)) :> ITaskItem
+#endif
let codeText = code.ToString()
File.WriteAllText(fileName, codeText)
diff --git a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
index 6307f17baf3..51c4017d67d 100644
--- a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
+++ b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
@@ -28,7 +28,9 @@
-
+
+
+
diff --git a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj
index b770a3cb615..133cfaab815 100644
--- a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj
+++ b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj
@@ -9,6 +9,7 @@
FSharp.Compiler.Private$(NoWarn);45;55;62;75;1204true
+ $(OtherFlags) --checknulls$(DefineConstants);COMPILER$(DefineConstants);MSBUILD_AT_LEAST_15$(OtherFlags) --warnon:1182 --maxerrors:20 --extraoptimizationloops:1
@@ -688,7 +689,9 @@
-
+
+
+
diff --git a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
index 75a7353bb96..e2e28bd0945 100644
--- a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
+++ b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
@@ -7,6 +7,7 @@
net472FSharp.Compiler.Server.Sharedtrue
+ $(OtherFlags) --checknulls
@@ -21,7 +22,9 @@
-
+
+
+
diff --git a/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuget.csproj b/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuget.csproj
index fd2d5162c75..e304369556b 100644
--- a/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuget.csproj
+++ b/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuget.csproj
@@ -10,7 +10,7 @@
-
+ false
diff --git a/src/fsharp/FSharp.Core/FSharp.Core.fsproj b/src/fsharp/FSharp.Core/FSharp.Core.fsproj
index 440850ed55c..7743ea13b34 100644
--- a/src/fsharp/FSharp.Core/FSharp.Core.fsproj
+++ b/src/fsharp/FSharp.Core/FSharp.Core.fsproj
@@ -8,8 +8,10 @@
netstandard1.6$(NoWarn);45;55;62;75;1204true
+ $(OtherFlags) --warnon:3218
+ $(OtherFlags) --compiling-fslib-40
+
$(DefineConstants);FSHARP_CORE
- BUILDING_WITH_LKG;$(DefineConstants)$(OtherFlags) --warnon:1182 --compiling-fslib --compiling-fslib-40 --maxerrors:20 --extraoptimizationloops:1truetrue
@@ -232,7 +234,7 @@
-
+
diff --git a/src/fsharp/FSharp.Core/array.fs b/src/fsharp/FSharp.Core/array.fs
index 8d7ce38869d..03436762dfa 100644
--- a/src/fsharp/FSharp.Core/array.fs
+++ b/src/fsharp/FSharp.Core/array.fs
@@ -571,12 +571,16 @@ namespace Microsoft.FSharp.Collections
maskArray.[maskIdx] <- mask
count
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let private createMask<'a> (f: 'a->bool) (src: array<'a>) (maskArrayOut: byref>) (leftoverMaskOut: byref) =
+#else
+ let private createMask<'a> (f: 'a->bool) (src: array<'a>) (maskArrayOut: byref?>) (leftoverMaskOut: byref) =
+#endif
let maskArrayLength = src.Length / 0x20
// null when there are less than 32 items in src array.
let maskArray =
- if maskArrayLength = 0 then Unchecked.defaultof<_>
+ if maskArrayLength = 0 then null
else Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked maskArrayLength
let mutable count =
@@ -657,7 +661,11 @@ namespace Microsoft.FSharp.Collections
dstIdx
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let private filterViaMask (maskArray: array) (leftoverMask: uint32) (count: int) (src: array<_>) =
+#else
+ let private filterViaMask (maskArray: array?) (leftoverMask: uint32) (count: int) (src: array<_>) =
+#endif
let dst = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked count
let mutable dstIdx = 0
@@ -676,10 +684,10 @@ namespace Microsoft.FSharp.Collections
dst
let filter f (src: array<_>) =
- let mutable maskArray = Unchecked.defaultof<_>
- let mutable leftOverMask = Unchecked.defaultof<_>
+ let mutable maskArray = null
+ let mutable leftOverMask = 0u
match createMask f src &maskArray &leftOverMask with
- | 0 -> empty
+ | 0 -> empty
| count -> filterViaMask maskArray leftOverMask count src
[]
diff --git a/src/fsharp/FSharp.Core/async.fs b/src/fsharp/FSharp.Core/async.fs
index 1f20f7c8110..37649d18013 100644
--- a/src/fsharp/FSharp.Core/async.fs
+++ b/src/fsharp/FSharp.Core/async.fs
@@ -1759,7 +1759,7 @@ namespace Microsoft.FSharp.Control
event.RemoveHandler handle
if args.Cancelled then
ccont (new OperationCanceledException())
- elif isNotNull args.Error then
+ elif isNonNull args.Error then
econt args.Error
else
cont (result args)
diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs
index dd8d087345e..b538c8f9f90 100644
--- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs
+++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs
@@ -369,7 +369,7 @@ namespace Microsoft.FSharp.Core.CompilerServices
type ITypeProvider =
inherit System.IDisposable
abstract GetNamespaces : unit -> IProvidedNamespace[]
- abstract GetStaticParameters : typeWithoutArguments:Type -> ParameterInfo[]
+ abstract GetStaticParameters : typeWithoutArguments:Type -> ParameterInfo[]
abstract ApplyStaticArguments : typeWithoutArguments:Type * typePathWithArguments:string[] * staticArguments:obj[] -> Type
abstract GetInvokerExpression : syntheticMethodBase:MethodBase * parameters:Microsoft.FSharp.Quotations.Expr[] -> Microsoft.FSharp.Quotations.Expr
diff --git a/src/fsharp/FSharp.Core/local.fs b/src/fsharp/FSharp.Core/local.fs
index 9fb452907f4..090537ca25e 100644
--- a/src/fsharp/FSharp.Core/local.fs
+++ b/src/fsharp/FSharp.Core/local.fs
@@ -1095,7 +1095,11 @@ module internal Array =
if len < 2 then ()
else Array.Sort<_>(array, fastComparerForArraySort())
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
let stableSortWithKeysAndComparer (cFast:IComparer<'Key>) (c:IComparer<'Key>) (array:array<'T>) (keys:array<'Key>) =
+#else
+ let stableSortWithKeysAndComparer (cFast:IComparer<'Key>?) (c:IComparer<'Key>) (array:array<'T>) (keys:array<'Key>) =
+#endif
// 'places' is an array or integers storing the permutation performed by the sort
let places = zeroCreateUnchecked array.Length
for i = 0 to array.Length - 1 do
diff --git a/src/fsharp/FSharp.Core/mailbox.fs b/src/fsharp/FSharp.Core/mailbox.fs
index b5c91fe49ee..1b54fefb3a1 100644
--- a/src/fsharp/FSharp.Core/mailbox.fs
+++ b/src/fsharp/FSharp.Core/mailbox.fs
@@ -353,7 +353,7 @@ namespace Microsoft.FSharp.Control
interface System.IDisposable with
member __.Dispose() =
- if isNotNull pulse then (pulse :> IDisposable).Dispose()
+ if isNonNull pulse then (pulse :> IDisposable).Dispose()
#if DEBUG
member x.UnsafeContents =
diff --git a/src/fsharp/FSharp.Core/option.fs b/src/fsharp/FSharp.Core/option.fs
index 552d1c9231f..1c8907810b5 100644
--- a/src/fsharp/FSharp.Core/option.fs
+++ b/src/fsharp/FSharp.Core/option.fs
@@ -85,11 +85,21 @@ module Option =
[]
let ofNullable (value:System.Nullable<'T>) = if value.HasValue then Some value.Value else None
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
[]
let ofObj value = match value with null -> None | _ -> Some value
[]
let toObj value = match value with None -> null | Some x -> x
+#else
+ []
+ let ofObj (value: 'T?) : 'T option when 'T: not struct and 'T : not null =
+ match value with null -> None | _ -> Some value
+
+ []
+ let toObj (value: 'T option) : 'T? when 'T: not struct (* and 'T : not null *) =
+ match value with None -> null | Some x -> x
+#endif
module ValueOption =
@@ -171,8 +181,18 @@ module ValueOption =
[]
let ofNullable (value:System.Nullable<'T>) = if value.HasValue then ValueSome value.Value else ValueNone
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
[]
let ofObj value = match value with null -> ValueNone | _ -> ValueSome value
[]
let toObj value = match value with ValueNone -> null | ValueSome x -> x
+#else
+ []
+ let ofObj (value: 'T?) : 'T voption when 'T: not struct and 'T : not null =
+ match value with null -> ValueNone | _ -> ValueSome value
+
+ []
+ let toObj (value : 'T voption) : 'T? when 'T: not struct (* and 'T : not null *) =
+ match value with ValueNone -> null | ValueSome x -> x
+#endif
\ No newline at end of file
diff --git a/src/fsharp/FSharp.Core/option.fsi b/src/fsharp/FSharp.Core/option.fsi
index 739484ae8cf..2e5a4ed2e3f 100644
--- a/src/fsharp/FSharp.Core/option.fsi
+++ b/src/fsharp/FSharp.Core/option.fsi
@@ -190,13 +190,23 @@ module Option =
/// The input value.
/// The result option.
[]
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
val ofObj: value: 'T -> 'T option when 'T : null
+#else
+ // TODO NULLNESS: assess this change - is it a breaking change?
+ val ofObj: value: 'T? -> 'T option when 'T : not struct and 'T : not null
+#endif
/// Convert an option to a potentially null value.
/// The input value.
/// The result value, which is null if the input was None.
[]
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
val toObj: value: 'T option -> 'T when 'T : null
+#else
+ // TODO NULLNESS: assess this change - is it a breaking change?
+ val toObj: value: 'T option -> 'T? when 'T : not struct (* and 'T : not null *)
+#endif
/// Basic operations on value options.
module ValueOption =
@@ -379,10 +389,20 @@ module ValueOption =
/// The input value.
/// The result value option.
[]
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
val ofObj: value: 'T -> 'T voption when 'T : null
+#else
+ // TODO NULLNESS: assess this change - is it a breaking change?
+ val ofObj: value: 'T? -> 'T voption when 'T : not struct and 'T : not null
+#endif
/// Convert an option to a potentially null value.
/// The input value.
/// The result value, which is null if the input was ValueNone.
[]
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
val toObj: value: 'T voption -> 'T when 'T : null
+#else
+ // TODO NULLNESS: assess this change - is it a breaking change?
+ val toObj: value: 'T voption -> 'T? when 'T : not struct (* and 'T : not null *)
+#endif
diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs
index 2e91dec124f..50770889cac 100644
--- a/src/fsharp/FSharp.Core/prim-types.fs
+++ b/src/fsharp/FSharp.Core/prim-types.fs
@@ -9,6 +9,8 @@
#nowarn "69" // Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration...
#nowarn "77" // Member constraints with the name 'Exp' are given special status by the F# compiler...
#nowarn "3218" // mismatch of parameter name for 'fst' and 'snd'
+#nowarn "3244" // no nullness checking
+#nowarn "3245" // no nullness checking
namespace Microsoft.FSharp.Core
@@ -821,7 +823,8 @@ namespace Microsoft.FSharp.Core
/// Implements generic comparison between two objects. This corresponds to the pseudo-code in the F#
/// specification. The treatment of NaNs is governed by "comp".
- let rec GenericCompare (comp:GenericComparer) (xobj:obj,yobj:obj) =
+ let rec GenericCompare (comp:GenericComparer) (xobj:obj, yobj:obj) =
+ (*if objEq xobj yobj then 0 else *)
match xobj,yobj with
| null,null -> 0
| null,_ -> -1
@@ -2404,9 +2407,7 @@ namespace Microsoft.FSharp.Core
parse p 0UL
let inline removeUnderscores (s:string) =
- match s with
- | null -> null
- | s -> s.Replace("_", "")
+ s.Replace("_", "")
let ParseUInt32 (s:string) =
if System.Object.ReferenceEquals(s,null) then
@@ -3378,17 +3379,67 @@ namespace Microsoft.FSharp.Core
| _ -> None
[]
- let inline isNull (value : 'T) =
- match value with
+ let inline isNull (value : 'T when 'T : null) =
+ match box value with
| null -> true
| _ -> false
- []
- let inline internal isNotNull (value : 'T) =
+ []
+ let inline internal isNonNull (value : 'T) =
match value with
| null -> false
| _ -> true
+#if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE
+
+ []
+ let inline isNullV (value : Nullable<'T>) = not value.HasValue
+
+ []
+ let inline nonNull (value : 'T? when 'T : not struct and 'T : not null) =
+ match box value with
+ | null -> raise (System.NullReferenceException())
+ | _ -> (# "" value : 'T #)
+
+ []
+ let inline nonNullV (value : Nullable<'T>) =
+ if value.HasValue then
+ value.Value
+ else
+ raise (System.NullReferenceException())
+
+ []
+ let inline (|Null|NotNull|) (value : 'T? when 'T : not null) =
+ match value with
+ | null -> Null ()
+ | _ -> NotNull (# "" value : 'T #)
+
+ []
+ let inline (|NullV|NotNullV|) (value : Nullable<'T>) =
+ if value.HasValue then NotNullV value.Value
+ else NullV ()
+
+ []
+ let inline (|NonNull|) (value : 'T? when 'T : not null) =
+ match box value with
+ | null -> raise (System.NullReferenceException())
+ | _ -> (# "" value : 'T #)
+
+ []
+ let inline (|NonNullV|) (value : Nullable<'T>) =
+ if value.HasValue then value.Value
+ else raise (System.NullReferenceException())
+
+ []
+ let inline withNull (value : 'T when 'T : not struct) = (# "" value : 'T? #)
+
+ []
+ let inline withNullV (value : 'T) : Nullable<'T> = Nullable<'T>(value)
+
+ []
+ let inline nullV<'T when 'T : struct and 'T : (new : unit -> 'T) and 'T :> ValueType> = Nullable<'T>()
+#endif
+
[]
let inline raise (exn: exn) = (# "throw" exn : 'T #)
@@ -3430,6 +3481,14 @@ namespace Microsoft.FSharp.Core
let inline nullArg (argumentName:string) =
raise (new System.ArgumentNullException(argumentName))
+#if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE
+ []
+ let inline nullArgCheck (argumentName:string) (value: 'T? when 'T : not struct and 'T : not null) =
+ match value with
+ | null -> raise (new System.ArgumentNullException(argumentName))
+ | _ -> (# "" value : 'T #)
+#endif
+
[]
[]
let inline invalidOp message = raise (System.InvalidOperationException(message))
@@ -3480,10 +3539,26 @@ namespace Microsoft.FSharp.Core
let (^) (s1: string) (s2: string) = System.String.Concat(s1, s2)
[]
- let defaultArg arg defaultValue = match arg with None -> defaultValue | Some v -> v
+ let inline defaultArg arg defaultValue =
+ match arg with None -> defaultValue | Some v -> v
[]
- let defaultValueArg arg defaultValue = match arg with ValueNone -> defaultValue | ValueSome v -> v
+ let inline defaultValueArg arg defaultValue =
+ match arg with ValueNone -> defaultValue | ValueSome v -> v
+
+ []
+ let inline defaultIfNone defaultValue arg =
+ match arg with None -> defaultValue | Some v -> v
+
+#if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE
+ []
+ let inline defaultIfNull defaultValue (arg: 'T? when 'T : not struct and 'T : not null) =
+ match arg with null -> defaultValue | _ -> (# "" arg : 'T #)
+
+ []
+ let inline defaultIfNullV defaultValue (arg: Nullable<'T>) =
+ if arg.HasValue then arg.Value else defaultValue
+#endif
[]
let inline (~-) (n: ^T) : ^T =
@@ -3729,9 +3804,16 @@ namespace Microsoft.FSharp.Core
let inline ParseUInt16 (s:string) = (# "conv.ovf.u2" (ParseUInt32 s) : uint16 #)
let inline ParseIntPtr (s:string) = (# "conv.ovf.i" (ParseInt64 s) : nativeint #)
let inline ParseUIntPtr (s:string) = (# "conv.ovf.u" (ParseInt64 s) : unativeint #)
- let inline ParseDouble (s:string) = Double.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)
- let inline ParseSingle (s:string) = Single.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)
-
+
+ let inline ParseDouble (s:string) =
+ if System.Object.ReferenceEquals(s,null) then
+ raise( new System.ArgumentNullException("s") )
+ Double.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)
+
+ let inline ParseSingle (s:string) =
+ if System.Object.ReferenceEquals(s,null) then
+ raise( new System.ArgumentNullException("s") )
+ Single.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)
[]
[]
diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi
index c977af45417..d1736607a65 100644
--- a/src/fsharp/FSharp.Core/prim-types.fsi
+++ b/src/fsharp/FSharp.Core/prim-types.fsi
@@ -952,7 +952,11 @@ namespace Microsoft.FSharp.Core
val inline FastGenericComparer<'T> : System.Collections.Generic.IComparer<'T> when 'T : comparison
/// Make an F# comparer object for the given type, where it can be null if System.Collections.Generic.Comparer<'T>.Default
+#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
val internal FastGenericComparerCanBeNull<'T> : System.Collections.Generic.IComparer<'T> when 'T : comparison
+#else
+ val internal FastGenericComparerCanBeNull<'T> : System.Collections.Generic.IComparer<'T>? when 'T : comparison
+#endif
/// Make an F# hash/equality object for the given type
val inline FastGenericEqualityComparer<'T> : System.Collections.Generic.IEqualityComparer<'T> when 'T : equality
@@ -2145,19 +2149,42 @@ namespace Microsoft.FSharp.Core
/// The function result.
val inline (<|||): func:('T1 -> 'T2 -> 'T3 -> 'U) -> arg1:'T1 * arg2:'T2 * arg3:'T3 -> 'U
+ /// Used to specify a default value for an optional argument in the implementation of a function
+ /// The default value of the argument.
+ /// An option representing the argument.
+ /// The argument value. If it is None, the defaultValue is returned.
+ []
+ val inline defaultIfNone : defaultValue:'T -> arg:'T option -> 'T
+
+#if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE
+ /// Used to specify a default value for a nullable reference argument in the implementation of a function
+ /// The default value of the argument.
+ /// A nullable value representing the argument.
+ /// The argument value. If it is null, the defaultValue is returned.
+ []
+ val inline defaultIfNull : defaultValue:'T -> arg:'T? -> 'T when 'T : not struct and 'T : not null
+
+ /// Used to specify a default value for an nullable value argument in the implementation of a function
+ /// The default value of the argument.
+ /// A nullable value representing the argument.
+ /// The argument value. If it is null, the defaultValue is returned.
+ []
+ val inline defaultIfNullV : defaultValue:'T -> arg:Nullable<'T> -> 'T
+#endif
+
/// Used to specify a default value for an optional argument in the implementation of a function
/// An option representing the argument.
/// The default value of the argument.
/// The argument value. If it is None, the defaultValue is returned.
[]
- val defaultArg : arg:'T option -> defaultValue:'T -> 'T
+ val inline defaultArg : arg:'T option -> defaultValue:'T -> 'T
/// Used to specify a default value for an optional argument in the implementation of a function
/// A value option representing the argument.
/// The default value of the argument.
/// The argument value. If it is None, the defaultValue is returned.
[]
- val defaultValueArg : arg:'T voption -> defaultValue:'T -> 'T
+ val inline defaultValueArg : arg:'T voption -> defaultValue:'T -> 'T
/// Concatenate two strings. The operator '+' may also be used.
[]
@@ -2253,17 +2280,80 @@ namespace Microsoft.FSharp.Core
/// The value to check.
/// True when value is null, false otherwise.
[]
- val inline isNull : value:'T -> bool when 'T : null
+ val inline isNull : value: 'T -> bool when 'T : null
+#if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE
+ /// Determines whether the given value is null.
+ /// The value to check.
+ /// A choice indicating whether the value is null or not-null.
+ []
+ val inline (|Null|NotNull|) : value: 'T? -> Choice when 'T : not null
+
+ /// Determines whether the given value is null.
+ /// The value to check.
+ /// A choice indicating whether the value is null or not-null.
+ []
+ val inline (|NullV|NotNullV|) : value: Nullable<'T> -> Choice
+
+ /// When used in a pattern checks the given value is not null.
+ /// The value to check.
+ /// The non-null value.
+ []
+ val inline (|NonNull|) : value: 'T? -> 'T when 'T : not null
+
+ /// When used in a pattern checks the given value is not null.
+ /// The value to check.
+ /// The non-null value.
+ []
+ val inline (|NonNullV|) : value: Nullable<'T> -> 'T
+
+ /// Determines whether the given value is null.
+ /// The value to check.
+ /// True when value is null, false otherwise.
+ []
+ val inline isNullV : value:Nullable<'T> -> bool
+#endif
+
/// Determines whether the given value is not null.
/// The value to check.
/// True when value is not null, false otherwise.
- []
- val inline internal isNotNull : value:'T -> bool when 'T : null
+ []
+ val inline internal isNonNull : value:'T -> bool when 'T : null
+
+#if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE
+ /// Get the null value for a value type.
+ /// The null value for a value type.
+ []
+ val inline nullV<'T when 'T : struct and 'T : (new : unit -> 'T) and 'T :> ValueType> : Nullable<'T>
+
+ /// Asserts that the value is non-null.
+ /// The value to check.
+ /// True when value is null, false otherwise.
+ []
+ val inline nonNull : value: 'T? -> 'T when 'T : not struct and 'T : not null
+
+ /// Asserts that the value is non-null.
+ /// The value to check.
+ /// True when value is null, false otherwise.
+ []
+ val inline nonNullV : value:Nullable<'T> -> 'T
+
+ /// Asserts that the value is non-null.
+ /// The value to check.
+ /// True when value is null, false otherwise.
+ []
+ val inline withNull : value:'T -> 'T? when 'T : not struct (* and 'T : not null *)
+
+ /// Asserts that the value is non-null.
+ /// The value to check.
+ /// True when value is null, false otherwise.
+ []
+ val inline withNullV : value:'T -> Nullable<'T>
+#endif
/// Throw a System.Exception exception.
/// The exception message.
- /// The result value.
+ /// Never returns.
[]
val inline failwith : message:string -> 'T
@@ -2271,16 +2361,24 @@ namespace Microsoft.FSharp.Core
/// the given argument name and message.
/// The argument name.
/// The exception message.
- /// The result value.
+ /// Never returns.
[]
val inline invalidArg : argumentName:string -> message:string -> 'T
/// Throw a System.ArgumentNullException exception
/// The argument name.
- /// The result value.
+ /// Never returns.
[]
val inline nullArg : argumentName:string -> 'T
+#if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE
+ /// Throw a System.ArgumentNullException if the given value is null exception
+ /// The argument name.
+ /// The result value.
+ []
+ val inline nullArgCheck : argumentName:string -> 'T? -> 'T when 'T : not struct and 'T : not null
+#endif
+
/// Throw a System.InvalidOperationException exception
/// The exception message.
/// The result value.
diff --git a/src/fsharp/FSharp.Core/reflect.fsi b/src/fsharp/FSharp.Core/reflect.fsi
index 359f36af777..9930e6f7196 100644
--- a/src/fsharp/FSharp.Core/reflect.fsi
+++ b/src/fsharp/FSharp.Core/reflect.fsi
@@ -18,12 +18,14 @@ open Microsoft.FSharp.Collections
type UnionCaseInfo =
/// The name of the case.
member Name : string
+
/// The type in which the case occurs.
member DeclaringType: Type
/// Returns the custom attributes associated with the case.
/// An array of custom attributes.
member GetCustomAttributes: unit -> obj[]
+
/// Returns the custom attributes associated with the case matching the given attribute type.
/// The type of attributes to return.
/// An array of custom attributes.
@@ -54,7 +56,7 @@ type FSharpValue =
/// Thrown when the input type is not a record type.
/// The field from the record.
static member GetRecordField: record:obj * info:PropertyInfo -> obj
-
+
/// Precompute a function for reading a particular field from a record.
/// Assumes the given type is a RecordType with a field of the given name.
/// If not, ArgumentException is raised during pre-computation.
@@ -101,6 +103,7 @@ type FSharpValue =
/// Thrown when the input type is not a record type.
/// An optimized reader for the given record type.
static member PreComputeRecordReader : recordType:Type * ?bindingFlags:BindingFlags -> (obj -> obj[])
+
/// Precompute a function for constructing a record value.
///
/// Assumes the given type is a RecordType.
@@ -137,7 +140,7 @@ type FSharpValue =
/// Thrown when the input type is not a union case value.
/// The description of the union case and its fields.
static member GetUnionFields: value:obj * unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo * obj []
-
+
/// Assumes the given type is a union type.
/// If not, ArgumentException is raised during pre-computation.
///
@@ -207,8 +210,8 @@ type FSharpValue =
/// The input tuple.
/// Thrown when the input is not a tuple value.
/// An array of the fields from the given tuple.
- static member GetTupleFields: tuple:obj -> obj []
-
+ static member GetTupleFields: tuple:obj -> obj[]
+
/// Precompute a function for reading the values of a particular tuple type
///
/// Assumes the given type is a TupleType.
@@ -217,7 +220,7 @@ type FSharpValue =
/// Thrown when the given type is not a tuple type.
/// A function to read values of the given tuple type.
static member PreComputeTupleReader : tupleType:Type -> (obj -> obj[])
-
+
/// Gets information that indicates how to read a field of a tuple
/// The input tuple type.
/// The index of the tuple element to describe.
@@ -360,7 +363,8 @@ module FSharpReflectionExtensions =
/// Optional flags that denotes accessibility of the private representation.
/// Thrown when the input type is not a record type.
/// The created record.
- static member MakeRecord: recordType:Type * values:obj [] * ?allowAccessToPrivateRepresentation : bool -> obj
+ static member MakeRecord: recordType:Type * values:obj[] * ?allowAccessToPrivateRepresentation : bool -> obj
+
/// Reads all the fields from a record value.
///
/// Assumes the given input is a record value. If not, ArgumentException is raised.
@@ -385,6 +389,7 @@ module FSharpReflectionExtensions =
/// Thrown when the input type is not a record type.
/// An optimized reader for the given record type.
static member PreComputeRecordReader : recordType:Type * ?allowAccessToPrivateRepresentation : bool -> (obj -> obj[])
+
/// Precompute a function for constructing a record value.
///
/// Assumes the given type is a RecordType.
@@ -400,13 +405,13 @@ module FSharpReflectionExtensions =
/// Optional flag that denotes accessibility of the private representation.
/// A ConstructorInfo for the given record type.
static member PreComputeRecordConstructorInfo: recordType:Type * ?allowAccessToPrivateRepresentation : bool-> ConstructorInfo
-
+
/// Create a union case value.
/// The description of the union case to create.
/// The array of arguments to construct the given case.
/// Optional flag that denotes accessibility of the private representation.
/// The constructed union case.
- static member MakeUnion: unionCase:UnionCaseInfo * args:obj [] * ?allowAccessToPrivateRepresentation : bool-> obj
+ static member MakeUnion: unionCase:UnionCaseInfo * args:obj[] * ?allowAccessToPrivateRepresentation : bool-> obj
/// Identify the union case and its fields for an object
///
@@ -420,8 +425,8 @@ module FSharpReflectionExtensions =
/// Optional flag that denotes accessibility of the private representation.
/// Thrown when the input type is not a union case value.
/// The description of the union case and its fields.
- static member GetUnionFields: value:obj * unionType:Type * ?allowAccessToPrivateRepresentation : bool -> UnionCaseInfo * obj []
-
+ static member GetUnionFields: value:obj * unionType:Type * ?allowAccessToPrivateRepresentation : bool -> UnionCaseInfo * obj[]
+
/// Assumes the given type is a union type.
/// If not, ArgumentException is raised during pre-computation.
///
diff --git a/src/fsharp/FindUnsolved.fs b/src/fsharp/FindUnsolved.fs
index ac64aa6c1df..8d1aeaba761 100644
--- a/src/fsharp/FindUnsolved.fs
+++ b/src/fsharp/FindUnsolved.fs
@@ -75,8 +75,8 @@ let rec accExpr (cenv:cenv) (env:env) expr =
accExprs cenv env argsl
| Expr.Lambda (_, _ctorThisValOpt, _baseValOpt, argvs, _body, m, rty) ->
- let topValInfo = ValReprInfo ([], [argvs |> List.map (fun _ -> ValReprInfo.unnamedTopArg1)], ValReprInfo.unnamedRetVal)
- let ty = mkMultiLambdaTy m argvs rty
+ let topValInfo = ValReprInfo ([],[argvs |> List.map (fun _ -> ValReprInfo.unnamedTopArg1)],ValReprInfo.unnamedRetVal)
+ let ty = mkMultiLambdaTy cenv.g m argvs rty
accLambdas cenv env topValInfo expr ty
| Expr.TyLambda (_, tps, _body, _m, rty) ->
diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs
index 09750c4f32d..62677b12966 100644
--- a/src/fsharp/IlxGen.fs
+++ b/src/fsharp/IlxGen.fs
@@ -116,7 +116,7 @@ type AttributeDecoder(namedArgs) =
let nameMap = namedArgs |> List.map (fun (AttribNamedArg(s, _, _, c)) -> s, c) |> NameMap.ofList
let findConst x = match NameMap.tryFind x nameMap with | Some(AttribExpr(_, Expr.Const (c, _, _))) -> Some c | _ -> None
- let findAppTr x = match NameMap.tryFind x nameMap with | Some(AttribExpr(_, Expr.App (_, _, [TType_app(tr, _)], _, _))) -> Some tr | _ -> None
+ let findAppTr x = match NameMap.tryFind x nameMap with | Some(AttribExpr(_, Expr.App (_, _, [TType_app(tr, _, _)], _, _))) -> Some tr | _ -> None
member __.FindInt16 x dflt = match findConst x with | Some(Const.Int16 x) -> x | _ -> dflt
@@ -516,12 +516,14 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty =
ignore voidOK
#endif
match stripTyEqnsAndMeasureEqns g ty with
- | TType_app (tcref, tinst) -> GenNamedTyAppAux amap m tyenv ptrsOK tcref tinst
+ | TType_app (tcref, tinst, _nullness) ->
+ GenNamedTyAppAux amap m tyenv ptrsOK tcref tinst
+ | TType_tuple (tupInfo, args) ->
+ GenTypeAux amap m tyenv VoidNotOK ptrsOK (mkCompiledTupleTy g (evalTupInfoIsStruct tupInfo) args)
- | TType_tuple (tupInfo, args) -> GenTypeAux amap m tyenv VoidNotOK ptrsOK (mkCompiledTupleTy g (evalTupInfoIsStruct tupInfo) args)
-
- | TType_fun (dty, returnTy) -> EraseClosures.mkILFuncTy g.ilxPubCloEnv (GenTypeArgAux amap m tyenv dty) (GenTypeArgAux amap m tyenv returnTy)
+ | TType_fun (dty, returnTy, _nullness) ->
+ EraseClosures.mkILFuncTy g.ilxPubCloEnv (GenTypeArgAux amap m tyenv dty) (GenTypeArgAux amap m tyenv returnTy)
| TType_anon (anonInfo, tinst) ->
let tref = anonInfo.ILTypeRef
@@ -537,7 +539,7 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty =
if tps.IsEmpty then GenTypeAux amap m tyenv VoidNotOK ptrsOK tau
else EraseClosures.mkILTyFuncTy g.ilxPubCloEnv
- | TType_var tp -> mkILTyvarTy tyenv.[tp, m]
+ | TType_var (tp, _nullness) -> mkILTyvarTy tyenv.[tp, m]
| TType_measure _ -> g.ilg.typ_Int32
@@ -1437,7 +1439,7 @@ type AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbu
NewRecdField false None (mkSynId m propName) false (mkTyparTy tp) true false [] [] XmlDoc.Empty taccessPublic false ])
let tcref = mkLocalTyconRef tycon
- let _, typ = generalizeTyconRef tcref
+ let _, typ = generalizeTyconRef cenv.g tcref
let tcaug = tcref.TypeContents
tcaug.tcaug_interfaces <-
@@ -2865,8 +2867,7 @@ and GenUntupledArgExpr cenv cgbuf eenv m argInfos expr sequel =
GenBinding cenv cgbuf eenvinner bind
let tys = destRefTupleTy g ty
assert (tys.Length = numRequiredExprs)
- // TODO - tupInfoRef
- argInfos |> List.iteri (fun i _ -> GenGetTupleField cenv cgbuf eenvinner (tupInfoRef (* TODO *), loce, tys, i, m) Continue)
+ argInfos |> List.iteri (fun i _ -> GenGetTupleField cenv cgbuf eenvinner (tupInfoRef, loce, tys, i, m) Continue)
GenSequel cenv eenv.cloc cgbuf sequel
)
@@ -5926,10 +5927,10 @@ and GenBindingRhs cenv cgbuf eenv sp (vspec: Val) e =
| Expr.TyLambda (_, tyargs, body, _, ttype) when
(
tyargs |> List.forall (fun tp -> tp.IsErased) &&
- (match StorageForVal vspec.Range vspec eenv with Local _ -> true | _ -> false) &&
- (isLocalTypeFunc ||
- (match ttype with
- TType_var typar -> match typar.Solution with Some(TType_app(t, _))-> t.IsStructOrEnumTycon | _ -> false
+ (match StorageForVal vspec.Range vspec eenv with Local _ -> true | _ -> false) &&
+ (isLocalTypeFunc ||
+ (match ttype with
+ TType_var(typar, _) -> match typar.Solution with Some(TType_app(t, _, _))-> t.IsStructOrEnumTycon | _ -> false
| _ -> false))
) ->
// type lambda with erased type arguments that is stored as local variable (not method or property)- inline body
@@ -6655,10 +6656,10 @@ and GenAbstractBinding cenv eenv tref (vref: ValRef) =
[], [], []
/// Generate a ToString method that calls 'sprintf "%A"'
-and GenToStringMethod cenv eenv ilThisTy m =
+and GenToStringMethod cenv eenv ilThisTy m =
let g = cenv.g
- [ match (eenv.valsInScope.TryFind g.sprintf_vref.Deref,
- eenv.valsInScope.TryFind g.new_format_vref.Deref) with
+ [ match (eenv.valsInScope.TryFind cenv.g.sprintf_vref.Deref,
+ eenv.valsInScope.TryFind cenv.g.new_format_vref.Deref) with
| Some(Lazy(Method(_, _, sprintfMethSpec, _, _, _, _))), Some(Lazy(Method(_, _, newFormatMethSpec, _, _, _, _))) ->
// The type returned by the 'sprintf' call
let funcTy = EraseClosures.mkILFuncTy g.ilxPubCloEnv ilThisTy g.ilg.typ_String
@@ -6667,18 +6668,18 @@ and GenToStringMethod cenv eenv ilThisTy m =
[// 'T -> string'
funcTy
// rest follow from 'StringFormat'
- GenUnitTy cenv eenv m
- g.ilg.typ_String
- g.ilg.typ_String
+ GenUnitTy cenv eenv m
+ g.ilg.typ_String
+ g.ilg.typ_String
ilThisTy], [])
// Instantiate with our own type
let sprintfMethSpec = mkILMethSpec(sprintfMethSpec.MethodRef, AsObject, [], [funcTy])
// Here's the body of the method. Call printf, then invoke the function it returns
let callInstrs = EraseClosures.mkCallFunc g.ilxPubCloEnv (fun _ -> 0us) eenv.tyenv.Count Normalcall (Apps_app(ilThisTy, Apps_done g.ilg.typ_String))
- let mdef =
+ let mdef =
mkILNonGenericVirtualMethod ("ToString", ILMemberAccess.Public, [],
mkILReturn g.ilg.typ_String,
- mkMethodBody (true, [], 2, nonBranchingInstrsToCode
+ mkMethodBody (true, [], 2, nonBranchingInstrsToCode
([ // load the hardwired format string
yield I_ldstr "%+A"
// make the printf format object
@@ -6708,7 +6709,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
| TAsmRepr _ | TILObjectRepr _ | TMeasureableRepr _ -> ()
| TFSharpObjectRepr _ | TRecdRepr _ | TUnionRepr _ ->
let eenvinner = ReplaceTyenv (TypeReprEnv.ForTycon tycon) eenv
- let thisTy = generalizedTyconRef tcref
+ let thisTy = generalizedTyOfTyconRef g tcref
let ilThisTy = GenType cenv.amap m eenvinner.tyenv thisTy
let tref = ilThisTy.TypeRef
@@ -6792,10 +6793,10 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let name = vref.DisplayName
match vref.MemberInfo with
| None -> None
- | Some memberInfo ->
- match name, memberInfo.MemberFlags.MemberKind with
- | ("Item" | "op_IndexedLookup"), (MemberKind.PropertyGet | MemberKind.PropertySet) when not (isNil (ArgInfosOfPropertyVal g vref.Deref)) ->
- Some( mkILCustomAttribute g.ilg (g.FindSysILTypeRef "System.Reflection.DefaultMemberAttribute", [g.ilg.typ_String], [ILAttribElem.String(Some name)], []) )
+ | Some memberInfo ->
+ match name, memberInfo.MemberFlags.MemberKind with
+ | ("Item" | "op_IndexedLookup"), (MemberKind.PropertyGet | MemberKind.PropertySet) when not (isNil (ArgInfosOfPropertyVal g vref.Deref)) ->
+ Some( mkILCustomAttribute g.ilg (g.FindSysILTypeRef "System.Reflection.DefaultMemberAttribute", [g.ilg.typ_String], [ILAttribElem.String(Some(name))], []) )
| _ -> None)
|> Option.toList
@@ -6805,8 +6806,9 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let debugDisplayAttrs, normalAttrs = tycon.Attribs |> List.partition (IsMatchingFSharpAttribute g g.attrib_DebuggerDisplayAttribute)
let securityAttrs, normalAttrs = normalAttrs |> List.partition (fun a -> IsSecurityAttribute g cenv.amap cenv.casApplied a m)
let generateDebugDisplayAttribute = not g.compilingFslib && tycon.IsUnionTycon && isNil debugDisplayAttrs
- let generateDebugProxies = (not (tyconRefEq g tcref g.unit_tcr_canon) &&
- not (HasFSharpAttribute g g.attrib_DebuggerTypeProxyAttribute tycon.Attribs))
+ let generateDebugProxies =
+ (not (tyconRefEq g tcref g.unit_tcr_canon) &&
+ not (HasFSharpAttribute g g.attrib_DebuggerTypeProxyAttribute tycon.Attribs))
let permissionSets = CreatePermissionSets cenv eenv securityAttrs
let secDecls = if List.isEmpty securityAttrs then emptyILSecurityDecls else mkILSecurityDecls permissionSets
@@ -6814,8 +6816,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let ilDebugDisplayAttributes =
[ yield! GenAttrs cenv eenv debugDisplayAttrs
if generateDebugDisplayAttribute then
- yield g.mkDebuggerDisplayAttribute ("{" + debugDisplayMethodName + "(),nq}") ]
-
+ yield g.mkDebuggerDisplayAttribute ("{" + debugDisplayMethodName + "(),nq}") ]
let ilCustomAttrs =
[ yield! defaultMemberAttrs
@@ -6847,9 +6848,9 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
tycon.AllFieldsArray |> Array.forall (fun f -> f.IsStatic)
isEmptyStruct && cenv.opts.workAroundReflectionEmitBugs && not tycon.TyparsNoRange.IsEmpty
-
+
// Compute a bunch of useful things for each field
- let isCLIMutable = (TryFindFSharpBoolAttribute g g.attrib_CLIMutableAttribute tycon.Attribs = Some true)
+ let isCLIMutable = (TryFindFSharpBoolAttribute g g.attrib_CLIMutableAttribute tycon.Attribs = Some true)
let fieldSummaries =
[ for fspec in tycon.AllFieldsArray do
@@ -6877,7 +6878,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let ilFieldOffset =
match TryFindFSharpAttribute g g.attrib_FieldOffsetAttribute fspec.FieldAttribs with
- | Some (Attrib(_, _, [ AttribInt32Arg fieldOffset ], _, _, _, _)) ->
+ | Some (Attrib(_, _, [ AttribInt32Arg fieldOffset ], _, _, _, _)) ->
Some fieldOffset
| Some (Attrib(_, _, _, _, _, _, m)) ->
errorR(Error(FSComp.SR.ilFieldOffsetAttributeCouldNotBeDecoded(), m))
@@ -6892,24 +6893,24 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
if useGenuineField then yield! fspec.PropertyAttribs
yield! fspec.FieldAttribs ]
-
+
let ilNotSerialized = HasFSharpAttributeOpt g g.attrib_NonSerializedAttribute attribs
-
- let fattribs =
+
+ let fattribs =
attribs
- // Do not generate FieldOffset as a true CLI custom attribute, since it is implied by other corresponding CLI metadata
- |> List.filter (IsMatchingFSharpAttribute g g.attrib_FieldOffsetAttribute >> not)
- // Do not generate NonSerialized as a true CLI custom attribute, since it is implied by other corresponding CLI metadata
- |> List.filter (IsMatchingFSharpAttributeOpt g g.attrib_NonSerializedAttribute >> not)
+ // Do not generate FieldOffset as a true CLI custom attribute, since it is implied by other corresponding CLI metadata
+ |> List.filter (IsMatchingFSharpAttribute g g.attrib_FieldOffsetAttribute >> not)
+ // Do not generate NonSerialized as a true CLI custom attribute, since it is implied by other corresponding CLI metadata
+ |> List.filter (IsMatchingFSharpAttributeOpt g g.attrib_NonSerializedAttribute >> not)
let ilFieldMarshal, fattribs = GenMarshal cenv fattribs
// The IL field is hidden if the property/field is hidden OR we're using a property AND the field is not mutable (because we can take the address of a mutable field).
// Otherwise fields are always accessed via their property getters/setters
let isFieldHidden = isPropHidden || (not useGenuineField && not isFSharpMutable)
-
- let extraAttribs =
- match tyconRepr with
+
+ let extraAttribs =
+ match tyconRepr with
| TRecdRepr _ when not useGenuineField -> [ g.DebuggerBrowsableNeverAttribute ] // hide fields in records in debug display
| _ -> [] // don't hide fields in classes in debug display
@@ -6933,13 +6934,13 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
.WithFieldMarshal(ilFieldMarshal)
yield fdef
- if requiresExtraField then
- yield mkILInstanceField("__dummy", g.ilg.typ_Int32, None, ILMemberAccess.Assembly) ]
-
- // Generate property definitions for the fields compiled as properties
- let ilPropertyDefsForFields =
+ if requiresExtraField then
+ yield mkILInstanceField ("__dummy", g.ilg.typ_Int32, None, ILMemberAccess.Assembly) ]
+
+ // Generate property definitions for the fields compiled as properties
+ let ilPropertyDefsForFields =
[ for (i, (useGenuineField, _, isFSharpMutable, isStatic, propAttribs, ilPropType, _, fspec)) in Seq.indexed fieldSummaries do
- if not useGenuineField then
+ if not useGenuineField then
let ilCallingConv = if isStatic then ILCallingConv.Static else ILCallingConv.Instance
let ilPropName = fspec.Name
let ilHasSetter = isCLIMutable || isFSharpMutable
@@ -6997,19 +6998,19 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
[// 'T -> string'
funcTy
// rest follow from 'StringFormat'
- GenUnitTy cenv eenv m
- g.ilg.typ_String
- g.ilg.typ_String
+ GenUnitTy cenv eenv m
+ g.ilg.typ_String
+ g.ilg.typ_String
g.ilg.typ_String], [])
// Instantiate with our own type
let sprintfMethSpec = mkILMethSpec(sprintfMethSpec.MethodRef, AsObject, [], [funcTy])
// Here's the body of the method. Call printf, then invoke the function it returns
let callInstrs = EraseClosures.mkCallFunc g.ilxPubCloEnv (fun _ -> 0us) eenv.tyenv.Count Normalcall (Apps_app(ilThisTy, Apps_done g.ilg.typ_String))
- let ilMethodDef = mkILNonGenericInstanceMethod (debugDisplayMethodName, ILMemberAccess.Assembly, [],
+ let ilMethodDef = mkILNonGenericInstanceMethod (debugDisplayMethodName,ILMemberAccess.Assembly, [],
mkILReturn g.ilg.typ_Object,
- mkMethodBody
+ mkMethodBody
(true, [], 2,
- nonBranchingInstrsToCode
+ nonBranchingInstrsToCode
([ // load the hardwired format string
yield I_ldstr "%+0.8A"
// make the printf format object
@@ -7058,10 +7059,11 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
// FSharp 3.0 feature: adding CLIMutable to a record type causes emit of default constructor, and all fields get property setters
// Records that are value types do not create a default constructor with CLIMutable or ComVisible
if not isStructRecord && (isCLIMutable || (TryFindFSharpBoolAttribute g g.attrib_ComVisibleAttribute tycon.Attribs = Some true)) then
- yield mkILSimpleStorageCtor(None, Some g.ilg.typ_Object.TypeSpec, ilThisTy, [], [], reprAccess)
-
+ yield mkILSimpleStorageCtor(None, Some g.ilg.typ_Object.TypeSpec, ilThisTy, [], [], reprAccess)
+
if not (tycon.HasMember g "ToString" []) then
yield! GenToStringMethod cenv eenv ilThisTy m
+
| TFSharpObjectRepr r when tycon.IsFSharpDelegateTycon ->
// Build all the methods that go with a delegate type
@@ -7077,9 +7079,9 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
| paraml -> paraml
GenActualSlotsig m cenv eenvinner (TSlotSig(nm, ty, ctps, mtps, paraml, returnTy)) [] []
yield! mkILDelegateMethods reprAccess g.ilg (g.iltyp_AsyncCallback, g.iltyp_IAsyncResult) (p, r)
- | _ ->
+ | _ ->
()
- | TUnionRepr _ when not (tycon.HasMember g "ToString" []) ->
+ | TUnionRepr _ when not (tycon.HasMember g "ToString" []) ->
yield! GenToStringMethod cenv eenv ilThisTy m
| _ -> () ]
@@ -7087,7 +7089,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let ilProperties = mkILProperties (ilPropertyDefsForFields @ abstractPropDefs)
let ilEvents = mkILEvents abstractEventDefs
let ilFields = mkILFields ilFieldDefs
-
+
let tdef, tdefDiscards =
let isSerializable = (TryFindFSharpBoolAttribute g g.attrib_AutoSerializableAttribute tycon.Attribs <> Some false)
@@ -7097,14 +7099,14 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let tdef = tdef.With(customAttrs = mkILCustomAttrs ilCustomAttrs, genericParams = ilGenParams)
tdef, None
- | TRecdRepr _ | TFSharpObjectRepr _ as tyconRepr ->
+ | TRecdRepr _ | TFSharpObjectRepr _ as tyconRepr ->
let super = superOfTycon g tycon
let ilBaseTy = GenType cenv.amap m eenvinner.tyenv super
// Build a basic type definition
let isObjectType = (match tyconRepr with TFSharpObjectRepr _ -> true | _ -> false)
- let ilAttrs =
- ilCustomAttrs @
+ let ilAttrs =
+ ilCustomAttrs @
[mkCompilationMappingAttr g
(int (if isObjectType
then SourceConstructFlags.ObjectType
@@ -7132,15 +7134,15 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
mkILMethods ilMethods, ilFields, emptyILTypeDefs, ilProperties, ilEvents, mkILCustomAttrs ilAttrs,
typeDefTrigger)
- // Set some the extra entries in the definition
+ // Set some the extra entries in the definition
let isTheSealedAttribute = tyconRefEq g tcref g.attrib_SealedAttribute.TyconRef
let tdef = tdef.WithSealed(isSealedTy g thisTy || isTheSealedAttribute).WithSerializable(isSerializable).WithAbstract(isAbstract).WithImport(isComInteropTy g thisTy)
let tdef = tdef.With(methodImpls=mkILMethodImpls methodImpls)
- let tdLayout, tdEncoding =
+ let tdLayout,tdEncoding =
match TryFindFSharpAttribute g g.attrib_StructLayoutAttribute tycon.Attribs with
- | Some (Attrib(_, _, [ AttribInt32Arg layoutKind ], namedArgs, _, _, _)) ->
+ | Some (Attrib(_, _, [ AttribInt32Arg(layoutKind) ], namedArgs, _, _, _)) ->
let decoder = AttributeDecoder namedArgs
let ilPack = decoder.FindInt32 "Pack" 0x0
let ilSize = decoder.FindInt32 "Size" 0x0
@@ -7218,8 +7220,8 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
cudAlternatives= alternatives
cudWhere = None}
- let layout =
- if isStructTy g thisTy then
+ let layout =
+ if isStructTy g thisTy then
if (match ilTypeDefKind with ILTypeDefKind.ValueType -> true | _ -> false) then
// Structs with no instance fields get size 1, pack 0
ILTypeDefLayout.Sequential { Size=Some 1; Pack=Some 0us }
@@ -7228,8 +7230,8 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
else
ILTypeDefLayout.Auto
- let cattrs =
- mkILCustomAttrs (ilCustomAttrs @
+ let cattrs =
+ mkILCustomAttrs (ilCustomAttrs @
[mkCompilationMappingAttr g
(int (if hiddenRepr
then SourceConstructFlags.SumType ||| SourceConstructFlags.NonPublicRepresentation
@@ -7257,9 +7259,9 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
.WithInitSemantics(ILTypeInit.BeforeField)
let tdef2 = g.eraseClassUnionDef tref tdef cuinfo
-
- // Discard the user-supplied (i.e. prim-type.fs) implementations of the get_Empty, get_IsEmpty, get_Value and get_None and Some methods.
- // This is because we will replace their implementations by ones that load the unique
+
+ // Discard the user-supplied (i.e. prim-type.fs) implementations of the get_Empty, get_IsEmpty, get_Value and get_None and Some methods.
+ // This is because we will replace their implementations by ones that load the unique
// private static field for lists etc.
//
// Also discard the F#-compiler supplied implementation of the Empty, IsEmpty, Value and None properties.
@@ -7294,7 +7296,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
/// Generate the type for an F# exception declaration.
and GenExnDef cenv mgbuf eenv m (exnc: Tycon) =
let g = cenv.g
- let exncref = mkLocalEntityRef exnc
+ let exncref = mkLocalEntityRef exnc
match exnc.ExceptionInfo with
| TExnAbbrevRepr _ | TExnAsmRepr _ | TExnNone -> ()
| TExnFresh _ ->
@@ -7323,27 +7325,27 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) =
init = None,
args = [],
customAttrs=mkILCustomAttrs (GenAttrs cenv eenv fld.PropertyAttribs @ [mkCompilationMappingAttrWithSeqNum g (int SourceConstructFlags.Field) i]))
- yield (ilMethodDef, ilFieldDef, ilPropDef, (ilPropName, ilFieldName, ilPropType)) ]
+ yield (ilMethodDef, ilFieldDef, ilPropDef, (ilPropName, ilFieldName, ilPropType)) ]
|> List.unzip4
- let ilCtorDef =
- mkILSimpleStorageCtorWithParamNames(None, Some g.iltyp_Exception.TypeSpec, ilThisTy, [], ChooseParamNames fieldNamesAndTypes, reprAccess)
+ let ilCtorDef =
+ mkILSimpleStorageCtorWithParamNames(None, Some g.iltyp_Exception.TypeSpec, ilThisTy, [], ChooseParamNames fieldNamesAndTypes, reprAccess)
// In compiled code, all exception types get a parameterless constructor for use with XML serialization
// This does default-initialization of all fields
- let ilCtorDefNoArgs =
- if not (isNil fieldNamesAndTypes) then
+ let ilCtorDefNoArgs =
+ if not (isNil fieldNamesAndTypes) then
[ mkILSimpleStorageCtor(None, Some g.iltyp_Exception.TypeSpec, ilThisTy, [], [], reprAccess) ]
else
[]
let serializationRelatedMembers =
// do not emit serialization related members if target framework lacks SerializationInfo or StreamingContext
- match g.iltyp_SerializationInfo, g.iltyp_StreamingContext with
- | Some serializationInfoType, Some streamingContextType ->
- let ilCtorDefForSerialziation =
+ match g.iltyp_SerializationInfo, g.iltyp_StreamingContext with
+ | Some serializationInfoType, Some streamingContextType ->
+ let ilCtorDefForSerialziation =
mkILCtor(ILMemberAccess.Family,
- [mkILParamNamed("info", serializationInfoType);mkILParamNamed("context", streamingContextType)],
+ [mkILParamNamed("info", serializationInfoType); mkILParamNamed("context", streamingContextType)],
mkMethodBody
(false, [], 8,
nonBranchingInstrsToCode
@@ -7352,7 +7354,7 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) =
mkLdarg 2us
mkNormalCall (mkILCtorMethSpecForTy (g.iltyp_Exception, [serializationInfoType; streamingContextType])) ],
None))
-
+
//#if BE_SECURITY_TRANSPARENT
[ilCtorDefForSerialziation]
//#else
diff --git a/src/fsharp/InfoReader.fs b/src/fsharp/InfoReader.fs
index 7e9dffdd52b..f0b403b62c0 100644
--- a/src/fsharp/InfoReader.fs
+++ b/src/fsharp/InfoReader.fs
@@ -19,6 +19,10 @@ open FSharp.Compiler.Tast
open FSharp.Compiler.Tastops
open FSharp.Compiler.TcGlobals
+#if !NO_EXTENSIONTYPING
+open FSharp.Compiler.ExtensionTyping
+#endif
+
/// Use the given function to select some of the member values from the members of an F# type
let private SelectImmediateMemberVals g optFilter f (tcref: TyconRef) =
let chooser (vref: ValRef) =
@@ -145,8 +149,8 @@ let rec GetImmediateIntrinsicPropInfosOfTypeAux (optFilter, ad) g amap m origTy
match optFilter with
| Some name ->
match st.PApply((fun st -> st.GetProperty name), m) with
- | Tainted.Null -> [||]
- | pi -> [|pi|]
+ | Tainted.Null -> [||]
+ | Tainted.NonNull pi -> [|pi|]
| None ->
st.PApplyArray((fun st -> st.GetProperties()), "GetProperties", m)
matchingProps
@@ -188,7 +192,7 @@ let IsIndexerType g amap ty =
isListTy g ty ||
match tryDestAppTy g ty with
| ValueSome tcref ->
- let _, entityTy = generalizeTyconRef tcref
+ let entityTy = generalizedTyOfTyconRef g tcref
let props = GetImmediateIntrinsicPropInfosOfType (None, AccessibleFromSomeFSharpCode) g amap range0 entityTy
props |> List.exists (fun x -> x.PropertyName = "Item")
| ValueNone -> false
@@ -220,8 +224,8 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) =
[ for fi in st.PApplyArray((fun st -> st.GetFields()), "GetFields", m) -> ProvidedField(amap, fi, m) ]
| Some name ->
match st.PApply ((fun st -> st.GetField name), m) with
- | Tainted.Null -> []
- | fi -> [ ProvidedField(amap, fi, m) ]
+ | Tainted.Null -> []
+ | Tainted.NonNull fi -> [ ProvidedField(amap, fi, m) ]
#endif
| ILTypeMetadata _ ->
let tinfo = ILTypeInfo.FromType g ty
@@ -245,8 +249,8 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) =
[ for ei in st.PApplyArray((fun st -> st.GetEvents()), "GetEvents", m) -> ProvidedEvent(amap, ei, m) ]
| Some name ->
match st.PApply ((fun st -> st.GetEvent name), m) with
- | Tainted.Null -> []
- | ei -> [ ProvidedEvent(amap, ei, m) ]
+ | Tainted.Null -> []
+ | Tainted.NonNull ei -> [ ProvidedEvent(amap, ei, m) ]
#endif
| ILTypeMetadata _ ->
let tinfo = ILTypeInfo.FromType g ty
@@ -343,7 +347,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) =
// a decent hash function for these.
canMemoize=(fun (_flags, (_: range), ty) ->
match stripTyEqns g ty with
- | TType_app(tcref, []) -> tcref.TypeContents.tcaug_closed
+ | TType_app(tcref, [], _nullness) -> tcref.TypeContents.tcaug_closed // TODO NULLNESS: consider whether ignoring _nullness is valid here
| _ -> false),
keyComparer=
@@ -352,13 +356,13 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) =
// Ignoring the ranges - that's OK.
flagsEq.Equals(flags1, flags2) &&
match stripTyEqns g typ1, stripTyEqns g typ2 with
- | TType_app(tcref1, []), TType_app(tcref2, []) -> tyconRefEq g tcref1 tcref2
+ | TType_app(tcref1, [], _nullness1),TType_app(tcref2, [], _nullness2) -> tyconRefEq g tcref1 tcref2 // TODO NULLNESS: consider whether ignoring _nullness is valid here
| _ -> false
member x.GetHashCode((flags, _, ty)) =
// Ignoring the ranges - that's OK.
flagsEq.GetHashCode flags +
(match stripTyEqns g ty with
- | TType_app(tcref, []) -> hash tcref.LogicalName
+ | TType_app(tcref, [], _nullness1) -> hash tcref.LogicalName // TODO NULLNESS: consider whether ignoring _nullness is valid here
| _ -> 0) })
@@ -733,8 +737,8 @@ let GetSigOfFunctionForDelegate (infoReader: InfoReader) delty m ad =
| _ -> compiledViewOfDelArgTys
let delRetTy = invokeMethInfo.GetFSharpReturnTy(amap, m, minst)
CheckMethInfoAttributes g m None invokeMethInfo |> CommitOperationResult
- let fty = mkIteratedFunTy fsharpViewOfDelArgTys delRetTy
- SigOfFunctionForDelegate(invokeMethInfo, compiledViewOfDelArgTys, delRetTy, fty)
+ let fty = mkIteratedFunTy g fsharpViewOfDelArgTys delRetTy
+ SigOfFunctionForDelegate(invokeMethInfo,compiledViewOfDelArgTys, delRetTy, fty)
/// Try and interpret a delegate type as a "standard" .NET delegate type associated with an event, with a "sender" parameter.
let TryDestStandardDelegateType (infoReader: InfoReader) m ad delTy =
diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fs b/src/fsharp/InnerLambdasToTopLevelFuncs.fs
index 1ff7ed3c7c1..d2f2e03df88 100644
--- a/src/fsharp/InnerLambdasToTopLevelFuncs.fs
+++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fs
@@ -843,7 +843,7 @@ let CreateNewValuesForTLR g tlrS arityM fclassM envPackM =
let newTps = envp.ep_etps @ tps
let fHatTy =
let newArgtys = List.map typeOfVal envp.ep_aenvs @ argtys
- mkLambdaTy newTps newArgtys res
+ mkLambdaTy g newTps newArgtys res
let fHatArity = MakeSimpleArityInfo newTps (envp.ep_aenvs.Length + wf)
let fHatName = globalNng.FreshCompilerGeneratedName(name, m)
@@ -987,8 +987,8 @@ module Pass4_RewriteAssembly =
(* REVIEW: is this mutation really, really necessary? *)
(* Why are we applying TLR if the thing already has an arity? *)
let fOrig = setValHasNoArity fOrig
- let fBind =
- mkMultiLambdaBind fOrig letSeqPtOpt m tps vss
+ let fBind =
+ mkMultiLambdaBind penv.g fOrig letSeqPtOpt m tps vss
(mkApps penv.g
((exprForVal m fHat, fHat.Type),
[List.map mkTyparTy (envp.ep_etps @ tps)],
@@ -1003,17 +1003,17 @@ module Pass4_RewriteAssembly =
// Don't take all the variables - only up to length wf
let vssTake, vssDrop = List.splitAt wf vss
// put the variables back on
- let b, rty = mkMultiLambdasCore b.Range vssDrop (b, rty)
- // fHat, args
+ let b, rty = mkMultiLambdasCore penv.g b.Range vssDrop (b, rty)
+ // fHat, args
let m = fHat.Range
// Add the type variables to the front
let fHat_tps = envp.ep_etps @ tps
// Add the 'aenv' and original taken variables to the front
let fHat_args = List.map List.singleton envp.ep_aenvs @ vssTake
- let fHat_body = mkLetsFromBindings m envp.ep_unpack b
- let fHat_body = mkLetsFromBindings m shortRecBinds fHat_body // bind "f" if have short recursive calls (somewhere)
- // fHat binding, f rebinding
- let fHatBind = mkMultiLambdaBind fHat letSeqPtOpt m fHat_tps fHat_args (fHat_body, rty)
+ let fHat_body = mkLetsFromBindings m envp.ep_unpack b
+ let fHat_body = mkLetsFromBindings m shortRecBinds fHat_body // bind "f" if have short recursive calls (somewhere)
+ // fHat binding, f rebinding
+ let fHatBind = mkMultiLambdaBind penv.g fHat letSeqPtOpt m fHat_tps fHat_args (fHat_body,rty)
fHatBind
let rebinds = binds |> List.map fRebinding
let shortRecBinds = rebinds |> List.filter (fun b -> penv.recShortCallS.Contains(b.Var))
diff --git a/src/fsharp/LegacyHostedCompilerForTesting.fs b/src/fsharp/LegacyHostedCompilerForTesting.fs
index b793915b5c8..ccc4cb9c406 100644
--- a/src/fsharp/LegacyHostedCompilerForTesting.fs
+++ b/src/fsharp/LegacyHostedCompilerForTesting.fs
@@ -136,12 +136,15 @@ type internal FscCompiler(legacyReferenceResolver) =
fun arg -> regex.IsMatch(arg)
/// do compilation as if args was argv to fsc.exe
- member this.Compile(args : string array) =
+ member this.Compile(args : string[]) =
// args.[0] is later discarded, assuming it is just the path to fsc.
// compensate for this in case caller didn't know
let args =
+ match box args with
+ | null -> [|"fsc"|]
+ | _ ->
match args with
- | [||] | null -> [|"fsc"|]
+ | [||] -> [|"fsc"|]
| a when not <| fscExeArg a.[0] -> Array.append [|"fsc"|] a
| _ -> args
diff --git a/src/fsharp/LexFilter.fs b/src/fsharp/LexFilter.fs
index 7cfdbcf494a..0bf2e8a13ef 100755
--- a/src/fsharp/LexFilter.fs
+++ b/src/fsharp/LexFilter.fs
@@ -864,6 +864,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer,
if isAdjacent tokenTup lookaheadTokenTup then
let stack = ref []
let rec scanAhead nParen =
+ assert (nParen >= 0)
let lookaheadTokenTup = popNextTokenTup()
let lookaheadToken = lookaheadTokenTup.Token
stack := (lookaheadTokenTup, true) :: !stack
@@ -877,6 +878,26 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer,
scanAhead nParen
else
false
+ | INFIX_COMPARE_OP "?>" ->
+ // just smash the token immediately
+ stack := (!stack).Tail
+ delayToken (lookaheadTokenTup.UseShiftedLocation(GREATER false, 1, 0))
+ delayToken (lookaheadTokenTup.UseShiftedLocation(QMARK, 0, -1))
+ scanAhead nParen
+ | INFIX_COMPARE_OP ">?>" ->
+ // just smash the token immediately
+ stack := (!stack).Tail
+ delayToken (lookaheadTokenTup.UseShiftedLocation(GREATER false, 2, 0))
+ delayToken (lookaheadTokenTup.UseShiftedLocation(QMARK, 1, -1))
+ delayToken (lookaheadTokenTup.UseShiftedLocation(GREATER false, 0, -2))
+ scanAhead nParen
+ | INFIX_COMPARE_OP "?>>" ->
+ // just smash the token immediately
+ stack := (!stack).Tail
+ delayToken (lookaheadTokenTup.UseShiftedLocation(GREATER false, 2, 0))
+ delayToken (lookaheadTokenTup.UseShiftedLocation(GREATER false, 1, -1))
+ delayToken (lookaheadTokenTup.UseShiftedLocation(QMARK, 0, -2))
+ scanAhead nParen
| GREATER _ | GREATER_RBRACK | GREATER_BAR_RBRACK ->
let nParen = nParen - 1
let hasAfterOp = (match lookaheadToken with GREATER _ -> false | _ -> true)
@@ -922,7 +943,9 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer,
// f<{| C : int |}>x
// fx
// fx
+ // fx
| DEFAULT | COLON | COLON_GREATER | STRUCT | NULL | DELEGATE | AND | WHEN
+ | QMARK | HACKNULL | AMBIVALENT
| DOT_DOT
| NEW
| LBRACE_BAR
diff --git a/src/fsharp/MSBuildReferenceResolver.fs b/src/fsharp/MSBuildReferenceResolver.fs
index 1a49c6a0fca..584b67a98c4 100644
--- a/src/fsharp/MSBuildReferenceResolver.fs
+++ b/src/fsharp/MSBuildReferenceResolver.fs
@@ -76,7 +76,7 @@ module internal FSharp.Compiler.MSBuildReferenceResolver
/// Get the path to the .NET Framework implementation assemblies by using ToolLocationHelper.GetPathToDotNetFramework
/// This is only used to specify the "last resort" path for assembly resolution.
- let GetPathToDotNetFrameworkImlpementationAssemblies(v) =
+ let GetPathToDotNetFrameworkImlpementationAssemblies(v) : string list =
let v =
match v with
| Net45 -> Some TargetDotNetFrameworkVersion.Version45
@@ -95,7 +95,7 @@ module internal FSharp.Compiler.MSBuildReferenceResolver
| Some v ->
match ToolLocationHelper.GetPathToDotNetFramework v with
| null -> []
- | x -> [x]
+ | NonNull x -> [x]
| _ -> []
let GetPathToDotNetFrameworkReferenceAssemblies(version) =
diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs
index 912a4035280..9e700ad0659 100644
--- a/src/fsharp/MethodCalls.fs
+++ b/src/fsharp/MethodCalls.fs
@@ -332,13 +332,16 @@ type CalledMeth<'T>
match epinfos with
| [pinfo] when pinfo.HasSetter && not pinfo.IsIndexer ->
let pminfo = pinfo.SetterMethod
- let pminst = match minfo with
- | MethInfo.FSMeth(_, TType.TType_app(_, types), _, _) -> types
- | _ -> freshenMethInfo m pminfo
+ let pminst =
+ match minfo with
+ | MethInfo.FSMeth(_, TType_app(_, types, _), _, _) -> types
+ | _ -> freshenMethInfo m pminfo
+
+ let pminst =
+ match tyargsOpt with
+ | Some (TType_app(_, types, _)) -> types
+ | _ -> pminst
- let pminst = match tyargsOpt with
- | Some(TType.TType_app(_, types)) -> types
- | _ -> pminst
Choice1Of2(AssignedItemSetter(id, AssignedPropSetter(pinfo, pminfo, pminst), e))
| _ ->
match infoReader.GetILFieldInfosOfType(Some(nm), ad, m, returnedObjTy) with
@@ -705,7 +708,7 @@ let MakeMethInfoCall amap m minfo minst args =
let isProp = false // not necessarily correct, but this is only used post-creflect where this flag is irrelevant
let ilMethodRef = Import.ImportProvidedMethodBaseAsILMethodRef amap m mi
let isConstructor = mi.PUntaint((fun c -> c.IsConstructor), m)
- let valu = mi.PUntaint((fun c -> c.DeclaringType.IsValueType), m)
+ let valu = mi.PUntaint((fun c -> (nonNull c.DeclaringType).IsValueType), m)
let actualTypeInst = [] // GENERIC TYPE PROVIDERS: for generics, we would have something here
let actualMethInst = [] // GENERIC TYPE PROVIDERS: for generics, we would have something here
let ilReturnTys = Option.toList (minfo.GetCompiledReturnTy(amap, m, [])) // GENERIC TYPE PROVIDERS: for generics, we would have more here
@@ -718,7 +721,7 @@ let MakeMethInfoCall amap m minfo minst args =
// This imports a provided method, and checks if it is a known compiler intrinsic like "1 + 2"
let TryImportProvidedMethodBaseAsLibraryIntrinsic (amap: Import.ImportMap, m: range, mbase: Tainted) =
let methodName = mbase.PUntaint((fun x -> x.Name), m)
- let declaringType = Import.ImportProvidedType amap m (mbase.PApply((fun x -> x.DeclaringType), m))
+ let declaringType = Import.ImportProvidedType amap m (mbase.PApply((fun x -> nonNull x.DeclaringType), m))
if isAppTy amap.g declaringType then
let declaringEntity = tcrefOfAppTy amap.g declaringType
if not declaringEntity.IsLocalRef && ccuEq declaringEntity.nlr.Ccu amap.g.fslibCcu then
@@ -820,8 +823,14 @@ let BuildMethodCall tcVal g amap isMutable m isProp minfo valUseFlags minst objA
// Build a 'call' to a struct default constructor
| DefaultStructCtor (g, ty) ->
- if not (TypeHasDefaultValue g m ty) then
- errorR(Error(FSComp.SR.tcDefaultStructConstructorCall(), m))
+ if g.langFeatureNullness then
+ if not (TypeHasDefaultValueNew g m ty) && not (TypeHasDefaultValueOld g m ty) then
+ errorR(Error(FSComp.SR.tcDefaultStructConstructorCall(), m))
+ if g.checkNullness && not (TypeHasDefaultValueNew g m ty) then
+ warning(Error(FSComp.SR.tcDefaultStructConstructorCallNulls(), m))
+ else
+ if not (TypeHasDefaultValueOld g m ty) then
+ errorR(Error(FSComp.SR.tcDefaultStructConstructorCall(), m))
mkDefault (m, ty), ty)
//-------------------------------------------------------------------------
@@ -948,7 +957,7 @@ module ProvidedMethodCalls =
st.PApply((fun st ->
match st.BaseType with
| null -> ProvidedType.CreateNoContext(typeof) // it might be an interface
- | st -> st), m)
+ | NonNull st -> st), m)
loop baseType
else
if isGeneric then
@@ -987,7 +996,7 @@ module ProvidedMethodCalls =
let fail() = error(Error(FSComp.SR.etUnsupportedProvidedExpression(ea.PUntaint((fun etree -> etree.UnderlyingExpressionString), m)), m))
match ea with
| Tainted.Null -> error(Error(FSComp.SR.etNullProvidedExpression(ea.TypeProviderDesignation), m))
- | _ ->
+ | Tainted.NonNull ea ->
match ea.PApplyOption((function ProvidedTypeAsExpr x -> Some x | _ -> None), m) with
| Some info ->
let (expr, targetTy) = info.PApply2(id, m)
@@ -1110,7 +1119,7 @@ module ProvidedMethodCalls =
let vsT = List.map addVar vs
let delegateBodyExprT = exprToExpr delegateBodyExpr
List.iter removeVar vs
- let lambdaExpr = mkLambdas m [] vsT (delegateBodyExprT, tyOfExpr g delegateBodyExprT)
+ let lambdaExpr = mkLambdas g m [] vsT (delegateBodyExprT, tyOfExpr g delegateBodyExprT)
let lambdaExprTy = tyOfExpr g lambdaExpr
let infoReader = InfoReader(g, amap)
let exprT = CoerceFromFSharpFuncToDelegate g amap infoReader AccessorDomain.AccessibleFromSomewhere lambdaExprTy m lambdaExpr delegateTyT
@@ -1251,7 +1260,7 @@ module ProvidedMethodCalls =
let thisArg, paramVars =
match objArgs with
| [objArg] ->
- let erasedThisTy = eraseSystemType (amap, m, mi.PApply((fun mi -> mi.DeclaringType), m))
+ let erasedThisTy = eraseSystemType (amap, m, mi.PApply((fun mi -> nonNull mi.DeclaringType), m))
let thisVar = erasedThisTy.PApply((fun ty -> ProvidedVar.Fresh("this", ty)), m)
Some objArg, Array.append [| thisVar |] paramVars
| [] -> None, paramVars
@@ -1271,7 +1280,7 @@ module ProvidedMethodCalls =
methInfoOpt, expr, exprty
with
| :? TypeProviderError as tpe ->
- let typeName = mi.PUntaint((fun mb -> mb.DeclaringType.FullName), m)
+ let typeName = mi.PUntaint((fun mb -> (nonNull mb.DeclaringType).FullName), m)
let methName = mi.PUntaint((fun mb -> mb.Name), m)
raise( tpe.WithContext(typeName, methName) ) // loses original stack trace
#endif
@@ -1302,7 +1311,7 @@ let MethInfoChecks g amap isInstance tyargsOpt objArgs ad m (minfo: MethInfo) =
match objArgs, ad with
| [objArg], AccessibleFrom(paths, Some tcref) ->
let objArgTy = tyOfExpr g objArg
- let ty = generalizedTyconRef tcref
+ let ty = generalizedTyOfTyconRef g tcref
// We get to keep our rights if the type we're in subsumes the object argument type
if TypeFeasiblySubsumesType 0 g amap m ty CanCoerce objArgTy then
ad
diff --git a/src/fsharp/MethodOverrides.fs b/src/fsharp/MethodOverrides.fs
index c621706b9b8..c689ecd7270 100644
--- a/src/fsharp/MethodOverrides.fs
+++ b/src/fsharp/MethodOverrides.fs
@@ -235,7 +235,7 @@ module DispatchSlotChecking =
let OverrideImplementsDispatchSlot g amap m dispatchSlot availPriorOverride =
IsExactMatch g amap m dispatchSlot availPriorOverride &&
// The override has to actually be in some subtype of the dispatch slot
- ExistsHeadTypeInEntireHierarchy g amap m (generalizedTyconRef availPriorOverride.BoundingTyconRef) dispatchSlot.DeclaringTyconRef
+ ExistsHeadTypeInEntireHierarchy g amap m (generalizedTyOfTyconRef g availPriorOverride.BoundingTyconRef) dispatchSlot.DeclaringTyconRef
/// Check if a dispatch slot is already implemented
let DispatchSlotIsAlreadyImplemented g amap m availPriorOverridesKeyed (dispatchSlot: MethInfo) =
@@ -417,7 +417,7 @@ module DispatchSlotChecking =
// dispatch slots are ordered from the derived classes to base
// so we can check the topmost dispatch slot if it is final
match dispatchSlots with
- | meth :: _ when meth.IsFinal -> errorR(Error(FSComp.SR.tcCannotOverrideSealedMethod((sprintf "%s::%s" (meth.ApparentEnclosingType.ToString()) (meth.LogicalName))), m))
+ | meth::_ when meth.IsFinal -> errorR(Error(FSComp.SR.tcCannotOverrideSealedMethod((sprintf "%s::%s" (NicePrint.stringOfTy denv meth.ApparentEnclosingType) meth.LogicalName)), m))
| _ -> ()
@@ -568,7 +568,7 @@ module DispatchSlotChecking =
let tcaug = tycon.TypeContents
let interfaces = tycon.ImmediateInterfacesOfFSharpTycon |> List.map (fun (ity, _compgen, m) -> (ity, m))
- let overallTy = generalizedTyconRef (mkLocalTyconRef tycon)
+ let overallTy = generalizedTyOfTyconRef g (mkLocalTyconRef tycon)
let allReqdTys = (overallTy, tycon.Range) :: interfaces
diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs
index 8a9b46298d4..d59aa32d124 100644
--- a/src/fsharp/NameResolution.fs
+++ b/src/fsharp/NameResolution.fs
@@ -115,9 +115,9 @@ let ActivePatternElemsOfModuleOrNamespace (modref: ModuleOrNamespaceRef) : NameM
/// Detect a use of a nominal type, including type abbreviations.
///
/// When reporting symbols, we care about abbreviations, e.g. 'int' and 'int32' count as two separate symbols
-let (|AbbrevOrAppTy|_|) (ty: TType) =
- match stripTyparEqns ty with
- | TType_app (tcref, _) -> Some tcref
+let (|AbbrevOrAppTy|_|) (ty: TType) =
+ match stripTyparEqns ty with
+ | TType_app (tcref, _, _) -> Some tcref
| _ -> None
[]
@@ -427,8 +427,8 @@ let private GetCSharpStyleIndexedExtensionMembersForTyconRef (amap: Import.Impor
// Type must be non-generic and have 'Extension' attribute
if isNil(tcrefOfStaticClass.Typars m) && TyconRefHasAttribute g m g.attrib_ExtensionAttribute tcrefOfStaticClass then
let pri = NextExtensionMethodPriority()
- let ty = generalizedTyconRef tcrefOfStaticClass
-
+ let ty = generalizedTyOfTyconRef g tcrefOfStaticClass
+
// Get the 'plain' methods, not interpreted as extension methods
let minfos = GetImmediateIntrinsicMethInfosOfType (None, AccessorDomain.AccessibleFromSomeFSharpCode) g amap m ty
[ for minfo in minfos do
@@ -580,10 +580,9 @@ let AddActivePatternResultTagsToNameEnv (apinfo: PrettyNaming.ActivePatternInfo)
||> List.foldBack (fun (j, nm) acc -> acc.Add(nm, Item.ActivePatternResult(apinfo, ty, j, m))) }
/// Generalize a union case, from Cons --> List.Cons
-let GeneralizeUnionCaseRef (ucref: UnionCaseRef) =
- UnionCaseInfo (fst (generalizeTyconRef ucref.TyconRef), ucref)
-
-
+let GeneralizeUnionCaseRef (ucref: UnionCaseRef) =
+ UnionCaseInfo (generalTyconRefInst ucref.TyconRef, ucref)
+
/// Add type definitions to the sub-table of the environment indexed by name and arity
let AddTyconsByDemangledNameAndArity (bulkAddMode: BulkAdd) (tcrefs: TyconRef[]) (tab: LayeredMap) =
if tcrefs.Length = 0 then tab else
@@ -665,11 +664,11 @@ let private AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition (g: TcGlobals)
// This may explore into an unreferenced assembly if the name
// is a type abbreviation. If it does, assume the name does not
// have a constructor.
- let mayHaveConstruction =
- protectAssemblyExploration
- false
- (fun () ->
- let ty = generalizedTyconRef tcref
+ let mayHaveConstruction =
+ protectAssemblyExploration
+ false
+ (fun () ->
+ let ty = generalizedTyOfTyconRef g tcref
isClassTy g ty || isStructTy g ty)
if mayHaveConstruction then
@@ -854,7 +853,7 @@ let AddDeclaredTyparsToNameEnv check nenv typars =
/// a fresh set of inference type variables for the type parameters of the union type.
let FreshenTycon (ncenv: NameResolver) m (tcref: TyconRef) =
let tinst = ncenv.InstantiationGenerator m (tcref.Typars m)
- let improvedTy = ncenv.g.decompileType tcref tinst
+ let improvedTy = ncenv.g.decompileType tcref tinst ncenv.g.knownWithoutNull
improvedTy
/// Convert a reference to a union case into a UnionCaseInfo that includes
@@ -1132,7 +1131,7 @@ let ResolveProvidedTypeNameInEntity (amap, m, typeName, modref: ModuleOrNamespac
//if staticResInfo.NumStaticArgs > 0 then
// error(Error(FSComp.SR.etNestedProvidedTypesDoNotTakeStaticArgumentsOrGenericParameters(), m))
[]
- | nestedSty ->
+ | Tainted.NonNull nestedSty ->
[AddEntityForProvidedType (amap, modref, resolutionEnvironment, nestedSty, m) ]
| _ -> []
#endif
@@ -1386,7 +1385,7 @@ let ItemsAreEffectivelyEqual g orig other =
nm1 = nm2 &&
(typeEquiv g (mkTyparTy tp1) (mkTyparTy tp2) ||
match stripTyparEqns (mkTyparTy tp1), stripTyparEqns (mkTyparTy tp2) with
- | TType_var tp1, TType_var tp2 ->
+ | TType_var (tp1, _), TType_var (tp2, _) ->
not tp1.IsCompilerGenerated && not tp1.IsFromError &&
not tp2.IsCompilerGenerated && not tp2.IsFromError &&
Range.equals tp1.Range tp2.Range
@@ -3731,10 +3730,13 @@ let rec ResolvePartialLongIdentInType (ncenv: NameResolver) nenv isApplicableMet
// e.g. ..
(rfinfos |> List.collect (fun x -> x.FieldType |> ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad false rest)) @
- // e.g. ..
- let FullTypeOfPinfo(pinfo: PropInfo) =
- let rty = pinfo.GetPropertyType(amap, m)
- let rty = if pinfo.IsIndexer then mkRefTupledTy g (pinfo.GetParamTypes(amap, m)) --> rty else rty
+ // e.g. ..
+ let FullTypeOfPinfo (pinfo: PropInfo) =
+ let rty = pinfo.GetPropertyType(amap, m)
+ let rty =
+ if pinfo.IsIndexer then
+ mkFunTy g (mkRefTupledTy g (pinfo.GetParamTypes(amap, m))) rty
+ else rty
rty
(ty
@@ -3921,10 +3923,11 @@ let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv is
@ (LookupTypeNameInEntityNoArity m id modref.ModuleOrNamespaceType
|> List.collect (fun tycon ->
- let tcref = modref.NestedTyconRef tycon
- if not (IsTyconUnseenObsoleteSpec ad g ncenv.amap m tcref allowObsolete) then
- tcref |> generalizedTyconRef |> ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad true rest
- else
+ let tcref = modref.NestedTyconRef tycon
+ if not (IsTyconUnseenObsoleteSpec ad g ncenv.amap m tcref allowObsolete) then
+ let ty = generalizedTyOfTyconRef g tcref
+ ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad true rest ty
+ else
[]))
/// Try to resolve a long identifier as type.
@@ -4176,8 +4179,8 @@ and ResolvePartialLongIdentToClassOrRecdFieldsImpl (ncenv: NameResolver) (nenv:
let recdFields =
nenv.eFieldLabels
|> Seq.collect (fun (KeyValue(_, v)) -> v)
- |> Seq.map (fun fref ->
- let typeInsts = fref.TyconRef.TyparsNoRange |> List.map (fun tyar -> tyar.AsType)
+ |> Seq.map (fun fref ->
+ let typeInsts = fref.TyconRef.TyparsNoRange |> List.map mkTyparTy
Item.RecdField(RecdFieldInfo(typeInsts, fref)))
|> List.ofSeq
@@ -4412,13 +4415,17 @@ let rec ResolvePartialLongIdentInTypeForItem (ncenv: NameResolver) nenv m ad sta
// e.g. ..
for rfinfo in rfinfos do
yield! ResolvePartialLongIdentInTypeForItem ncenv nenv m ad false rest item rfinfo.FieldType
-
- // e.g. ..
- let fullTypeOfPinfo (pinfo: PropInfo) =
- let rty = pinfo.GetPropertyType(amap, m)
- let rty = if pinfo.IsIndexer then mkRefTupledTy g (pinfo.GetParamTypes(amap, m)) --> rty else rty
- rty
-
+
+ // e.g. ..
+ let fullTypeOfPinfo (pinfo: PropInfo) =
+ let rty = pinfo.GetPropertyType(amap, m)
+ let rty =
+ if pinfo.IsIndexer then
+ mkFunTy g (mkRefTupledTy g (pinfo.GetParamTypes(amap, m))) rty
+ else
+ rty
+ rty
+
let pinfos =
ty
|> AllPropInfosOfTypeInScope ResultCollectionSettings.AllResults ncenv.InfoReader nenv (Some id) ad IgnoreOverrides m
@@ -4528,9 +4535,10 @@ let rec ResolvePartialLongIdentInModuleOrNamespaceForItem (ncenv: NameResolver)
| _ -> ()
for tycon in LookupTypeNameInEntityNoArity m id modref.ModuleOrNamespaceType do
- let tcref = modref.NestedTyconRef tycon
- if not (IsTyconUnseenObsoleteSpec ad g ncenv.amap m tcref true) then
- yield! tcref |> generalizedTyconRef |> ResolvePartialLongIdentInTypeForItem ncenv nenv m ad true rest item
+ let tcref = modref.NestedTyconRef tycon
+ if not (IsTyconUnseenObsoleteSpec ad g ncenv.amap m tcref true) then
+ let ty = tcref |> generalizedTyOfTyconRef g
+ yield! ResolvePartialLongIdentInTypeForItem ncenv nenv m ad true rest item ty
}
let rec PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThenLazy f plid (modref: ModuleOrNamespaceRef) =
diff --git a/src/fsharp/NicePrint.fs b/src/fsharp/NicePrint.fs
index ab45f12c137..fcc98ab0e6c 100644
--- a/src/fsharp/NicePrint.fs
+++ b/src/fsharp/NicePrint.fs
@@ -836,6 +836,8 @@ module private PrintTypes =
[layoutTypeAppWithInfoAndPrec denv env (WordL.keywordDelegate) 2 true [aty;bty] |> longConstraintPrefix]
| TyparConstraint.SupportsNull _ ->
[wordL (tagKeyword "null") |> longConstraintPrefix]
+ | TyparConstraint.NotSupportsNull _ ->
+ [(wordL (tagKeyword "not") ^^ wordL(tagKeyword "null")) |> longConstraintPrefix]
| TyparConstraint.IsNonNullableStruct _ ->
if denv.shortConstraints then
[wordL (tagText "value type")]
@@ -912,30 +914,40 @@ module private PrintTypes =
| [arg] -> layoutTypeWithInfoAndPrec denv env 2 arg ^^ tcL
| args -> bracketIfL (prec <= 1) (bracketL (layoutTypesWithInfoAndPrec denv env 2 (sepL (tagPunctuation ",")) args) --- tcL)
+ and layoutNullness part2 (nullness: Nullness) =
+ match nullness.Evaluate() with
+ | NullnessInfo.WithNull -> part2 ^^ rightL (tagText "?")
+ | NullnessInfo.WithoutNull -> part2
+ | NullnessInfo.AmbivalentToNull -> part2 // TODO NULLNESS: emit this optionally ^^ wordL (tagText "%")
+
/// Layout a type, taking precedence into account to insert brackets where needed
and layoutTypeWithInfoAndPrec denv env prec ty =
match stripTyparEqns ty with
- // Always prefer to format 'byref' as 'inref