]
+type Trace
type OptionalTrace =
| NoTrace
diff --git a/src/fsharp/DetupleArgs.fs b/src/fsharp/DetupleArgs.fs
index 640459eb3a0..1da56444ed3 100644
--- a/src/fsharp/DetupleArgs.fs
+++ b/src/fsharp/DetupleArgs.fs
@@ -227,13 +227,13 @@ module GlobalUsageAnalysis =
let logNonRecBinding z (bind:Binding) =
let v = bind.Var
let vs = FlatList.one v
- {z with RecursiveBindings = Zmap.add v (false,vs) z.RecursiveBindings;
+ {z with RecursiveBindings = Zmap.add v (false,vs) z.RecursiveBindings
Defns = Zmap.add v bind.Expr z.Defns }
/// Log the definition of a recursive binding
let logRecBindings z binds =
let vs = valsOfBinds binds
- {z with RecursiveBindings = (z.RecursiveBindings,vs) ||> FlatList.fold (fun mubinds v -> Zmap.add v (true,vs) mubinds);
+ {z with RecursiveBindings = (z.RecursiveBindings,vs) ||> FlatList.fold (fun mubinds v -> Zmap.add v (true,vs) mubinds)
Defns = (z.Defns,binds) ||> FlatList.fold (fun eqns bind -> Zmap.add bind.Var bind.Expr eqns) }
/// Work locally under a lambda of some kind
@@ -392,7 +392,7 @@ let rebuildTS g m ts vs =
(x,ty),vs
let (x,_ty),vs = rebuild vs ts
- if vs.Length <> 0 then internalError "rebuildTS: had more fringe vars than fringe. REPORT BUG" else ();
+ if vs.Length <> 0 then internalError "rebuildTS: had more fringe vars than fringe. REPORT BUG"
x
/// CallPattern is tuple-structure for each argument position.
@@ -794,7 +794,7 @@ let passBind penv (TBind(fOrig,repr,letSeqPtOpt) as bind) =
// fCBody - parts - formals
let transformedFormals = trans.transformedFormals
let p = transformedFormals.Length
- if (vss.Length < p) then internalError "passBinds: |vss|[,[,public|private]]"
optsDebugPM,"Emit debug information (Short form: -g)"
-optsDebug,"Specify debugging type: full, portable, pdbonly. ('full' is the default and enables attaching a debugger to a running program. 'portable' is a cross-platform format)."
+optsDebug,"Specify debugging type: full, portable, pdbonly. ('%s' is the default if no debuggging type specified and enables attaching a debugger to a running program. 'portable' is a cross-platform format)."
optsOptimize,"Enable optimizations (Short form: -O)"
optsTailcalls,"Enable or disable tailcalls"
optsCrossoptimize,"Enable or disable cross-module optimizations"
@@ -985,7 +986,7 @@ lexUnexpectedChar,"Unexpected character '%s'"
1153,lexInvalidFloat,"Invalid floating point number"
1154,lexOusideDecimal,"This number is outside the allowable range for decimal literals"
1155,lexOusideThirtyTwoBitFloat,"This number is outside the allowable range for 32-bit floats"
-1156,lexInvalidNumericLiteral,"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), 1ui (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger)."
+1156,lexInvalidNumericLiteral,"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)."
1157,lexInvalidByteLiteral,"This is not a valid byte literal"
1158,lexInvalidCharLiteral,"This is not a valid character literal"
1159,lexThisUnicodeOnlyInStringLiterals,"This Unicode encoding is only valid in string literals"
@@ -1076,6 +1077,8 @@ lexIndentOffForML,"Consider using a file with extension '.ml' or '.mli' instead"
1243,parsUnexpectedQuotationOperatorInTypeAliasDidYouMeanVerbatimString,"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."
1244,parsErrorParsingAsOperatorName,"Attempted to parse this as an operator name, but failed"
1245,lexInvalidUnicodeLiteral,"\U%s is not a valid Unicode character escape sequence"
+1246,tcCallerInfoWrongType,"'%s' must be applied to an argument of type '%s', but has been applied to an argument of type '%s'"
+1247,tcCallerInfoNotOptional,"'%s' can only be applied to optional arguments"
# reshapedmsbuild.fs
1300,toolLocationHelperUnsupportedFrameworkVersion,"The specified .NET Framework version "%s" is not supported. Please specify a value from the enumeration Microsoft.Build.Utilities.TargetDotNetFrameworkVersion."
# -----------------------------------------------------------------------------
@@ -1307,3 +1310,8 @@ estApplyStaticArgumentsForMethodNotImplemented,"A type provider implemented GetS
3201,tcModuleAbbrevFirstInMutRec,"In a recursive declaration group, module abbreviations must come after all 'open' declarations and before other declarations"
3202,tcUnsupportedMutRecDecl,"This declaration is not supported in recursive declaration groups"
3203,parsInvalidUseOfRec,"Invalid use of 'rec' keyword"
+3204,tcStructUnionMultiCase,"A union type which is a struct must have only one case."
+3205,tcUseMayNotBeMutable,"This feature is deprecated. A 'use' binding may not be marked 'mutable'."
+3206,CallerMemberNameIsOverriden,"The CallerMemberNameAttribute applied to parameter '%s' will have no effect. It is overridden by the CallerFilePathAttribute."
+3207,tcFixedNotAllowed,"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'"
+3208,tcCouldNotFindOffsetToStringData,"Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression."
diff --git a/src/fsharp/FSStrings.resx b/src/fsharp/FSStrings.resx
index f95cf777b4a..f028e00b6f8 100644
--- a/src/fsharp/FSStrings.resx
+++ b/src/fsharp/FSStrings.resx
@@ -892,7 +892,7 @@
This expression is a function value, i.e. is missing arguments. Its type is {0}.
- This expression should have type 'unit', but has type '{0}'. Use 'ignore' to discard the result of the expression, or 'let' to bind the result to a name.
+ The result of this expression is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.
This expression should have type 'unit', but has type '{0}'. If assigning to a property use the syntax 'obj.Prop <- expr'.
diff --git a/src/fsharp/FSharp.Build-proto/FSharp.Build-proto.fsproj b/src/fsharp/FSharp.Build-proto/FSharp.Build-proto.fsproj
index d8db6885063..31d192aceab 100644
--- a/src/fsharp/FSharp.Build-proto/FSharp.Build-proto.fsproj
+++ b/src/fsharp/FSharp.Build-proto/FSharp.Build-proto.fsproj
@@ -47,11 +47,18 @@
-
-
-
-
-
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Framework.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Utilities.Core.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Tasks.Core.dll
+
diff --git a/src/fsharp/FSharp.Build/FSharp.Build.fsproj b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
index 407bc789856..e835d52c57a 100644
--- a/src/fsharp/FSharp.Build/FSharp.Build.fsproj
+++ b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
@@ -55,11 +55,18 @@
-
-
-
-
-
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Framework.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Utilities.Core.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Tasks.Core.dll
+
diff --git a/src/fsharp/FSharp.Build/project.json b/src/fsharp/FSharp.Build/project.json
index 49e360894f7..cdec2ffe079 100644
--- a/src/fsharp/FSharp.Build/project.json
+++ b/src/fsharp/FSharp.Build/project.json
@@ -1,22 +1,22 @@
-{
- "dependencies": {
- "Microsoft.Build": "0.1.0-preview-00022",
- "Microsoft.Build.Framework": "0.1.0-preview-00022",
- "Microsoft.Build.Tasks.Core": "0.1.0-preview-00022",
- "Microsoft.Build.Utilities.Core": "0.1.0-preview-00022",
- "Microsoft.NETCore.Platforms": "1.0.1-rc2-24027",
- "Microsoft.Win32.Registry": {
- "version": "4.0.0-rc2-24027",
- "exclude": "Compile"
- },
- "System.AppContext": "4.1.0-rc2-24027",
- "System.Diagnostics.Tools": "4.0.1-rc2-24027",
- "System.Reflection.Primitives": "4.0.1-rc2-24027",
- "System.Resources.ResourceManager": "4.0.1-rc2-24027",
- },
- "frameworks": {
- "dnxcore50": {
- "imports": "portable-net45+win8",
- }
- }
-}
\ No newline at end of file
+{
+ "dependencies": {
+ "Microsoft.Build": "0.1.0-preview-00028-160627",
+ "Microsoft.Build.Framework": "0.1.0-preview-00028-160627",
+ "Microsoft.Build.Tasks.Core": "0.1.0-preview-00028-160627",
+ "Microsoft.Build.Utilities.Core": "0.1.0-preview-00028-160627",
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.Win32.Registry": {
+ "version": "4.0.0",
+ "exclude": "Compile"
+ },
+ "System.AppContext": "4.1.0",
+ "System.Diagnostics.Tools": "4.0.1",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Resources.ResourceManager": "4.0.1"
+ },
+ "frameworks": {
+ "netstandard1.6": {
+ "imports": "portable-net45+win8"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj b/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj
index 7eb20114970..b005eaa8a68 100644
--- a/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj
+++ b/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj
@@ -434,12 +434,6 @@
IlxGen.fs
-
- TraceCall.fsi
-
-
- TraceCall.fs
-
CompileOps.fsi
@@ -467,16 +461,36 @@
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Framework.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Utilities.Core.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Tasks.Core.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.DiaSymReader.PortablePdb.1.0.0-rc-60301\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.DiaSymReader.1.0.7\lib\portable-net45+win8\Microsoft.DiaSymReader.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\System.Collections.Immutable.1.2.0-rc3-23805\lib\portable-net45+win8+wp8+wpa81
+
-
- ..\..\..\packages\Microsoft.DiaSymReader.PortablePdb.1.0.0-rc-60301\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll
- ..\..\..\packages\Microsoft.DiaSymReader.1.0.7\lib\portable-net45+win8\Microsoft.DiaSymReader.dll
- ..\..\..\packages\System.Reflection.Metadata.1.3.0-beta-23816\lib\portable-net45+win8\System.Reflection.Metadata.dll
- ..\..\..\packages\System.Collections.Immutable.1.2.0-rc3-23805\lib\portable-net45+win8+wp8+wpa81
+ ..\..\..\packages\Microsoft.DiaSymReader.PortablePdb.1.1.0\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll
+ ..\..\..\packages\Microsoft.DiaSymReader.1.0.8\lib\portable-net45+win8\Microsoft.DiaSymReader.dll
+ ..\..\..\packages\System.Reflection.Metadata.1.4.1-beta-24227-04\lib\portable-net45+win8\System.Reflection.Metadata.dll
+ ..\..\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81
diff --git a/src/fsharp/FSharp.Compiler.Host.netcore.nuget/Microsoft.FSharp.Compiler.Host.netcore.nuspec b/src/fsharp/FSharp.Compiler.Host.netcore.nuget/Microsoft.FSharp.Compiler.Host.netcore.nuspec
index c389117159b..a6dd2dd07f7 100644
--- a/src/fsharp/FSharp.Compiler.Host.netcore.nuget/Microsoft.FSharp.Compiler.Host.netcore.nuspec
+++ b/src/fsharp/FSharp.Compiler.Host.netcore.nuget/Microsoft.FSharp.Compiler.Host.netcore.nuspec
@@ -3,10 +3,10 @@
Microsoft.FSharp.Compiler.Host.netcore
- netcore compatible version of the fsharp compiler fsc.exe.
+ .NET Core compatible version of the fsharp compiler fsc.exe.
Supported Platforms:
- - .NET Core (netstandard1.5)
+ - .NET Core (netstandard1.6)
en-US
true
@@ -16,12 +16,10 @@
$projectUrl$
$tags$
-
-
-
-
-
-
+
+
+
+
diff --git a/src/fsharp/FSharp.Compiler.Interactive.Settings/project.json b/src/fsharp/FSharp.Compiler.Interactive.Settings/project.json
index 12f15a49c0f..4e1804794a8 100644
--- a/src/fsharp/FSharp.Compiler.Interactive.Settings/project.json
+++ b/src/fsharp/FSharp.Compiler.Interactive.Settings/project.json
@@ -1,19 +1,19 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.0.1-rc2-24027",
- "NETStandard.Library": "1.5.0-rc2-24027",
- "System.Linq.Expressions": "4.0.11-rc2-24027",
- "System.Reflection.TypeExtensions": "4.1.0-rc2-24027",
- "System.Runtime.Loader": "4.0.0-rc2-24027",
- "System.Threading.Thread": "4.0.0-rc2-24027",
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "NETStandard.Library": "1.6.0",
+ "System.Linq.Expressions": "4.1.0",
+ "System.Reflection.TypeExtensions": "4.1.0",
+ "System.Runtime.Loader": "4.0.0",
+ "System.Threading.Thread": "4.0.0"
},
"runtimes": {
"win7-x86": { },
"win7-x64": { },
- "osx.10.10-x64": { },
+ "osx.10.11-x64": { },
"ubuntu.14.04-x64": { }
},
"frameworks": {
- "netstandard1.5": { }
+ "netstandard1.6": { }
}
}
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 be04c8c83f2..62e8f108384 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
@@ -36,23 +36,16 @@
-
-
-
-
-
- $(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Utilities.14.2.25123\lib\net45\Microsoft.VisualStudio.Utilities.dll
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Shell.$(RoslynVSBinariesVersion).$(RoslynVSPackagesVersion)\lib\Microsoft.VisualStudio.Shell.$(RoslynVSBinariesVersion).dll
-
+
+
+
+
$(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Threading.14.1.131\lib\net45\Microsoft.VisualStudio.Threading.dll
-
-
-
-
-
-
diff --git a/src/fsharp/FSharp.Compiler.netcore.nuget/Microsoft.FSharp.Compiler.netcore.nuspec b/src/fsharp/FSharp.Compiler.netcore.nuget/Microsoft.FSharp.Compiler.netcore.nuspec
index beff3bf51c3..849d54eac48 100644
--- a/src/fsharp/FSharp.Compiler.netcore.nuget/Microsoft.FSharp.Compiler.netcore.nuspec
+++ b/src/fsharp/FSharp.Compiler.netcore.nuget/Microsoft.FSharp.Compiler.netcore.nuspec
@@ -3,8 +3,8 @@
Microsoft.FSharp.Compiler.netcore
- netcore compatible version of the fsharp compiler fsc.exe.
- Supported Platforms: - .NET Core (.netstandard1.5)
+ .NET Core compatible version of the fsharp compiler fsc.exe.
+ Supported Platforms: - .NET Core (.netstandard1.6)
en-US
true
@@ -14,37 +14,34 @@
$projectUrl$
$tags$
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
diff --git a/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj b/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj
index 9ba9ef50d9f..8432cb86d70 100644
--- a/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj
+++ b/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj
@@ -29,7 +29,7 @@
$(FSharpSourcesRoot)\..\loc\lcl\{Lang}\$(AssemblyName).dll.lcl
$(FSharpSourcesRoot)\..\loc\lci\$(AssemblyName).dll.lci
false
- false
+ false
@@ -141,12 +141,6 @@
Utilities\lib.fs
-
- Utilities\TraceCall.fsi
-
-
- Utilities\TraceCall.fs
-
Utilities\rational.fsi
@@ -518,15 +512,35 @@
-
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Framework.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Utilities.Core.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Tasks.Core.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.DiaSymReader.PortablePdb.1.0.0-rc-60301\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.DiaSymReader.1.0.7\lib\portable-net45+win8\Microsoft.DiaSymReader.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\System.Collections.Immutable.1.2.0-rc3-23805\lib\portable-net45+win8+wp8+wpa81
+
- ..\..\..\packages\Microsoft.DiaSymReader.PortablePdb.1.0.0-rc-60301\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll
- ..\..\..\packages\Microsoft.DiaSymReader.1.0.7\lib\portable-net45+win8\Microsoft.DiaSymReader.dll
- ..\..\..\packages\System.Reflection.Metadata.1.3.0-beta-23816\lib\portable-net45+win8\System.Reflection.Metadata.dll
- ..\..\..\packages\System.Collections.Immutable.1.2.0-rc3-23805\lib\portable-net45+win8+wp8+wpa81
+ ..\..\..\packages\Microsoft.DiaSymReader.PortablePdb.1.1.0\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll
+ ..\..\..\packages\Microsoft.DiaSymReader.1.0.8\lib\portable-net45+win8\Microsoft.DiaSymReader.dll
+ ..\..\..\packages\System.Reflection.Metadata.1.4.1-beta-24227-04\lib\portable-net45+win8\System.Reflection.Metadata.dll
+ ..\..\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81
diff --git a/src/fsharp/FSharp.Compiler/InternalsVisibleTo.fs b/src/fsharp/FSharp.Compiler/InternalsVisibleTo.fs
index 6c96244239b..8adb8815036 100644
--- a/src/fsharp/FSharp.Compiler/InternalsVisibleTo.fs
+++ b/src/fsharp/FSharp.Compiler/InternalsVisibleTo.fs
@@ -6,7 +6,6 @@ open System.Reflection
[]
[]
[]
-[]
[]
[]
[]
@@ -18,6 +17,7 @@ open System.Reflection
[]
[]
[]
+[]
do()
diff --git a/src/fsharp/FSharp.Compiler/project.json b/src/fsharp/FSharp.Compiler/project.json
index ac47a5e454c..5ee32fdfe28 100644
--- a/src/fsharp/FSharp.Compiler/project.json
+++ b/src/fsharp/FSharp.Compiler/project.json
@@ -1,36 +1,33 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.0.1-rc2-24027",
- "NETStandard.Library": "1.5.0-rc2-24027",
- "System.Collections.Immutable":"1.2.0-rc2-24027",
- "System.Diagnostics.Process": "4.1.0-rc2-24027",
- "System.Diagnostics.TraceSource": "4.0.0-rc2-24027",
- "System.Linq.Expressions": "4.0.11-rc2-24027",
- "System.Linq.Queryable": "4.0.1-rc2-24027",
- "System.Net.Requests": "4.0.11-rc2-24027",
- "System.Reflection.Emit": "4.0.1-rc2-24027",
- "System.Reflection.Emit.ILGeneration": "4.0.1-rc2-24027",
- "System.Reflection.Metadata": "1.3.0-rc2-24027",
- "System.Reflection.TypeExtensions": "4.1.0-rc2-24027",
- "System.Runtime.InteropServices": "4.1.0-rc2-24027",
- "System.Runtime.InteropServices.PInvoke": "4.0.0-rc2-24027",
- "System.Runtime.Loader": "4.0.0-rc2-24027",
- "System.Security.Cryptography.Algorithms": "4.1.0-rc2-24027",
- "System.Security.Cryptography.Primitives": "4.0.0-rc2-24027",
- "System.Threading.Tasks.Parallel": "4.0.1-rc2-24027",
- "System.Threading.Thread": "4.0.0-rc2-24027",
- "System.Threading.ThreadPool": "4.0.10-rc2-24027",
- "Microsoft.DiaSymReader.PortablePdb": "1.0.0-rc-60301",
- "Microsoft.DiaSymReader": "1.0.7",
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "NETStandard.Library": "1.6.0",
+ "System.Collections.Immutable":"1.2.0",
+ "System.Diagnostics.Process": "4.1.0",
+ "System.Diagnostics.TraceSource": "4.0.0",
+ "System.Linq.Expressions": "4.1.0",
+ "System.Linq.Queryable": "4.0.1",
+ "System.Net.Requests": "4.0.11",
+ "System.Reflection.Emit": "4.0.1",
+ "System.Reflection.Metadata": "1.4.1-beta-24227-04",
+ "System.Reflection.TypeExtensions": "4.1.0",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Runtime.Loader": "4.0.0",
+ "System.Security.Cryptography.Algorithms": "4.2.0",
+ "System.Threading.Tasks.Parallel": "4.0.1",
+ "System.Threading.Thread": "4.0.0",
+ "System.Threading.ThreadPool": "4.0.10",
+ "Microsoft.DiaSymReader.PortablePdb": "1.1.0",
+ "Microsoft.DiaSymReader": "1.0.8"
},
"runtimes": {
"win7-x86": { },
"win7-x64": { },
- "osx.10.10-x64": { },
+ "osx.10.11-x64": { },
"ubuntu.14.04-x64": { }
},
"frameworks": {
- "netstandard1.5": {
+ "netstandard1.6": {
"imports": "portable-net45+win8"
}
}
diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj b/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj
index 83ed633defa..9e389c299e6 100644
--- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj
+++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj
@@ -112,7 +112,7 @@
-
+
@@ -120,6 +120,7 @@
+
diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/DiscrimantedUnionType.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/DiscrimantedUnionType.fs
index 42f038b67bc..517e69a9200 100644
--- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/DiscrimantedUnionType.fs
+++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/DiscrimantedUnionType.fs
@@ -1,10 +1,25 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-namespace FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Core
+module FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Core.DiscriminatedUnionTypes
open System
open System.Numerics
+open System.Reflection
+open System.Runtime.InteropServices
open FSharp.Core.Unittests.LibraryTestFx
open NUnit.Framework
+open FsCheck
+open FsCheck.PropOperators
+
+#if FX_RESHAPED_REFLECTION
+open FSharp.Reflection.FSharpReflectionExtensions
+
+[]
+module PrimReflectionAdapters =
+
+ type System.Type with
+ member this.IsValueType = this.GetTypeInfo().IsValueType
+#endif
+
type EnumUnion =
| A
@@ -95,4 +110,142 @@ type UseUnionsWithData() =
| _ -> Assert.Fail()
match a2 with
| Alpha x when x = 2 -> ()
- | _ -> Assert.Fail()
\ No newline at end of file
+ | _ -> Assert.Fail()
+
+[]
+type StructUnion = SU of C : int * D : int
+
+let private hasAttribute<'T,'Attr>() =
+ typeof<'T>.GetTypeInfo().GetCustomAttributes() |> Seq.exists (fun x -> x.GetType() = typeof<'Attr>)
+
+
+let [] ``struct unions hold [] metadata`` () =
+ Assert.IsTrue (hasAttribute())
+
+
+let [] ``struct unions are comparable`` () =
+ Check.QuickThrowOnFailure <|
+ fun (i1:int) (i2:int) ->
+ i1 <> i2 ==>
+ let sr1 = SU (i1, i2)
+ let sr2 = SU (i1, i2)
+ let sr3 = SU (i2, i1)
+ (sr1 = sr2) |@ "sr1 = sr2" .&.
+ (sr1 <> sr3) |@ "sr1 <> sr3" .&.
+ (sr1.Equals sr2) |@ "sr1.Equals sr2"
+
+
+let [] ``struct unions support pattern matching`` () =
+ Check.QuickThrowOnFailure <|
+ fun (i1:int) (i2:int) ->
+ let sr1 = SU(i1, i2)
+ (match sr1 with
+ | SU(c,d) when c = i1 && d = i2 -> true
+ | _ -> false)
+ |@ "with pattern match on struct union" .&.
+ (sr1 |> function
+ | SU(c,d) when c = i1 && d = i2 -> true
+ | _ -> false)
+ |@ "function pattern match on struct union"
+
+
+let [] ``struct unions support let binds using `` () =
+ Check.QuickThrowOnFailure <|
+ fun (i1:int) (i2:int) ->
+ let sr1 = SU(i1,i2)
+ let (SU (c1,d2)) as sr2 = sr1
+ (sr1 = sr2) |@ "sr1 = sr2" .&.
+ (c1 = i1 && d2 = i2) |@ "c1 = i1 && d2 = i2"
+
+
+let [] ``struct unions support function argument bindings`` () =
+ Check.QuickThrowOnFailure <|
+ fun (i1:int) (i2:int) ->
+ let sr1 = SU(i1,i2)
+ let test sr1 (SU (c1,d2) as sr2) =
+ sr1 = sr2 && c1 = i1 && d2 = i2
+ test sr1 sr1
+
+
+
+[]
+[]
+type ComparisonStructUnion =
+ | SU2 of int * int
+ member x.C1 = (match x with SU2(a,b) -> a)
+ member x.C2 = (match x with SU2(a,b) -> b)
+ override self.Equals other =
+ match other with
+ | :? ComparisonStructUnion as o -> (self.C1 + self.C2) = (o.C1 + o.C2)
+ | _ -> false
+
+ override self.GetHashCode() = hash self
+ interface IComparable with
+ member self.CompareTo other =
+ match other with
+ | :? ComparisonStructUnion as o -> compare (self.C1 + self.C2) (o.C1 + o.C2)
+ | _ -> invalidArg "other" "cannot compare values of different types"
+
+
+[]
+let ``struct unions support []`` () =
+ Check.QuickThrowOnFailure <|
+ fun (i1:int) (i2:int) ->
+ let sr1 = SU2(i1,i2)
+ let sr2 = SU2(i1,i2)
+ (sr1.Equals sr2)
+
+
+[]
+let ``struct unions support []`` () =
+ Check.QuickThrowOnFailure <|
+ fun (i1:int) (i2:int) (k1:int) (k2:int) ->
+ let sr1 = SU2(i1,i2)
+ let sr2 = SU2(k1,k2)
+ if sr1 > sr2 then compare sr1 sr2 = 1
+ elif sr1 < sr2 then compare sr1 sr2 = -1
+ elif sr1 = sr2 then compare sr1 sr2 = 0
+ else false
+
+
+[]
+let ``struct unions hold [] [] metadata`` () =
+ Assert.IsTrue (hasAttribute())
+ Assert.IsTrue (hasAttribute())
+
+
+[]
+[]
+type NoComparisonStructUnion =
+ | SU3 of int * int
+
+
+
+[]
+let ``struct unions hold [] [] metadata`` () =
+ Assert.IsTrue (hasAttribute())
+ Assert.IsTrue (hasAttribute())
+
+
+let [] ``can properly construct a struct union using FSharpValue.MakeUnionCase, and we get the fields`` () =
+ let cases = Microsoft.FSharp.Reflection.FSharpType.GetUnionCases(typeof)
+
+ Assert.AreEqual (1, cases.Length)
+ let case = cases.[0]
+
+ Assert.AreEqual ("SU", case.Name)
+
+ let structUnion = Microsoft.FSharp.Reflection.FSharpValue.MakeUnion (case, [|box 1234; box 3456|])
+
+ Assert.IsTrue (structUnion.GetType().IsValueType)
+
+ let _uc, fieldVals = Microsoft.FSharp.Reflection.FSharpValue.GetUnionFields(structUnion, typeof)
+
+ Assert.AreEqual (2, fieldVals.Length)
+
+ let c = (fieldVals.[0] :?> int)
+ Assert.AreEqual (1234, c)
+
+ let c2 = (fieldVals.[1] :?> int)
+ Assert.AreEqual (3456, c2)
+
diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs
index cfa03d36597..3f5aff83e1f 100644
--- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs
+++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs
@@ -584,96 +584,4 @@ type AsyncModule() =
Assert.AreEqual(0, !okCount)
Assert.AreEqual(0, !errCount)
#endif
-#endif
-
-#if FSHARP_CORE_PORTABLE
-// nothing
-#else
-#if FSHARP_CORE_2_0
-// nothing
-#else
-#if FSHARP_CORE_NETCORE_PORTABLE || coreclr
-//nothing
-#else
-// we are on the desktop
- member this.RunExeAndExpectOutput(exeName, expected:string) =
- let curDir = (new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase)).LocalPath |> System.IO.Path.GetDirectoryName
- let psi = System.Diagnostics.ProcessStartInfo(exeName)
- psi.WorkingDirectory <- curDir
- psi.RedirectStandardOutput <- true
- psi.UseShellExecute <- false
- let p = System.Diagnostics.Process.Start(psi)
- let out = p.StandardOutput.ReadToEnd()
- p.WaitForExit()
- let out = out.Replace("\r\n", "\n")
- let expected = expected.Replace("\r\n", "\n")
- Assert.AreEqual(expected, out)
-#if OPEN_BUILD
-#else
- []
- member this.``ContinuationsThreadingDetails.AsyncWithSyncContext``() =
- this.RunExeAndExpectOutput("AsyncWithSyncContext.exe", """
-EmptyParallel [|("ok", true); ("caught:boom", true)|]
-NonEmptyParallel [|("ok", true); ("form exception:boom", true)|]
-ParallelSeqArgumentThrows [|("error", true)|]
-Sleep1Return [|("ok", true); ("form exception:boom", true)|]
-Sleep0Return [|("ok", true); ("form exception:boom", true)|]
-Return [|("ok", true); ("caught:boom", true)|]
-FromContinuationsSuccess [|("ok", true); ("caught:boom", true)|]
-FromContinuationsError [|("error", true)|]
-FromContinuationsCancel [|("cancel", true)|]
-FromContinuationsThrows [|("error", true)|]
-FromContinuationsSchedulesFutureSuccess [|("ok", false); ("unhandled", false)|]
-FromContinuationsSchedulesFutureError [|("error", false)|]
-FromContinuationsSchedulesFutureCancel [|("cancel", false)|]
-FromContinuationsSchedulesFutureSuccessAndThrowsQuickly [|("error", true); ("unhandled", false)|]
-FromContinuationsSchedulesFutureErrorAndThrowsQuickly [|("error", true); ("unhandled", false)|]
-FromContinuationsSchedulesFutureCancelAndThrowsQuickly [|("error", true); ("unhandled", false)|]
-FromContinuationsSchedulesFutureSuccessAndThrowsSlowly [|("ok", false); ("unhandled", false);
- ("caught:A continuation provided by Async.FromContinuations was invoked multiple times",
- true)|]
-FromContinuationsSchedulesFutureErrorAndThrowsSlowly [|("error", false);
- ("caught:A continuation provided by Async.FromContinuations was invoked multiple times",
- true)|]
-FromContinuationsSchedulesFutureCancelAndThrowsSlowly [|("cancel", false);
- ("caught:A continuation provided by Async.FromContinuations was invoked multiple times",
- true)|]
-AwaitWaitHandleAlreadySignaled0 [|("ok", true); ("caught:boom", true)|]
-AwaitWaitHandleAlreadySignaled1 [|("ok", true); ("form exception:boom", true)|]
-""" )
- []
- member this.``ContinuationsThreadingDetails.AsyncSansSyncContext``() =
- this.RunExeAndExpectOutput("AsyncSansSyncContext.exe", """
-EmptyParallel [|("ok", true); ("caught:boom", true)|]
-NonEmptyParallel [|("ok", false); ("unhandled", false)|]
-ParallelSeqArgumentThrows [|("error", true)|]
-Sleep1Return [|("ok", false); ("unhandled", false)|]
-Sleep0Return [|("ok", false); ("unhandled", false)|]
-Return [|("ok", true); ("caught:boom", true)|]
-FromContinuationsSuccess [|("ok", true); ("caught:boom", true)|]
-FromContinuationsError [|("error", true)|]
-FromContinuationsCancel [|("cancel", true)|]
-FromContinuationsThrows [|("error", true)|]
-FromContinuationsSchedulesFutureSuccess [|("ok", false); ("unhandled", false)|]
-FromContinuationsSchedulesFutureError [|("error", false)|]
-FromContinuationsSchedulesFutureCancel [|("cancel", false)|]
-FromContinuationsSchedulesFutureSuccessAndThrowsQuickly [|("error", true); ("unhandled", false)|]
-FromContinuationsSchedulesFutureErrorAndThrowsQuickly [|("error", true); ("unhandled", false)|]
-FromContinuationsSchedulesFutureCancelAndThrowsQuickly [|("error", true); ("unhandled", false)|]
-FromContinuationsSchedulesFutureSuccessAndThrowsSlowly [|("ok", false); ("unhandled", false);
- ("caught:A continuation provided by Async.FromContinuations was invoked multiple times",
- true)|]
-FromContinuationsSchedulesFutureErrorAndThrowsSlowly [|("error", false);
- ("caught:A continuation provided by Async.FromContinuations was invoked multiple times",
- true)|]
-FromContinuationsSchedulesFutureCancelAndThrowsSlowly [|("cancel", false);
- ("caught:A continuation provided by Async.FromContinuations was invoked multiple times",
- true)|]
-AwaitWaitHandleAlreadySignaled0 [|("ok", true); ("caught:boom", true)|]
-AwaitWaitHandleAlreadySignaled1 [|("ok", false); ("unhandled", false)|]
-""" )
-#endif
-
-#endif
-#endif
#endif
\ No newline at end of file
diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Core/ResultTests.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Core/ResultTests.fs
new file mode 100644
index 00000000000..0eefa2126f1
--- /dev/null
+++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Core/ResultTests.fs
@@ -0,0 +1,44 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+// Various tests for:
+// Microsoft.FSharp.Core.Result
+
+namespace FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Core
+
+open System
+open FSharp.Core.Unittests.LibraryTestFx
+open NUnit.Framework
+
+type EmailValidation=
+ | Empty
+ | NoAt
+
+module Results=
+ let bind f m = match m with Error e -> Error e | Ok x -> f x
+
+open Results
+
+[]
+type ResultTests() =
+
+ let fail_if_empty email=
+ if String.IsNullOrEmpty(email) then Error Empty else Ok email
+
+ let fail_if_not_at (email:string)=
+ if (email.Contains("@")) then Ok email else Error NoAt
+
+ let validate_email =
+ fail_if_empty
+ >> bind fail_if_not_at
+
+ let test_validate_email email (expected:Result) =
+ let actual = validate_email email
+ Assert.AreEqual(expected, actual)
+
+
+ []
+ member this.CanChainTogetherSuccessiveValidations() =
+ test_validate_email "" (Error Empty)
+ test_validate_email "something_else" (Error NoAt)
+ test_validate_email "some@email.com" (Ok "some@email.com")
+
diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/RecordTypes.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/RecordTypes.fs
index 694052fa4d2..2d9695b08fa 100644
--- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/RecordTypes.fs
+++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/RecordTypes.fs
@@ -325,4 +325,48 @@ let [] ``can properly construct a struct record using FSharpValue.MakeReco
let d = (fields.[1] :?> int)
Assert.AreEqual (999, d)
-
\ No newline at end of file
+type DefaultLayoutMutableRecord =
+ { mutable First : int
+ mutable Second : float
+ mutable Third : decimal
+ mutable Fourth : int
+ }
+
+let inline CX_get_A(x: ^T) =
+ ( (^T : (member A : int) (x)) )
+
+let inline CX_get_C(x: ^T) =
+ ( (^T : (member C : int) (x)) )
+
+let inline CX_set_First(x: ^T, v) =
+ ( (^T : (member First : int with set) (x,v)) )
+
+
+type Members() =
+ static member CreateMutableStructRecord() = { M1 = 1; M2 = 2 }
+
+
+let [] ``inline constraints resolve correctly`` () =
+ let v = CX_get_A ({ A = 1; B = 2 })
+ Assert.AreEqual (1, v)
+
+ let v2 = CX_get_C ({ C = 1; D = 2 })
+ Assert.AreEqual (1, v2)
+
+ let mutable m : DefaultLayoutMutableRecord =
+ { First = 0xbaad1
+ Second = 0.987654
+ Third = 100.32M
+ Fourth = 0xbaad4 }
+
+ let v3 = CX_set_First (m,1)
+ Assert.AreEqual (1, m.First)
+
+let [] ``member setters resolve correctly`` () =
+
+ let v = Members.CreateMutableStructRecord()
+ Assert.AreEqual (1, v.M1)
+
+ //let v2 = Members.CreateMutableStructRecord(M1 = 100)
+ //Assert.AreEqual (100, v2.M1)
+
diff --git a/src/fsharp/FSharp.Core.Unittests/LibraryTestFx.fs b/src/fsharp/FSharp.Core.Unittests/LibraryTestFx.fs
index af62c8ffb75..6fe9224d6a8 100644
--- a/src/fsharp/FSharp.Core.Unittests/LibraryTestFx.fs
+++ b/src/fsharp/FSharp.Core.Unittests/LibraryTestFx.fs
@@ -126,12 +126,7 @@ module SurfaceArea =
// verify public surface area matches expected
let verify expected platform fileName =
- let workDir =
- #if OPEN_BUILD
- TestContext.CurrentContext.WorkDirectory
- #else
- ""
- #endif
+ let workDir = TestContext.CurrentContext.WorkDirectory
let logFile = sprintf "%s\\CoreUnit_%s_Xml.xml" workDir platform
let normalize (s:string) =
Regex.Replace(s, "(\\r\\n|\\n)+", "\r\n").Trim([|'\r';'\n'|])
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.Silverlight.2.0.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.Silverlight.2.0.fs
index 3d933f40517..0d5f50d6290 100644
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.Silverlight.2.0.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.Silverlight.2.0.fs
@@ -1821,6 +1821,69 @@ Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents()
Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError Item
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T Item
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.Type GetType()
Microsoft.FSharp.Core.FSharpTypeFunc: Boolean Equals(System.Object)
Microsoft.FSharp.Core.FSharpTypeFunc: Int32 GetHashCode()
Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]()
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net20.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net20.fs
index c8caf782564..104874e1a6a 100644
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net20.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net20.fs
@@ -2000,6 +2000,69 @@ Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents()
Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError Item
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T Item
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.Type GetType()
Microsoft.FSharp.Core.FSharpTypeFunc: Boolean Equals(System.Object)
Microsoft.FSharp.Core.FSharpTypeFunc: Int32 GetHashCode()
Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]()
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs
index 6879946205f..492dd473b10 100644
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs
@@ -2161,6 +2161,69 @@ Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents()
Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError Item
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T Item
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.Type GetType()
Microsoft.FSharp.Core.FSharpTypeFunc: Boolean Equals(System.Object)
Microsoft.FSharp.Core.FSharpTypeFunc: Int32 GetHashCode()
Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]()
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs
index 2102f9d951d..eb21e466f4f 100644
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs
@@ -2137,6 +2137,69 @@ Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents()
Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError Item
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T Item
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.Type GetType()
Microsoft.FSharp.Core.FSharpTypeFunc: Boolean Equals(System.Object)
Microsoft.FSharp.Core.FSharpTypeFunc: Int32 GetHashCode()
Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]()
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs
index 856107f69f2..d1fed8d0a16 100644
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs
@@ -2134,6 +2134,69 @@ Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents()
Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError Item
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T Item
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.Type GetType()
Microsoft.FSharp.Core.FSharpTypeFunc: Boolean Equals(System.Object)
Microsoft.FSharp.Core.FSharpTypeFunc: Int32 GetHashCode()
Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]()
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs
index 745df1359bf..3916c3bf8ce 100644
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs
@@ -2150,6 +2150,69 @@ Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents()
Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError Item
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T Item
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.Type GetType()
Microsoft.FSharp.Core.FSharpTypeFunc: Boolean Equals(System.Object)
Microsoft.FSharp.Core.FSharpTypeFunc: Int32 GetHashCode()
Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]()
diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs
index 72df723cf36..1520f4cb004 100644
--- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs
+++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs
@@ -2137,6 +2137,69 @@ Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents()
Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T)
Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError Item
+Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]: TError get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T Item
+Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]: T get_Item()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: System.Type GetType()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError])
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Error[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Ok[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T)
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.String ToString()
+Microsoft.FSharp.Core.FSharpResult`2[T,TError]: System.Type GetType()
Microsoft.FSharp.Core.FSharpTypeFunc: Boolean Equals(System.Object)
Microsoft.FSharp.Core.FSharpTypeFunc: Int32 GetHashCode()
Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]()
diff --git a/src/fsharp/FSharp.Core.Unittests/project.json b/src/fsharp/FSharp.Core.Unittests/project.json
index 2ab29cb86b4..79647ccbf80 100644
--- a/src/fsharp/FSharp.Core.Unittests/project.json
+++ b/src/fsharp/FSharp.Core.Unittests/project.json
@@ -1,23 +1,24 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.0.1-rc2-24027",
- "NETStandard.Library": "1.5.0-rc2-24027",
- "System.Linq.Expressions": "4.0.11-rc2-24027",
- "System.Linq.Queryable": "4.0.1-rc2-24027",
- "System.Reflection.Emit": "4.0.1-rc2-24027",
- "System.Runtime.Loader": "4.0.0-rc2-24027",
- "System.Net.Requests": "4.0.11-rc2-24027",
- "System.Threading.Tasks.Parallel": "4.0.1-rc2-24027",
- "System.Threading.Thread": "4.0.0-rc2-24027",
- "System.Threading.ThreadPool": "4.0.10-rc2-24027",
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "NETStandard.Library": "1.6.0",
+ "System.Linq.Expressions": "4.1.0",
+ "System.Linq.Queryable": "4.0.1",
+ "System.Net.Requests": "4.0.11",
+ "System.Reflection.Emit": "4.0.1",
+ "System.Runtime.Loader": "4.0.0",
+ "System.Text.RegularExpressions": "4.1.0",
+ "System.Threading.Tasks.Parallel": "4.0.1",
+ "System.Threading.Thread": "4.0.0",
+ "System.Threading.ThreadPool": "4.0.10"
},
"runtimes": {
"win7-x86": { },
"win7-x64": { },
- "osx.10.10-x64": { },
+ "osx.10.11-x64": { },
"ubuntu.14.04-x64": { }
},
"frameworks": {
- "netstandard1.5": { }
+ "netstandard1.6": { }
}
}
diff --git a/src/fsharp/FSharp.Core/control.fs b/src/fsharp/FSharp.Core/control.fs
index 298da186887..a33b91faf4b 100644
--- a/src/fsharp/FSharp.Core/control.fs
+++ b/src/fsharp/FSharp.Core/control.fs
@@ -600,7 +600,7 @@ namespace Microsoft.FSharp.Control
let mutable defaultCancellationTokenSource = new CancellationTokenSource()
[]
- type Result<'T> =
+ type AsyncImplResult<'T> =
| Ok of 'T
| Error of ExceptionDispatchInfo
| Canceled of OperationCanceledException
@@ -804,9 +804,9 @@ namespace Microsoft.FSharp.Control
let reify res =
unprotectedPrimitive (fun args ->
match res with
- | Result.Ok r -> args.cont r
- | Result.Error e -> args.aux.econt e
- | Result.Canceled oce -> args.aux.ccont oce)
+ | AsyncImplResult.Ok r -> args.cont r
+ | AsyncImplResult.Error e -> args.aux.econt e
+ | AsyncImplResult.Canceled oce -> args.aux.ccont oce)
//----------------------------------
// BUILDER OPREATIONS
@@ -1235,7 +1235,7 @@ namespace Microsoft.FSharp.Control
let subSource = new LinkedSubSource(token)
subSource.Token, Some subSource
- use resultCell = new ResultCell>()
+ use resultCell = new ResultCell>()
queueAsync
token
(fun res -> resultCell.RegisterResult(Ok(res),reuseThread=true))
@@ -1261,7 +1261,7 @@ namespace Microsoft.FSharp.Control
commit res
let private RunSynchronouslyInCurrentThread (token:CancellationToken,computation) =
- use resultCell = new ResultCell>()
+ use resultCell = new ResultCell>()
let trampolineHolder = TrampolineHolder()
trampolineHolder.Protect
@@ -1791,7 +1791,7 @@ namespace Microsoft.FSharp.Control
/// Await the result of a result cell without a timeout
- static member ReifyResult(result:Result<'T>) : Async<'T> =
+ static member ReifyResult(result:AsyncImplResult<'T>) : Async<'T> =
unprotectedPrimitive(fun ({ aux = aux } as args) ->
(match result with
| Ok v -> args.cont v
@@ -1799,7 +1799,7 @@ namespace Microsoft.FSharp.Control
| Canceled exn -> aux.ccont exn) )
/// Await the result of a result cell without a timeout
- static member AwaitAndReifyResult(resultCell:ResultCell>) : Async<'T> =
+ static member AwaitAndReifyResult(resultCell:ResultCell>) : Async<'T> =
async {
let! result = resultCell.AwaitResult
return! Async.ReifyResult(result)
@@ -1811,7 +1811,7 @@ namespace Microsoft.FSharp.Control
///
/// Always resyncs to the synchronization context if needed, by virtue of it being built
/// from primitives which resync.
- static member AsyncWaitAsyncWithTimeout(innerCTS : CancellationTokenSource, resultCell:ResultCell>,millisecondsTimeout) : Async<'T> =
+ static member AsyncWaitAsyncWithTimeout(innerCTS : CancellationTokenSource, resultCell:ResultCell>,millisecondsTimeout) : Async<'T> =
match millisecondsTimeout with
| None | Some -1 ->
resultCell |> Async.AwaitAndReifyResult
@@ -1917,9 +1917,9 @@ namespace Microsoft.FSharp.Control
let cts = new CancellationTokenSource()
- let result = new ResultCell>()
+ let result = new ResultCell>()
- member s.SetResult(v: Result<'T>) =
+ member s.SetResult(v: AsyncImplResult<'T>) =
result.RegisterResult(v,reuseThread=true) |> unfake
match callback with
| null -> ()
@@ -2206,7 +2206,7 @@ namespace Microsoft.FSharp.Control
| :? System.Net.WebException as webExn
when webExn.Status = System.Net.WebExceptionStatus.RequestCanceled && !canceled ->
- Async.ReifyResult(Result.Canceled (OperationCanceledException webExn.Message))
+ Async.ReifyResult(AsyncImplResult.Canceled (OperationCanceledException webExn.Message))
| _ ->
edi.ThrowAny())
@@ -2278,9 +2278,9 @@ namespace Microsoft.FSharp.Control
let! ct = Async.CancellationToken
let start a f =
Async.StartWithContinuationsUsingDispatchInfo(a,
- (fun res -> c.RegisterResult(f res |> Result.Ok, reuseThread=false) |> unfake),
- (fun edi -> c.RegisterResult(edi |> Result.Error, reuseThread=false) |> unfake),
- (fun oce -> c.RegisterResult(oce |> Result.Canceled, reuseThread=false) |> unfake),
+ (fun res -> c.RegisterResult(f res |> AsyncImplResult.Ok, reuseThread=false) |> unfake),
+ (fun edi -> c.RegisterResult(edi |> AsyncImplResult.Error, reuseThread=false) |> unfake),
+ (fun oce -> c.RegisterResult(oce |> AsyncImplResult.Canceled, reuseThread=false) |> unfake),
cancellationToken = ct
)
start a1 Choice1Of2
diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs
index 43531b98838..3cfbd74f3f7 100644
--- a/src/fsharp/FSharp.Core/prim-types.fs
+++ b/src/fsharp/FSharp.Core/prim-types.fs
@@ -3470,6 +3470,12 @@ namespace Microsoft.FSharp.Core
and 'T option = Option<'T>
+ []
+ []
+ type Result<'T,'TError> =
+ | Ok of 'T
+ | Error of 'TError
+
//============================================================================
//============================================================================
diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi
index d3202b3aeee..ad84f0fd2d3 100644
--- a/src/fsharp/FSharp.Core/prim-types.fsi
+++ b/src/fsharp/FSharp.Core/prim-types.fsi
@@ -1770,6 +1770,15 @@ namespace Microsoft.FSharp.Core
and 'T option = Option<'T>
+ /// Helper type for error handling without exceptions.
+ []
+ []
+ type Result<'T,'TError> =
+ /// Represents an OK or a Successful result. The code succeeded with a value of 'T.
+ | Ok of 'T
+ /// Represents an Error or a Failure. The code failed with a value of 'TError representing what went wrong.
+ | Error of 'TError
+
namespace Microsoft.FSharp.Collections
open System
diff --git a/src/fsharp/FSharp.Core/project.json b/src/fsharp/FSharp.Core/project.json
index d3ee8bd7886..c14efc45130 100644
--- a/src/fsharp/FSharp.Core/project.json
+++ b/src/fsharp/FSharp.Core/project.json
@@ -1,38 +1,38 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.0.1-rc2-24027",
- "Microsoft.NETCore.Runtime": "1.0.2-rc2-24027",
- "System.Collections": "4.0.11-rc2-24027",
- "System.Console": "4.0.0-rc2-24027",
- "System.Diagnostics.Debug": "4.0.11-rc2-24027",
- "System.Diagnostics.Tools": "4.0.1-rc2-24027",
- "System.Globalization": "4.0.11-rc2-24027",
- "System.IO": "4.1.0-rc2-24027",
- "System.Linq": "4.1.0-rc2-24027",
- "System.Linq.Expressions": "4.0.11-rc2-24027",
- "System.Linq.Queryable": "4.0.1-rc2-24027",
- "System.Net.Requests": "4.0.11-rc2-24027",
- "System.Reflection": "4.1.0-rc2-24027",
- "System.Reflection.Extensions": "4.0.1-rc2-24027",
- "System.Resources.ResourceManager":"4.0.1-rc2-24027",
- "System.Runtime": "4.1.0-rc2-24027",
- "System.Runtime.Extensions": "4.1.0-rc2-24027",
- "System.Runtime.Numerics": "4.0.1-rc2-24027",
- "System.Text.RegularExpressions": "4.0.12-rc2-24027",
- "System.Threading": "4.0.11-rc2-24027",
- "System.Threading.Tasks": "4.0.11-rc2-24027",
- "System.Threading.Tasks.Parallel": "4.0.1-rc2-24027",
- "System.Threading.Thread": "4.0.0-rc2-24027",
- "System.Threading.ThreadPool": "4.0.10-rc2-24027",
- "System.Threading.Timer": "4.0.1-rc2-24027"
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Runtime.CoreCLR": "1.0.2",
+ "System.Collections": "4.0.11",
+ "System.Console": "4.0.0",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Diagnostics.Tools": "4.0.1",
+ "System.Globalization": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Linq": "4.1.0",
+ "System.Linq.Expressions": "4.1.0",
+ "System.Linq.Queryable": "4.0.1",
+ "System.Net.Requests": "4.0.11",
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Extensions": "4.0.1",
+ "System.Resources.ResourceManager":"4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Numerics": "4.0.1",
+ "System.Text.RegularExpressions": "4.1.0",
+ "System.Threading": "4.0.11",
+ "System.Threading.Tasks": "4.0.11",
+ "System.Threading.Tasks.Parallel": "4.0.1",
+ "System.Threading.Thread": "4.0.0",
+ "System.Threading.ThreadPool": "4.0.10",
+ "System.Threading.Timer": "4.0.1"
},
"runtimes": {
"win7-x86": { },
"win7-x64": { },
- "osx.10.10-x64": { },
+ "osx.10.11-x64": { },
"ubuntu.14.04-x64": { }
},
"frameworks": {
- "netstandard1.5": { }
+ "netstandard1.6": { }
}
}
diff --git a/src/fsharp/FSharp.Data.TypeProviders/FSharp.Data.TypeProviders.fsproj b/src/fsharp/FSharp.Data.TypeProviders/FSharp.Data.TypeProviders.fsproj
deleted file mode 100644
index 810ecac2122..00000000000
--- a/src/fsharp/FSharp.Data.TypeProviders/FSharp.Data.TypeProviders.fsproj
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
- ..\..
-
-
-
- Debug
- AnyCPU
- Library
- FSharp.Data.TypeProviders
- true
- {cb7d20c4-6506-406d-9144-5342c3595f03}
- $(OtherFlags) --warnon:1182
-
-
-
-
-
-
- TypeProviderRuntimeAttribute.fs
- true
-
-
-
-
-
- assemblyinfo.FSharp.Data.TypeProviders.dll.fs
-
-
-
-
-
-
-
-
-
- {DED3BBD7-53F4-428A-8C9F-27968E768605}
- FSharp.Core
-
-
-
-
\ No newline at end of file
diff --git a/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj b/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj
index 189ff8c596e..f7d1e977252 100644
--- a/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj
+++ b/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj
@@ -151,9 +151,6 @@
Utilities\rational.fs
-
- Utilities\TraceCall.fs
-
ErrorLogging\range.fsi
@@ -564,32 +561,53 @@
-
-
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Shell.$(RoslynVSBinariesVersion).$(RoslynVSPackagesVersion)\lib\Microsoft.VisualStudio.Shell.$(RoslynVSBinariesVersion).dll
+
-
+
$(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Threading.14.1.131\lib\net45\Microsoft.VisualStudio.Threading.dll
-
- $(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Shell.Design.14.2.25123\lib\net45\Microsoft.VisualStudio.Shell.Design.dll
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Shell.Design.$(RoslynVSPackagesVersion)\lib\net45\Microsoft.VisualStudio.Shell.Design.dll
-
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Framework.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Utilities.Core.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.0\lib\net45\Microsoft.Build.Tasks.Core.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.DiaSymReader.PortablePdb.1.0.0-rc-60301\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\Microsoft.DiaSymReader.1.0.7\lib\portable-net45+win8\Microsoft.DiaSymReader.dll
+
+
+ $(FSharpSourcesRoot)\..\packages\System.Collections.Immutable.1.2.0-rc3-23805\lib\portable-net45+win8+wp8+wpa81
+
- ..\..\..\packages\Microsoft.DiaSymReader.PortablePdb.1.0.0-rc-60301\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll
- ..\..\..\packages\Microsoft.DiaSymReader.1.0.7\lib\portable-net45+win8\Microsoft.DiaSymReader.dll
- ..\..\..\packages\System.Reflection.Metadata.1.3.0-beta-23816\lib\portable-net45+win8\System.Reflection.Metadata.dll
- ..\..\..\packages\System.Collections.Immutable.1.2.0-rc3-23805\lib\portable-net45+win8+wp8+wpa81
+ ..\..\..\packages\Microsoft.DiaSymReader.PortablePdb.1.1.0\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll
+ ..\..\..\packages\Microsoft.DiaSymReader.1.0.8\lib\portable-net45+win8\Microsoft.DiaSymReader.dll
+ ..\..\..\packages\System.Reflection.Metadata.1.4.1-beta-24227-04\lib\portable-net45+win8\System.Reflection.Metadata.dll
+ ..\..\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81
{DED3BBD7-53F4-428A-8C9F-27968E768605}
FSharp.Core
diff --git a/src/fsharp/FSharp.LanguageService.Compiler/InternalsVisibleTo.fs b/src/fsharp/FSharp.LanguageService.Compiler/InternalsVisibleTo.fs
index 319ad669029..0460b3c185d 100644
--- a/src/fsharp/FSharp.LanguageService.Compiler/InternalsVisibleTo.fs
+++ b/src/fsharp/FSharp.LanguageService.Compiler/InternalsVisibleTo.fs
@@ -6,7 +6,6 @@ open System.Reflection
[]
[]
[]
-[]
[]
[]
[]
@@ -16,7 +15,7 @@ open System.Reflection
[]
[]
[]
-
+[]
do()
diff --git a/src/fsharp/FindUnsolved.fs b/src/fsharp/FindUnsolved.fs
index 66f421f3522..0635dc3c189 100644
--- a/src/fsharp/FindUnsolved.fs
+++ b/src/fsharp/FindUnsolved.fs
@@ -29,9 +29,9 @@ open Microsoft.FSharp.Compiler.Infos
type env = Nix
type cenv =
- { g: TcGlobals;
- amap: Import.ImportMap;
- denv: DisplayEnv;
+ { g: TcGlobals
+ amap: Import.ImportMap
+ denv: DisplayEnv
mutable unsolved: Typars }
let accTy cenv _env ty =
@@ -50,29 +50,29 @@ let rec accExpr (cenv:cenv) (env:env) expr =
let expr = stripExpr expr
match expr with
| Expr.Sequential (e1,e2,_,_,_) ->
- accExpr cenv env e1;
+ accExpr cenv env e1
accExpr cenv env e2
| Expr.Let (bind,body,_,_) ->
- accBind cenv env bind ;
+ accBind cenv env bind
accExpr cenv env body
| Expr.Const (_,_,ty) ->
accTy cenv env ty
| Expr.Val (_v,_vFlags,_m) -> ()
| Expr.Quote(ast,_,_,_m,ty) ->
- accExpr cenv env ast;
- accTy cenv env ty;
+ accExpr cenv env ast
+ accTy cenv env ty
| Expr.Obj (_,typ,basev,basecall,overrides,iimpls,_m) ->
accTy cenv env typ
- accExpr cenv env basecall;
- accMethods cenv env basev overrides ;
- accIntfImpls cenv env basev iimpls;
+ accExpr cenv env basecall
+ accMethods cenv env basev overrides
+ accIntfImpls cenv env basev iimpls
| Expr.Op (c,tyargs,args,m) ->
accOp cenv env (c,tyargs,args,m)
| Expr.App(f,fty,tyargs,argsl,_m) ->
- accTy cenv env fty;
- accTypeInst cenv env tyargs;
- accExpr cenv env f;
+ accTy cenv env fty
+ accTypeInst cenv env tyargs
+ accExpr cenv env f
accExprs cenv env argsl
// REVIEW: fold the next two cases together
| Expr.Lambda(_,_ctorThisValOpt,_baseValOpt,argvs,_body,m,rty) ->
@@ -81,24 +81,24 @@ let rec accExpr (cenv:cenv) (env:env) expr =
accLambdas cenv env topValInfo expr ty
| Expr.TyLambda(_,tps,_body,_m,rty) ->
let topValInfo = ValReprInfo (ValReprInfo.InferTyparInfo tps,[],ValReprInfo.unnamedRetVal)
- accTy cenv env rty;
+ accTy cenv env rty
let ty = tryMkForallTy tps rty
accLambdas cenv env topValInfo expr ty
| Expr.TyChoose(_tps,e1,_m) ->
accExpr cenv env e1
| Expr.Match(_,_exprm,dtree,targets,m,ty) ->
- accTy cenv env ty;
- accDTree cenv env dtree;
- accTargets cenv env m ty targets;
+ accTy cenv env ty
+ accDTree cenv env dtree
+ accTargets cenv env m ty targets
| Expr.LetRec (binds,e,_m,_) ->
- accBinds cenv env binds;
+ accBinds cenv env binds
accExpr cenv env e
| Expr.StaticOptimization (constraints,e2,e3,_m) ->
- accExpr cenv env e2;
- accExpr cenv env e3;
+ accExpr cenv env e2
+ accExpr cenv env e3
constraints |> List.iter (function
| TTyconEqualsTycon(ty1,ty2) ->
- accTy cenv env ty1;
+ accTy cenv env ty1
accTy cenv env ty2
| TTyconIsStruct(ty1) ->
accTy cenv env ty1)
@@ -106,7 +106,7 @@ let rec accExpr (cenv:cenv) (env:env) expr =
and accMethods cenv env baseValOpt l = List.iter (accMethod cenv env baseValOpt) l
and accMethod cenv env _baseValOpt (TObjExprMethod(_slotsig,_attribs,_tps,vs,e,_m)) =
- vs |> List.iterSquared (accVal cenv env);
+ vs |> List.iterSquared (accVal cenv env)
accExpr cenv env e
and accIntfImpls cenv env baseValOpt l = List.iter (accIntfImpl cenv env baseValOpt) l
@@ -116,16 +116,16 @@ and accIntfImpl cenv env baseValOpt (ty,overrides) =
and accOp cenv env (op,tyargs,args,_m) =
// Special cases
- accTypeInst cenv env tyargs;
- accExprs cenv env args;
+ accTypeInst cenv env tyargs
+ accExprs cenv env args
match op with
// Handle these as special cases since mutables are allowed inside their bodies
| TOp.ILCall (_,_,_,_,_,_,_,_,enclTypeArgs,methTypeArgs,tys) ->
- accTypeInst cenv env enclTypeArgs;
- accTypeInst cenv env methTypeArgs;
+ accTypeInst cenv env enclTypeArgs
+ accTypeInst cenv env methTypeArgs
accTypeInst cenv env tys
| TOp.TraitCall(TTrait(tys,_nm,_,argtys,rty,_sln)) ->
- argtys |> accTypeInst cenv env ;
+ argtys |> accTypeInst cenv env
rty |> Option.iter (accTy cenv env)
tys |> List.iter (accTy cenv env)
@@ -139,11 +139,11 @@ and accLambdas cenv env topValInfo e ety =
| Expr.Lambda _
| Expr.TyLambda _ ->
let _tps,ctorThisValOpt,baseValOpt,vsl,body,bodyty = destTopLambda cenv.g cenv.amap topValInfo (e, ety)
- accTy cenv env bodyty;
- vsl |> List.iterSquared (accVal cenv env);
- baseValOpt |> Option.iter (accVal cenv env);
- ctorThisValOpt |> Option.iter (accVal cenv env);
- accExpr cenv env body;
+ accTy cenv env bodyty
+ vsl |> List.iterSquared (accVal cenv env)
+ baseValOpt |> Option.iter (accVal cenv env)
+ ctorThisValOpt |> Option.iter (accVal cenv env)
+ accExpr cenv env body
| _ ->
accExpr cenv env e
@@ -151,17 +151,17 @@ and accExprs cenv env exprs = exprs |> List.iter (accExpr cenv env)
and accFlatExprs cenv env exprs = exprs |> FlatList.iter (accExpr cenv env)
and accTargets cenv env m ty targets = Array.iter (accTarget cenv env m ty) targets
-and accTarget cenv env _m _ty (TTarget(_vs,e,_)) = accExpr cenv env e;
+and accTarget cenv env _m _ty (TTarget(_vs,e,_)) = accExpr cenv env e
and accDTree cenv env x =
match x with
- | TDSuccess (es,_n) -> accFlatExprs cenv env es;
+ | TDSuccess (es,_n) -> accFlatExprs cenv env es
| TDBind(bind,rest) -> accBind cenv env bind; accDTree cenv env rest
| TDSwitch (e,cases,dflt,m) -> accSwitch cenv env (e,cases,dflt,m)
and accSwitch cenv env (e,cases,dflt,_m) =
- accExpr cenv env e;
- cases |> List.iter (fun (TCase(discrim,e)) -> accDiscrim cenv env discrim; accDTree cenv env e) ;
+ accExpr cenv env e
+ cases |> List.iter (fun (TCase(discrim,e)) -> accDiscrim cenv env discrim; accDTree cenv env e)
dflt |> Option.iter (accDTree cenv env)
and accDiscrim cenv env d =
@@ -172,31 +172,31 @@ and accDiscrim cenv env d =
| Test.IsNull -> ()
| Test.IsInst (srcty,tgty) -> accTy cenv env srcty; accTy cenv env tgty
| Test.ActivePatternCase (exp, tys, _, _, _) ->
- accExpr cenv env exp;
+ accExpr cenv env exp
accTypeInst cenv env tys
and accAttrib cenv env (Attrib(_,_k,args,props,_,_,_m)) =
- args |> List.iter (fun (AttribExpr(e1,_)) -> accExpr cenv env e1);
+ args |> List.iter (fun (AttribExpr(e1,_)) -> accExpr cenv env e1)
props |> List.iter (fun (AttribNamedArg(_nm,_ty,_flg,AttribExpr(expr,_))) -> accExpr cenv env expr)
and accAttribs cenv env attribs = List.iter (accAttrib cenv env) attribs
and accValReprInfo cenv env (ValReprInfo(_,args,ret)) =
- args |> List.iterSquared (accArgReprInfo cenv env);
- ret |> accArgReprInfo cenv env;
+ args |> List.iterSquared (accArgReprInfo cenv env)
+ ret |> accArgReprInfo cenv env
and accArgReprInfo cenv env (argInfo: ArgReprInfo) =
accAttribs cenv env argInfo.Attribs
and accVal cenv env v =
- v.Attribs |> accAttribs cenv env;
- v.ValReprInfo |> Option.iter (accValReprInfo cenv env);
+ v.Attribs |> accAttribs cenv env
+ v.ValReprInfo |> Option.iter (accValReprInfo cenv env)
v.Type |> accTy cenv env
and accBind cenv env (bind:Binding) =
- accVal cenv env bind.Var;
+ accVal cenv env bind.Var
let topValInfo = match bind.Var.ValReprInfo with Some info -> info | _ -> ValReprInfo.emptyValData
- accLambdas cenv env topValInfo bind.Expr bind.Var.Type;
+ accLambdas cenv env topValInfo bind.Expr bind.Var.Type
and accBinds cenv env xs = xs |> FlatList.iter (accBind cenv env)
@@ -205,15 +205,15 @@ and accBinds cenv env xs = xs |> FlatList.iter (accBind cenv env)
//--------------------------------------------------------------------------
let accTyconRecdField cenv env _tycon (rfield:RecdField) =
- accAttribs cenv env rfield.PropertyAttribs;
+ accAttribs cenv env rfield.PropertyAttribs
accAttribs cenv env rfield.FieldAttribs
let accTycon cenv env (tycon:Tycon) =
- accAttribs cenv env tycon.Attribs;
- tycon.AllFieldsArray |> Array.iter (accTyconRecdField cenv env tycon);
+ accAttribs cenv env tycon.Attribs
+ tycon.AllFieldsArray |> Array.iter (accTyconRecdField cenv env tycon)
if tycon.IsUnionTycon then (* This covers finite unions. *)
tycon.UnionCasesAsList |> List.iter (fun uc ->
- accAttribs cenv env uc.Attribs;
+ accAttribs cenv env uc.Attribs
uc.RecdFields |> List.iter (accTyconRecdField cenv env tycon))
@@ -232,7 +232,7 @@ and accModuleOrNamespaceDefs cenv env x = List.iter (accModuleOrNamespaceDef cen
and accModuleOrNamespaceDef cenv env x =
match x with
| TMDefRec(_,tycons,mbinds,_m) ->
- accTycons cenv env tycons;
+ accTycons cenv env tycons
accModuleOrNamespaceBinds cenv env mbinds
| TMDefLet(bind,_m) -> accBind cenv env bind
| TMDefDo(e,_m) -> accExpr cenv env e
@@ -246,12 +246,12 @@ and accModuleOrNamespaceBind cenv env x =
let UnsolvedTyparsOfModuleDef g amap denv (mdef, extraAttribs) =
let cenv =
- { g =g ;
- amap=amap;
- denv=denv;
+ { g =g
+ amap=amap
+ denv=denv
unsolved = [] }
- accModuleOrNamespaceDef cenv Nix mdef;
- accAttribs cenv Nix extraAttribs;
+ accModuleOrNamespaceDef cenv Nix mdef
+ accAttribs cenv Nix extraAttribs
List.rev cenv.unsolved
diff --git a/src/fsharp/Fsc/project.json b/src/fsharp/Fsc/project.json
index 1a1ee3bbd68..b246aa367ea 100644
--- a/src/fsharp/Fsc/project.json
+++ b/src/fsharp/Fsc/project.json
@@ -1,17 +1,17 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.0.1-rc2-24027",
- "NETStandard.Library": "1.5.0-rc2-24027",
- "System.Linq.Expressions": "4.0.11-rc2-24027",
- "System.Reflection.Metadata": "1.3.0-rc2-24027",
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "NETStandard.Library": "1.6.0",
+ "System.Linq.Expressions": "4.1.0",
+ "System.Reflection.Metadata": "1.4.1-beta-24227-04"
},
"runtimes": {
"win7-x86": { },
"win7-x64": { },
- "osx.10.10-x64": { },
+ "osx.10.11-x64": { },
"ubuntu.14.04-x64": { }
},
"frameworks": {
- "netstandard1.5": { }
+ "netstandard1.6": { }
}
}
diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs
index 2c5de389d77..85e07ad0d67 100644
--- a/src/fsharp/IlxGen.fs
+++ b/src/fsharp/IlxGen.fs
@@ -124,7 +124,7 @@ let ReportStatistics (oc:TextWriter) = reports oc
let NewCounter nm =
let count = ref 0
- AddReport (fun oc -> if !count <> 0 then oc.WriteLine (string !count + " " + nm));
+ AddReport (fun oc -> if !count <> 0 then oc.WriteLine (string !count + " " + nm))
(fun () -> incr count)
let CountClosure = NewCounter "closures"
@@ -194,8 +194,8 @@ type cenv =
viewCcu: CcuThunk
opts: IlxGenOptions
/// Cache the generation of the "unit" type
- mutable ilUnitTy: ILType option;
- amap: Import.ImportMap;
+ mutable ilUnitTy: ILType option
+ amap: Import.ImportMap
intraAssemblyInfo : IlxGenIntraAssemblyInfo
/// Cache methods with SecurityAttribute applied to them, to prevent unnecessary calls to ExistsInEntireHierarchyOfType
casApplied : Dictionary }
@@ -226,10 +226,10 @@ let useCallVirt cenv boxity (mspec : ILMethodSpec) isBaseCall =
/// Referencing other stuff, and descriptions of where items are to be placed
/// within the generated IL namespace/typespace. This should be cleaned up.
type CompileLocation =
- { clocScope: IL.ILScopeRef;
- clocTopImplQualifiedName: string;
- clocNamespace: string option;
- clocEncl: string list;
+ { clocScope: IL.ILScopeRef
+ clocTopImplQualifiedName: string
+ clocNamespace: string option
+ clocEncl: string list
clocQualifiedNameOfFile : string }
//--------------------------------------------------------------------------
@@ -239,10 +239,10 @@ type CompileLocation =
let mkTopName ns n = String.concat "." (match ns with Some x -> [x;n] | None -> [n])
let CompLocForFragment fragName (ccu:CcuThunk) =
- { clocQualifiedNameOfFile =fragName;
- clocTopImplQualifiedName= fragName;
- clocScope=ccu.ILScopeRef;
- clocNamespace=None;
+ { clocQualifiedNameOfFile =fragName
+ clocTopImplQualifiedName= fragName
+ clocScope=ccu.ILScopeRef
+ clocNamespace=None
clocEncl=[]}
let CompLocForCcu (ccu:CcuThunk) = CompLocForFragment ccu.AssemblyName ccu
@@ -259,10 +259,10 @@ let CompLocForFixedPath fragName qname (CompPath(sref,cpath)) =
let ns = textOfPath ns
let encl = t |> List.map (fun (s ,_)-> s)
let ns = if ns = "" then None else Some ns
- { clocQualifiedNameOfFile =fragName;
- clocTopImplQualifiedName=qname;
- clocScope=sref;
- clocNamespace=ns;
+ { clocQualifiedNameOfFile =fragName
+ clocTopImplQualifiedName=qname
+ clocScope=sref
+ clocNamespace=ns
clocEncl=encl }
let CompLocForFixedModule fragName qname (mspec:ModuleOrNamespace) =
@@ -333,7 +333,7 @@ type TypeReprEnv(reprs : Map, count: int) =
member tyenv.Item (tp:Typar, m:range) =
try reprs.[tp.Stamp]
with :? KeyNotFoundException ->
- errorR(InternalError("Undefined or unsolved type variable: " + showL(typarL tp),m));
+ errorR(InternalError("Undefined or unsolved type variable: " + showL(typarL tp),m))
// Random value for post-hoc diagnostic analysis on generated tree *
uint16 666
@@ -366,7 +366,7 @@ type TypeReprEnv(reprs : Map, count: int) =
//--------------------------------------------------------------------------
let GenTyconRef (tcref:TyconRef) =
- assert(not tcref.IsTypeAbbrev);
+ assert(not tcref.IsTypeAbbrev)
tcref.CompiledRepresentation
type VoidNotOK = VoidNotOK | VoidOK
@@ -422,7 +422,7 @@ and GenNamedTyAppAux (amap:Import.ImportMap) m g tyenv ptrsOK tcref tinst =
and GenTypeAux amap m g (tyenv: TypeReprEnv) voidOK ptrsOK ty =
#if DEBUG
- voidCheck m g voidOK ty;
+ voidCheck m g voidOK ty
#else
ignore voidOK
#endif
@@ -457,7 +457,7 @@ and GenUnionCaseRef amap m g tyenv i (fspecs:RecdField array) =
and GenUnionRef amap m g (tcref: TyconRef) =
let tycon = tcref.Deref
- assert(not tycon.IsTypeAbbrev);
+ assert(not tycon.IsTypeAbbrev)
match tycon.UnionTypeInfo with
| None -> failwith "GenUnionRef m"
| Some funion ->
@@ -468,12 +468,13 @@ and GenUnionRef amap m g (tcref: TyconRef) =
| CompiledTypeRepr.ILAsmNamed (tref,_,_) ->
let alternatives =
tycon.UnionCasesArray |> Array.mapi (fun i cspec ->
- { altName=cspec.CompiledName;
- altCustomAttrs=emptyILCustomAttrs;
+ { altName=cspec.CompiledName
+ altCustomAttrs=emptyILCustomAttrs
altFields=GenUnionCaseRef amap m g tyenvinner i cspec.RecdFieldsArray })
let nullPermitted = IsUnionTypeWithNullAsTrueValue g tycon
let hasHelpers = ComputeUnionHasHelpers g tcref
- IlxUnionRef(tref,alternatives,nullPermitted,hasHelpers))
+ let boxity = (if tcref.IsStructOrEnumTycon then ILBoxity.AsValue else ILBoxity.AsObject)
+ IlxUnionRef(boxity, tref,alternatives,nullPermitted,hasHelpers))
and ComputeUnionHasHelpers g (tcref : TyconRef) =
if tyconRefEq g tcref g.unit_tcr_canon then NoHelpers
@@ -484,7 +485,7 @@ and ComputeUnionHasHelpers g (tcref : TyconRef) =
| Some(Attrib(_,_,[ AttribBoolArg (b) ],_,_,_,_)) ->
if b then AllHelpers else NoHelpers
| Some (Attrib(_,_,_,_,_,_,m)) ->
- errorR(Error(FSComp.SR.ilDefaultAugmentationAttributeCouldNotBeDecoded(),m));
+ errorR(Error(FSComp.SR.ilDefaultAugmentationAttributeCouldNotBeDecoded(),m))
AllHelpers
| _ ->
AllHelpers (* not hiddenRepr *)
@@ -572,17 +573,17 @@ type ArityInfo = int list
[]
type IlxClosureInfo =
- { cloExpr: Expr;
- cloName: string;
- cloArityInfo: ArityInfo;
- cloILFormalRetTy: ILType;
+ { cloExpr: Expr
+ cloName: string
+ cloArityInfo: ArityInfo
+ cloILFormalRetTy: ILType
/// An immutable array of free variable descriptions for the closure
- cloILFreeVars: IlxClosureFreeVar[];
- cloSpec: IlxClosureSpec;
- cloAttribs: Attribs;
- cloILGenericParams: IL.ILGenericParameterDefs;
- cloFreeVars: Val list; (* nb. the freevars we actually close over *)
- ilCloLambdas: IlxClosureLambdas;
+ cloILFreeVars: IlxClosureFreeVar[]
+ cloSpec: IlxClosureSpec
+ cloAttribs: Attribs
+ cloILGenericParams: IL.ILGenericParameterDefs
+ cloFreeVars: Val list (* nb. the freevars we actually close over *)
+ ilCloLambdas: IlxClosureLambdas
(* local type func support *)
/// The free type parameters occuring in the type of the closure (and not just its body)
@@ -595,10 +596,10 @@ type IlxClosureInfo =
/// At the callsite we generate
/// unbox ty['fv]
/// callvirt clo.DirectInvoke
- localTypeFuncILGenericArgs: ILType list;
- localTypeFuncContractFreeTypars: Typar list;
+ localTypeFuncILGenericArgs: ILType list
+ localTypeFuncContractFreeTypars: Typar list
localTypeFuncDirectILGenericParams: IL.ILGenericParameterDefs
- localTypeFuncInternalFreeTypars: Typar list;}
+ localTypeFuncInternalFreeTypars: Typar list}
//--------------------------------------------------------------------------
@@ -639,8 +640,8 @@ and NamedLocalIlxClosureInfo =
| NamedLocalIlxClosureInfoGenerated of IlxClosureInfo
and ModuleStorage =
- { Vals: Lazy> ;
- SubModules: Lazy>; }
+ { Vals: Lazy>
+ SubModules: Lazy> }
/// BranchCallItems are those where a call to the value can be implemented as
/// a branch. At the moment these are only used for generating branch calls back to
@@ -664,23 +665,23 @@ and Mark =
member x.CodeLabel = (let (Mark(lab)) = x in lab)
and IlxGenEnv =
- { tyenv: TypeReprEnv;
- someTypeInThisAssembly: ILType;
- isFinalFile: bool;
+ { tyenv: TypeReprEnv
+ someTypeInThisAssembly: ILType
+ isFinalFile: bool
/// Where to place the stuff we're currently generating
- cloc: CompileLocation;
+ cloc: CompileLocation
/// Hiding information down the signature chain, used to compute what's public to the assembly
- sigToImplRemapInfo: (Remap * SignatureHidingInfo) list;
+ sigToImplRemapInfo: (Remap * SignatureHidingInfo) list
/// All values in scope
- valsInScope: ValMap>;
+ valsInScope: ValMap>
/// For optimizing direct tail recusion to a loop - mark says where to branch to. Length is 0 or 1.
/// REVIEW: generalize to arbitrary nested local loops??
- innerVals: (ValRef * (BranchCallItem * Mark)) list;
+ innerVals: (ValRef * (BranchCallItem * Mark)) list
/// Full list of enclosing bound values. First non-compiler-generated element is used to help give nice names for closures and other expressions.
- letBoundVars: ValRef list;
+ letBoundVars: ValRef list
/// The set of IL local variable indexes currently in use by lexically scoped variables, to allow reuse on different branches.
/// Really an integer set.
- liveLocals: IntMap;
+ liveLocals: IntMap
/// Are we under the scope of a try, catch or finally? If so we can't tailcall. SEH = structured exception handling
withinSEH: bool }
@@ -750,7 +751,7 @@ let StorageForVal m v eenv =
try eenv.valsInScope.[v]
with :? KeyNotFoundException ->
assert false
- errorR(Error(FSComp.SR.ilUndefinedValue(showL(vspecAtBindL v)),m));
+ errorR(Error(FSComp.SR.ilUndefinedValue(showL(vspecAtBindL v)),m))
notlazy (Arg 668(* random value for post-hoc diagnostic analysis on generated tree *) )
v.Force()
@@ -771,7 +772,7 @@ let IsValRefIsDllImport g (vref:ValRef) =
let GetMethodSpecForMemberVal amap g (memberInfo:ValMemberInfo) (vref:ValRef) =
let m = vref.Range
let tps,curriedArgInfos,returnTy,retInfo =
- assert(vref.ValReprInfo.IsSome);
+ assert(vref.ValReprInfo.IsSome)
GetTopValTypeInCompiledForm g (Option.get vref.ValReprInfo) vref.Type m
let tyenvUnderTypars = TypeReprEnv.ForTypars tps
let flatArgInfos = List.concat curriedArgInfos
@@ -780,7 +781,7 @@ let GetMethodSpecForMemberVal amap g (memberInfo:ValMemberInfo) (vref:ValRef) =
let parentTcref = vref.TopValActualParent
let parentTypars = parentTcref.TyparsNoRange
let numParentTypars = parentTypars.Length
- if tps.Length < numParentTypars then error(InternalError("CodeGen check: type checking did not ensure that this method is sufficiently generic", m));
+ if tps.Length < numParentTypars then error(InternalError("CodeGen check: type checking did not ensure that this method is sufficiently generic", m))
let ctps,mtps = List.chop numParentTypars tps
let isCompiledAsInstance = ValRefIsCompiledAsInstanceMember g vref
@@ -807,7 +808,7 @@ let GetMethodSpecForMemberVal amap g (memberInfo:ValMemberInfo) (vref:ValRef) =
if not (typeEquiv g (mkTyparTy gtp) ty2) then
warning(InternalError("CodeGen check: type checking did not quantify the correct type variables for this method: generalization list contained " + gtp.Name + "#" + string gtp.Stamp + " and list from 'this' pointer contained " + (showL(typeL ty2)), m)))
ctps
- thisArgTys;
+ thisArgTys
let methodArgTys,paramInfos = List.unzip flatArgInfos
let ilMethodArgTys = GenParamTypes amap m g tyenvUnderTypars methodArgTys
let ilMethodInst = GenTypeArgs amap m g tyenvUnderTypars (List.map mkTyparTy mtps)
@@ -1041,17 +1042,17 @@ let MergeOptions m o1 o2 =
| Some x, Some _ ->
#if DEBUG
// This warning fires on some code that also triggers this warning:
- // warning(Error("The implementation of a specified generic interface required a method implementation not fully supported by F# Interactive. In the unlikely event that the resulting class fails to load then compile the interface type into a statically-compiled DLL and reference it using '#r'",m));
+ // warning(Error("The implementation of a specified generic interface required a method implementation not fully supported by F# Interactive. In the unlikely event that the resulting class fails to load then compile the interface type into a statically-compiled DLL and reference it using '#r'",m))
// THe code is OK so we don't print this.
- errorR(InternalError("MergeOptions: two values given",m));
+ errorR(InternalError("MergeOptions: two values given",m))
#else
ignore m
#endif
Some x
let MergePropertyPair m (pd: ILPropertyDef) pdef =
- {pd with GetMethod=MergeOptions m pd.GetMethod pdef.GetMethod;
- SetMethod=MergeOptions m pd.SetMethod pdef.SetMethod;}
+ {pd with GetMethod=MergeOptions m pd.GetMethod pdef.GetMethod
+ SetMethod=MergeOptions m pd.SetMethod pdef.SetMethod}
type PropKey = PropKey of string * ILTypes * ILThisConvention
@@ -1067,7 +1068,7 @@ let AddPropertyDefToHash (m:range) (ht:Dictionary
/// Merge a whole group of properties all at once
let MergePropertyDefs m ilPropertyDefs =
let ht = new Dictionary<_,_>(3,HashIdentity.Structural)
- ilPropertyDefs |> List.iter (AddPropertyDefToHash m ht);
+ ilPropertyDefs |> List.iter (AddPropertyDefToHash m ht)
HashRangeSorted ht
//--------------------------------------------------------------------------
@@ -1084,10 +1085,10 @@ type TypeDefBuilder(tdef, tdefDiscards) =
member b.Close() =
{ tdef with
- Methods = mkILMethods (tdef.Methods.AsList @ ResizeArray.toList gmethods);
- Fields = mkILFields (tdef.Fields.AsList @ ResizeArray.toList gfields);
- Properties = mkILProperties (tdef.Properties.AsList @ HashRangeSorted gproperties );
- Events = mkILEvents (tdef.Events.AsList @ ResizeArray.toList gevents);
+ Methods = mkILMethods (tdef.Methods.AsList @ ResizeArray.toList gmethods)
+ Fields = mkILFields (tdef.Fields.AsList @ ResizeArray.toList gfields)
+ Properties = mkILProperties (tdef.Properties.AsList @ HashRangeSorted gproperties )
+ Events = mkILEvents (tdef.Events.AsList @ ResizeArray.toList gevents)
NestedTypes = mkILTypeDefs (tdef.NestedTypes.AsList @ gnested.Close()) }
@@ -1168,7 +1169,7 @@ type AssemblyBuilder(cenv:cenv) as mgbuf =
let vtref = NestedTypeRefForCompLoc cloc vtdef.Name
let vtspec = mkILTySpec(vtref,[])
let vtdef = {vtdef with Access= ComputeTypeAccess vtref true}
- mgbuf.AddTypeDef(vtref, vtdef, false, true, None);
+ mgbuf.AddTypeDef(vtref, vtdef, false, true, None)
vtspec),
keyComparer=HashIdentity.Structural)
@@ -1204,7 +1205,7 @@ type AssemblyBuilder(cenv:cenv) as mgbuf =
gtdefs.FindNestedTypeDefsBuilder(tref.Enclosing).AddTypeDef(tdef, eliminateIfEmpty, addAtEnd, tdefDiscards)
member mgbuf.GetCurrentFields(tref:ILTypeRef) =
- gtdefs.FindNestedTypeDefBuilder(tref).GetCurrentFields();
+ gtdefs.FindNestedTypeDefBuilder(tref).GetCurrentFields()
member mgbuf.AddReflectedDefinition(vspec : Tast.Val,expr) =
// preserve order by storing index of item
@@ -1217,7 +1218,7 @@ type AssemblyBuilder(cenv:cenv) as mgbuf =
| _ -> ()
member mgbuf.AddMethodDef(tref:ILTypeRef,ilMethodDef) =
- gtdefs.FindNestedTypeDefBuilder(tref).AddMethodDef(ilMethodDef);
+ gtdefs.FindNestedTypeDefBuilder(tref).AddMethodDef(ilMethodDef)
if ilMethodDef.IsEntryPoint then
explicitEntryPointInfo <- Some(tref)
@@ -1226,9 +1227,9 @@ type AssemblyBuilder(cenv:cenv) as mgbuf =
// Doing both a store and load keeps FxCop happier because it thinks the field is useful
let instrs =
[ yield! (if condition "NO_ADD_FEEFEE_TO_CCTORS" then [] elif condition "ADD_SEQPT_TO_CCTORS" then seqpt else feefee) // mark start of hidden code
- yield mkLdcInt32 0;
- yield mkNormalStsfld fspec;
- yield mkNormalLdsfld fspec;
+ yield mkLdcInt32 0
+ yield mkNormalStsfld fspec
+ yield mkNormalLdsfld fspec
yield AI_pop]
gtdefs.FindNestedTypeDefBuilder(tref).PrependInstructionsToSpecificMethodDef(cond,instrs,sourceOpt)
@@ -1277,7 +1278,7 @@ type CodeGenBuffer(m:range,
alreadyUsedLocals:int,
zapFirstSeqPointToStart:bool) =
- let locals = new ResizeArray<((string * (Mark * Mark)) list * ILType)>(10)
+ let locals = new ResizeArray<((string * (Mark * Mark)) list * ILType * bool)>(10)
let codebuf = new ResizeArray(200)
let exnSpecs = new ResizeArray(10)
@@ -1301,12 +1302,12 @@ type CodeGenBuffer(m:range,
let mutable lastSeqPoint = None
// Add a nop to make way for the first sequence point. There is always such a
// sequence point even when zapFirstSeqPointToStart=false
- do if mgbuf.cenv.opts.generateDebugSymbols then codebuf.Add(AI_nop);
+ do if mgbuf.cenv.opts.generateDebugSymbols then codebuf.Add(AI_nop)
member cgbuf.DoPushes (pushes: Pushes) =
for ty in pushes do
- stack <- ty :: stack;
- nstack <- nstack + 1;
+ stack <- ty :: stack
+ nstack <- nstack + 1
maxStack <- Operators.max maxStack nstack
member cgbuf.DoPops (n:Pops) =
@@ -1315,9 +1316,9 @@ type CodeGenBuffer(m:range,
| [] ->
let msg = sprintf "pop on empty stack during code generation, methodName = %s, m = %s" methodName (stringOfRange m)
System.Diagnostics.Debug.Assert(false, msg)
- warning(InternalError(msg,m));
+ warning(InternalError(msg,m))
| _ :: t ->
- stack <- t;
+ stack <- t
nstack <- nstack - 1
member cgbuf.GetCurrentStack() = stack
@@ -1325,17 +1326,17 @@ type CodeGenBuffer(m:range,
if nonNil stack then
let msg = sprintf "stack flush didn't work, or extraneous expressions left on stack before stack restore, methodName = %s, stack = %+A, m = %s" methodName stack (stringOfRange m)
System.Diagnostics.Debug.Assert(false, msg)
- warning(InternalError(msg,m));
+ warning(InternalError(msg,m))
()
member cgbuf.EmitInstr(pops,pushes,i) =
- cgbuf.DoPops pops;
- cgbuf.DoPushes pushes;
+ cgbuf.DoPops pops
+ cgbuf.DoPushes pushes
codebuf.Add i
member cgbuf.EmitInstrs (pops,pushes,is) =
- cgbuf.DoPops pops;
- cgbuf.DoPushes pushes;
+ cgbuf.DoPops pops
+ cgbuf.DoPushes pushes
is |> List.iter codebuf.Add
member cgbuf.GetLastSequencePoint() =
@@ -1349,16 +1350,16 @@ type CodeGenBuffer(m:range,
| I_seqpoint sm when sm.Line <> FeeFee mgbuf.cenv -> true
| _ -> false)) then
- codebuf.Add(AI_nop);
+ codebuf.Add(AI_nop)
member cgbuf.EmitSeqPoint(src) =
if mgbuf.cenv.opts.generateDebugSymbols then
cgbuf.EnsureNopBetweenDebugPoints()
let attr = GenILSourceMarker mgbuf.cenv.g src
- assert(isSome(attr));
+ assert(isSome(attr))
let i = I_seqpoint (Option.get attr)
- codebuf.Add i;
+ codebuf.Add i
// Save the first sequence point away to snap it to the top of the method
match seqpoint with
| Some _ -> ()
@@ -1370,7 +1371,7 @@ type CodeGenBuffer(m:range,
member cgbuf.EmitStartOfHiddenCode() =
if mgbuf.cenv.opts.generateDebugSymbols && not mgbuf.cenv.opts.localOptimizationsAreOn then
let doc = mgbuf.cenv.g.memoize_file m.FileIndex
- codebuf.Add(FeeFeeInstr mgbuf.cenv doc);
+ codebuf.Add(FeeFeeInstr mgbuf.cenv doc)
member cgbuf.EmitExceptionClause(clause) =
exnSpecs.Add clause
@@ -1384,7 +1385,7 @@ type CodeGenBuffer(m:range,
if codeLabelToCodeLabel.ContainsKey(lab1) then
let msg = sprintf "two values given for label %s, methodName = %s, m = %s" (formatCodeLabel lab1) methodName (stringOfRange m)
System.Diagnostics.Debug.Assert(false, msg)
- warning(InternalError(msg,m));
+ warning(InternalError(msg,m))
#endif
codeLabelToCodeLabel.[lab1] <- lab2
@@ -1393,7 +1394,7 @@ type CodeGenBuffer(m:range,
if codeLabelToPC.ContainsKey(lab) then
let msg = sprintf "two values given for label %s, methodName = %s, m = %s" (formatCodeLabel lab) methodName (stringOfRange m)
System.Diagnostics.Debug.Assert(false, msg)
- warning(InternalError(msg,m));
+ warning(InternalError(msg,m))
#endif
codeLabelToPC.[lab] <- pc
@@ -1404,32 +1405,32 @@ type CodeGenBuffer(m:range,
cgbuf.SetCodeLabelToPC(lab,codebuf.Count)
member cgbuf.SetStack(s) =
- stack <- s;
+ stack <- s
nstack <- s.Length
member cgbuf.Mark(s) =
let res = cgbuf.GenerateDelayMark(s)
- cgbuf.SetMarkToHere(res);
+ cgbuf.SetMarkToHere(res)
res
member cgbuf.mgbuf = mgbuf
member cgbuf.MethodName = methodName
member cgbuf.PreallocatedArgCount = alreadyUsedArgs
- member cgbuf.AllocLocal(ranges,ty) =
+ member cgbuf.AllocLocal(ranges,ty,isFixed) =
let j = locals.Count
- locals.Add((ranges,ty));
+ locals.Add((ranges,ty,isFixed))
j
- member cgbuf.ReallocLocal(cond,ranges,ty) =
+ member cgbuf.ReallocLocal(cond,ranges,ty,isFixed) =
let j =
match ResizeArray.tryFindIndexi cond locals with
| Some j ->
- let (prevRanges,_) = locals.[j]
- locals.[j] <- ((ranges@prevRanges),ty);
+ let (prevRanges,_,isFixed) = locals.[j]
+ locals.[j] <- ((ranges@prevRanges),ty,isFixed)
j
| None ->
- cgbuf.AllocLocal(ranges,ty)
+ cgbuf.AllocLocal(ranges,ty,isFixed)
let j = j + alreadyUsedLocals
j
@@ -1487,7 +1488,7 @@ let GenString cenv cgbuf s =
let GenConstArray cenv (cgbuf:CodeGenBuffer) eenv ilElementType (data:'a[]) (write : ByteBuffer -> 'a -> unit) =
let buf = ByteBuffer.Create data.Length
- data |> Array.iter (write buf);
+ data |> Array.iter (write buf)
let bytes = buf.Close()
let ilArrayType = mkILArr1DTy ilElementType
if data.Length = 0 then
@@ -1499,15 +1500,15 @@ let GenConstArray cenv (cgbuf:CodeGenBuffer) eenv ilElementType (data:'a[]) (wri
let ilFieldDef = mkILStaticField (ilFieldName,fty, None, Some bytes, ILMemberAccess.Assembly)
let ilFieldDef = { ilFieldDef with CustomAttrs = mkILCustomAttrs [ cenv.g.ilg.mkDebuggerBrowsableNeverAttribute() ] }
let fspec = mkILFieldSpecInTy (mkILTyForCompLoc eenv.cloc,ilFieldName, fty)
- CountStaticFieldDef();
- cgbuf.mgbuf.AddFieldDef(fspec.EnclosingTypeRef,ilFieldDef);
+ CountStaticFieldDef()
+ cgbuf.mgbuf.AddFieldDef(fspec.EnclosingTypeRef,ilFieldDef)
CG.EmitInstrs cgbuf
(pop 0)
(Push [ ilArrayType; ilArrayType; cenv.g.ilg.typ_RuntimeFieldHandle ])
- [ mkLdcInt32 data.Length;
- I_newarr (ILArrayShape.SingleDimensional,ilElementType);
- AI_dup;
- I_ldtoken (ILToken.ILField fspec); ]
+ [ mkLdcInt32 data.Length
+ I_newarr (ILArrayShape.SingleDimensional,ilElementType)
+ AI_dup
+ I_ldtoken (ILToken.ILField fspec) ]
CG.EmitInstrs cgbuf
(pop 2)
Push0
@@ -1553,23 +1554,24 @@ let CodeGenThen cenv mgbuf (zapFirstSeqPointToStart,entryPointInfo,methodName,ee
let innerVals = entryPointInfo |> List.map (fun (v,kind) -> (v,(kind,start)))
(* Call the given code generator *)
- codeGenFunction cgbuf {eenv with withinSEH=false;
- liveLocals=IntMap.empty();
- innerVals = innerVals};
+ codeGenFunction cgbuf {eenv with withinSEH=false
+ liveLocals=IntMap.empty()
+ innerVals = innerVals}
let locals,maxStack,lab2pc,code,exnSpecs,hasSequencePoints = cgbuf.Close()
let localDebugSpecs : ILLocalDebugInfo list =
locals
- |> List.mapi (fun i (nms,_) -> List.map (fun nm -> (i,nm)) nms)
+ |> List.mapi (fun i (nms,_,_isFixed) -> List.map (fun nm -> (i,nm)) nms)
|> List.concat
|> List.map (fun (i,(nm,(start,finish))) ->
- { Range=(start.CodeLabel, finish.CodeLabel);
+ { Range=(start.CodeLabel, finish.CodeLabel)
DebugMappings= [{ LocalIndex=i; LocalName=nm }] })
let ilLocals =
locals
- |> List.map (fun (infos, ty) ->
+ |> List.map (fun (infos, ty, isFixed) ->
+ let loc =
// in interactive environment, attach name and range info to locals to improve debug experience
if cenv.opts.isInteractive && cenv.opts.generateDebugSymbols then
match infos with
@@ -1579,7 +1581,8 @@ let CodeGenThen cenv mgbuf (zapFirstSeqPointToStart,entryPointInfo,methodName,ee
| [] -> mkILLocal ty None
// if not interactive, don't bother adding this info
else
- mkILLocal ty None)
+ mkILLocal ty None
+ if isFixed then { loc with IsPinned=true } else loc)
(ilLocals,
maxStack,
@@ -1619,7 +1622,7 @@ let StartLocalScope nm cgbuf =
let LocalScope nm cgbuf (f : (Mark * Mark) -> 'a) : 'a =
let _,endScope as scopeMarks = StartLocalScope nm cgbuf
let res = f scopeMarks
- CG.SetMarkToHere cgbuf endScope;
+ CG.SetMarkToHere cgbuf endScope
res
let compileSequenceExpressions = true // try (System.Environment.GetEnvironmentVariable("COMPILED_SEQ") <> null) with _ -> false
@@ -1685,7 +1688,7 @@ let rec GenExpr cenv (cgbuf:CodeGenBuffer) eenv sp expr sequel =
let expr = stripExpr expr
if not (WillGenerateSequencePoint sp expr) && not (AlwaysSuppressSequencePoint sp expr) then
- CG.EmitSeqPoint cgbuf expr.Range;
+ CG.EmitSeqPoint cgbuf expr.Range
match (if compileSequenceExpressions then LowerCallsAndSeqs.LowerSeqExpr cenv.g cenv.amap expr else None) with
| Some info ->
@@ -1707,8 +1710,8 @@ let rec GenExpr cenv (cgbuf:CodeGenBuffer) eenv sp expr sequel =
let startScope,endScope as scopeMarks = StartDelayedLocalScope "let" cgbuf
let eenv = AllocStorageForBind cenv cgbuf scopeMarks eenv bind
let spBind = GenSequencePointForBind cenv cgbuf eenv bind
- CG.SetMarkToHere cgbuf startScope;
- GenBindAfterSequencePoint cenv cgbuf eenv spBind bind;
+ CG.SetMarkToHere cgbuf startScope
+ GenBindAfterSequencePoint cenv cgbuf eenv spBind bind
// Work out if we need a sequence point for the body. For any "user" binding then the body gets SPAlways.
// For invisible compiler-generated bindings we just use "sp", unless its body is another invisible binding
@@ -1754,6 +1757,8 @@ let rec GenExpr cenv (cgbuf:CodeGenBuffer) eenv sp expr sequel =
GenGetExnField cenv cgbuf eenv (e,ecref,n,m) sequel
| TOp.UnionCaseFieldGet(ucref,n),[e],_ ->
GenGetUnionCaseField cenv cgbuf eenv (e,ucref,tyargs,n,m) sequel
+ | TOp.UnionCaseFieldGetAddr(ucref,n),[e],_ ->
+ GenGetUnionCaseFieldAddr cenv cgbuf eenv (e,ucref,tyargs,n,m) sequel
| TOp.UnionCaseTagGet ucref,[e],_ ->
GenGetUnionCaseTag cenv cgbuf eenv (e,ucref,tyargs,m) sequel
| TOp.UnionCaseProof ucref,[e],_ ->
@@ -1799,13 +1804,13 @@ let rec GenExpr cenv (cgbuf:CodeGenBuffer) eenv sp expr sequel =
| TOp.Array,elems,[elemTy] -> GenNewArray cenv cgbuf eenv (elems,elemTy,m) sequel
| TOp.Bytes bytes,[],[] ->
if cenv.opts.emitConstantArraysUsingStaticDataBlobs then
- GenConstArray cenv cgbuf eenv cenv.g.ilg.typ_uint8 bytes (fun buf b -> buf.EmitByte b);
+ GenConstArray cenv cgbuf eenv cenv.g.ilg.typ_uint8 bytes (fun buf b -> buf.EmitByte b)
GenSequel cenv eenv.cloc cgbuf sequel
else
GenNewArraySimple cenv cgbuf eenv (List.ofArray (Array.map (mkByte cenv.g m) bytes),cenv.g.byte_ty,m) sequel
| TOp.UInt16s arr,[],[] ->
if cenv.opts.emitConstantArraysUsingStaticDataBlobs then
- GenConstArray cenv cgbuf eenv cenv.g.ilg.typ_uint16 arr (fun buf b -> buf.EmitUInt16 b);
+ GenConstArray cenv cgbuf eenv cenv.g.ilg.typ_uint16 arr (fun buf b -> buf.EmitUInt16 b)
GenSequel cenv eenv.cloc cgbuf sequel
else
GenNewArraySimple cenv cgbuf eenv (List.ofArray (Array.map (mkUInt16 cenv.g m) arr),cenv.g.uint16_ty,m) sequel
@@ -1813,7 +1818,7 @@ let rec GenExpr cenv (cgbuf:CodeGenBuffer) eenv sp expr sequel =
if cgbuf.mgbuf.cenv.opts.generateDebugSymbols then
cgbuf.EmitStartOfHiddenCode()
CG.EmitInstr cgbuf (pop 0) Push0 AI_nop
- CG.EmitInstr cgbuf (pop 0) Push0 (I_br label);
+ CG.EmitInstr cgbuf (pop 0) Push0 (I_br label)
// NOTE: discard sequel
| TOp.Return,[e],_ ->
GenExpr cenv cgbuf eenv SPSuppress e Return
@@ -1895,7 +1900,7 @@ and GenSequel cenv cloc cgbuf sequel =
(match sq with
| Continue -> ()
| DiscardThen sq ->
- CG.EmitInstr cgbuf (pop 1) Push0 AI_pop;
+ CG.EmitInstr cgbuf (pop 1) Push0 AI_pop
GenSequel cenv cloc cgbuf sq
| ReturnVoid ->
CG.EmitInstr cgbuf (pop 0) Push0 I_ret
@@ -1916,12 +1921,12 @@ and GenSequel cenv cloc cgbuf sequel =
if isFinally then
CG.EmitInstr cgbuf (pop 1) Push0 AI_pop
else
- EmitSetLocal cgbuf whereToSaveResult;
+ EmitSetLocal cgbuf whereToSaveResult
CG.EmitInstr cgbuf (pop 0) Push0 (if isFinally then I_endfinally else I_leave(x.CodeLabel))
| EndFilter ->
CG.EmitInstr cgbuf (pop 1) Push0 I_endfilter
- );
- GenSequelEndScopes cgbuf sequel;
+ )
+ GenSequelEndScopes cgbuf sequel
//--------------------------------------------------------------------------
@@ -1989,11 +1994,11 @@ and GenAllocTuple cenv cgbuf eenv (args,argtys,m) sequel =
let ntyvars = if (tys.Length - 1) < goodTupleFields then (tys.Length - 1) else goodTupleFields
let formalTyvars = [ for n in 0 .. ntyvars do yield mkILTyvarTy (uint16 n) ]
- GenExprs cenv cgbuf eenv args;
+ GenExprs cenv cgbuf eenv args
// Generate a reference to the constructor
CG.EmitInstr cgbuf (pop args.Length) (Push [typ])
(mkNormalNewobj
- (mkILCtorMethSpecForTy (typ,formalTyvars)));
+ (mkILCtorMethSpecForTy (typ,formalTyvars)))
GenSequel cenv eenv.cloc cgbuf sequel
and GenGetTupleField cenv cgbuf eenv (e,tys,n,m) sequel =
@@ -2020,20 +2025,20 @@ and GenGetTupleField cenv cgbuf eenv (e,tys,n,m) sequel =
and GenAllocExn cenv cgbuf eenv (c,args,m) sequel =
- GenExprs cenv cgbuf eenv args;
+ GenExprs cenv cgbuf eenv args
let typ = GenExnType cenv.amap m cenv.g eenv.tyenv c
let flds = recdFieldsOfExnDefRef c
let argtys = flds |> List.map (fun rfld -> GenType cenv.amap m cenv.g eenv.tyenv rfld.FormalType)
let mspec = mkILCtorMethSpecForTy (typ, argtys)
CG.EmitInstr cgbuf
(pop args.Length) (Push [typ])
- (mkNormalNewobj mspec) ;
+ (mkNormalNewobj mspec)
GenSequel cenv eenv.cloc cgbuf sequel
and GenAllocUnionCase cenv cgbuf eenv (c,tyargs,args,m) sequel =
- GenExprs cenv cgbuf eenv args;
+ GenExprs cenv cgbuf eenv args
let cuspec,idx = GenUnionCaseSpec cenv.amap m cenv.g eenv.tyenv c tyargs
- CG.EmitInstrs cgbuf (pop args.Length) (Push [cuspec.EnclosingType]) (EraseUnions.mkNewData cenv.g.ilg (cuspec, idx));
+ CG.EmitInstrs cgbuf (pop args.Length) (Push [cuspec.EnclosingType]) (EraseUnions.mkNewData cenv.g.ilg (cuspec, idx))
GenSequel cenv eenv.cloc cgbuf sequel
and GenAllocRecd cenv cgbuf eenv ctorInfo (tcref,argtys,args,m) sequel =
@@ -2048,19 +2053,19 @@ and GenAllocRecd cenv cgbuf eenv ctorInfo (tcref,argtys,args,m) sequel =
match ctorInfo with
| RecdExprIsObjInit ->
(args,relevantFields) ||> List.iter2 (fun e f ->
- CG.EmitInstr cgbuf (pop 0) (Push (if tcref.IsStructOrEnumTycon then [ILType.Byref typ] else [typ])) mkLdarg0;
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ CG.EmitInstr cgbuf (pop 0) (Push (if tcref.IsStructOrEnumTycon then [ILType.Byref typ] else [typ])) mkLdarg0
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
GenFieldStore false cenv cgbuf eenv (tcref.MakeNestedRecdFieldRef f,argtys,m) discard)
// Object construction doesn't generate a true value.
// Object constructions will always just get thrown away so this is safe
GenSequel cenv eenv.cloc cgbuf sequel
| RecdExpr ->
- GenExprs cenv cgbuf eenv args;
+ GenExprs cenv cgbuf eenv args
// generate a reference to the record constructor
let tyenvinner = TypeReprEnv.ForTyconRef tcref
CG.EmitInstr cgbuf (pop args.Length) (Push [typ])
(mkNormalNewobj
- (mkILCtorMethSpecForTy (typ,relevantFields |> List.map (fun f -> GenType cenv.amap m cenv.g tyenvinner f.FormalType) )));
+ (mkILCtorMethSpecForTy (typ,relevantFields |> List.map (fun f -> GenType cenv.amap m cenv.g tyenvinner f.FormalType) )))
GenSequel cenv eenv.cloc cgbuf sequel
@@ -2068,10 +2073,10 @@ and GenNewArraySimple cenv cgbuf eenv (elems,elemTy,m) sequel =
let ilElemTy = GenType cenv.amap m cenv.g eenv.tyenv elemTy
let ilArrTy = mkILArr1DTy ilElemTy
- CG.EmitInstrs cgbuf (pop 0) (Push [ilArrTy]) [ (AI_ldc (DT_I4,ILConst.I4 (elems.Length))); I_newarr (ILArrayShape.SingleDimensional,ilElemTy) ];
+ CG.EmitInstrs cgbuf (pop 0) (Push [ilArrTy]) [ (AI_ldc (DT_I4,ILConst.I4 (elems.Length))); I_newarr (ILArrayShape.SingleDimensional,ilElemTy) ]
elems |> List.iteri (fun i e ->
- CG.EmitInstrs cgbuf (pop 0) (Push [ilArrTy; cenv.g.ilg.typ_int32]) [ AI_dup; (AI_ldc (DT_I4,ILConst.I4 i)) ];
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ CG.EmitInstrs cgbuf (pop 0) (Push [ilArrTy; cenv.g.ilg.typ_int32]) [ AI_dup; (AI_ldc (DT_I4,ILConst.I4 i)) ]
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
CG.EmitInstr cgbuf (pop 3) Push0 (I_stelem_any (ILArrayShape.SingleDimensional,ilElemTy)))
GenSequel cenv eenv.cloc cgbuf sequel
@@ -2103,7 +2108,7 @@ and GenNewArray cenv cgbuf eenv (elems: Expr list,elemTy,m) sequel =
if elems' |> Array.forall (function Expr.Const(c,_,_) -> test c | _ -> false) then
let ilElemTy = GenType cenv.amap m cenv.g eenv.tyenv elemTy
- GenConstArray cenv cgbuf eenv ilElemTy elems' (fun buf -> function Expr.Const(c,_,_) -> write buf c | _ -> failwith "unreachable");
+ GenConstArray cenv cgbuf eenv ilElemTy elems' (fun buf -> function Expr.Const(c,_,_) -> write buf c | _ -> failwith "unreachable")
GenSequel cenv eenv.cloc cgbuf sequel
else
@@ -2118,38 +2123,38 @@ and GenCoerce cenv cgbuf eenv (e,tgty,m,srcty) sequel =
// The .NET IL doesn't always support implict subsumption for interface types, e.g. at stack merge points
// Hence be conservative here and always cast explicitly.
if (isInterfaceTy cenv.g tgty) then (
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let ilToTy = GenType cenv.amap m cenv.g eenv.tyenv tgty
- CG.EmitInstrs cgbuf (pop 1) (Push [ilToTy]) [ I_unbox_any ilToTy; ];
+ CG.EmitInstrs cgbuf (pop 1) (Push [ilToTy]) [ I_unbox_any ilToTy ]
GenSequel cenv eenv.cloc cgbuf sequel
) else (
- GenExpr cenv cgbuf eenv SPSuppress e sequel;
+ GenExpr cenv cgbuf eenv SPSuppress e sequel
)
end
else
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
if not (isObjTy cenv.g srcty) then
let ilFromTy = GenType cenv.amap m cenv.g eenv.tyenv srcty
- CG.EmitInstrs cgbuf (pop 1) (Push [cenv.g.ilg.typ_Object]) [ I_box ilFromTy; ];
+ CG.EmitInstrs cgbuf (pop 1) (Push [cenv.g.ilg.typ_Object]) [ I_box ilFromTy ]
if not (isObjTy cenv.g tgty) then
let ilToTy = GenType cenv.amap m cenv.g eenv.tyenv tgty
- CG.EmitInstrs cgbuf (pop 1) (Push [ilToTy]) [ I_unbox_any ilToTy; ];
+ CG.EmitInstrs cgbuf (pop 1) (Push [ilToTy]) [ I_unbox_any ilToTy ]
GenSequel cenv eenv.cloc cgbuf sequel
and GenReraise cenv cgbuf eenv (rtnty,m) sequel =
let ilReturnTy = GenType cenv.amap m cenv.g eenv.tyenv rtnty
- CG.EmitInstrs cgbuf (pop 0) Push0 [I_rethrow];
+ CG.EmitInstrs cgbuf (pop 0) Push0 [I_rethrow]
// [See comment related to I_throw].
// Rethrow does not return. Required to push dummy value on the stack.
// This follows prior behaviour by prim-types reraise<_>.
- CG.EmitInstrs cgbuf (pop 0) (Push [ilReturnTy]) [AI_ldnull; I_unbox_any ilReturnTy ];
+ CG.EmitInstrs cgbuf (pop 0) (Push [ilReturnTy]) [AI_ldnull; I_unbox_any ilReturnTy ]
GenSequel cenv eenv.cloc cgbuf sequel
and GenGetExnField cenv cgbuf eenv (e,ecref,fieldNum,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let exnc = stripExnEqns ecref
let typ = GenExnType cenv.amap m cenv.g eenv.tyenv ecref
- CG.EmitInstrs cgbuf (pop 0) Push0 [ I_castclass typ];
+ CG.EmitInstrs cgbuf (pop 0) Push0 [ I_castclass typ]
let fld = List.item fieldNum exnc.TrueInstanceFieldsAsList
let ftyp = GenType cenv.amap m cenv.g eenv.tyenv fld.FormalType
@@ -2160,46 +2165,57 @@ and GenGetExnField cenv cgbuf eenv (e,ecref,fieldNum,m) sequel =
GenSequel cenv eenv.cloc cgbuf sequel
and GenSetExnField cenv cgbuf eenv (e,ecref,fieldNum,e2,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let exnc = stripExnEqns ecref
let typ = GenExnType cenv.amap m cenv.g eenv.tyenv ecref
- CG.EmitInstrs cgbuf (pop 0) Push0 [ I_castclass typ ];
+ CG.EmitInstrs cgbuf (pop 0) Push0 [ I_castclass typ ]
let fld = List.item fieldNum exnc.TrueInstanceFieldsAsList
let ftyp = GenType cenv.amap m cenv.g eenv.tyenv fld.FormalType
let ilFieldName = ComputeFieldName exnc fld
- GenExpr cenv cgbuf eenv SPSuppress e2 Continue;
- CG.EmitInstr cgbuf (pop 2) Push0 (mkNormalStfld(mkILFieldSpecInTy (typ,ilFieldName,ftyp)));
+ GenExpr cenv cgbuf eenv SPSuppress e2 Continue
+ CG.EmitInstr cgbuf (pop 2) Push0 (mkNormalStfld(mkILFieldSpecInTy (typ,ilFieldName,ftyp)))
GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel
and UnionCodeGen (cgbuf: CodeGenBuffer) =
{ new EraseUnions.ICodeGen with
member __.CodeLabel(m) = m.CodeLabel
member __.GenerateDelayMark() = CG.GenerateDelayMark cgbuf "unionCodeGenMark"
- member __.GenLocal(ilty) = cgbuf.AllocLocal([],ilty) |> uint16
+ member __.GenLocal(ilty) = cgbuf.AllocLocal([],ilty,false) |> uint16
member __.SetMarkToHere(m) = CG.SetMarkToHere cgbuf m
member __.EmitInstr x = CG.EmitInstr cgbuf (pop 0) (Push []) x
member __.EmitInstrs xs = CG.EmitInstrs cgbuf (pop 0) (Push []) xs }
and GenUnionCaseProof cenv cgbuf eenv (e,ucref,tyargs,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let cuspec,idx = GenUnionCaseSpec cenv.amap m cenv.g eenv.tyenv ucref tyargs
let fty = EraseUnions.GetILTypeForAlternative cuspec idx
- EraseUnions.emitCastData cenv.g.ilg (UnionCodeGen cgbuf) (false,cuspec,idx)
+ let avoidHelpers = entityRefInThisAssembly cenv.g.compilingFslib ucref.TyconRef
+ EraseUnions.emitCastData cenv.g.ilg (UnionCodeGen cgbuf) (false,avoidHelpers,cuspec,idx)
CG.EmitInstrs cgbuf (pop 1) (Push [fty]) [ ] // push/pop to match the line above
GenSequel cenv eenv.cloc cgbuf sequel
and GenGetUnionCaseField cenv cgbuf eenv (e,ucref,tyargs,n,m) sequel =
- assert (isProvenUnionCaseTy (tyOfExpr cenv.g e));
+ assert (ucref.Tycon.IsStructOrEnumTycon || isProvenUnionCaseTy (tyOfExpr cenv.g e))
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let cuspec,idx = GenUnionCaseSpec cenv.amap m cenv.g eenv.tyenv ucref tyargs
let fty = actualTypOfIlxUnionField cuspec idx n
let avoidHelpers = entityRefInThisAssembly cenv.g.compilingFslib ucref.TyconRef
- CG.EmitInstrs cgbuf (pop 1) (Push [fty]) (EraseUnions.mkLdData (avoidHelpers, cuspec, idx, n));
+ CG.EmitInstrs cgbuf (pop 1) (Push [fty]) (EraseUnions.mkLdData (avoidHelpers, cuspec, idx, n))
+ GenSequel cenv eenv.cloc cgbuf sequel
+
+and GenGetUnionCaseFieldAddr cenv cgbuf eenv (e,ucref,tyargs,n,m) sequel =
+ assert (ucref.Tycon.IsStructOrEnumTycon || isProvenUnionCaseTy (tyOfExpr cenv.g e))
+
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
+ let cuspec,idx = GenUnionCaseSpec cenv.amap m cenv.g eenv.tyenv ucref tyargs
+ let fty = actualTypOfIlxUnionField cuspec idx n
+ let avoidHelpers = entityRefInThisAssembly cenv.g.compilingFslib ucref.TyconRef
+ CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref fty]) (EraseUnions.mkLdDataAddr (avoidHelpers, cuspec, idx, n))
GenSequel cenv eenv.cloc cgbuf sequel
and GenGetUnionCaseTag cenv cgbuf eenv (e,tcref,tyargs,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let cuspec = GenUnionSpec cenv.amap m cenv.g eenv.tyenv tcref tyargs
let avoidHelpers = entityRefInThisAssembly cenv.g.compilingFslib tcref
EraseUnions.emitLdDataTag cenv.g.ilg (UnionCodeGen cgbuf) (avoidHelpers, cuspec)
@@ -2207,41 +2223,42 @@ and GenGetUnionCaseTag cenv cgbuf eenv (e,tcref,tyargs,m) sequel =
GenSequel cenv eenv.cloc cgbuf sequel
and GenSetUnionCaseField cenv cgbuf eenv (e,ucref,tyargs,n,e2,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let cuspec,idx = GenUnionCaseSpec cenv.amap m cenv.g eenv.tyenv ucref tyargs
- EraseUnions.emitCastData cenv.g.ilg (UnionCodeGen cgbuf) (false,cuspec,idx)
+ let avoidHelpers = entityRefInThisAssembly cenv.g.compilingFslib ucref.TyconRef
+ EraseUnions.emitCastData cenv.g.ilg (UnionCodeGen cgbuf) (false,avoidHelpers,cuspec,idx)
CG.EmitInstrs cgbuf (pop 1) (Push [cuspec.EnclosingType]) [ ] // push/pop to match the line above
- GenExpr cenv cgbuf eenv SPSuppress e2 Continue;
- CG.EmitInstrs cgbuf (pop 2) Push0 (EraseUnions.mkStData (cuspec, idx, n));
+ GenExpr cenv cgbuf eenv SPSuppress e2 Continue
+ CG.EmitInstrs cgbuf (pop 2) Push0 (EraseUnions.mkStData (cuspec, idx, n))
GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel
and GenGetRecdFieldAddr cenv cgbuf eenv (e,f,tyargs,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let fref = GenRecdFieldRef m cenv eenv.tyenv f tyargs
- CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref fref.ActualType]) [ I_ldflda fref ] ;
+ CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref fref.ActualType]) [ I_ldflda fref ]
GenSequel cenv eenv.cloc cgbuf sequel
and GenGetStaticFieldAddr cenv cgbuf eenv (f,tyargs,m) sequel =
let fspec = GenRecdFieldRef m cenv eenv.tyenv f tyargs
- CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref fspec.ActualType]) [ I_ldsflda fspec ] ;
+ CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref fspec.ActualType]) [ I_ldsflda fspec ]
GenSequel cenv eenv.cloc cgbuf sequel
and GenGetRecdField cenv cgbuf eenv (e,f,tyargs,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
- GenFieldGet false cenv cgbuf eenv (f,tyargs,m);
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
+ GenFieldGet false cenv cgbuf eenv (f,tyargs,m)
GenSequel cenv eenv.cloc cgbuf sequel
and GenSetRecdField cenv cgbuf eenv (e1,f,tyargs,e2,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e1 Continue;
- GenExpr cenv cgbuf eenv SPSuppress e2 Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e1 Continue
+ GenExpr cenv cgbuf eenv SPSuppress e2 Continue
GenFieldStore false cenv cgbuf eenv (f,tyargs,m) sequel
and GenGetStaticField cenv cgbuf eenv (f,tyargs,m) sequel =
- GenFieldGet true cenv cgbuf eenv (f,tyargs,m);
+ GenFieldGet true cenv cgbuf eenv (f,tyargs,m)
GenSequel cenv eenv.cloc cgbuf sequel
and GenSetStaticField cenv cgbuf eenv (f,tyargs,e2,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e2 Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e2 Continue
GenFieldStore true cenv cgbuf eenv (f,tyargs,m) sequel
and mk_field_pops isStatic n = if isStatic then pop n else pop (n+1)
@@ -2268,7 +2285,7 @@ and GenFieldStore isStatic cenv cgbuf eenv (rfref:RecdFieldRef,tyargs,m) sequel
else
let vol = if rfref.RecdField.IsVolatile then Volatile else Nonvolatile
let instr = if isStatic then I_stsfld (vol, fspec) else I_stfld (ILAlignment.Aligned, vol, fspec)
- CG.EmitInstr cgbuf (mk_field_pops isStatic 1) Push0 instr;
+ CG.EmitInstr cgbuf (mk_field_pops isStatic 1) Push0 instr
GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel
//--------------------------------------------------------------------------
@@ -2287,7 +2304,7 @@ and GenUntupledArgsDiscardingLoneUnit cenv cgbuf eenv m numObjArgs curriedArgInf
// obj.M()
| [[_];[]],[arg1;arg2] when numObjArgs = 1 ->
assert isUnitTy cenv.g (tyOfExpr cenv.g arg2)
- GenExpr cenv cgbuf eenv SPSuppress arg1 Continue;
+ GenExpr cenv cgbuf eenv SPSuppress arg1 Continue
GenExpr cenv cgbuf eenv SPSuppress arg2 discard
| _ ->
(curriedArgInfos,args) ||> List.iter2 (fun argInfos x ->
@@ -2301,8 +2318,8 @@ and GenUntupledArgExpr cenv cgbuf eenv m argInfos expr sequel =
GenExpr cenv cgbuf eenv SPSuppress expr sequel
elif isTupleExpr expr then
let es = tryDestTuple expr
- if es.Length <> numRequiredExprs then error(InternalError("GenUntupledArgExpr (2)",m));
- es |> List.iter (fun x -> GenExpr cenv cgbuf eenv SPSuppress x Continue);
+ if es.Length <> numRequiredExprs then error(InternalError("GenUntupledArgExpr (2)",m))
+ es |> List.iter (fun x -> GenExpr cenv cgbuf eenv SPSuppress x Continue)
GenSequel cenv eenv.cloc cgbuf sequel
else
let ty = tyOfExpr cenv.g expr
@@ -2310,10 +2327,10 @@ and GenUntupledArgExpr cenv cgbuf eenv m argInfos expr sequel =
let bind = mkCompGenBind locv expr
LocalScope "untuple" cgbuf (fun scopeMarks ->
let eenvinner = AllocStorageForBind cenv cgbuf scopeMarks eenv bind
- GenBind cenv cgbuf eenvinner bind;
+ GenBind cenv cgbuf eenvinner bind
let tys = destTupleTy cenv.g ty
assert (tys.Length = numRequiredExprs)
- argInfos |> List.iteri (fun i _ -> GenGetTupleField cenv cgbuf eenvinner (loce,tys,i,m) Continue);
+ argInfos |> List.iteri (fun i _ -> GenGetTupleField cenv cgbuf eenvinner (loce,tys,i,m) Continue)
GenSequel cenv eenv.cloc cgbuf sequel
)
@@ -2350,13 +2367,13 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
match kind with
| BranchCallClosure arityInfo ->
let ntmargs = List.foldBack (+) arityInfo 0
- GenExprs cenv cgbuf eenv args;
+ GenExprs cenv cgbuf eenv args
ntmargs
| BranchCallMethod (arityInfo,curriedArgInfos,_,ntmargs,numObjArgs) ->
assert (curriedArgInfos.Length = arityInfo.Length )
assert (curriedArgInfos.Length = args.Length)
//assert (curriedArgInfos.Length = ntmargs )
- GenUntupledArgsDiscardingLoneUnit cenv cgbuf eenv m numObjArgs curriedArgInfos args;
+ GenUntupledArgsDiscardingLoneUnit cenv cgbuf eenv m numObjArgs curriedArgInfos args
if v.IsExtensionMember then
match curriedArgInfos, args with
| [[]],[_] when numObjArgs = 0 -> (ntmargs-1)
@@ -2378,9 +2395,9 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
(valRefEq cenv.g v cenv.g.reference_equality_inner_vref)
&& isAppTy cenv.g ty ->
- GenExpr cenv cgbuf eenv SPSuppress arg1 Continue;
- GenExpr cenv cgbuf eenv SPSuppress arg2 Continue;
- CG.EmitInstr cgbuf (pop 2) (Push [cenv.g.ilg.typ_bool]) AI_ceq;
+ GenExpr cenv cgbuf eenv SPSuppress arg1 Continue
+ GenExpr cenv cgbuf eenv SPSuppress arg2 Continue
+ CG.EmitInstr cgbuf (pop 2) (Push [cenv.g.ilg.typ_bool]) AI_ceq
GenSequel cenv eenv.cloc cgbuf sequel
// Emit "methodhandleof" calls as ldtoken instructions
@@ -2397,7 +2414,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
let storage = StorageForValRef m vref eenv
match storage with
| Method (_,_,mspec,_,_,_) ->
- CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.ilg.typ_RuntimeMethodHandle]) (I_ldtoken (ILToken.ILMethod mspec));
+ CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.ilg.typ_RuntimeMethodHandle]) (I_ldtoken (ILToken.ILMethod mspec))
| _ ->
errorR(Error(FSComp.SR.ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen(), m))
@@ -2408,7 +2425,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
let boxity = (if valu then AsValue else AsObject)
let mkFormalParams gparams = gparams |> DropErasedTyargs |> List.mapi (fun n _gf -> mkILTyvarTy (uint16 n))
let ilGenericMethodSpec = IL.mkILMethSpec (ilMethRef, boxity, mkFormalParams actualTypeInst, mkFormalParams actualMethInst)
- let i = I_ldtoken (ILToken.ILMethod ilGenericMethodSpec);
+ let i = I_ldtoken (ILToken.ILMethod ilGenericMethodSpec)
CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.ilg.typ_RuntimeMethodHandle]) i
| _ ->
@@ -2455,7 +2472,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
| _ -> 0
let (ilEnclArgTys,ilMethArgTys) =
- if ilTyArgs.Length < numEnclILTypeArgs then error(InternalError("length mismatch",m));
+ if ilTyArgs.Length < numEnclILTypeArgs then error(InternalError("length mismatch",m))
List.chop numEnclILTypeArgs ilTyArgs
let boxity = mspec.EnclosingType.Boxity
@@ -2493,9 +2510,9 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
// ok, now we're ready to generate
if isSuperInit || isSelfInit then
- CG.EmitInstrs cgbuf (pop 0) (Push [mspec.EnclosingType ]) [ mkLdarg0 ] ;
+ CG.EmitInstrs cgbuf (pop 0) (Push [mspec.EnclosingType ]) [ mkLdarg0 ]
- GenUntupledArgsDiscardingLoneUnit cenv cgbuf eenv m vref.NumObjArgs curriedArgInfos nowArgs;
+ GenUntupledArgsDiscardingLoneUnit cenv cgbuf eenv m vref.NumObjArgs curriedArgInfos nowArgs
// Generate laterArgs (for effects) and save
LocalScope "callstack" cgbuf (fun scopeMarks ->
@@ -2504,7 +2521,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
// Only save arguments that have effects
if Optimizer.ExprHasEffect cenv.g laterArg then
let ilTy = laterArg |> tyOfExpr cenv.g |> GenType cenv.amap m cenv.g eenv.tyenv
- let loc,eenv = AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("arg",m), ilTy) scopeMarks
+ let loc,eenv = AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("arg",m), ilTy, false) scopeMarks
GenExpr cenv cgbuf eenv SPSuppress laterArg Continue
EmitSetLocal cgbuf loc
Choice1Of2 (ilTy,loc),eenv
@@ -2513,10 +2530,10 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
let nargs = mspec.FormalArgTypes.Length
CG.EmitInstr cgbuf (pop (nargs + (if mspec.CallingConv.IsStatic || newobj then 0 else 1)))
- (if mustGenerateUnitAfterCall || isSuperInit || isSelfInit then Push0 else (Push [(GenType cenv.amap m cenv.g eenv.tyenv actualRetTy)])) callInstr;
+ (if mustGenerateUnitAfterCall || isSuperInit || isSelfInit then Push0 else (Push [(GenType cenv.amap m cenv.g eenv.tyenv actualRetTy)])) callInstr
// For isSuperInit, load the 'this' pointer as the pretend 'result' of the operation. It will be popped again in most cases
- if isSuperInit then CG.EmitInstrs cgbuf (pop 0) (Push [mspec.EnclosingType]) [ mkLdarg0 ] ;
+ if isSuperInit then CG.EmitInstrs cgbuf (pop 0) (Push [mspec.EnclosingType]) [ mkLdarg0 ]
// When generating debug code, generate a 'nop' after a 'call' that returns 'void'
// This is what C# does, as it allows the call location to be maintained correctly in the stack frame
@@ -2545,7 +2562,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
| _ ->
(* worst case: generate a first-class function value and call *)
- GenExpr cenv cgbuf eenv SPSuppress f Continue;
+ GenExpr cenv cgbuf eenv SPSuppress f Continue
GenArgsAndIndirectCall cenv cgbuf eenv (fty,tyargs,args,m) sequel
and CanTailcall (hasStructObjArg, ccallInfo, withinSEH, hasByrefArg, mustGenerateUnitAfterCall, isDllImport, isSelfInit, makesNoCriticalTailcalls, sequel) =
@@ -2575,17 +2592,17 @@ and GenNamedLocalTyFuncCall cenv (cgbuf: CodeGenBuffer) eenv typ cloinfo tyargs
let ilContractTy = mkILBoxedTy ilContractCloTySpec.TypeRef ilContractClassTyargs
- if not (ilContractMethTyargs.Length = ilTyArgs.Length) then errorR(Error(FSComp.SR.ilIncorrectNumberOfTypeArguments(),m));
+ if not (ilContractMethTyargs.Length = ilTyArgs.Length) then errorR(Error(FSComp.SR.ilIncorrectNumberOfTypeArguments(),m))
// Local TyFunc are represented as a $contract type. they currently get stored in a value of type object
// Recover result (value or reference types) via unbox_any.
- CG.EmitInstrs cgbuf (pop 1) (Push [ilContractTy]) [I_unbox_any ilContractTy];
+ CG.EmitInstrs cgbuf (pop 1) (Push [ilContractTy]) [I_unbox_any ilContractTy]
let actualRetTy = applyTys cenv.g typ (tyargs,[])
let ilDirectInvokeMethSpec = mkILInstanceMethSpecInTy(ilContractTy, "DirectInvoke", [], ilContractFormalRetTy, ilTyArgs)
let ilActualRetTy = GenType cenv.amap m cenv.g eenv.tyenv actualRetTy
- CountCallFuncInstructions();
- CG.EmitInstr cgbuf (pop 1) (Push [ilActualRetTy]) (mkNormalCallvirt ilDirectInvokeMethSpec);
+ CountCallFuncInstructions()
+ CG.EmitInstr cgbuf (pop 1) (Push [ilActualRetTy]) (mkNormalCallvirt ilDirectInvokeMethSpec)
actualRetTy
@@ -2593,7 +2610,7 @@ and GenNamedLocalTyFuncCall cenv (cgbuf: CodeGenBuffer) eenv typ cloinfo tyargs
and GenArgsAndIndirectCall cenv cgbuf eenv (functy,tyargs,args,m) sequel =
// Generate the arguments to the indirect call
- GenExprs cenv cgbuf eenv args;
+ GenExprs cenv cgbuf eenv args
GenIndirectCall cenv cgbuf eenv (functy,tyargs,args,m) sequel
/// Generate an indirect call, converting to an ILX callfunc instruction
@@ -2634,11 +2651,11 @@ and GenIndirectCall cenv cgbuf eenv (functy,tyargs,args,m) sequel =
check ilxClosureApps
let isTailCall = CanTailcall(false,None,eenv.withinSEH,hasByrefArg,false,false,false,false,sequel)
- CountCallFuncInstructions();
+ CountCallFuncInstructions()
// Generate the code code an ILX callfunc operation
- let instrs = EraseClosures.mkCallFunc cenv.g.ilxPubCloEnv (fun ty -> cgbuf.AllocLocal([], ty) |> uint16) eenv.tyenv.Count isTailCall ilxClosureApps
- CG.EmitInstrs cgbuf (pop (1+args.Length)) (Push [ilActualRetTy]) instrs;
+ let instrs = EraseClosures.mkCallFunc cenv.g.ilxPubCloEnv (fun ty -> cgbuf.AllocLocal([], ty,false) |> uint16) eenv.tyenv.Count isTailCall ilxClosureApps
+ CG.EmitInstrs cgbuf (pop (1+args.Length)) (Push [ilActualRetTy]) instrs
// Done compiling indirect call...
GenSequel cenv eenv.cloc cgbuf sequel
@@ -2660,14 +2677,14 @@ and GenTry cenv cgbuf eenv scopeMarks (e1,m,resty,spTry) =
let afterHandler = CG.GenerateDelayMark cgbuf "afterHandler"
let eenvinner = {eenvinner with withinSEH = true}
let ilResultTy = GenType cenv.amap m cenv.g eenvinner.tyenv resty
- let whereToSave,eenvinner = AllocLocal cenv cgbuf eenvinner true (ilxgenGlobalNng.FreshCompilerGeneratedName ("tryres",m),ilResultTy) (startTryMark,endTryMark)
+ let whereToSave,eenvinner = AllocLocal cenv cgbuf eenvinner true (ilxgenGlobalNng.FreshCompilerGeneratedName ("tryres",m),ilResultTy, false) (startTryMark,endTryMark)
// Generate the body of the try. In the normal case (SequencePointAtTry) we generate a sequence point
// both on the 'try' keyword and on the start of the expression in the 'try'. For inlined code and
// compiler generated 'try' blocks (i.e. NoSequencePointAtTry, used for the try/finally implicit
// in a 'use' or 'foreach'), we suppress the sequence point
- GenExpr cenv cgbuf eenvinner sp e1 (LeaveHandler (false, whereToSave,afterHandler));
- CG.SetMarkToHere cgbuf endTryMark;
+ GenExpr cenv cgbuf eenvinner sp e1 (LeaveHandler (false, whereToSave,afterHandler))
+ CG.SetMarkToHere cgbuf endTryMark
let tryMarks = (startTryMark.CodeLabel, endTryMark.CodeLabel)
whereToSave,eenvinner,stack,tryMarks,afterHandler,ilResultTy
@@ -2699,32 +2716,32 @@ and GenTryCatch cenv cgbuf eenv (e1,vf:Val,ef,vh:Val,eh,m,resty,spTry,spWith) se
| NoSequencePointAtWith -> ()
- CG.SetStack cgbuf [cenv.g.ilg.typ_Object];
+ CG.SetStack cgbuf [cenv.g.ilg.typ_Object]
let _,eenvinner = AllocLocalVal cenv cgbuf vf eenvinner None (startOfFilter,afterFilter)
- CG.EmitInstr cgbuf (pop 1) (Push [cenv.g.ilg.typ_Exception]) (I_castclass cenv.g.ilg.typ_Exception);
+ CG.EmitInstr cgbuf (pop 1) (Push [cenv.g.ilg.typ_Exception]) (I_castclass cenv.g.ilg.typ_Exception)
- GenStoreVal cgbuf eenvinner vf.Range vf;
+ GenStoreVal cgbuf eenvinner vf.Range vf
// Why SPSuppress? Because we do not emit a sequence point at the start of the List.filter - we've already put one on
// the 'with' keyword above
- GenExpr cenv cgbuf eenvinner SPSuppress ef sequelOnBranches;
- CG.SetMarkToHere cgbuf afterJoin;
- CG.SetStack cgbuf stackAfterJoin;
- GenSequel cenv eenv.cloc cgbuf sequelAfterJoin;
- end;
+ GenExpr cenv cgbuf eenvinner SPSuppress ef sequelOnBranches
+ CG.SetMarkToHere cgbuf afterJoin
+ CG.SetStack cgbuf stackAfterJoin
+ GenSequel cenv eenv.cloc cgbuf sequelAfterJoin
+ end
let endOfFilter = CG.GenerateMark cgbuf "endOfFilter"
let filterMarks = (startOfFilter.CodeLabel, endOfFilter.CodeLabel)
- CG.SetMarkToHere cgbuf afterFilter;
+ CG.SetMarkToHere cgbuf afterFilter
let startOfHandler = CG.GenerateMark cgbuf "startOfHandler"
begin
- CG.SetStack cgbuf [cenv.g.ilg.typ_Object];
+ CG.SetStack cgbuf [cenv.g.ilg.typ_Object]
let _,eenvinner = AllocLocalVal cenv cgbuf vh eenvinner None (startOfHandler,afterHandler)
- CG.EmitInstr cgbuf (pop 1) (Push [cenv.g.ilg.typ_Exception]) (I_castclass cenv.g.ilg.typ_Exception);
- GenStoreVal cgbuf eenvinner vh.Range vh;
+ CG.EmitInstr cgbuf (pop 1) (Push [cenv.g.ilg.typ_Exception]) (I_castclass cenv.g.ilg.typ_Exception)
+ GenStoreVal cgbuf eenvinner vh.Range vh
- GenExpr cenv cgbuf eenvinner SPAlways eh (LeaveHandler (false, whereToSave,afterHandler));
- end;
+ GenExpr cenv cgbuf eenvinner SPAlways eh (LeaveHandler (false, whereToSave,afterHandler))
+ end
let endOfHandler = CG.GenerateMark cgbuf "endOfHandler"
let handlerMarks = (startOfHandler.CodeLabel, endOfHandler.CodeLabel)
ILExceptionClause.FilterCatch(filterMarks, handlerMarks)
@@ -2735,31 +2752,31 @@ and GenTryCatch cenv cgbuf eenv (e1,vf:Val,ef,vh:Val,eh,m,resty,spTry,spWith) se
| SequencePointAtWith m -> CG.EmitSeqPoint cgbuf m
| NoSequencePointAtWith -> ()
- CG.SetStack cgbuf [cenv.g.ilg.typ_Object];
+ CG.SetStack cgbuf [cenv.g.ilg.typ_Object]
let _,eenvinner = AllocLocalVal cenv cgbuf vh eenvinner None (startOfHandler,afterHandler)
- CG.EmitInstr cgbuf (pop 1) (Push [cenv.g.ilg.typ_Exception]) (I_castclass cenv.g.ilg.typ_Exception);
+ CG.EmitInstr cgbuf (pop 1) (Push [cenv.g.ilg.typ_Exception]) (I_castclass cenv.g.ilg.typ_Exception)
- GenStoreVal cgbuf eenvinner m vh;
+ GenStoreVal cgbuf eenvinner m vh
- GenExpr cenv cgbuf eenvinner SPAlways eh (LeaveHandler (false, whereToSave,afterHandler));
- end;
+ GenExpr cenv cgbuf eenvinner SPAlways eh (LeaveHandler (false, whereToSave,afterHandler))
+ end
let endOfHandler = CG.GenerateMark cgbuf "endOfHandler"
let handlerMarks = (startOfHandler.CodeLabel, endOfHandler.CodeLabel)
ILExceptionClause.TypeCatch(cenv.g.ilg.typ_Object, handlerMarks)
cgbuf.EmitExceptionClause
- { Clause = seh;
- Range= tryMarks } ;
+ { Clause = seh
+ Range= tryMarks }
- CG.SetMarkToHere cgbuf afterHandler;
- CG.SetStack cgbuf [];
+ CG.SetMarkToHere cgbuf afterHandler
+ CG.SetStack cgbuf []
- cgbuf.EmitStartOfHiddenCode();
+ cgbuf.EmitStartOfHiddenCode()
(* Restore the stack and load the result *)
- EmitRestoreStack cgbuf stack; (* RESTORE *)
+ EmitRestoreStack cgbuf stack (* RESTORE *)
- EmitGetLocal cgbuf ilResultTy whereToSave;
+ EmitGetLocal cgbuf ilResultTy whereToSave
GenSequel cenv eenv.cloc cgbuf sequel
)
@@ -2773,14 +2790,14 @@ and GenTryFinally cenv cgbuf eenv (bodyExpr,handlerExpr,m,resty,spTry,spFinally)
// Now the catch/finally block
let startOfHandler = CG.GenerateMark cgbuf "startOfHandler"
- CG.SetStack cgbuf [];
+ CG.SetStack cgbuf []
let sp =
match spFinally with
| SequencePointAtFinally m -> CG.EmitSeqPoint cgbuf m; SPAlways
| NoSequencePointAtFinally -> SPSuppress
- GenExpr cenv cgbuf eenvinner sp handlerExpr (LeaveHandler (true, whereToSave,afterHandler));
+ GenExpr cenv cgbuf eenvinner sp handlerExpr (LeaveHandler (true, whereToSave,afterHandler))
let endOfHandler = CG.GenerateMark cgbuf "endOfHandler"
let handlerMarks = (startOfHandler.CodeLabel, endOfHandler.CodeLabel)
cgbuf.EmitExceptionClause
@@ -2815,68 +2832,68 @@ and GenForLoop cenv cgbuf eenv (spFor,v,e1,dir,e2,loopBody,m) sequel =
let test = CG.GenerateDelayMark cgbuf "for_test"
let stack,eenvinner = EmitSaveStack cenv cgbuf eenv m (start,finish)
- let isUp = (match dir with | FSharpForLoopUp | CSharpForLoopUp -> true | FSharpForLoopDown -> false);
- let isFSharpStyle = (match dir with FSharpForLoopUp | FSharpForLoopDown -> true | CSharpForLoopUp -> false);
+ let isUp = (match dir with | FSharpForLoopUp | CSharpForLoopUp -> true | FSharpForLoopDown -> false)
+ let isFSharpStyle = (match dir with FSharpForLoopUp | FSharpForLoopDown -> true | CSharpForLoopUp -> false)
let finishIdx,eenvinner =
if isFSharpStyle then
- let v,eenvinner = AllocLocal cenv cgbuf eenvinner true (ilxgenGlobalNng.FreshCompilerGeneratedName ("endLoop",m), cenv.g.ilg.typ_int32) (start,finish)
+ let v,eenvinner = AllocLocal cenv cgbuf eenvinner true (ilxgenGlobalNng.FreshCompilerGeneratedName ("endLoop",m), cenv.g.ilg.typ_int32, false) (start,finish)
v, eenvinner
else
-1,eenvinner
let _, eenvinner = AllocLocalVal cenv cgbuf v eenvinner None (start,finish) (* note: eenvStack noted stack spill vars are live *)
match spFor with
- | SequencePointAtForLoop(spStart) -> CG.EmitSeqPoint cgbuf spStart;
+ | SequencePointAtForLoop(spStart) -> CG.EmitSeqPoint cgbuf spStart
| NoSequencePointAtForLoop -> ()
- GenExpr cenv cgbuf eenv SPSuppress e1 Continue;
- GenStoreVal cgbuf eenvinner m v;
+ GenExpr cenv cgbuf eenv SPSuppress e1 Continue
+ GenStoreVal cgbuf eenvinner m v
if isFSharpStyle then
- GenExpr cenv cgbuf eenvinner SPSuppress e2 Continue;
+ GenExpr cenv cgbuf eenvinner SPSuppress e2 Continue
EmitSetLocal cgbuf finishIdx
EmitGetLocal cgbuf cenv.g.ilg.typ_int32 finishIdx
- GenGetLocalVal cenv cgbuf eenvinner e2.Range v None;
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp ((if isUp then BI_blt else BI_bgt),finish.CodeLabel));
+ GenGetLocalVal cenv cgbuf eenvinner e2.Range v None
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp ((if isUp then BI_blt else BI_bgt),finish.CodeLabel))
else
- CG.EmitInstr cgbuf (pop 0) Push0 (I_br test.CodeLabel);
+ CG.EmitInstr cgbuf (pop 0) Push0 (I_br test.CodeLabel)
// .inner
- CG.SetMarkToHere cgbuf inner;
+ CG.SetMarkToHere cgbuf inner
//
- GenExpr cenv cgbuf eenvinner SPAlways loopBody discard;
+ GenExpr cenv cgbuf eenvinner SPAlways loopBody discard
// v++ or v--
- GenGetLocalVal cenv cgbuf eenvinner e2.Range v None;
+ GenGetLocalVal cenv cgbuf eenvinner e2.Range v None
- CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.ilg.typ_int32]) (mkLdcInt32 1);
- CG.EmitInstr cgbuf (pop 1) Push0 (if isUp then AI_add else AI_sub);
- GenStoreVal cgbuf eenvinner m v;
+ CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.ilg.typ_int32]) (mkLdcInt32 1)
+ CG.EmitInstr cgbuf (pop 1) Push0 (if isUp then AI_add else AI_sub)
+ GenStoreVal cgbuf eenvinner m v
// .text
- CG.SetMarkToHere cgbuf test;
+ CG.SetMarkToHere cgbuf test
// FSharpForLoopUp: if v <> e2 + 1 then goto .inner
// FSharpForLoopDown: if v <> e2 - 1 then goto .inner
// CSharpStyle: if v < e2 then goto .inner
- CG.EmitSeqPoint cgbuf e2.Range;
- GenGetLocalVal cenv cgbuf eenvinner e2.Range v None;
+ CG.EmitSeqPoint cgbuf e2.Range
+ GenGetLocalVal cenv cgbuf eenvinner e2.Range v None
let cmp = match dir with FSharpForLoopUp | FSharpForLoopDown -> BI_bne_un | CSharpForLoopUp -> BI_blt
- let e2Sequel = (CmpThenBrOrContinue (pop 2, [ I_brcmp(cmp,inner.CodeLabel) ]));
+ let e2Sequel = (CmpThenBrOrContinue (pop 2, [ I_brcmp(cmp,inner.CodeLabel) ]))
if isFSharpStyle then
EmitGetLocal cgbuf cenv.g.ilg.typ_int32 finishIdx
- CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.ilg.typ_int32]) (mkLdcInt32 1);
- CG.EmitInstr cgbuf (pop 1) Push0 (if isUp then AI_add else AI_sub);
+ CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.ilg.typ_int32]) (mkLdcInt32 1)
+ CG.EmitInstr cgbuf (pop 1) Push0 (if isUp then AI_add else AI_sub)
GenSequel cenv eenv.cloc cgbuf e2Sequel
else
- GenExpr cenv cgbuf eenv SPSuppress e2 e2Sequel;
+ GenExpr cenv cgbuf eenv SPSuppress e2 e2Sequel
// .finish - loop-exit here
- CG.SetMarkToHere cgbuf finish;
+ CG.SetMarkToHere cgbuf finish
// Restore the stack and load the result
- EmitRestoreStack cgbuf stack;
+ EmitRestoreStack cgbuf stack
GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel
//--------------------------------------------------------------------------
@@ -2888,14 +2905,14 @@ and GenWhileLoop cenv cgbuf eenv (spWhile,e1,e2,m) sequel =
let startTest = CG.GenerateMark cgbuf "startTest"
match spWhile with
- | SequencePointAtWhileLoop(spStart) -> CG.EmitSeqPoint cgbuf spStart;
+ | SequencePointAtWhileLoop(spStart) -> CG.EmitSeqPoint cgbuf spStart
| NoSequencePointAtWhileLoop -> ()
// SEQUENCE POINTS: Emit a sequence point to cover all of 'while e do'
- GenExpr cenv cgbuf eenv SPSuppress e1 (CmpThenBrOrContinue (pop 1, [ I_brcmp(BI_brfalse,finish.CodeLabel) ]));
+ GenExpr cenv cgbuf eenv SPSuppress e1 (CmpThenBrOrContinue (pop 1, [ I_brcmp(BI_brfalse,finish.CodeLabel) ]))
- GenExpr cenv cgbuf eenv SPAlways e2 (DiscardThen (Br startTest));
- CG.SetMarkToHere cgbuf finish;
+ GenExpr cenv cgbuf eenv SPAlways e2 (DiscardThen (Br startTest))
+ CG.SetMarkToHere cgbuf finish
// SEQUENCE POINTS: Emit a sequence point to cover 'done' if present
GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel
@@ -2915,11 +2932,11 @@ and GenSequential cenv cgbuf eenv spIn (e1,e2,specialSeqFlag,spSeq,_m) sequel =
| SuppressSequencePointOnStmtOfSequential -> spIn,SPSuppress)
match specialSeqFlag with
| NormalSeq ->
- GenExpr cenv cgbuf eenv spAction e1 discard;
+ GenExpr cenv cgbuf eenv spAction e1 discard
GenExpr cenv cgbuf eenv spExpr e2 sequel
| ThenDoSeq ->
- GenExpr cenv cgbuf eenv spExpr e1 Continue;
- GenExpr cenv cgbuf eenv spAction e2 discard;
+ GenExpr cenv cgbuf eenv spExpr e1 Continue
+ GenExpr cenv cgbuf eenv spAction e2 discard
GenSequel cenv eenv.cloc cgbuf sequel
//--------------------------------------------------------------------------
@@ -2971,7 +2988,7 @@ and GenAsmCode cenv cgbuf eenv (il,tyargs,args,returnTys,m) sequel =
// "Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr."
| _ ->
- if not (isNil tyargs) then err "Bad polymorphic IL instruction";
+ if not (isNil tyargs) then err "Bad polymorphic IL instruction"
i)
match ilAfterInst,args,sequel,ilReturnTys with
@@ -2980,7 +2997,7 @@ and GenAsmCode cenv cgbuf eenv (il,tyargs,args,returnTys,m) sequel =
| [typ] ->
GenDefaultValue cenv cgbuf eenv (typ,m)
GenSequel cenv eenv.cloc cgbuf sequel
- | _ -> failwith "Bad polymorphic IL instruction";
+ | _ -> failwith "Bad polymorphic IL instruction"
// Strip off any ("ceq" x false) when the sequel is a comparison branch and change the BI_brfalse to a BI_brtrue
// This is the instruction sequence for "not"
@@ -2995,13 +3012,13 @@ and GenAsmCode cenv cgbuf eenv (il,tyargs,args,returnTys,m) sequel =
// Query; when do we get a 'ret' in IL assembly code?
| [ I_ret ], [arg1],sequel,[_ilRetTy] ->
- GenExpr cenv cgbuf eenv SPSuppress arg1 Continue;
- CG.EmitInstr cgbuf (pop 1) Push0 I_ret;
+ GenExpr cenv cgbuf eenv SPSuppress arg1 Continue
+ CG.EmitInstr cgbuf (pop 1) Push0 I_ret
GenSequelEndScopes cgbuf sequel
// Query; when do we get a 'ret' in IL assembly code?
| [ I_ret ], [],sequel,[_ilRetTy] ->
- CG.EmitInstr cgbuf (pop 1) Push0 I_ret;
+ CG.EmitInstr cgbuf (pop 1) Push0 I_ret
GenSequelEndScopes cgbuf sequel
// 'throw' instructions are a bit of a problem - e.g. let x = (throw ...) in ... expects a value *)
@@ -3014,60 +3031,60 @@ and GenAsmCode cenv cgbuf eenv (il,tyargs,args,returnTys,m) sequel =
match sequelIgnoreEndScopes sequel with
| s when IsSequelImmediate s ->
(* In most cases we can avoid doing this... *)
- GenExpr cenv cgbuf eenv SPSuppress arg1 Continue;
- CG.EmitInstr cgbuf (pop 1) Push0 I_throw;
+ GenExpr cenv cgbuf eenv SPSuppress arg1 Continue
+ CG.EmitInstr cgbuf (pop 1) Push0 I_throw
GenSequelEndScopes cgbuf sequel
| _ ->
let after1 = CG.GenerateDelayMark cgbuf ("fake_join")
let after2 = CG.GenerateDelayMark cgbuf ("fake_join")
let after3 = CG.GenerateDelayMark cgbuf ("fake_join")
- CG.EmitInstrs cgbuf (pop 0) Push0 [mkLdcInt32 0; I_brcmp (BI_brfalse,after2.CodeLabel); ];
+ CG.EmitInstrs cgbuf (pop 0) Push0 [mkLdcInt32 0; I_brcmp (BI_brfalse,after2.CodeLabel) ]
- CG.SetMarkToHere cgbuf after1;
- CG.EmitInstrs cgbuf (pop 0) (Push [ilRetTy]) [AI_ldnull; I_unbox_any ilRetTy; I_br after3.CodeLabel ];
+ CG.SetMarkToHere cgbuf after1
+ CG.EmitInstrs cgbuf (pop 0) (Push [ilRetTy]) [AI_ldnull; I_unbox_any ilRetTy; I_br after3.CodeLabel ]
- CG.SetMarkToHere cgbuf after2;
- GenExpr cenv cgbuf eenv SPSuppress arg1 Continue;
- CG.EmitInstr cgbuf (pop 1) Push0 I_throw;
- CG.SetMarkToHere cgbuf after3;
- GenSequel cenv eenv.cloc cgbuf sequel;
+ CG.SetMarkToHere cgbuf after2
+ GenExpr cenv cgbuf eenv SPSuppress arg1 Continue
+ CG.EmitInstr cgbuf (pop 1) Push0 I_throw
+ CG.SetMarkToHere cgbuf after3
+ GenSequel cenv eenv.cloc cgbuf sequel
| _ ->
// float or float32 or float<_> or float32<_>
let g = cenv.g in
let anyfpType ty = typeEquivAux EraseMeasures g g.float_ty ty || typeEquivAux EraseMeasures g g.float32_ty ty
// Otherwise generate the arguments, and see if we can use a I_brcmp rather than a comparison followed by an I_brfalse/I_brtrue
- GenExprs cenv cgbuf eenv args;
+ GenExprs cenv cgbuf eenv args
match ilAfterInst,sequel with
// NOTE: THESE ARE NOT VALID ON FLOATING POINT DUE TO NaN. Hence INLINE ASM ON FP. MUST BE CAREFULLY WRITTEN
| [ AI_clt ], CmpThenBrOrContinue(1,[ I_brcmp (BI_brfalse, label1) ]) when not (anyfpType (tyOfExpr g args.Head)) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bge,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bge,label1))
| [ AI_cgt ], CmpThenBrOrContinue(1,[ I_brcmp (BI_brfalse, label1) ]) when not (anyfpType (tyOfExpr g args.Head)) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_ble,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_ble,label1))
| [ AI_clt_un ], CmpThenBrOrContinue(1,[ I_brcmp (BI_brfalse, label1) ]) when not (anyfpType (tyOfExpr g args.Head)) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bge_un,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bge_un,label1))
| [ AI_cgt_un ], CmpThenBrOrContinue(1, [I_brcmp (BI_brfalse, label1) ]) when not (anyfpType (tyOfExpr g args.Head)) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_ble_un,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_ble_un,label1))
| [ AI_ceq ], CmpThenBrOrContinue(1,[ I_brcmp (BI_brfalse, label1) ]) when not (anyfpType (tyOfExpr g args.Head)) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bne_un,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bne_un,label1))
// THESE ARE VALID ON FP w.r.t. NaN
| [ AI_clt ], CmpThenBrOrContinue(1,[ I_brcmp (BI_brtrue, label1) ]) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_blt,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_blt,label1))
| [ AI_cgt ], CmpThenBrOrContinue(1,[ I_brcmp (BI_brtrue, label1) ]) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bgt,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bgt,label1))
| [ AI_clt_un ], CmpThenBrOrContinue(1,[ I_brcmp (BI_brtrue, label1) ]) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_blt_un,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_blt_un,label1))
| [ AI_cgt_un ], CmpThenBrOrContinue(1,[ I_brcmp (BI_brtrue, label1) ]) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bgt_un,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bgt_un,label1))
| [ AI_ceq ], CmpThenBrOrContinue(1, [ I_brcmp (BI_brtrue, label1) ]) ->
- CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_beq,label1));
+ CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_beq,label1))
| _ ->
// Failing that, generate the real IL leaving value(s) on the stack
- CG.EmitInstrs cgbuf (pop args.Length) (Push ilReturnTys) ilAfterInst;
+ CG.EmitInstrs cgbuf (pop args.Length) (Push ilReturnTys) ilAfterInst
// If no return values were specified generate a "unit"
if isNil returnTys then
@@ -3147,8 +3164,8 @@ and GenILCall cenv cgbuf eenv (virt,valu,newobj,valUseFlags,isDllImport,ilMethRe
// Load the 'this' pointer to pass to the superclass constructor. This argument is not
// in the expression tree since it can't be treated like an ordinary value
- if isSuperInit then CG.EmitInstrs cgbuf (pop 0) (Push [ilMethSpec.EnclosingType]) [ mkLdarg0 ] ;
- GenExprs cenv cgbuf eenv argExprs;
+ if isSuperInit then CG.EmitInstrs cgbuf (pop 0) (Push [ilMethSpec.EnclosingType]) [ mkLdarg0 ]
+ GenExprs cenv cgbuf eenv argExprs
let il =
if newobj then [ I_newobj(ilMethSpec,None) ]
else
@@ -3160,11 +3177,11 @@ and GenILCall cenv cgbuf eenv (virt,valu,newobj,valUseFlags,isDllImport,ilMethRe
if useICallVirt then [ I_callvirt(tail,ilMethSpec,None) ]
else [ I_call(tail,ilMethSpec,None) ]
- CG.EmitInstrs cgbuf (pop (argExprs.Length + (if isSuperInit then 1 else 0))) (if isSuperInit then Push0 else Push ilReturnTys) il;
+ CG.EmitInstrs cgbuf (pop (argExprs.Length + (if isSuperInit then 1 else 0))) (if isSuperInit then Push0 else Push ilReturnTys) il
// Load the 'this' pointer as the pretend 'result' of the isSuperInit operation.
// It will be immediately popped in most cases, but may also be used as the target of ome "property set" operations.
- if isSuperInit then CG.EmitInstrs cgbuf (pop 0) (Push [ilMethSpec.EnclosingType]) [ mkLdarg0 ] ;
+ if isSuperInit then CG.EmitInstrs cgbuf (pop 0) (Push [ilMethSpec.EnclosingType]) [ mkLdarg0 ]
CommitCallSequel cenv eenv m eenv.cloc cgbuf mustGenerateUnitAfterCall sequel
and CommitCallSequel cenv eenv m cloc cgbuf mustGenerateUnitAfterCall sequel =
@@ -3190,9 +3207,9 @@ and GenTraitCall cenv cgbuf eenv (traitInfo, argExprs, m) expr sequel =
//--------------------------------------------------------------------------
and GenGetAddrOfRefCellField cenv cgbuf eenv (e,ty,m) sequel =
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let fref = GenRecdFieldRef m cenv eenv.tyenv (mkRefCellContentsRef cenv.g) [ty]
- CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref fref.ActualType]) [ I_ldflda fref ] ;
+ CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref fref.ActualType]) [ I_ldflda fref ]
GenSequel cenv eenv.cloc cgbuf sequel
and GenGetValAddr cenv cgbuf eenv (v: ValRef, m) sequel =
@@ -3200,32 +3217,32 @@ and GenGetValAddr cenv cgbuf eenv (v: ValRef, m) sequel =
let ilTy = GenTypeOfVal cenv eenv vspec
match StorageForValRef m v eenv with
| Local (idx,None) ->
- CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldloca (uint16 idx) ] ;
+ CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldloca (uint16 idx) ]
| Arg idx ->
- CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldarga (uint16 idx) ] ;
+ CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldarga (uint16 idx) ]
| StaticField (fspec, _vref, hasLiteralAttr, _ilTyForProperty, _, ilTy, _, _, _) ->
- if hasLiteralAttr then errorR(Error(FSComp.SR.ilAddressOfLiteralFieldIsInvalid(),m));
+ if hasLiteralAttr then errorR(Error(FSComp.SR.ilAddressOfLiteralFieldIsInvalid(),m))
let ilTy = if ilTy.IsNominal && ilTy.Boxity = ILBoxity.AsValue then ILType.Byref ilTy else ilTy
EmitGetStaticFieldAddr cgbuf ilTy fspec
| Env (_,_,ilField,_) ->
- CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ mkLdarg0; mkNormalLdflda ilField ];
+ CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ mkLdarg0; mkNormalLdflda ilField ]
| Local (_,Some _) | StaticProperty _ | Method _ | Env _ | Unrealized | Null ->
- errorR(Error(FSComp.SR.ilAddressOfValueHereIsInvalid(v.DisplayName),m));
+ errorR(Error(FSComp.SR.ilAddressOfValueHereIsInvalid(v.DisplayName),m))
CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref ilTy]) [ I_ldarga (uint16 669 (* random value for post-hoc diagnostic analysis on generated tree *) ) ] ;
GenSequel cenv eenv.cloc cgbuf sequel
and GenGetByref cenv cgbuf eenv (v:ValRef,m) sequel =
- GenGetLocalVRef cenv cgbuf eenv m v None;
+ GenGetLocalVRef cenv cgbuf eenv m v None
let ilty = GenType cenv.amap m cenv.g eenv.tyenv (destByrefTy cenv.g v.Type)
- CG.EmitInstrs cgbuf (pop 1) (Push [ilty]) [ mkNormalLdobj ilty ];
+ CG.EmitInstrs cgbuf (pop 1) (Push [ilty]) [ mkNormalLdobj ilty ]
GenSequel cenv eenv.cloc cgbuf sequel
and GenSetByref cenv cgbuf eenv (v:ValRef,e,m) sequel =
- GenGetLocalVRef cenv cgbuf eenv m v None;
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenGetLocalVRef cenv cgbuf eenv m v None
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let ilty = GenType cenv.amap m cenv.g eenv.tyenv (destByrefTy cenv.g v.Type)
- CG.EmitInstrs cgbuf (pop 2) Push0 [ mkNormalStobj ilty ];
+ CG.EmitInstrs cgbuf (pop 2) Push0 [ mkNormalStobj ilty ]
GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel
and GenDefaultValue cenv cgbuf eenv (ty,m) =
@@ -3253,14 +3270,14 @@ and GenDefaultValue cenv cgbuf eenv (ty,m) =
| _ ->
let ilTy = GenType cenv.amap m cenv.g eenv.tyenv ty
LocalScope "ilzero" cgbuf (fun scopeMarks ->
- let locIdx, _ = AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("default",m), ilTy) scopeMarks
+ let locIdx, _ = AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("default",m), ilTy, false) scopeMarks
// "initobj" (Generated by EmitInitLocal) doesn't work on byref types
// But ilzero(&ty) only gets generated in the built-in get-address function so
// we can just rely on zeroinit of all IL locals.
match ilTy with
| ILType.Byref _ -> ()
| _ -> EmitInitLocal cgbuf ilTy locIdx
- EmitGetLocal cgbuf ilTy locIdx;
+ EmitGetLocal cgbuf ilTy locIdx
)
//--------------------------------------------------------------------------
@@ -3291,13 +3308,13 @@ and GenGenericParam cenv eenv (tp:Typar) =
elif nm.Length >= 1 && nm.[0] = 'T' && (nm.Length = 1 || not (System.Char.IsLower nm.[1])) then nm
else "T" + (String.capitalize nm)
else
- nm;
+ nm
- Constraints=mkILTypes subTypeConstraints;
- Variance=NonVariant;
- CustomAttrs = mkILCustomAttrs (GenAttrs cenv eenv tp.Attribs);
- HasReferenceTypeConstraint=refTypeConstraint;
- HasNotNullableValueTypeConstraint=notNullableValueTypeConstraint;
+ Constraints=mkILTypes subTypeConstraints
+ Variance=NonVariant
+ CustomAttrs = mkILCustomAttrs (GenAttrs cenv eenv tp.Attribs)
+ HasReferenceTypeConstraint=refTypeConstraint
+ HasNotNullableValueTypeConstraint=notNullableValueTypeConstraint
HasDefaultConstructorConstraint= defaultConstructorConstraint }
//--------------------------------------------------------------------------
@@ -3307,13 +3324,13 @@ and GenGenericParam cenv eenv (tp:Typar) =
and GenSlotParam m cenv eenv (TSlotParam(nm,ty,inFlag,outFlag,optionalFlag,attribs)) : ILParameter =
let inFlag2,outFlag2,optionalFlag2,paramMarshal2,attribs = GenParamAttribs cenv attribs
- { Name=nm;
- Type= GenParamType cenv.amap m cenv.g eenv.tyenv ty;
- Default=None;
- Marshal=paramMarshal2;
- IsIn=inFlag || inFlag2;
- IsOut=outFlag || outFlag2;
- IsOptional=optionalFlag || optionalFlag2;
+ { Name=nm
+ Type= GenParamType cenv.amap m cenv.g eenv.tyenv ty
+ Default=None
+ Marshal=paramMarshal2
+ IsIn=inFlag || inFlag2
+ IsOut=outFlag || outFlag2
+ IsOptional=optionalFlag || optionalFlag2
CustomAttrs= mkILCustomAttrs (GenAttrs cenv eenv attribs) }
and GenFormalSlotsig m cenv eenv (TSlotSig(_,typ,ctps,mtps,paraml,returnTy)) =
@@ -3351,7 +3368,7 @@ and GenMethodImpl cenv eenv (useMethodImpl,(TSlotSig(nameOfOverridenMethod,_,_,_
let ilOverrideMethGenericParams = GenGenericParams cenv eenvForOverrideBy methTyparsOfOverridingMethod
let ilOverrideMethGenericArgs = mkILFormalGenericArgs ilOverrideMethGenericParams
let ilOverrideBy = mkILInstanceMethSpecInTy(ilTyForOverriding, nameOfOverridingMethod, typesOfILParamsList ilParamsOfOverridingMethod, ilReturnOfOverridingMethod.Type, ilOverrideMethGenericArgs)
- { Overrides = OverridesSpec(ilOverrideMethRef,ilOverrideTy);
+ { Overrides = OverridesSpec(ilOverrideMethRef,ilOverrideTy)
OverrideBy = ilOverrideBy })
and bindBaseOrThisVarOpt cenv eenv baseValOpt =
@@ -3361,7 +3378,7 @@ and bindBaseOrThisVarOpt cenv eenv baseValOpt =
and fixupVirtualSlotFlags mdef =
{mdef with
- IsHideBySig=true;
+ IsHideBySig=true
mdKind = (match mdef.mdKind with
| MethodKind.Virtual vinfo ->
MethodKind.Virtual
@@ -3374,15 +3391,15 @@ and renameMethodDef nameOfOverridingMethod (mdef : ILMethodDef) =
and fixupMethodImplFlags mdef =
{mdef with
- Access=ILMemberAccess.Private;
- IsHideBySig=true;
+ Access=ILMemberAccess.Private
+ IsHideBySig=true
mdKind=(match mdef.mdKind with
| MethodKind.Virtual vinfo ->
MethodKind.Virtual
{vinfo with
- IsCheckAccessOnOverride=false;
- IsFinal=true;
- IsNewSlot=true; }
+ IsCheckAccessOnOverride=false
+ IsFinal=true
+ IsNewSlot=true }
| _ -> failwith "fixupMethodImpl") }
and GenObjectMethod cenv eenvinner (cgbuf:CodeGenBuffer) useMethodImpl tmethod =
@@ -3429,7 +3446,7 @@ and GenObjectExpr cenv cgbuf eenvouter expr (baseType,baseValOpt,basecall,overri
let ilxCloSpec = cloinfo.cloSpec
let ilCloFreeVars = cloinfo.cloILFreeVars
let ilCloGenericFormals = cloinfo.cloILGenericParams
- assert(isNil cloinfo.localTypeFuncDirectILGenericParams);
+ assert(isNil cloinfo.localTypeFuncDirectILGenericParams)
let ilCloGenericActuals = cloinfo.cloSpec.GenericArgs
let ilCloRetTy = cloinfo.cloILFormalRetTy
let ilCloTypeRef = cloinfo.cloSpec.TypeRef
@@ -3462,10 +3479,10 @@ and GenObjectExpr cenv cgbuf eenvouter expr (baseType,baseValOpt,basecall,overri
let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef,ilCloGenericFormals,attrs,ilCloFreeVars,ilCloLambdas,ilCtorBody,mdefs,mimpls,super,interfaceTys)
for cloTypeDef in cloTypeDefs do
- cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None);
- CountClosure();
- GenGetLocalVals cenv cgbuf eenvouter m cloFreeVars;
- CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [ EraseClosures.mkTyOfLambdas cenv.g.ilxPubCloEnv ilCloLambdas]) (I_newobj (ilxCloSpec.Constructor,None));
+ cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None)
+ CountClosure()
+ GenGetLocalVals cenv cgbuf eenvouter m cloFreeVars
+ CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [ EraseClosures.mkTyOfLambdas cenv.g.ilxPubCloEnv ilCloLambdas]) (I_newobj (ilxCloSpec.Constructor,None))
GenSequel cenv eenvouter.cloc cgbuf sequel
and GenSequenceExpr cenv (cgbuf:CodeGenBuffer) eenvouter (nextEnumeratorValRef:ValRef,pcvref:ValRef,currvref:ValRef,stateVars,generateNextExpr,closeExpr,checkCloseExpr:Expr,seqElemTy, m) sequel =
@@ -3511,8 +3528,8 @@ and GenSequenceExpr cenv (cgbuf:CodeGenBuffer) eenvouter (nextEnumeratorValRef:V
if stateVarsSet.Contains fv then
GenDefaultValue cenv cgbuf eenv (fv.Type,m)
else
- GenGetLocalVal cenv cgbuf eenv m fv None;
- CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [ilCloRetTyInner]) (I_newobj (formalClospec.Constructor,None));
+ GenGetLocalVal cenv cgbuf eenv m fv None
+ CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [ilCloRetTyInner]) (I_newobj (formalClospec.Constructor,None))
GenSequel cenv eenv.cloc cgbuf Return),
m)
mkILNonGenericVirtualMethod("GetFreshEnumerator",ILMemberAccess.Public, [], mkILReturn ilCloEnumeratorTy, MethodBody.IL mbody)
@@ -3545,17 +3562,17 @@ and GenSequenceExpr cenv (cgbuf:CodeGenBuffer) eenvouter (nextEnumeratorValRef:V
let attrs = GenAttrs cenv eenvinner cloAttribs
let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef,ilCloGenericParams,attrs,ilCloFreeVars,ilCloLambdas,ilCtorBody,[generateNextMethod;closeMethod;checkCloseMethod;lastGeneratedMethod;getFreshMethod],[],ilCloBaseTy,[])
for cloTypeDef in cloTypeDefs do
- cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None);
- CountClosure();
+ cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None)
+ CountClosure()
for fv in cloFreeVars do
/// State variables always get zero-initialized
if stateVarsSet.Contains fv then
GenDefaultValue cenv cgbuf eenvouter (fv.Type,m)
else
- GenGetLocalVal cenv cgbuf eenvouter m fv None;
+ GenGetLocalVal cenv cgbuf eenvouter m fv None
- CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [ilCloRetTyOuter]) (I_newobj (ilxCloSpec.Constructor,None));
+ CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [ilCloRetTyOuter]) (I_newobj (ilxCloSpec.Constructor,None))
GenSequel cenv eenvouter.cloc cgbuf sequel
@@ -3570,29 +3587,29 @@ and GenClosureTypeDefs cenv (tref:ILTypeRef, ilGenParams, attrs, ilCloFreeVars,
cloCode=notlazy ilCtorBody }
let td =
- { Name = tref.Name;
- Layout = ILTypeDefLayout.Auto;
- Access = ComputeTypeAccess tref true;
- GenericParams = ilGenParams;
- CustomAttrs = mkILCustomAttrs(attrs @ [mkCompilationMappingAttr cenv.g (int SourceConstructFlags.Closure) ]);
- Fields = emptyILFields;
- InitSemantics=ILTypeInit.BeforeField;
- IsSealed=true;
- IsAbstract=false;
- tdKind=ILTypeDefKind.Class;
- Events= emptyILEvents;
- Properties = emptyILProperties;
- Methods= mkILMethods mdefs;
- MethodImpls= mkILMethodImpls mimpls;
- IsSerializable= cenv.opts.netFxHasSerializableAttribute;
- IsComInterop= false;
- IsSpecialName= true;
- NestedTypes=emptyILTypeDefs;
- Encoding= ILDefaultPInvokeEncoding.Auto;
- Implements= mkILTypes ilIntfTys;
- Extends= Some ext;
- SecurityDecls= emptyILSecurityDecls;
- HasSecurity=false; }
+ { Name = tref.Name
+ Layout = ILTypeDefLayout.Auto
+ Access = ComputeTypeAccess tref true
+ GenericParams = ilGenParams
+ CustomAttrs = mkILCustomAttrs(attrs @ [mkCompilationMappingAttr cenv.g (int SourceConstructFlags.Closure) ])
+ Fields = emptyILFields
+ InitSemantics=ILTypeInit.BeforeField
+ IsSealed=true
+ IsAbstract=false
+ tdKind=ILTypeDefKind.Class
+ Events= emptyILEvents
+ Properties = emptyILProperties
+ Methods= mkILMethods mdefs
+ MethodImpls= mkILMethodImpls mimpls
+ IsSerializable= cenv.opts.netFxHasSerializableAttribute
+ IsComInterop= false
+ IsSpecialName= true
+ NestedTypes=emptyILTypeDefs
+ Encoding= ILDefaultPInvokeEncoding.Auto
+ Implements= mkILTypes ilIntfTys
+ Extends= Some ext
+ SecurityDecls= emptyILSecurityDecls
+ HasSecurity=false }
let tdefs = EraseClosures.convIlxClosureDef cenv.g.ilxPubCloEnv tref.Enclosing td cloInfo
tdefs
@@ -3626,30 +3643,30 @@ and GenLambdaClosure cenv (cgbuf:CodeGenBuffer) eenv isLocalTypeFunc selfv expr
let ilContractMeths = [ilContractCtor; mkILGenericVirtualMethod("DirectInvoke",ILMemberAccess.Assembly,ilContractMethTyargs,[],mkILReturn ilContractFormalRetTy, MethodBody.Abstract) ]
let ilContractTypeDef =
- { Name = ilContractTypeRef.Name;
- Layout = ILTypeDefLayout.Auto;
- Access = ComputeTypeAccess ilContractTypeRef true;
- GenericParams = ilContractGenericParams;
- CustomAttrs = mkILCustomAttrs [mkCompilationMappingAttr cenv.g (int SourceConstructFlags.Closure) ];
- Fields = emptyILFields;
- InitSemantics=ILTypeInit.BeforeField;
- IsSealed=false; // the contract type is an abstract type and not sealed
- IsAbstract=true; // the contract type is an abstract type
- tdKind=ILTypeDefKind.Class;
- Events= emptyILEvents;
- Properties = emptyILProperties;
- Methods= mkILMethods ilContractMeths;
- MethodImpls= emptyILMethodImpls;
- IsSerializable= cenv.opts.netFxHasSerializableAttribute;
- IsComInterop=false;
- IsSpecialName= true;
- NestedTypes=emptyILTypeDefs;
- Encoding= ILDefaultPInvokeEncoding.Auto;
- Implements= mkILTypes [];
- Extends= Some cenv.g.ilg.typ_Object;
- SecurityDecls= emptyILSecurityDecls;
- HasSecurity=false; }
- cgbuf.mgbuf.AddTypeDef(ilContractTypeRef, ilContractTypeDef, false, false, None);
+ { Name = ilContractTypeRef.Name
+ Layout = ILTypeDefLayout.Auto
+ Access = ComputeTypeAccess ilContractTypeRef true
+ GenericParams = ilContractGenericParams
+ CustomAttrs = mkILCustomAttrs [mkCompilationMappingAttr cenv.g (int SourceConstructFlags.Closure) ]
+ Fields = emptyILFields
+ InitSemantics=ILTypeInit.BeforeField
+ IsSealed=false // the contract type is an abstract type and not sealed
+ IsAbstract=true // the contract type is an abstract type
+ tdKind=ILTypeDefKind.Class
+ Events= emptyILEvents
+ Properties = emptyILProperties
+ Methods= mkILMethods ilContractMeths
+ MethodImpls= emptyILMethodImpls
+ IsSerializable= cenv.opts.netFxHasSerializableAttribute
+ IsComInterop=false
+ IsSpecialName= true
+ NestedTypes=emptyILTypeDefs
+ Encoding= ILDefaultPInvokeEncoding.Auto
+ Implements= mkILTypes []
+ Extends= Some cenv.g.ilg.typ_Object
+ SecurityDecls= emptyILSecurityDecls
+ HasSecurity=false }
+ cgbuf.mgbuf.AddTypeDef(ilContractTypeRef, ilContractTypeDef, false, false, None)
let ilCtorBody = mkILMethodBody (true,emptyILLocals,8,nonBranchingInstrsToCode (mkCallBaseConstructor(ilContractTy,[])), None )
let cloMethods = [ mkILGenericVirtualMethod("DirectInvoke",ILMemberAccess.Assembly,cloinfo.localTypeFuncDirectILGenericParams,[],mkILReturn (cloinfo.cloILFormalRetTy), MethodBody.IL ilCloBody) ]
@@ -3658,14 +3675,14 @@ and GenLambdaClosure cenv (cgbuf:CodeGenBuffer) eenv isLocalTypeFunc selfv expr
else
GenClosureTypeDefs cenv (ilCloTypeRef,cloinfo.cloILGenericParams,[],cloinfo.cloILFreeVars,cloinfo.ilCloLambdas,ilCloBody,[],[],cenv.g.ilg.typ_Object,[])
- CountClosure();
+ CountClosure()
for cloTypeDef in cloTypeDefs do
- cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None);
+ cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None)
cloinfo,m
| _ -> failwith "GenLambda: not a lambda"
and GenLambdaVal cenv (cgbuf:CodeGenBuffer) eenv (cloinfo,m) =
- GenGetLocalVals cenv cgbuf eenv m cloinfo.cloFreeVars;
+ GenGetLocalVals cenv cgbuf eenv m cloinfo.cloFreeVars
CG.EmitInstr cgbuf
(pop cloinfo.cloILFreeVars.Length)
(Push [EraseClosures.mkTyOfLambdas cenv.g.ilxPubCloEnv cloinfo.ilCloLambdas])
@@ -3673,7 +3690,7 @@ and GenLambdaVal cenv (cgbuf:CodeGenBuffer) eenv (cloinfo,m) =
and GenLambda cenv cgbuf eenv isLocalTypeFunc selfv expr sequel =
let cloinfo,m = GenLambdaClosure cenv cgbuf eenv isLocalTypeFunc selfv expr
- GenLambdaVal cenv cgbuf eenv (cloinfo,m);
+ GenLambdaVal cenv cgbuf eenv (cloinfo,m)
GenSequel cenv eenv.cloc cgbuf sequel
and GenTypeOfVal cenv eenv (v:Val) =
@@ -3900,20 +3917,20 @@ and GetIlxClosureInfo cenv m isLocalTypeFunc selfv eenvouter expr =
let ilxCloSpec = IlxClosureSpec.Create(IlxClosureRef(ilCloTypeRef, ilCloLambdas, ilCloFreeVars), mkILGenericArgs ilCloGenericActuals)
let cloinfo =
- { cloExpr=expr;
- cloName=ilCloTypeRef.Name;
- cloArityInfo =narginfo;
- ilCloLambdas=ilCloLambdas;
- cloILFreeVars = ilCloFreeVars;
- cloILFormalRetTy=ilReturnTy;
- cloSpec = ilxCloSpec;
- cloILGenericParams = ilCloGenericFormals;
- cloFreeVars=cloFreeVars;
- cloAttribs=cloAttribs;
- localTypeFuncContractFreeTypars = cloContractFreeTyvars;
- localTypeFuncInternalFreeTypars = cloInternalFreeTyvars;
- localTypeFuncILGenericArgs = ilContractGenericActuals;
- localTypeFuncDirectILGenericParams = ilDirectGenericParams; }
+ { cloExpr=expr
+ cloName=ilCloTypeRef.Name
+ cloArityInfo =narginfo
+ ilCloLambdas=ilCloLambdas
+ cloILFreeVars = ilCloFreeVars
+ cloILFormalRetTy=ilReturnTy
+ cloSpec = ilxCloSpec
+ cloILGenericParams = ilCloGenericFormals
+ cloFreeVars=cloFreeVars
+ cloAttribs=cloAttribs
+ localTypeFuncContractFreeTypars = cloContractFreeTyvars
+ localTypeFuncInternalFreeTypars = cloInternalFreeTyvars
+ localTypeFuncILGenericArgs = ilContractGenericActuals
+ localTypeFuncDirectILGenericParams = ilDirectGenericParams }
cloinfo,body,eenvinner
//--------------------------------------------------------------------------
@@ -3996,19 +4013,19 @@ and GenDelegateExpr cenv cgbuf eenvouter expr (TObjExprMethod((TSlotSig(_,delega
let ilAttribs = GenAttrs cenv eenvinner cloAttribs
let cloTypeDefs = GenClosureTypeDefs cenv (ilDelegeeTypeRef,ilDelegeeGenericParams,ilAttribs,ilCloFreeVars,ilCloLambdas,ilCtorBody,[delegeeInvokeMeth],[],cenv.g.ilg.typ_Object,[])
for cloTypeDef in cloTypeDefs do
- cgbuf.mgbuf.AddTypeDef(ilDelegeeTypeRef, cloTypeDef, false, false, None);
- CountClosure();
+ cgbuf.mgbuf.AddTypeDef(ilDelegeeTypeRef, cloTypeDef, false, false, None)
+ CountClosure()
let ctxtGenericArgsForDelegee = GenGenericArgs m eenvouter.tyenv cloFreeTyvars
let ilxCloSpec = IlxClosureSpec.Create(IlxClosureRef(ilDelegeeTypeRef, ilCloLambdas, ilCloFreeVars), mkILGenericArgs ctxtGenericArgsForDelegee)
- GenGetLocalVals cenv cgbuf eenvouter m cloFreeVars;
- CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [EraseClosures.mkTyOfLambdas cenv.g.ilxPubCloEnv ilCloLambdas]) (I_newobj (ilxCloSpec.Constructor,None));
+ GenGetLocalVals cenv cgbuf eenvouter m cloFreeVars
+ CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [EraseClosures.mkTyOfLambdas cenv.g.ilxPubCloEnv ilCloLambdas]) (I_newobj (ilxCloSpec.Constructor,None))
let ilDelegeeTyOuter = mkILBoxedTy ilDelegeeTypeRef ctxtGenericArgsForDelegee
let ilDelegeeInvokeMethOuter = mkILNonGenericInstanceMethSpecInTy (ilDelegeeTyOuter,"Invoke",typesOfILParamsList ilDelegeeParams, ilDelegeeRet.Type)
let ilDelegeeCtorMethOuter = mkCtorMethSpecForDelegate cenv.g.ilg (ilCtxtDelTy,useUIntPtrForDelegateCtor)
CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.ilg.typ_IntPtr]) (I_ldftn ilDelegeeInvokeMethOuter)
- CG.EmitInstr cgbuf (pop 2) (Push [ilCtxtDelTy]) (I_newobj(ilDelegeeCtorMethOuter,None));
+ CG.EmitInstr cgbuf (pop 2) (Push [ilCtxtDelTy]) (I_newobj(ilDelegeeCtorMethOuter,None))
GenSequel cenv eenvouter.cloc cgbuf sequel
//-------------------------------------------------------------------------
@@ -4102,11 +4119,11 @@ and GenMatch cenv cgbuf eenv (spBind,_exprm,tree,targets,m,ty) sequel =
// match-testing (dtrees) should not contribute to the stack.
// Each branch-RHS (targets) may contribute to the stack, leaving it in the "stackAfterJoin" state, for the join point.
// Since code is branching and joining, the cgbuf stack is maintained manually.
- GenDecisionTreeAndTargets cenv cgbuf stackAtTargets eenv tree targets repeatSP sequelOnBranches;
- CG.SetMarkToHere cgbuf afterJoin;
+ GenDecisionTreeAndTargets cenv cgbuf stackAtTargets eenv tree targets repeatSP sequelOnBranches
+ CG.SetMarkToHere cgbuf afterJoin
- //assert(cgbuf.GetCurrentStack() = stackAfterJoin); // REVIEW: Since gen_dtree* now sets stack, stack should be stackAfterJoin at this point...
- CG.SetStack cgbuf stackAfterJoin;
+ //assert(cgbuf.GetCurrentStack() = stackAfterJoin) // REVIEW: Since gen_dtree* now sets stack, stack should be stackAfterJoin at this point...
+ CG.SetStack cgbuf stackAfterJoin
// If any values are left on the stack after the join then we're certainly going to do something with them
// For example, we may be about to execute a 'stloc' for
//
@@ -4119,7 +4136,7 @@ and GenMatch cenv cgbuf eenv (spBind,_exprm,tree,targets,m,ty) sequel =
// In both cases, any instructions that come after this point will be falsely associated with the last branch of the control
// prior to the join point. This is base, e.g. see FSharp 1.0 bug 5155
if nonNil stackAfterJoin then
- cgbuf.EmitStartOfHiddenCode();
+ cgbuf.EmitStartOfHiddenCode()
GenSequel cenv eenv.cloc cgbuf sequelAfterJoin
@@ -4138,19 +4155,19 @@ and TryFindTargetInfo targetInfos n =
/// When inplabOpt is "Some inplab", we are assuming an existing branch to "inplab" and can optionally
/// set inplab to point to another location if no codegen is required.
and GenDecisionTreeAndTargetsInner cenv cgbuf inplabOpt stackAtTargets eenv tree targets repeatSP targetInfos sequel =
- CG.SetStack cgbuf stackAtTargets; // Set the expected initial stack.
+ CG.SetStack cgbuf stackAtTargets // Set the expected initial stack.
match tree with
| TDBind(bind,rest) ->
match inplabOpt with Some inplab -> CG.SetMarkToHere cgbuf inplab | None -> ()
let startScope,endScope as scopeMarks = StartDelayedLocalScope "dtreeBind" cgbuf
let eenv = AllocStorageForBind cenv cgbuf scopeMarks eenv bind
let sp = GenSequencePointForBind cenv cgbuf eenv bind
- CG.SetMarkToHere cgbuf startScope;
- GenBindAfterSequencePoint cenv cgbuf eenv sp bind;
+ CG.SetMarkToHere cgbuf startScope
+ GenBindAfterSequencePoint cenv cgbuf eenv sp bind
// We don't get the scope marks quite right for dtree-bound variables. This is because
// we effectively lose an EndLocalScope for all dtrees that go to the same target
// So we just pretend that the variable goes out of scope here.
- CG.SetMarkToHere cgbuf endScope;
+ CG.SetMarkToHere cgbuf endScope
GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv rest targets repeatSP targetInfos sequel
| TDSuccess (es,targetIdx) ->
@@ -4160,7 +4177,7 @@ and GenDecisionTreeAndTargetsInner cenv cgbuf inplabOpt stackAtTargets eenv tree
GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases dflt m targets repeatSP targetInfos sequel
and GetTarget (targets:_[]) n =
- if n >= targets.Length then failwith "GetTarget: target not found in decision tree";
+ if n >= targets.Length then failwith "GetTarget: target not found in decision tree"
targets.[n]
and GenDecisionTreeSuccess cenv cgbuf inplabOpt stackAtTargets eenv es targetIdx targets repeatSP targetInfos sequel =
@@ -4173,23 +4190,23 @@ and GenDecisionTreeSuccess cenv cgbuf inplabOpt stackAtTargets eenv es targetIdx
// In this case each case will just go straight to "e"
if FlatList.isEmpty vs then
match inplabOpt with
- | None -> CG.EmitInstr cgbuf (pop 0) Push0 (I_br targetMarkAfterBinds.CodeLabel);
- | Some inplab -> CG.SetMark cgbuf inplab targetMarkAfterBinds;
+ | None -> CG.EmitInstr cgbuf (pop 0) Push0 (I_br targetMarkAfterBinds.CodeLabel)
+ | Some inplab -> CG.SetMark cgbuf inplab targetMarkAfterBinds
else
- match inplabOpt with None -> () | Some inplab -> CG.SetMarkToHere cgbuf inplab;
- repeatSP();
+ match inplabOpt with None -> () | Some inplab -> CG.SetMarkToHere cgbuf inplab
+ repeatSP()
// It would be better not to emit any expressions here, and instead push these assignments into the postponed target
// However not all targets are currently postponed (we only postpone in debug code), pending further testing of the performance
// impact of postponing.
(vs,es) ||> FlatList.iter2 (GenBindRhs cenv cgbuf eenv SPSuppress)
vs |> List.rev |> FlatList.iter (fun v -> GenStoreVal cgbuf eenvAtTarget v.Range v)
- CG.EmitInstr cgbuf (pop 0) Push0 (I_br targetMarkAfterBinds.CodeLabel);
+ CG.EmitInstr cgbuf (pop 0) Push0 (I_br targetMarkAfterBinds.CodeLabel)
targetInfos
| None ->
- match inplabOpt with None -> () | Some inplab -> CG.SetMarkToHere cgbuf inplab;
+ match inplabOpt with None -> () | Some inplab -> CG.SetMarkToHere cgbuf inplab
let targetMarkBeforeBinds = CG.GenerateDelayMark cgbuf "targetBeforeBinds"
let targetMarkAfterBinds = CG.GenerateDelayMark cgbuf "targetAfterBinds"
let startScope,endScope as scopeMarks = StartDelayedLocalScope "targetBinds" cgbuf
@@ -4200,10 +4217,10 @@ and GenDecisionTreeSuccess cenv cgbuf inplabOpt stackAtTargets eenv es targetIdx
// In debug mode push all decision tree targets to after the switching
let isTargetPostponed =
if cenv.opts.localOptimizationsAreOn then
- GenDecisionTreeTarget cenv cgbuf stackAtTargets targetIdx targetInfo sequel;
+ GenDecisionTreeTarget cenv cgbuf stackAtTargets targetIdx targetInfo sequel
false
else
- CG.EmitInstr cgbuf (pop 0) Push0 (I_br targetMarkBeforeBinds.CodeLabel);
+ CG.EmitInstr cgbuf (pop 0) Push0 (I_br targetMarkBeforeBinds.CodeLabel)
true
let targetInfos = IntMap.add targetIdx (targetInfo,isTargetPostponed) targetInfos
@@ -4233,29 +4250,34 @@ and GenDecisionTreeTarget cenv cgbuf stackAtTargets _targetIdx (targetMarkBefore
| SuppressSequencePointAtTarget -> cgbuf.EmitStartOfHiddenCode()
CG.SetMarkToHere cgbuf startScope
- GenBindings cenv cgbuf eenvAtTarget binds;
+ GenBindings cenv cgbuf eenvAtTarget binds
CG.SetMarkToHere cgbuf targetMarkAfterBinds
- CG.SetStack cgbuf stackAtTargets;
- GenExpr cenv cgbuf eenvAtTarget spExpr successExpr (EndLocalScope(sequel,endScope));
+ CG.SetStack cgbuf stackAtTargets
+ GenExpr cenv cgbuf eenvAtTarget spExpr successExpr (EndLocalScope(sequel,endScope))
and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defaultTargetOpt switchm targets repeatSP targetInfos sequel =
let m = e.Range
- match inplabOpt with None -> () | Some inplab -> CG.SetMarkToHere cgbuf inplab;
+ match inplabOpt with None -> () | Some inplab -> CG.SetMarkToHere cgbuf inplab
- repeatSP();
+ repeatSP()
match cases with
// optimize a test against a boolean value, i.e. the all-important if-then-else
| TCase(Test.Const(Const.Bool b), successTree) :: _ ->
let failureTree = (match defaultTargetOpt with None -> cases.Tail.Head.CaseTree | Some d -> d)
GenDecisionTreeTest cenv eenv.cloc cgbuf stackAtTargets e None eenv (if b then successTree else failureTree) (if b then failureTree else successTree) targets repeatSP targetInfos sequel
- // optimize a single test for a type constructor to an "isdata" test - much
+ // // Remove a single test for a union case . Union case tests are always exa
+ //| [ TCase(Test.UnionCase _, successTree) ] when (defaultTargetOpt.IsNone) ->
+ // GenDecisionTreeAndTargetsInner cenv cgbuf inplabOpt stackAtTargets eenv successTree targets repeatSP targetInfos sequel
+ // //GenDecisionTree cenv eenv.cloc cgbuf stackAtTargets e (Some (pop 1, Push [cenv.g.ilg.typ_bool], Choice1Of2 (avoidHelpers, cuspec, idx))) eenv successTree failureTree targets repeatSP targetInfos sequel
+
+ // Optimize a single test for a union case to an "isdata" test - much
// more efficient code, and this case occurs in the generated equality testers where perf is important
- | TCase(Test.UnionCase(c,tyargs), successTree) :: rest when List.length rest = (match defaultTargetOpt with None -> 1 | Some _ -> 0) ->
+ | TCase(Test.UnionCase(c,tyargs), successTree) :: rest when rest.Length = (match defaultTargetOpt with None -> 1 | Some _ -> 0) ->
let failureTree =
match defaultTargetOpt with
- | None -> cases.Tail.Head.CaseTree
+ | None -> rest.Head.CaseTree
| Some tg -> tg
let cuspec = GenUnionSpec cenv.amap m cenv.g eenv.tyenv c.TyconRef tyargs
let idx = c.Index
@@ -4272,45 +4294,45 @@ and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defau
| Test.ArrayLength _
| Test.IsNull
| Test.Const(Const.Zero) ->
- if List.length cases <> 1 || isNone defaultTargetOpt then failwith "internal error: GenDecisionTreeSwitch: Test.IsInst/isnull/query";
+ if List.length cases <> 1 || isNone defaultTargetOpt then failwith "internal error: GenDecisionTreeSwitch: Test.IsInst/isnull/query"
let bi =
match firstDiscrim with
| Test.Const(Const.Zero) ->
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
BI_brfalse
| Test.IsNull ->
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let srcTy = tyOfExpr cenv.g e
if isTyparTy cenv.g srcTy then
let ilFromTy = GenType cenv.amap m cenv.g eenv.tyenv srcTy
- CG.EmitInstr cgbuf (pop 1) (Push [cenv.g.ilg.typ_Object]) (I_box ilFromTy);
+ CG.EmitInstr cgbuf (pop 1) (Push [cenv.g.ilg.typ_Object]) (I_box ilFromTy)
BI_brfalse
| Test.IsInst (_srcty,tgty) ->
let e = mkCallTypeTest cenv.g m tgty e
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
BI_brtrue
| _ -> failwith "internal error: GenDecisionTreeSwitch"
- CG.EmitInstr cgbuf (pop 1) Push0 (I_brcmp (bi,(List.head caseLabels).CodeLabel));
+ CG.EmitInstr cgbuf (pop 1) Push0 (I_brcmp (bi,(List.head caseLabels).CodeLabel))
GenDecisionTreeCases cenv cgbuf stackAtTargets eenv targets repeatSP targetInfos defaultTargetOpt caseLabels cases sequel
| Test.ActivePatternCase _ -> error(InternalError("internal error in codegen: Test.ActivePatternCase",switchm))
| Test.UnionCase (hdc,tyargs) ->
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
let cuspec = GenUnionSpec cenv.amap m cenv.g eenv.tyenv hdc.TyconRef tyargs
let dests =
- if cases.Length <> caseLabels.Length then failwith "internal error: Test.UnionCase";
+ if cases.Length <> caseLabels.Length then failwith "internal error: Test.UnionCase"
(cases , caseLabels) ||> List.map2 (fun case label ->
match case with
| TCase(Test.UnionCase (c,_),_) -> (c.Index, label.CodeLabel)
| _ -> failwith "error: mixed constructor/const test?")
let avoidHelpers = entityRefInThisAssembly cenv.g.compilingFslib hdc.TyconRef
- EraseUnions.emitDataSwitch cenv.g.ilg (UnionCodeGen cgbuf) (avoidHelpers,cuspec,dests);
+ EraseUnions.emitDataSwitch cenv.g.ilg (UnionCodeGen cgbuf) (avoidHelpers,cuspec,dests)
CG.EmitInstrs cgbuf (pop 1) Push0 [ ] // push/pop to match the line above
GenDecisionTreeCases cenv cgbuf stackAtTargets eenv targets repeatSP targetInfos defaultTargetOpt caseLabels cases sequel
| Test.Const c ->
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
match c with
| Const.Bool _ -> failwith "should have been done earlier"
| Const.SByte _
@@ -4320,7 +4342,7 @@ and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defau
| Const.UInt16 _
| Const.UInt32 _
| Const.Char _ ->
- if List.length cases <> List.length caseLabels then failwith "internal error: ";
+ if List.length cases <> List.length caseLabels then failwith "internal error: "
let dests =
(cases,caseLabels) ||> List.map2 (fun case label ->
let i =
@@ -4345,16 +4367,16 @@ and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defau
if mx - mn = (List.length dests - 1) then
let destinationLabels = dests |> List.sortBy fst |> List.map snd
if mn <> 0 then
- CG.EmitInstrs cgbuf (pop 0) (Push [cenv.g.ilg.typ_int32]) [ mkLdcInt32 mn];
- CG.EmitInstrs cgbuf (pop 1) Push0 [ AI_sub ];
- CG.EmitInstr cgbuf (pop 1) Push0 (I_switch destinationLabels);
+ CG.EmitInstrs cgbuf (pop 0) (Push [cenv.g.ilg.typ_int32]) [ mkLdcInt32 mn]
+ CG.EmitInstrs cgbuf (pop 1) Push0 [ AI_sub ]
+ CG.EmitInstr cgbuf (pop 1) Push0 (I_switch destinationLabels)
else
- error(InternalError("non-dense integer matches not implemented in codegen - these should have been removed by the pattern match compiler",switchm));
+ error(InternalError("non-dense integer matches not implemented in codegen - these should have been removed by the pattern match compiler",switchm))
GenDecisionTreeCases cenv cgbuf stackAtTargets eenv targets repeatSP targetInfos defaultTargetOpt caseLabels cases sequel
| _ -> error(InternalError("these matches should never be needed",switchm))
and GenDecisionTreeCases cenv cgbuf stackAtTargets eenv targets repeatSP targetInfos defaultTargetOpt caseLabels cases sequel =
- assert(cgbuf.GetCurrentStack() = stackAtTargets); // cgbuf stack should be unchanged over tests. [bug://1750].
+ assert(cgbuf.GetCurrentStack() = stackAtTargets) // cgbuf stack should be unchanged over tests. [bug://1750].
let targetInfos =
match defaultTargetOpt with
@@ -4385,17 +4407,17 @@ and GenDecisionTreeTest cenv cloc cgbuf stackAtTargets e tester eenv successTree
match GetTarget targets n1, GetTarget targets n2 with
| TTarget(_,BoolExpr(b1),_),_ ->
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
match tester with
| Some (pops,pushes,i) ->
match i with
| Choice1Of2 (avoidHelpers,cuspec,idx) -> CG.EmitInstrs cgbuf pops pushes (EraseUnions.mkIsData cenv.g.ilg (avoidHelpers, cuspec, idx))
- | Choice2Of2 i -> CG.EmitInstr cgbuf pops pushes i;
- | _ -> ();
+ | Choice2Of2 i -> CG.EmitInstr cgbuf pops pushes i
+ | _ -> ()
if not b1 then
- CG.EmitInstrs cgbuf (pop 0) (Push [cenv.g.ilg.typ_bool]) [mkLdcInt32 (0); ];
- CG.EmitInstrs cgbuf (pop 1) Push0 [AI_ceq];
- GenSequel cenv cloc cgbuf sequel;
+ CG.EmitInstrs cgbuf (pop 0) (Push [cenv.g.ilg.typ_bool]) [mkLdcInt32 (0) ]
+ CG.EmitInstrs cgbuf (pop 1) Push0 [AI_ceq]
+ GenSequel cenv cloc cgbuf sequel
targetInfos
| _ -> failwith "internal error: GenDecisionTreeTest during bool elim"
@@ -4405,11 +4427,11 @@ and GenDecisionTreeTest cenv cloc cgbuf stackAtTargets e tester eenv successTree
match tester with
| None ->
// generate the expression, then test it for "false"
- GenExpr cenv cgbuf eenv SPSuppress e (CmpThenBrOrContinue(pop 1, [ I_brcmp (BI_brfalse, failure.CodeLabel) ]));
+ GenExpr cenv cgbuf eenv SPSuppress e (CmpThenBrOrContinue(pop 1, [ I_brcmp (BI_brfalse, failure.CodeLabel) ]))
// Turn 'isdata' tests that branch into EI_brisdata tests
| Some (_,_,Choice1Of2 (avoidHelpers,cuspec,idx)) ->
- GenExpr cenv cgbuf eenv SPSuppress e (CmpThenBrOrContinue(pop 1, EraseUnions.mkBrIsNotData cenv.g.ilg (avoidHelpers,cuspec, idx, failure.CodeLabel)));
+ GenExpr cenv cgbuf eenv SPSuppress e (CmpThenBrOrContinue(pop 1, EraseUnions.mkBrIsNotData cenv.g.ilg (avoidHelpers,cuspec, idx, failure.CodeLabel)))
| Some (pops,pushes,i) ->
GenExpr cenv cgbuf eenv SPSuppress e Continue
@@ -4427,9 +4449,9 @@ and GenDecisionTreeTest cenv cloc cgbuf stackAtTargets e tester eenv successTree
//-------------------------------------------------------------------------
and GenLetRecFixup cenv cgbuf eenv (ilxCloSpec:IlxClosureSpec,e,ilField:ILFieldSpec,e2,_m) =
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
- CG.EmitInstrs cgbuf (pop 0) Push0 [ I_castclass ilxCloSpec.ILType ];
- GenExpr cenv cgbuf eenv SPSuppress e2 Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
+ CG.EmitInstrs cgbuf (pop 0) Push0 [ I_castclass ilxCloSpec.ILType ]
+ GenExpr cenv cgbuf eenv SPSuppress e2 Continue
CG.EmitInstrs cgbuf (pop 2) Push0 [ mkNormalStfld (mkILFieldSpec(ilField.FieldRef,ilxCloSpec.ILType)) ]
and GenLetRecBinds cenv cgbuf eenv (allBinds: Bindings,m) =
@@ -4472,7 +4494,7 @@ and GenLetRecBinds cenv cgbuf eenv (allBinds: Bindings,m) =
bind.Expr |> IterateRecursiveFixups cenv.g (Some bind.Var)
(computeFixupsForOneRecursiveVar bind.Var forwardReferenceSet fixups)
(exprForVal m bind.Var,
- (fun _ -> failwith ("internal error: should never need to set non-delayed recursive val: " + bind.Var.LogicalName)));
+ (fun _ -> failwith ("internal error: should never need to set non-delayed recursive val: " + bind.Var.LogicalName)))
// Record the variable as defined
let forwardReferenceSet = Zset.remove bind.Var forwardReferenceSet
forwardReferenceSet)
@@ -4480,11 +4502,11 @@ and GenLetRecBinds cenv cgbuf eenv (allBinds: Bindings,m) =
// Generate the actual bindings
let _ =
(recursiveVars, allBinds) ||> FlatList.fold (fun forwardReferenceSet (bind:Binding) ->
- GenBind cenv cgbuf eenv bind;
+ GenBind cenv cgbuf eenv bind
// Record the variable as defined
let forwardReferenceSet = Zset.remove bind.Var forwardReferenceSet
// Execute and discard any fixups that can now be committed
- fixups := !fixups |> List.filter (fun (boundv, fv, action) -> if (Zset.contains boundv forwardReferenceSet || Zset.contains fv forwardReferenceSet) then true else (action(); false));
+ fixups := !fixups |> List.filter (fun (boundv, fv, action) -> if (Zset.contains boundv forwardReferenceSet || Zset.contains fv forwardReferenceSet) then true else (action(); false))
forwardReferenceSet)
()
@@ -4492,7 +4514,7 @@ and GenLetRecBinds cenv cgbuf eenv (allBinds: Bindings,m) =
and GenLetRec cenv cgbuf eenv (binds,body,m) sequel =
let _,endScope as scopeMarks = StartLocalScope "letrec" cgbuf
let eenv = AllocStorageForBinds cenv cgbuf scopeMarks eenv binds
- GenLetRecBinds cenv cgbuf eenv (binds,m);
+ GenLetRecBinds cenv cgbuf eenv (binds,m)
let sp = if FlatList.exists bindHasSeqPt binds || FlatList.forall bindIsInvisible binds then SPAlways else SPSuppress
GenExpr cenv cgbuf eenv sp body (EndLocalScope(sequel,endScope))
@@ -4512,7 +4534,7 @@ and GenSequencePointForBind _cenv cgbuf eenv (TBind(vspec,e,spBind)) =
// SEQUENCE POINT REVIEW: don't emit for lazy either, nor any builder expressions
| _, (Expr.Lambda _ | Expr.TyLambda _) -> SPSuppress
| SequencePointAtBinding m,_ ->
- CG.EmitSeqPoint cgbuf m;
+ CG.EmitSeqPoint cgbuf m
SPSuppress
let m = vspec.Range
@@ -4579,17 +4601,17 @@ and GenBindAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec,rhsExpr,_)) =
let ilAttribs = GenAttrs cenv eenv vspec.Attribs
let ilTy = ilGetterMethSpec.FormalReturnType
let ilPropDef =
- { Name = PrettyNaming.ChopPropertyName ilGetterMethSpec.Name;
- IsRTSpecialName = false;
- IsSpecialName = false;
- SetMethod = None;
- GetMethod = Some ilGetterMethSpec.MethodRef;
- CallingConv = ILThisConvention.Static;
- Type = ilTy;
- Init = None;
- Args = mkILTypes [];
+ { Name = PrettyNaming.ChopPropertyName ilGetterMethSpec.Name
+ IsRTSpecialName = false
+ IsSpecialName = false
+ SetMethod = None
+ GetMethod = Some ilGetterMethSpec.MethodRef
+ CallingConv = ILThisConvention.Static
+ Type = ilTy
+ Init = None
+ Args = mkILTypes []
CustomAttrs = mkILCustomAttrs ilAttribs }
- cgbuf.mgbuf.AddOrMergePropertyDef(ilGetterMethSpec.MethodRef.EnclosingTypeRef, ilPropDef,m);
+ cgbuf.mgbuf.AddOrMergePropertyDef(ilGetterMethSpec.MethodRef.EnclosingTypeRef, ilPropDef,m)
let ilMethodDef =
let ilMethodBody = MethodBody.IL(CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress, [], ilGetterMethSpec.Name, eenv, 0, 0, rhsExpr, Return))
@@ -4597,13 +4619,13 @@ and GenBindAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec,rhsExpr,_)) =
|> AddSpecialNameFlag
|> AddNonUserCompilerGeneratedAttribs cenv.g
- CountMethodDef();
+ CountMethodDef()
cgbuf.mgbuf.AddMethodDef(ilGetterMethSpec.MethodRef.EnclosingTypeRef, ilMethodDef)
match optShadowLocal with
| NoShadowLocal -> ()
| ShadowLocal storage ->
- CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call (Normalcall, ilGetterMethSpec, None));
+ CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call (Normalcall, ilGetterMethSpec, None))
GenSetStorage m cgbuf storage
| StaticField (fspec, vref, hasLiteralAttr, ilTyForProperty, ilPropName, fty, ilGetterMethRef, ilSetterMethRef, optShadowLocal) ->
@@ -4647,8 +4669,8 @@ and GenBindAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec,rhsExpr,_)) =
let ilTypeRefForProperty = ilTyForProperty.TypeRef
for (tref,ilFieldDef) in ilFieldDefs do
- cgbuf.mgbuf.AddFieldDef(tref,ilFieldDef);
- CountStaticFieldDef();
+ cgbuf.mgbuf.AddFieldDef(tref,ilFieldDef)
+ CountStaticFieldDef()
// ... and the get/set properties to access it.
if not hasLiteralAttr then
@@ -4657,23 +4679,23 @@ and GenBindAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec,rhsExpr,_)) =
|> List.filter (fun (Attrib(_,_,_,_,_,targets,_)) -> canTarget(targets, System.AttributeTargets.Property))
|> GenAttrs cenv eenv // property only gets attributes that target properties
let ilPropDef =
- { Name=ilPropName;
- IsRTSpecialName=false;
- IsSpecialName=false;
- SetMethod=if mut || cenv.opts.isInteractiveItExpr then Some ilSetterMethRef else None;
- GetMethod=Some ilGetterMethRef;
- CallingConv=ILThisConvention.Static;
- Type=fty;
- Init=None;
- Args= mkILTypes [];
- CustomAttrs=mkILCustomAttrs (ilAttribs @ [mkCompilationMappingAttr cenv.g (int SourceConstructFlags.Value)]); }
- cgbuf.mgbuf.AddOrMergePropertyDef(ilTypeRefForProperty,ilPropDef,m);
+ { Name=ilPropName
+ IsRTSpecialName=false
+ IsSpecialName=false
+ SetMethod=if mut || cenv.opts.isInteractiveItExpr then Some ilSetterMethRef else None
+ GetMethod=Some ilGetterMethRef
+ CallingConv=ILThisConvention.Static
+ Type=fty
+ Init=None
+ Args= mkILTypes []
+ CustomAttrs=mkILCustomAttrs (ilAttribs @ [mkCompilationMappingAttr cenv.g (int SourceConstructFlags.Value)]) }
+ cgbuf.mgbuf.AddOrMergePropertyDef(ilTypeRefForProperty,ilPropDef,m)
let getterMethod =
mkILStaticMethod([],ilGetterMethRef.Name,access,[],mkILReturn fty,
mkMethodBody(true,emptyILLocals,2,nonBranchingInstrsToCode [ mkNormalLdsfld fspec ],None))
|> AddSpecialNameFlag
- cgbuf.mgbuf.AddMethodDef(ilTypeRefForProperty,getterMethod) ;
+ cgbuf.mgbuf.AddMethodDef(ilTypeRefForProperty,getterMethod)
if mut || cenv.opts.isInteractiveItExpr then
let setterMethod =
mkILStaticMethod([],ilSetterMethRef.Name,access,[mkILParamNamed("value",fty)],mkILReturn ILType.Void,
@@ -4681,7 +4703,7 @@ and GenBindAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec,rhsExpr,_)) =
|> AddSpecialNameFlag
cgbuf.mgbuf.AddMethodDef(ilTypeRefForProperty,setterMethod)
- GenBindRhs cenv cgbuf eenv sp vspec rhsExpr;
+ GenBindRhs cenv cgbuf eenv sp vspec rhsExpr
match optShadowLocal with
| NoShadowLocal ->
EmitSetStaticField cgbuf fspec
@@ -4817,7 +4839,7 @@ and GenMarshal cenv attribs =
| _ -> ILNativeType.Empty
Some(decodeUnmanagedType unmanagedType), otherAttribs
| Some (Attrib(_,_,_,_,_,_,m)) ->
- errorR(Error(FSComp.SR.ilMarshalAsAttributeCannotBeDecoded(),m));
+ errorR(Error(FSComp.SR.ilMarshalAsAttributeCannotBeDecoded(),m))
None, attribs
| _ ->
// No MarshalAs detected
@@ -4870,13 +4892,13 @@ and GenParams cenv eenv (mspec:ILMethodSpec) (attribs:ArgReprInfo list) (implVal
None, takenNames
let param : ILParameter =
- { Name=nmOpt;
- Type= ilArgTy;
- Default=None; (* REVIEW: support "default" attributes *)
- Marshal=Marshal;
- IsIn=inFlag;
- IsOut=outFlag;
- IsOptional=optionalFlag;
+ { Name=nmOpt
+ Type= ilArgTy
+ Default=None (* REVIEW: support "default" attributes *)
+ Marshal=Marshal
+ IsIn=inFlag
+ IsOut=outFlag
+ IsOptional=optionalFlag
CustomAttrs= mkILCustomAttrs (GenAttrs cenv eenv attribs) }
param, takenNames)
@@ -4884,23 +4906,23 @@ and GenParams cenv eenv (mspec:ILMethodSpec) (attribs:ArgReprInfo list) (implVal
and GenReturnInfo cenv eenv ilRetTy (retInfo : ArgReprInfo) : ILReturn =
let marshal,attrs = GenMarshal cenv retInfo.Attribs
- { Type=ilRetTy;
- Marshal=marshal;
+ { Type=ilRetTy
+ Marshal=marshal
CustomAttrs= mkILCustomAttrs (GenAttrs cenv eenv attrs) }
and GenPropertyForMethodDef compileAsInstance tref mdef (v:Val) (memberInfo:ValMemberInfo) ilArgTys ilPropTy ilAttrs compiledName =
let name = match compiledName with | Some n -> n | _ -> v.PropertyName in (* chop "get_" *)
- { Name=name;
- IsRTSpecialName=false;
- IsSpecialName=false;
- SetMethod=(if memberInfo.MemberFlags.MemberKind= MemberKind.PropertySet then Some(mkRefToILMethod(tref,mdef)) else None);
- GetMethod=(if memberInfo.MemberFlags.MemberKind= MemberKind.PropertyGet then Some(mkRefToILMethod(tref,mdef)) else None);
- CallingConv=(if compileAsInstance then ILThisConvention.Instance else ILThisConvention.Static);
- Type=ilPropTy;
- Init=None;
- Args= mkILTypes ilArgTys;
- CustomAttrs=ilAttrs; }
+ { Name=name
+ IsRTSpecialName=false
+ IsSpecialName=false
+ SetMethod=(if memberInfo.MemberFlags.MemberKind= MemberKind.PropertySet then Some(mkRefToILMethod(tref,mdef)) else None)
+ GetMethod=(if memberInfo.MemberFlags.MemberKind= MemberKind.PropertyGet then Some(mkRefToILMethod(tref,mdef)) else None)
+ CallingConv=(if compileAsInstance then ILThisConvention.Instance else ILThisConvention.Static)
+ Type=ilPropTy
+ Init=None
+ Args= mkILTypes ilArgTys
+ CustomAttrs=ilAttrs }
and GenEventForProperty cenv eenvForMeth (mspec:ILMethodSpec) (v:Val) ilAttrsThatGoOnPrimaryItem m returnTy =
let evname = v.PropertyName
@@ -4909,15 +4931,15 @@ and GenEventForProperty cenv eenvForMeth (mspec:ILMethodSpec) (v:Val) ilAttrsTha
let ilThisTy = mspec.EnclosingType
let addMethRef = mkILMethRef (ilThisTy.TypeRef,mspec.CallingConv,"add_" + evname,0,[ilDelegateTy],ILType.Void)
let removeMethRef = mkILMethRef (ilThisTy.TypeRef,mspec.CallingConv,"remove_" + evname,0,[ilDelegateTy],ILType.Void)
- { Type = Some(ilDelegateTy);
- Name= evname;
- IsRTSpecialName=false;
- IsSpecialName=false;
- AddMethod = addMethRef;
- RemoveMethod = removeMethRef;
- FireMethod= None;
- OtherMethods= [];
- CustomAttrs = mkILCustomAttrs ilAttrsThatGoOnPrimaryItem; }
+ { Type = Some(ilDelegateTy)
+ Name= evname
+ IsRTSpecialName=false
+ IsSpecialName=false
+ AddMethod = addMethRef
+ RemoveMethod = removeMethRef
+ FireMethod= None
+ OtherMethods= []
+ CustomAttrs = mkILCustomAttrs ilAttrsThatGoOnPrimaryItem }
and ComputeFlagFixupsForMemberBinding cenv (v:Val,memberInfo:ValMemberInfo) =
@@ -5020,12 +5042,12 @@ and GenMethodForBinding
let hasPreserveSigNamedArg,ilMethodBody,_hasDllImport =
match TryFindFSharpAttributeOpt cenv.g cenv.g.attrib_DllImportAttribute v.Attribs with
| Some (Attrib(_,_,[ AttribStringArg(dll) ],namedArgs,_,_,m)) ->
- if nonNil tps then error(Error(FSComp.SR.ilSignatureForExternalFunctionContainsTypeParameters(),m));
+ if nonNil tps then error(Error(FSComp.SR.ilSignatureForExternalFunctionContainsTypeParameters(),m))
let hasPreserveSigNamedArg, mbody = GenPInvokeMethod (v.CompiledName,dll,namedArgs)
hasPreserveSigNamedArg, mbody, true
| Some (Attrib(_,_,_,_,_,_,m)) ->
- error(Error(FSComp.SR.ilDllImportAttributeCouldNotBeDecoded(),m));
+ error(Error(FSComp.SR.ilDllImportAttributeCouldNotBeDecoded(),m))
| _ ->
// Replace the body of ValInline.PseudoVal "must inline" methods with a 'throw'
// However still generate the code for reflection etc.
@@ -5084,10 +5106,10 @@ and GenMethodForBinding
let mdef =
{mdef with
- IsPreserveSig = hasPreserveSigImplFlag || hasPreserveSigNamedArg;
- IsSynchronized = hasSynchronizedImplFlag;
- IsEntryPoint = isExplicitEntryPoint;
- IsNoInline = hasNoInliningFlag;
+ IsPreserveSig = hasPreserveSigImplFlag || hasPreserveSigNamedArg
+ IsSynchronized = hasSynchronizedImplFlag
+ IsEntryPoint = isExplicitEntryPoint
+ IsNoInline = hasNoInliningFlag
HasSecurity = mdef.HasSecurity || (securityAttributes.Length > 0)
SecurityDecls = secDecls }
@@ -5101,7 +5123,7 @@ and GenMethodForBinding
{mdef with IsSpecialName=true}
else
mdef
- CountMethodDef();
+ CountMethodDef()
cgbuf.mgbuf.AddMethodDef(tref,mdef)
@@ -5116,13 +5138,13 @@ and GenMethodForBinding
if memberInfo.MemberFlags.MemberKind = MemberKind.Constructor then
assert (isNil ilMethTypars)
let mdef = mkILCtor (access,ilParams,ilMethodBody)
- let mdef = { mdef with CustomAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated) };
+ let mdef = { mdef with CustomAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated) }
EmitTheMethodDef mdef
elif memberInfo.MemberFlags.MemberKind = MemberKind.ClassConstructor then
assert (isNil ilMethTypars)
let mdef = mkILClassCtor ilMethodBody
- let mdef = { mdef with CustomAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated) };
+ let mdef = { mdef with CustomAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated) }
EmitTheMethodDef mdef
// Generate virtual/override methods + method-impl information if needed
@@ -5153,15 +5175,15 @@ and GenMethodForBinding
{mdef with
mdKind=match mdef.mdKind with
| MethodKind.Virtual vinfo ->
- MethodKind.Virtual {vinfo with IsFinal=memberInfo.MemberFlags.IsFinal;
- IsAbstract=isAbstract; }
+ MethodKind.Virtual {vinfo with IsFinal=memberInfo.MemberFlags.IsFinal
+ IsAbstract=isAbstract }
| k -> k }
match memberInfo.MemberFlags.MemberKind with
| (MemberKind.PropertySet | MemberKind.PropertyGet) ->
if nonNil ilMethTypars then
- error(InternalError("A property may not be more generic than the enclosing type - constrain the polymorphism in the expression",v.Range));
+ error(InternalError("A property may not be more generic than the enclosing type - constrain the polymorphism in the expression",v.Range))
// Check if we're compiling the property as a .NET event
if CompileAsEvent cenv.g v.Attribs then
@@ -5183,10 +5205,10 @@ and GenMethodForBinding
// Add the special name flag for all properties
let mdef = mdef |> AddSpecialNameFlag
- let mdef = { mdef with CustomAttrs= mkILCustomAttrs ((GenAttrs cenv eenv attrsAppliedToGetterOrSetter) @ sourceNameAttribs @ ilAttrsCompilerGenerated) };
+ let mdef = { mdef with CustomAttrs= mkILCustomAttrs ((GenAttrs cenv eenv attrsAppliedToGetterOrSetter) @ sourceNameAttribs @ ilAttrsCompilerGenerated) }
EmitTheMethodDef mdef
| _ ->
- let mdef = { mdef with CustomAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated) };
+ let mdef = { mdef with CustomAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated) }
EmitTheMethodDef mdef
| _ ->
@@ -5210,11 +5232,11 @@ and GenMethodForBinding
and GenPInvokeMethod (nm,dll,namedArgs) =
let decoder = AttributeDecoder namedArgs
- let hasPreserveSigNamedArg = decoder.FindBool "PreserveSig" true;
+ let hasPreserveSigNamedArg = decoder.FindBool "PreserveSig" true
hasPreserveSigNamedArg,
MethodBody.PInvoke
- { Where=mkSimpleModRef dll;
- Name=decoder.FindString "EntryPoint" nm;
+ { Where=mkSimpleModRef dll
+ Name=decoder.FindString "EntryPoint" nm
CallingConv=
match decoder.FindInt32 "CallingConvention" 0 with
| 1 -> PInvokeCallingConvention.WinApi
@@ -5222,17 +5244,17 @@ and GenPInvokeMethod (nm,dll,namedArgs) =
| 3 -> PInvokeCallingConvention.Stdcall
| 4 -> PInvokeCallingConvention.Thiscall
| 5 -> PInvokeCallingConvention.Fastcall
- | _ -> PInvokeCallingConvention.WinApi;
+ | _ -> PInvokeCallingConvention.WinApi
CharEncoding=
match decoder.FindInt32 "CharSet" 0 with
| 1 -> PInvokeCharEncoding.None
| 2 -> PInvokeCharEncoding.Ansi
| 3 -> PInvokeCharEncoding.Unicode
| 4 -> PInvokeCharEncoding.Auto
- | _ -> PInvokeCharEncoding.None;
- NoMangle= decoder.FindBool "ExactSpelling" false;
- LastError= decoder.FindBool "SetLastError" false;
- ThrowOnUnmappableChar= if (decoder.FindBool "ThrowOnUnmappableChar" false) then PInvokeThrowOnUnmappableChar.Enabled else PInvokeThrowOnUnmappableChar.UseAssembly;
+ | _ -> PInvokeCharEncoding.None
+ NoMangle= decoder.FindBool "ExactSpelling" false
+ LastError= decoder.FindBool "SetLastError" false
+ ThrowOnUnmappableChar= if (decoder.FindBool "ThrowOnUnmappableChar" false) then PInvokeThrowOnUnmappableChar.Enabled else PInvokeThrowOnUnmappableChar.UseAssembly
CharBestFit=if (decoder.FindBool "BestFitMapping" false) then PInvokeCharBestFit.Enabled else PInvokeCharBestFit.UseAssembly }
@@ -5246,10 +5268,10 @@ and GenSetVal cenv cgbuf eenv (vref,e,m) sequel =
let storage = StorageForValRef m vref eenv
match storage with
| Env (ilCloTy,_,_,_) ->
- CG.EmitInstr cgbuf (pop 0) (Push [ilCloTy]) mkLdarg0;
+ CG.EmitInstr cgbuf (pop 0) (Push [ilCloTy]) mkLdarg0
| _ ->
()
- GenExpr cenv cgbuf eenv SPSuppress e Continue;
+ GenExpr cenv cgbuf eenv SPSuppress e Continue
GenSetStorage vref.Range cgbuf storage
GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel
@@ -5258,7 +5280,7 @@ and GenGetValRefAndSequel cenv cgbuf eenv m (v:ValRef) fetchSequel =
GenGetStorageAndSequel cenv cgbuf eenv m (ty, GenType cenv.amap m cenv.g eenv.tyenv ty) (StorageForValRef m v eenv) fetchSequel
and GenGetVal cenv cgbuf eenv (v:ValRef,m) sequel =
- GenGetValRefAndSequel cenv cgbuf eenv m v None;
+ GenGetValRefAndSequel cenv cgbuf eenv m v None
GenSequel cenv eenv.cloc cgbuf sequel
and GenBindRhs cenv cgbuf eenv sp (vspec:Val) e =
@@ -5277,10 +5299,10 @@ and GenBindRhs cenv cgbuf eenv sp (vspec:Val) e =
let selfv = if isLocalTypeFunc then None else Some (mkLocalValRef vspec)
GenLambda cenv cgbuf eenv isLocalTypeFunc selfv e Continue
| _ ->
- GenExpr cenv cgbuf eenv sp e Continue;
+ GenExpr cenv cgbuf eenv sp e Continue
and GenSetBindValue cenv cgbuf eenv eenv2 (vspec:Val) e =
- GenBindRhs cenv cgbuf eenv2 SPSuppress vspec e;
+ GenBindRhs cenv cgbuf eenv2 SPSuppress vspec e
GenStoreVal cgbuf eenv vspec.Range vspec
and EmitInitLocal cgbuf typ idx = CG.EmitInstrs cgbuf (pop 0) Push0 [I_ldloca (uint16 idx); (I_initobj typ) ]
@@ -5294,7 +5316,7 @@ and GenSetStorage m cgbuf storage =
match storage with
| Local (idx,_) -> EmitSetLocal cgbuf idx
| StaticField (_, _, hasLiteralAttr, ilContainerTy, _, _, _, ilSetterMethRef, _) ->
- if hasLiteralAttr then errorR(Error(FSComp.SR.ilLiteralFieldsCannotBeSet(),m));
+ if hasLiteralAttr then errorR(Error(FSComp.SR.ilLiteralFieldsCannotBeSet(),m))
CG.EmitInstr cgbuf (pop 1) Push0 (I_call(Normalcall,mkILMethSpecForMethRefInTy(ilSetterMethRef,ilContainerTy,[]),None))
| StaticProperty (ilGetterMethSpec,_) ->
error(Error(FSComp.SR.ilStaticMethodIsNotLambda(ilGetterMethSpec.Name),m))
@@ -5313,7 +5335,7 @@ and CommitGetStorageSequel cenv cgbuf eenv m typ localCloInfo storeSequel =
match localCloInfo,storeSequel with
| Some {contents =NamedLocalIlxClosureInfoGenerator _cloinfo},_ -> error(InternalError("Unexpected generator",m))
| Some {contents =NamedLocalIlxClosureInfoGenerated cloinfo},Some (tyargs,args,m,sequel) when nonNil tyargs ->
- let actualRetTy = GenNamedLocalTyFuncCall cenv cgbuf eenv typ cloinfo tyargs m;
+ let actualRetTy = GenNamedLocalTyFuncCall cenv cgbuf eenv typ cloinfo tyargs m
CommitGetStorageSequel cenv cgbuf eenv m actualRetTy None (Some ([],args,m,sequel))
| _, None -> ()
| _,Some ([],[],_,sequel) ->
@@ -5324,7 +5346,7 @@ and CommitGetStorageSequel cenv cgbuf eenv m typ localCloInfo storeSequel =
and GenGetStorageAndSequel cenv cgbuf eenv m (typ,ilTy) storage storeSequel =
match storage with
| Local (idx,localCloInfo) ->
- EmitGetLocal cgbuf ilTy idx;
+ EmitGetLocal cgbuf ilTy idx
CommitGetStorageSequel cenv cgbuf eenv m typ localCloInfo storeSequel
| StaticField (fspec, _, hasLiteralAttr, ilContainerTy, _, _, ilGetterMethRef, _, _) ->
@@ -5332,11 +5354,11 @@ and GenGetStorageAndSequel cenv cgbuf eenv m (typ,ilTy) storage storeSequel =
if hasLiteralAttr then
EmitGetStaticField cgbuf ilTy fspec
else
- CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call(Normalcall, mkILMethSpecForMethRefInTy (ilGetterMethRef, ilContainerTy, []), None));
+ CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call(Normalcall, mkILMethSpecForMethRefInTy (ilGetterMethRef, ilContainerTy, []), None))
CommitGetStorageSequel cenv cgbuf eenv m typ None storeSequel
| StaticProperty (ilGetterMethSpec, _) ->
- CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call (Normalcall, ilGetterMethSpec, None));
+ CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call (Normalcall, ilGetterMethSpec, None))
CommitGetStorageSequel cenv cgbuf eenv m typ None storeSequel
| Method (topValInfo,vref,mspec,_,_,_) ->
@@ -5355,19 +5377,19 @@ and GenGetStorageAndSequel cenv cgbuf eenv m (typ,ilTy) storage storeSequel =
GenLambda cenv cgbuf eenv false None expr Continue
| Some (tyargs',args,m,sequel) ->
let specializedExpr =
- if isNil args && isNil tyargs' then failwith ("non-lambda at use of method " + mspec.Name);
+ if isNil args && isNil tyargs' then failwith ("non-lambda at use of method " + mspec.Name)
MakeApplicationAndBetaReduce cenv.g (expr,exprty,[tyargs'],args,m)
GenExpr cenv cgbuf eenv SPSuppress specializedExpr sequel
| Null ->
- CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (AI_ldnull);
+ CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (AI_ldnull)
CommitGetStorageSequel cenv cgbuf eenv m typ None storeSequel
| Unrealized ->
- error(InternalError(sprintf "getting an unrealized value of type '%s'" (showL(typeL typ)),m));
+ error(InternalError(sprintf "getting an unrealized value of type '%s'" (showL(typeL typ)),m))
| Arg i ->
- CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdarg (uint16 i));
+ CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdarg (uint16 i))
CommitGetStorageSequel cenv cgbuf eenv m typ None storeSequel
| Env (_,_,ilField,localCloInfo) ->
@@ -5376,7 +5398,7 @@ and GenGetStorageAndSequel cenv cgbuf eenv m (typ,ilTy) storage storeSequel =
CommitGetStorageSequel cenv cgbuf eenv m typ localCloInfo storeSequel
and GenGetLocalVals cenv cgbuf eenvouter m fvs =
- List.iter (fun v -> GenGetLocalVal cenv cgbuf eenvouter m v None) fvs;
+ List.iter (fun v -> GenGetLocalVal cenv cgbuf eenvouter m v None) fvs
and GenGetLocalVal cenv cgbuf eenv m (vspec:Val) fetchSequel =
GenGetStorageAndSequel cenv cgbuf eenv m (vspec.Type, GenTypeOfVal cenv eenv vspec) (StorageForVal m vspec eenv) fetchSequel
@@ -5391,14 +5413,14 @@ and GenStoreVal cgbuf eenv m (vspec:Val) =
// Allocate locals for values
//--------------------------------------------------------------------------
-and AllocLocal cenv cgbuf eenv compgen (v,ty) (scopeMarks: Mark * Mark) =
+and AllocLocal cenv cgbuf eenv compgen (v,ty,isFixed) (scopeMarks: Mark * Mark) =
// The debug range for the local
let ranges = if compgen then [] else [(v,scopeMarks)]
// Get an index for the local
let j =
if cenv.opts.localOptimizationsAreOn
- then cgbuf.ReallocLocal((fun i (_,ty') -> not (IntMap.mem i eenv.liveLocals) && (ty = ty')),ranges,ty)
- else cgbuf.AllocLocal(ranges,ty)
+ then cgbuf.ReallocLocal((fun i (_,ty',isFixed') -> not isFixed' && not isFixed && not (IntMap.mem i eenv.liveLocals) && (ty = ty')),ranges,ty,isFixed)
+ else cgbuf.AllocLocal(ranges,ty,isFixed)
j, { eenv with liveLocals = IntMap.add j () eenv.liveLocals }
and AllocLocalVal cenv cgbuf v eenv repr scopeMarks =
@@ -5414,11 +5436,11 @@ and AllocLocalVal cenv cgbuf v eenv repr scopeMarks =
let cloinfo,_,_ = GetIlxClosureInfo cenv v.Range true None eenvinner (Option.get repr)
cloinfo
- let idx,eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName, cenv.g.ilg.typ_Object) scopeMarks
+ let idx,eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName, cenv.g.ilg.typ_Object, false) scopeMarks
Local (idx,Some(ref (NamedLocalIlxClosureInfoGenerator cloinfoGenerate))),eenv
else
(* normal local *)
- let idx,eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName, GenTypeOfVal cenv eenv v) scopeMarks
+ let idx,eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName, GenTypeOfVal cenv eenv v, v.IsFixed) scopeMarks
Local (idx,None),eenv
let eenv = AddStorageForVal cenv.g (v,notlazy repr) eenv
Some repr, eenv
@@ -5443,7 +5465,7 @@ and AllocStorageForBinds cenv cgbuf scopeMarks eenv binds =
| NamedLocalIlxClosureInfoGenerator f -> g := NamedLocalIlxClosureInfoGenerated (f eenv)
| NamedLocalIlxClosureInfoGenerated _ -> ()
| _ -> ()
- | _ -> ());
+ | _ -> ())
eenv
@@ -5488,14 +5510,14 @@ and AllocTopValWithinExpr cenv cgbuf cloc scopeMarks v eenv =
/// - and because IL requires empty stack following a forward br (jump).
and EmitSaveStack cenv cgbuf eenv m scopeMarks =
let savedStack = (cgbuf.GetCurrentStack())
- let savedStackLocals,eenvinner = List.mapFold (fun eenv ty -> AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("spill",m), ty) scopeMarks) eenv savedStack
- List.iter (EmitSetLocal cgbuf) savedStackLocals;
- cgbuf.AssertEmptyStack();
+ let savedStackLocals,eenvinner = List.mapFold (fun eenv ty -> AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("spill",m), ty, false) scopeMarks) eenv savedStack
+ List.iter (EmitSetLocal cgbuf) savedStackLocals
+ cgbuf.AssertEmptyStack()
(savedStack,savedStackLocals),eenvinner (* need to return, it marks locals "live" *)
/// Restore the stack and load the result
and EmitRestoreStack cgbuf (savedStack,savedStackLocals) =
- cgbuf.AssertEmptyStack();
+ cgbuf.AssertEmptyStack()
List.iter2 (EmitGetLocal cgbuf) (List.rev savedStack) (List.rev savedStackLocals)
//-------------------------------------------------------------------------
@@ -5595,7 +5617,7 @@ and GenAttr amap g eenv (Attrib(_,k,args,props,_,_,_)) =
match k with
| ILAttrib(mref) -> mkILMethSpec(mref,AsObject,[],[])
| FSAttrib(vref) ->
- assert(vref.IsMember);
+ assert(vref.IsMember)
let mspec,_,_,_,_ = GetMethodSpecForMemberVal amap g (Option.get vref.MemberInfo) vref
mspec
let ilArgs = List.map2 (fun (AttribExpr(_,vexpr)) ty -> GenAttribArg amap g eenv vexpr ty) args (ILList.toList mspec.FormalArgTypes)
@@ -5683,7 +5705,7 @@ and GenModuleDef cenv (cgbuf:CodeGenBuffer) qname lazyInitInfo eenv x =
GenBindings cenv cgbuf eenv (FlatList.one bind)
| TMDefDo(e,_) ->
- GenExpr cenv cgbuf eenv SPAlways e discard;
+ GenExpr cenv cgbuf eenv SPAlways e discard
| TMAbstract(mexpr) ->
GenModuleExpr cenv cgbuf qname lazyInitInfo eenv mexpr
@@ -5696,7 +5718,7 @@ and GenModuleDef cenv (cgbuf:CodeGenBuffer) qname lazyInitInfo eenv x =
and GenModuleBinding cenv (cgbuf:CodeGenBuffer) (qname:QualifiedNameOfFile) lazyInitInfo eenv m x =
match x with
| ModuleOrNamespaceBinding.Binding bind ->
- GenLetRecBinds cenv cgbuf eenv ([bind],m);
+ GenLetRecBinds cenv cgbuf eenv ([bind],m)
| ModuleOrNamespaceBinding.Module (mspec, mdef) ->
let hidden = IsHiddenTycon eenv.sigToImplRemapInfo mspec
@@ -5716,16 +5738,16 @@ and GenModuleBinding cenv (cgbuf:CodeGenBuffer) (qname:QualifiedNameOfFile) lazy
// "main" method in the case where the "main" method is implicit.
let staticClassTrigger = (* if eenv.isFinalFile then *) ILTypeInit.OnAny (* else ILTypeInit.BeforeField *)
- GenTypeDefForCompLoc (cenv, eenvinner, cgbuf.mgbuf, eenvinner.cloc, hidden, mspec.Attribs, staticClassTrigger, false, (* atEnd= *) true);
+ GenTypeDefForCompLoc (cenv, eenvinner, cgbuf.mgbuf, eenvinner.cloc, hidden, mspec.Attribs, staticClassTrigger, false, (* atEnd= *) true)
// Generate the declarations in the module and its initialization code
- GenModuleDef cenv cgbuf qname lazyInitInfo eenvinner mdef;
+ GenModuleDef cenv cgbuf qname lazyInitInfo eenvinner mdef
// If the module has a .cctor for some mutable fields, we need to ensure that when
// those fields are "touched" the InitClass .cctor is forced. The InitClass .cctor will
// then fill in the value of the mutable fields.
if not mspec.IsNamespace && (cgbuf.mgbuf.GetCurrentFields(TypeRefForCompLoc eenvinner.cloc) |> Seq.isEmpty |> not) then
- GenForceWholeFileInitializationAsPartOfCCtor cenv cgbuf.mgbuf lazyInitInfo (TypeRefForCompLoc eenvinner.cloc) mspec.Range;
+ GenForceWholeFileInitializationAsPartOfCCtor cenv cgbuf.mgbuf lazyInitInfo (TypeRefForCompLoc eenvinner.cloc) mspec.Range
/// Generate the namespace fragments in a single file
@@ -5740,14 +5762,14 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic
let initClassTrigger = (* if isFinalFile then *) ILTypeInit.OnAny (* else ILTypeInit.BeforeField *)
- let eenv = {eenv with cloc = initClassCompLoc;
- isFinalFile = isFinalFile;
+ let eenv = {eenv with cloc = initClassCompLoc
+ isFinalFile = isFinalFile
someTypeInThisAssembly = initClassTy }
// Create the class to hold the initialization code and static fields for this file.
// internal static class $ {}
// Put it at the end since that gives an approximation of dependency order (to aid FSI.EXE's code generator - see FSharp 1.0 5548)
- GenTypeDefForCompLoc (cenv, eenv, mgbuf, initClassCompLoc, useHiddenInitCode, [], initClassTrigger, false, (*atEnd=*)true);
+ GenTypeDefForCompLoc (cenv, eenv, mgbuf, initClassCompLoc, useHiddenInitCode, [], initClassTrigger, false, (*atEnd=*)true)
// lazyInitInfo is an accumulator of functions which add the forced initialization of the storage module to
// - mutable fields in public modules
@@ -5775,7 +5797,7 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic
CodeGenMethod cenv mgbuf
(true,[],methodName,eenv,0,0,
(fun cgbuf eenv ->
- GenModuleExpr cenv cgbuf qname lazyInitInfo eenv mexpr;
+ GenModuleExpr cenv cgbuf qname lazyInitInfo eenv mexpr
CG.EmitInstr cgbuf (pop 0) Push0 I_ret),m)
// The code generation for the initialization is now complete and the IL code is in topCode.
@@ -5813,10 +5835,10 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic
if doesSomething then
lazyInitInfo.Add (fun fspec feefee seqpt ->
// This adds the explicit init of the .cctor to the explicit entrypoint main method
- mgbuf.AddExplicitInitToSpecificMethodDef((fun md -> md.IsEntryPoint), tref, fspec, GenPossibleILSourceMarker cenv m, feefee, seqpt));
+ mgbuf.AddExplicitInitToSpecificMethodDef((fun md -> md.IsEntryPoint), tref, fspec, GenPossibleILSourceMarker cenv m, feefee, seqpt))
let cctorMethDef = mkILClassCtor (MethodBody.IL topCode)
- mgbuf.AddMethodDef(initClassTy.TypeRef,cctorMethDef);
+ mgbuf.AddMethodDef(initClassTy.TypeRef,cctorMethDef)
// Final file, implicit entry point. We generate no .cctor.
// void main@() {
@@ -5827,14 +5849,14 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic
let ilAttrs = mkILCustomAttrs (GenAttrs cenv eenv mainInfo)
if not cenv.opts.isInteractive && not doesSomething then
let errorM = m.EndRange
- warning (Error(FSComp.SR.ilMainModuleEmpty(), errorM));
+ warning (Error(FSComp.SR.ilMainModuleEmpty(), errorM))
// generate main@
let ilMainMethodDef =
let mdef = mkILNonGenericStaticMethod(mainMethName,ILMemberAccess.Public,[],mkILReturn ILType.Void, MethodBody.IL topCode)
{mdef with IsEntryPoint= true; CustomAttrs = ilAttrs }
- mgbuf.AddMethodDef(initClassTy.TypeRef,ilMainMethodDef);
+ mgbuf.AddMethodDef(initClassTy.TypeRef,ilMainMethodDef)
// Library file : generate an optional .cctor if topCode has initialization effect
@@ -5843,7 +5865,7 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic
// Add the cctor
let cctorMethDef = mkILClassCtor (MethodBody.IL topCode)
- mgbuf.AddMethodDef(initClassTy.TypeRef,cctorMethDef);
+ mgbuf.AddMethodDef(initClassTy.TypeRef,cctorMethDef)
end
@@ -5860,12 +5882,12 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic
|> addFieldGeneratedAttrs cenv.g.ilg
let fspec = mkILFieldSpecInTy (initClassTy, initFieldName, cenv. g.ilg.typ_Int32)
- CountStaticFieldDef();
- mgbuf.AddFieldDef(initClassTy.TypeRef,ilFieldDef);
+ CountStaticFieldDef()
+ mgbuf.AddFieldDef(initClassTy.TypeRef,ilFieldDef)
// Run the imperative (yuck!) actions that force the generation
// of references to the cctor for nested modules etc.
- lazyInitInfo |> Seq.iter (fun f -> f fspec feefee seqpt);
+ lazyInitInfo |> Seq.iter (fun f -> f fspec feefee seqpt)
if isScript && not(isFinalFile) then
mgbuf.AddScriptInitFieldSpec(fspec,m)
@@ -5895,8 +5917,8 @@ and GenEqualsOverrideCallingIComparable cenv (tcref:TyconRef, ilThisTy, _ilThatT
mkILReturn cenv.g.ilg.typ_bool,
mkMethodBody(true,emptyILLocals,2,
nonBranchingInstrsToCode
- [ yield mkLdarg0;
- yield mkLdarg 1us;
+ [ yield mkLdarg0
+ yield mkLdarg 1us
if tcref.IsStructOrEnumTycon then
yield I_callconstraint ( Normalcall, ilThisTy,mspec,None)
else
@@ -5926,7 +5948,7 @@ and GenFieldInit m c =
and GenAbstractBinding cenv eenv tref (vref:ValRef) =
- assert(vref.IsMember);
+ assert(vref.IsMember)
let m = vref.Range
let memberInfo = Option.get vref.MemberInfo
let attribs = vref.Attribs
@@ -5948,13 +5970,13 @@ and GenAbstractBinding cenv eenv tref (vref:ValRef) =
let mdef = fixupVirtualSlotFlags mdef
let mdef =
{mdef with
- IsPreserveSig=hasPreserveSigImplFlag;
- IsSynchronized=hasSynchronizedImplFlag;
- IsNoInline=hasNoInliningFlag;
+ IsPreserveSig=hasPreserveSigImplFlag
+ IsSynchronized=hasSynchronizedImplFlag
+ IsNoInline=hasNoInliningFlag
mdKind=match mdef.mdKind with
| MethodKind.Virtual vinfo ->
- MethodKind.Virtual {vinfo with IsFinal=memberInfo.MemberFlags.IsFinal;
- IsAbstract=memberInfo.MemberFlags.IsDispatchSlot; }
+ MethodKind.Virtual {vinfo with IsFinal=memberInfo.MemberFlags.IsFinal
+ IsAbstract=memberInfo.MemberFlags.IsDispatchSlot }
| k -> k }
match memberInfo.MemberFlags.MemberKind with
@@ -5963,7 +5985,7 @@ and GenAbstractBinding cenv eenv tref (vref:ValRef) =
| MemberKind.Member ->
let mdef = {mdef with CustomAttrs= mkILCustomAttrs ilAttrs }
[mdef], [], []
- | MemberKind.PropertyGetSet -> error(Error(FSComp.SR.ilUnexpectedGetSetAnnotation(),m));
+ | MemberKind.PropertyGetSet -> error(Error(FSComp.SR.ilUnexpectedGetSetAnnotation(),m))
| MemberKind.PropertySet | MemberKind.PropertyGet ->
let v = vref.Deref
let vtyp = ReturnTypeOfPropertyVal cenv.g v
@@ -6046,7 +6068,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
// REVIEW: no method impl generated for IStructuralHash or ICompare
let methodImpls =
[ for vref in tycon.MembersOfFSharpTyconByName |> NameMultiMap.range do
- assert(vref.IsMember);
+ assert(vref.IsMember)
let memberInfo = vref.MemberInfo.Value
if memberInfo.MemberFlags.IsOverrideOrExplicitImpl && not (CompileAsEvent cenv.g vref.Attribs) then
@@ -6122,7 +6144,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
| TTyconInterface -> ILTypeDefKind.Interface
| TTyconEnum -> ILTypeDefKind.Enum
| TTyconDelegate _ -> ILTypeDefKind.Delegate
- | TRecdRepr _ when tycon.IsStructRecordTycon -> ILTypeDefKind.ValueType
+ | TRecdRepr _ | TUnionRepr _ when tycon.IsStructOrEnumTycon -> ILTypeDefKind.ValueType
| _ -> ILTypeDefKind.Class
let requiresExtraField =
@@ -6164,7 +6186,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
| Some (Attrib(_,_,[ AttribInt32Arg(fieldOffset) ],_,_,_,_)) ->
Some fieldOffset
| Some (Attrib(_,_,_,_,_,_,m)) ->
- errorR(Error(FSComp.SR.ilFieldOffsetAttributeCouldNotBeDecoded(),m));
+ errorR(Error(FSComp.SR.ilFieldOffsetAttributeCouldNotBeDecoded(),m))
None
| _ ->
None
@@ -6198,18 +6220,18 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
| _ -> [] // don't hide fields in classes in debug display
yield
- { Name = ilFieldName;
- Type = ilPropType;
- IsStatic = isStatic;
- Access = ComputeMemberAccess isFieldHidden;
- Data = None;
- LiteralValue = Option.map (GenFieldInit m) fspec.LiteralValue;
- Offset = ilFieldOffset;
- IsSpecialName = (ilFieldName="value__" && tycon.IsEnumTycon);
+ { Name = ilFieldName
+ Type = ilPropType
+ IsStatic = isStatic
+ Access = ComputeMemberAccess isFieldHidden
+ Data = None
+ LiteralValue = Option.map (GenFieldInit m) fspec.LiteralValue
+ Offset = ilFieldOffset
+ IsSpecialName = (ilFieldName="value__" && tycon.IsEnumTycon)
Marshal = ilFieldMarshal
- NotSerialized = ilNotSerialized;
- IsInitOnly = false;
- IsLiteral = fspec.LiteralValue.IsSome;
+ NotSerialized = ilNotSerialized
+ IsInitOnly = false
+ IsLiteral = fspec.LiteralValue.IsSome
CustomAttrs = mkILCustomAttrs (GenAttrs cenv eenv fattribs @ extraAttribs) }
if requiresExtraField then
@@ -6224,16 +6246,16 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
let ilHasSetter = isCLIMutable || isFSharpMutable
let ilFieldAttrs = GenAttrs cenv eenv propAttribs @ [mkCompilationMappingAttrWithSeqNum cenv.g (int SourceConstructFlags.Field) i]
yield
- { Name = ilPropName;
- IsRTSpecialName = false;
- IsSpecialName = false;
- SetMethod = (if ilHasSetter then Some(mkILMethRef(tref,ilCallingConv,"set_" + ilPropName,0,[ilPropType],ILType.Void)) else None);
- GetMethod = Some(mkILMethRef(tref,ilCallingConv,"get_" + ilPropName,0,[],ilPropType));
- CallingConv = ilCallingConv.ThisConv;
- Type = ilPropType;
- Init = None;
- Args = mkILTypes [];
- CustomAttrs = mkILCustomAttrs ilFieldAttrs; } ]
+ { Name = ilPropName
+ IsRTSpecialName = false
+ IsSpecialName = false
+ SetMethod = (if ilHasSetter then Some(mkILMethRef(tref,ilCallingConv,"set_" + ilPropName,0,[ilPropType],ILType.Void)) else None)
+ GetMethod = Some(mkILMethRef(tref,ilCallingConv,"get_" + ilPropName,0,[],ilPropType))
+ CallingConv = ilCallingConv.ThisConv
+ Type = ilPropType
+ Init = None
+ Args = mkILTypes []
+ CustomAttrs = mkILCustomAttrs ilFieldAttrs } ]
let methodDefs =
[ // Generate property getter methods for those fields that have properties
@@ -6275,11 +6297,11 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
// Give the instantiation of the printf format object, i.e. a Format`5 object compatible with StringFormat
let newFormatMethSpec = mkILMethSpec(newFormatMethSpec.MethodRef,AsObject,
[// 'T -> string'
- funcTy;
+ funcTy
// rest follow from 'StringFormat'
- GenUnitTy cenv eenv m;
- cenv.g.ilg.typ_String;
- cenv.g.ilg.typ_String;
+ GenUnitTy cenv eenv m
+ cenv.g.ilg.typ_String
+ cenv.g.ilg.typ_String
cenv.g.ilg.typ_String],[])
// Instantiate with our own type
let sprintfMethSpec = mkILMethSpec(sprintfMethSpec.MethodRef,AsObject,[],[funcTy])
@@ -6291,13 +6313,15 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
(true,emptyILLocals,2,
nonBranchingInstrsToCode
([ // load the hardwired format string
- I_ldstr "%+0.8A";
+ yield I_ldstr "%+0.8A"
// make the printf format object
- mkNormalNewobj newFormatMethSpec;
+ yield mkNormalNewobj newFormatMethSpec
// call sprintf
- mkNormalCall sprintfMethSpec;
+ yield mkNormalCall sprintfMethSpec
// call the function returned by sprintf
- mkLdarg0 ] @
+ yield mkLdarg0
+ if ilThisTy.Boxity = ILBoxity.AsValue then
+ yield mkNormalLdobj ilThisTy ] @
callInstrs),
None))
yield ilMethodDef |> AddSpecialNameFlag |> AddNonUserCompilerGeneratedAttribs cenv.g
@@ -6325,7 +6349,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
relevantFields
|> List.map (fun (_,ilFieldName,_,_,_,ilPropType,_,fspec) -> (fspec.Name,ilFieldName,ilPropType))
- let isStructRecord = tycon.IsStructRecordTycon
+ let isStructRecord = tycon.IsStructRecordOrUnionTycon
// No type spec if the record is a value type
let spec = if isStructRecord then None else Some(cenv.g.ilg.tspec_Object)
@@ -6412,10 +6436,10 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
// Set some the extra entries in the definition
let isTheSealedAttribute = tyconRefEq cenv.g tcref cenv.g.attrib_SealedAttribute.TyconRef
- let tdef = { tdef with IsSealed = isSealedTy cenv.g thisTy || isTheSealedAttribute;
- IsSerializable = isSerializable;
- MethodImpls=mkILMethodImpls methodImpls;
- IsAbstract=isAbstract;
+ let tdef = { tdef with IsSealed = isSealedTy cenv.g thisTy || isTheSealedAttribute
+ IsSerializable = isSerializable
+ MethodImpls=mkILMethodImpls methodImpls
+ IsAbstract=isAbstract
IsComInterop=isComInteropTy cenv.g thisTy }
let tdLayout,tdEncoding =
@@ -6442,7 +6466,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
| _ -> ILTypeDefLayout.Auto
tdLayout,tdEncoding
| Some (Attrib(_,_,_,_,_,_,m)) ->
- errorR(Error(FSComp.SR.ilStructLayoutAttributeCouldNotBeDecoded(),m));
+ errorR(Error(FSComp.SR.ilStructLayoutAttributeCouldNotBeDecoded(),m))
ILTypeDefLayout.Auto, ILDefaultPInvokeEncoding.Ansi
| _ when (match ilTypeDefKind with ILTypeDefKind.ValueType -> true | _ -> false) ->
@@ -6486,46 +6510,46 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
| TUnionRepr _ ->
let alternatives =
tycon.UnionCasesArray |> Array.mapi (fun i ucspec ->
- { altName=ucspec.CompiledName;
- altFields=GenUnionCaseRef cenv.amap m cenv.g eenvinner.tyenv i ucspec.RecdFieldsArray;
+ { altName=ucspec.CompiledName
+ altFields=GenUnionCaseRef cenv.amap m cenv.g eenvinner.tyenv i ucspec.RecdFieldsArray
altCustomAttrs= mkILCustomAttrs (GenAttrs cenv eenv ucspec.Attribs @ [mkCompilationMappingAttrWithSeqNum cenv.g (int SourceConstructFlags.UnionCase) i]) })
let cuinfo =
- { cudReprAccess=reprAccess;
- cudNullPermitted=IsUnionTypeWithNullAsTrueValue cenv.g tycon;
- cudHelpersAccess=reprAccess;
- cudHasHelpers=ComputeUnionHasHelpers cenv.g tcref;
- cudDebugProxies= generateDebugProxies;
- cudDebugDisplayAttributes= ilDebugDisplayAttributes;
- cudAlternatives= alternatives;
- cudWhere = None};
+ { cudReprAccess=reprAccess
+ cudNullPermitted=IsUnionTypeWithNullAsTrueValue cenv.g tycon
+ cudHelpersAccess=reprAccess
+ cudHasHelpers=ComputeUnionHasHelpers cenv.g tcref
+ cudDebugProxies= generateDebugProxies
+ cudDebugDisplayAttributes= ilDebugDisplayAttributes
+ cudAlternatives= alternatives
+ cudWhere = None}
let tdef =
- { Name = ilTypeName;
- Layout = ILTypeDefLayout.Auto;
- Access = access;
- GenericParams = ilGenParams;
+ { Name = ilTypeName
+ Layout = ILTypeDefLayout.Auto
+ Access = access
+ GenericParams = ilGenParams
CustomAttrs =
mkILCustomAttrs (ilCustomAttrs @
[mkCompilationMappingAttr cenv.g
(int (if hiddenRepr
then SourceConstructFlags.SumType ||| SourceConstructFlags.NonPublicRepresentation
- else SourceConstructFlags.SumType)) ]);
- InitSemantics=ILTypeInit.BeforeField;
- IsSealed=true;
- IsAbstract=false;
- tdKind= ILTypeDefKind.Class
- Fields = ilFields;
- Events= ilEvents;
- Properties = ilProperties;
- Methods= mkILMethods ilMethods;
- MethodImpls= mkILMethodImpls methodImpls;
- IsComInterop=false;
- IsSerializable= isSerializable;
- IsSpecialName= false;
- NestedTypes=emptyILTypeDefs;
- Encoding= ILDefaultPInvokeEncoding.Auto;
- Implements= mkILTypes ilIntfTys;
- Extends= Some cenv.g.ilg.typ_Object;
- SecurityDecls= emptyILSecurityDecls;
+ else SourceConstructFlags.SumType)) ])
+ InitSemantics=ILTypeInit.BeforeField
+ IsSealed=true
+ IsAbstract=false
+ tdKind= (if tycon.IsStructOrEnumTycon then ILTypeDefKind.ValueType else ILTypeDefKind.Class)
+ Fields = ilFields
+ Events= ilEvents
+ Properties = ilProperties
+ Methods= mkILMethods ilMethods
+ MethodImpls= mkILMethodImpls methodImpls
+ IsComInterop=false
+ IsSerializable= isSerializable
+ IsSpecialName= false
+ NestedTypes=emptyILTypeDefs
+ Encoding= ILDefaultPInvokeEncoding.Auto
+ Implements= mkILTypes ilIntfTys
+ Extends= Some (if tycon.IsStructOrEnumTycon then cenv.g.ilg.typ_ValueType else cenv.g.ilg.typ_Object)
+ SecurityDecls= emptyILSecurityDecls
HasSecurity=false }
let tdef2 = EraseUnions.mkClassUnionDef cenv.g.ilg tref tdef cuinfo
@@ -6548,7 +6572,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
| _ -> failwith "??"
let tdef = {tdef with SecurityDecls= secDecls; HasSecurity=securityAttrs.Length > 0}
- mgbuf.AddTypeDef(tref, tdef, false, false, tdefDiscards);
+ mgbuf.AddTypeDef(tref, tdef, false, false, tdefDiscards)
// If a non-generic type is written with "static let" and "static do" (i.e. it has a ".cctor")
// then the code for the .cctor is placed into .cctor for the backing static class for the file.
@@ -6583,16 +6607,16 @@ and GenExnDef cenv mgbuf eenv m (exnc:Tycon) =
let ilMethodDef = mkLdfldMethodDef (ilMethName,reprAccess,false,ilThisTy,ilFieldName,ilPropType)
let ilFieldDef = IL.mkILInstanceField(ilFieldName,ilPropType, None, ILMemberAccess.Assembly)
let ilPropDef =
- { Name=ilPropName;
- IsRTSpecialName=false;
- IsSpecialName=false;
- SetMethod=None;
- GetMethod=Some(mkILMethRef(tref,ILCallingConv.Instance,ilMethName,0,[],ilPropType));
- CallingConv=ILThisConvention.Instance;
- Type=ilPropType;
- Init=None;
- Args=mkILTypes [];
- CustomAttrs=mkILCustomAttrs (GenAttrs cenv eenv fld.PropertyAttribs @ [mkCompilationMappingAttrWithSeqNum cenv.g (int SourceConstructFlags.Field) i]); }
+ { Name=ilPropName
+ IsRTSpecialName=false
+ IsSpecialName=false
+ SetMethod=None
+ GetMethod=Some(mkILMethRef(tref,ILCallingConv.Instance,ilMethName,0,[],ilPropType))
+ CallingConv=ILThisConvention.Instance
+ Type=ilPropType
+ Init=None
+ Args=mkILTypes []
+ CustomAttrs=mkILCustomAttrs (GenAttrs cenv eenv fld.PropertyAttribs @ [mkCompilationMappingAttrWithSeqNum cenv.g (int SourceConstructFlags.Field) i]) }
yield (ilMethodDef,ilFieldDef,ilPropDef,(ilPropName,ilFieldName,ilPropType)) ]
|> List.unzip4
@@ -6619,9 +6643,9 @@ and GenExnDef cenv mgbuf eenv m (exnc:Tycon) =
mkMethodBody
(false,emptyILLocals,8,
nonBranchingInstrsToCode
- [ mkLdarg0;
- mkLdarg 1us;
- mkLdarg 2us;
+ [ mkLdarg0
+ mkLdarg 1us
+ mkLdarg 2us
mkNormalCall (mkILCtorMethSpecForTy (cenv.g.ilg.typ_Exception,[serializationInfoType; cenv.g.ilg.typ_StreamingContext])) ]
,None))
@@ -6637,9 +6661,9 @@ and GenExnDef cenv mgbuf eenv m (exnc:Tycon) =
mkILReturn ILType.Void,
(let code =
nonBranchingInstrsToCode
- [ mkLdarg0;
- mkLdarg 1us;
- mkLdarg 2us;
+ [ mkLdarg0
+ mkLdarg 1us
+ mkLdarg 2us
mkNormalCall (mkILNonGenericInstanceMethSpecInTy (cenv.g.ilg.typ_Exception, "GetObjectData", [serializationInfoType; cenv.g.ilg.typ_StreamingContext], ILType.Void))
]
mkMethodBody(true,emptyILLocals,8,code,None)))
@@ -6649,7 +6673,7 @@ and GenExnDef cenv mgbuf eenv m (exnc:Tycon) =
| None -> ilMethodDef
| Some securityPermissionAttributeType ->
{ ilMethodDef with
- SecurityDecls=mkILSecurityDecls [ IL.mkPermissionSet cenv.g.ilg (ILSecurityAction.Demand,[(securityPermissionAttributeType, [("SerializationFormatter",cenv.g.ilg.typ_Bool, ILAttribElem.Bool(true))])])];
+ SecurityDecls=mkILSecurityDecls [ IL.mkPermissionSet cenv.g.ilg (ILSecurityAction.Demand,[(securityPermissionAttributeType, [("SerializationFormatter",cenv.g.ilg.typ_Bool, ILAttribElem.Bool(true))])])]
HasSecurity=true }
[ilCtorDefForSerialziation; getObjectDataMethodForSerialization]
#endif
@@ -6688,21 +6712,21 @@ let CodegenAssembly cenv eenv mgbuf fileImpls =
let GetEmptyIlxGenEnv (ilg : ILGlobals) ccu =
let thisCompLoc = CompLocForCcu ccu
- { tyenv=TypeReprEnv.Empty;
- cloc = thisCompLoc;
- valsInScope=ValMap<_>.Empty;
- someTypeInThisAssembly=ilg.typ_Object; (* dummy value *)
- isFinalFile = false;
- letBoundVars=[];
- liveLocals=IntMap.empty();
- innerVals = [];
- sigToImplRemapInfo = []; (* "module remap info" *)
+ { tyenv=TypeReprEnv.Empty
+ cloc = thisCompLoc
+ valsInScope=ValMap<_>.Empty
+ someTypeInThisAssembly=ilg.typ_Object (* dummy value *)
+ isFinalFile = false
+ letBoundVars=[]
+ liveLocals=IntMap.empty()
+ innerVals = []
+ sigToImplRemapInfo = [] (* "module remap info" *)
withinSEH = false }
type IlxGenResults =
- { ilTypeDefs: ILTypeDef list;
- ilAssemAttrs : ILAttribute list;
- ilNetModuleAttrs: ILAttribute list;
+ { ilTypeDefs: ILTypeDef list
+ ilAssemAttrs : ILAttribute list
+ ilNetModuleAttrs: ILAttribute list
quotationResourceInfo: (ILTypeRef list * byte[]) list }
@@ -6715,10 +6739,10 @@ let GenerateCode (cenv, eenv, TAssembly fileImpls, assemAttribs, moduleAttribs)
let eenv = { eenv with cloc = CompLocForFragment cenv.opts.fragName cenv.viewCcu }
// Generate the PrivateImplementationDetails type
- GenTypeDefForCompLoc (cenv, eenv, mgbuf, CompLocForPrivateImplementationDetails eenv.cloc, useHiddenInitCode, [], ILTypeInit.BeforeField, true, (* atEnd= *) true);
+ GenTypeDefForCompLoc (cenv, eenv, mgbuf, CompLocForPrivateImplementationDetails eenv.cloc, useHiddenInitCode, [], ILTypeInit.BeforeField, true, (* atEnd= *) true)
// Generate the whole assembly
- CodegenAssembly cenv eenv mgbuf fileImpls;
+ CodegenAssembly cenv eenv mgbuf fileImpls
let ilAssemAttrs = GenAttrs cenv eenv assemAttribs
@@ -6749,7 +6773,7 @@ let GenerateCode (cenv, eenv, TAssembly fileImpls, assemAttribs, moduleAttribs)
let referencedTypeDefs, freeTypes, spliceArgExprs = qscope.Close()
for (_freeType, m) in freeTypes do
- error(InternalError("A free type variable was detected in a reflected definition",m));
+ error(InternalError("A free type variable was detected in a reflected definition",m))
for (_spliceArgExpr, m) in spliceArgExprs do
error(Error(FSComp.SR.ilReflectedDefinitionsCannotUseSliceOperator(),m))
@@ -6777,9 +6801,9 @@ open System.Reflection
/// The lookup* functions are the conversions available from ilreflect.
type ExecutionContext =
- { LookupFieldRef : (ILFieldRef -> FieldInfo);
+ { LookupFieldRef : (ILFieldRef -> FieldInfo)
LookupMethodRef : (ILMethodRef -> MethodInfo)
- LookupTypeRef : (ILTypeRef -> Type);
+ LookupTypeRef : (ILTypeRef -> Type)
LookupType : (ILType -> Type) }
// A helper to generate a default value for any System.Type. I couldn't find a System.Reflection
@@ -6913,7 +6937,7 @@ type IlxAssemblyGenerator(amap: Import.ImportMap, tcGlobals: TcGlobals, tcVal :
{ g=tcGlobals
TcVal = tcVal
viewCcu = ccu
- ilUnitTy = None;
+ ilUnitTy = None
amap = amap
casApplied = casApplied
intraAssemblyInfo = intraAssemblyInfo
diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fs b/src/fsharp/InnerLambdasToTopLevelFuncs.fs
index 5bbc36c6e1b..21556822240 100644
--- a/src/fsharp/InnerLambdasToTopLevelFuncs.fs
+++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fs
@@ -237,7 +237,7 @@ module Pass1_DetermineTLRAndArities =
(* REPORT OVER *)
let arityM = Zmap.ofList valOrder fArities
#if DEBUG
- if verboseTLR then DumpArity arityM;
+ if verboseTLR then DumpArity arityM
#endif
tlrS,topValS, arityM
@@ -342,20 +342,20 @@ let reqdItemOrder =
/// The reqdTypars are the free reqdTypars of the defns, and those required by any direct TLR arity-met calls.
/// The reqdItems are the ids/subEnvs required from calls to freeVars.
type ReqdItemsForDefn =
- { reqdTypars : Zset;
- reqdItems : Zset;
- m : Range.range; }
+ { reqdTypars : Zset
+ reqdItems : Zset
+ m : Range.range }
member env.ReqdSubEnvs = [ for x in env.reqdItems do match x with | ReqdSubEnv f -> yield f | ReqdVal _ -> () ]
member env.ReqdVals = [ for x in env.reqdItems do match x with | ReqdSubEnv _ -> () | ReqdVal v -> yield v ]
member env.Extend (typars,items) =
{env with
- reqdTypars = Zset.addList typars env.reqdTypars;
+ reqdTypars = Zset.addList typars env.reqdTypars
reqdItems = Zset.addList items env.reqdItems}
static member Initial typars m =
- {reqdTypars = Zset.addList typars (Zset.empty typarOrder);
- reqdItems = Zset.empty reqdItemOrder;
+ {reqdTypars = Zset.addList typars (Zset.empty typarOrder)
+ reqdItems = Zset.empty reqdItemOrder
m = m }
override env.ToString() =
@@ -427,19 +427,19 @@ module Pass2_DetermineReqdItems =
///
/// recShortCalls to f will require a binding for f in terms of fHat within the fHatBody.
type state =
- { stack : (BindingGroupSharingSameReqdItems * Generators * ReqdItemsForDefn) list;
- reqdItemsMap : Zmap;
- fclassM : Zmap;
- revDeclist : BindingGroupSharingSameReqdItems list;
- recShortCallS : Zset;
+ { stack : (BindingGroupSharingSameReqdItems * Generators * ReqdItemsForDefn) list
+ reqdItemsMap : Zmap
+ fclassM : Zmap
+ revDeclist : BindingGroupSharingSameReqdItems list
+ recShortCallS : Zset
}
let state0 =
- { stack = [];
- reqdItemsMap = Zmap.empty fclassOrder;
- fclassM = Zmap.empty valOrder;
- revDeclist = [];
- recShortCallS = Zset.empty valOrder; }
+ { stack = []
+ reqdItemsMap = Zmap.empty fclassOrder
+ fclassM = Zmap.empty valOrder
+ revDeclist = []
+ recShortCallS = Zset.empty valOrder }
/// PUSH = start collecting for fclass
let PushFrame (fclass: BindingGroupSharingSameReqdItems) (reqdTypars0,reqdVals0,m) state =
@@ -447,12 +447,12 @@ module Pass2_DetermineReqdItems =
state
else
{state with
- revDeclist = fclass :: state.revDeclist;
- stack = (let env = ReqdItemsForDefn.Initial reqdTypars0 m in (fclass,reqdVals0,env)::state.stack); }
+ revDeclist = fclass :: state.revDeclist
+ stack = (let env = ReqdItemsForDefn.Initial reqdTypars0 m in (fclass,reqdVals0,env)::state.stack) }
/// POP & SAVE = end collecting for fclass and store
let SaveFrame (fclass: BindingGroupSharingSameReqdItems) state =
- if verboseTLR then dprintf "SaveFrame: %A\n" fclass;
+ if verboseTLR then dprintf "SaveFrame: %A\n" fclass
if fclass.IsEmpty then
state
else
@@ -460,8 +460,8 @@ module Pass2_DetermineReqdItems =
| [] -> internalError "trl: popFrame has empty stack"
| (fclass,_reqdVals0,env)::stack -> (* ASSERT: same fclass *)
{state with
- stack = stack;
- reqdItemsMap = Zmap.add fclass env state.reqdItemsMap;
+ stack = stack
+ reqdItemsMap = Zmap.add fclass env state.reqdItemsMap
fclassM = FlatList.fold (fun mp (k,v) -> Zmap.add k v mp) state.fclassM fclass.Pairs }
/// Log requirements for gv in the relevant stack frames
@@ -478,12 +478,12 @@ module Pass2_DetermineReqdItems =
let LogShortCall gv state =
if state.stack |> List.exists (fun (fclass,_reqdVals0,_env) -> fclass.Contains gv) then
- if verboseTLR then dprintf "shortCall: rec: %s\n" gv.LogicalName;
+ if verboseTLR then dprintf "shortCall: rec: %s\n" gv.LogicalName
// Have short call to gv within it's (mutual) definition(s)
{state with
recShortCallS = Zset.add gv state.recShortCallS}
else
- if verboseTLR then dprintf "shortCall: not-rec: %s\n" gv.LogicalName;
+ if verboseTLR then dprintf "shortCall: not-rec: %s\n" gv.LogicalName
state
let FreeInBindings bs = FlatList.fold (foldOn (freeInBindingRhs CollectTyparsAndLocals) unionFreeVars) emptyFreeVars bs
@@ -569,7 +569,7 @@ module Pass2_DetermineReqdItems =
/// For each direct call to a gv, a generator for fclass,
/// Required to include the reqdTypars(gv) in reqdTypars(fclass).
let CloseReqdTypars fclassM reqdItemsMap =
- if verboseTLR then dprintf "CloseReqdTypars------\n";
+ if verboseTLR then dprintf "CloseReqdTypars------\n"
let closeStep reqdItemsMap changed fc (env: ReqdItemsForDefn) =
let directCallReqdEnvs = env.ReqdSubEnvs
@@ -584,7 +584,7 @@ module Pass2_DetermineReqdItems =
let env = {env with reqdTypars = reqdTypars}
#if DEBUG
if verboseTLR then
- dprintf "closeStep: fc=%30A nSubs=%d reqdTypars0=%s reqdTypars=%s\n" fc directCallReqdEnvs.Length (showTyparSet reqdTypars0) (showTyparSet reqdTypars);
+ dprintf "closeStep: fc=%30A nSubs=%d reqdTypars0=%s reqdTypars=%s\n" fc directCallReqdEnvs.Length (showTyparSet reqdTypars0) (showTyparSet reqdTypars)
directCallReqdEnvs |> List.iter (fun f -> dprintf "closeStep: dcall f=%s\n" f.LogicalName)
directCallReqdEnvs |> List.iter (fun f -> dprintf "closeStep: dcall fc=%A\n" (Zmap.find f fclassM))
directCallReqdTypars |> List.iter (fun _reqdTypars -> dprintf "closeStep: dcall reqdTypars=%s\n" (showTyparSet reqdTypars0))
@@ -610,7 +610,7 @@ module Pass2_DetermineReqdItems =
#endif
let DetermineReqdItems (tlrS,arityM) expr =
- if verboseTLR then dprintf "DetermineReqdItems------\n";
+ if verboseTLR then dprintf "DetermineReqdItems------\n"
let folder = {ExprFolder0 with exprIntercept = ExprEnvIntercept (tlrS,arityM)}
let z = state0
// Walk the entire assembly
@@ -622,7 +622,7 @@ module Pass2_DetermineReqdItems =
let recShortCallS = z.recShortCallS
// diagnostic dump
#if DEBUG
- if verboseTLR then DumpReqdValMap reqdItemsMap;
+ if verboseTLR then DumpReqdValMap reqdItemsMap
#endif
// close the reqdTypars under the subEnv reln
let reqdItemsMap = CloseReqdTypars fclassM reqdItemsMap
@@ -633,7 +633,7 @@ module Pass2_DetermineReqdItems =
#if DEBUG
// diagnostic dump
if verboseTLR then
- DumpReqdValMap reqdItemsMap;
+ DumpReqdValMap reqdItemsMap
declist |> List.iter (fun fc -> dprintf "Declist: %A\n" fc)
recShortCallS |> Zset.iter (fun f -> dprintf "RecShortCall: %s\n" f.LogicalName)
#endif
@@ -659,13 +659,13 @@ module Pass2_DetermineReqdItems =
type PackedReqdItems =
{ /// The actual typars
- ep_etps : Typars;
+ ep_etps : Typars
/// The actual env carrier values
- ep_aenvs : Val list;
+ ep_aenvs : Val list
/// Sequentially define the aenvs in terms of the fvs
- ep_pack : Bindings;
+ ep_pack : Bindings
/// Sequentially define the fvs in terms of the aenvs
- ep_unpack : Bindings;
+ ep_unpack : Bindings
}
@@ -696,7 +696,7 @@ exception AbortTLR of Range.range
let FlatEnvPacks g fclassM topValS declist (reqdItemsMap: Zmap) =
let fclassOf f = Zmap.force f fclassM ("fclassM",nameOfVal)
let packEnv carrierMaps (fc:BindingGroupSharingSameReqdItems) =
- if verboseTLR then dprintf "\ntlr: packEnv fc=%A\n" fc;
+ if verboseTLR then dprintf "\ntlr: packEnv fc=%A\n" fc
let env = Zmap.force fc reqdItemsMap ("packEnv",string)
// carrierMaps = (fclass,(v,aenv)map)map
@@ -722,10 +722,10 @@ let FlatEnvPacks g fclassM topValS declist (reqdItemsMap: Zmap FlatList.tryFind (IsGenericValWithGenericContraints g) with
| None -> ()
- | Some v -> raise (AbortTLR v.Range);
+ | Some v -> raise (AbortTLR v.Range)
// build cmap for env
let cmapPairs = vals |> FlatList.map (fun v -> (v,(mkCompGenLocal env.m v.LogicalName v.Type |> fst)))
@@ -774,17 +774,17 @@ let FlatEnvPacks g fclassM topValS declist (reqdItemsMap: Zmap showL (valL v)))
let fc = Zmap.force f fclassM ("createFHat - fc",nameOfVal)
@@ -866,16 +866,16 @@ let CreateNewValuesForTLR g tlrS arityM fclassM envPackM =
module Pass4_RewriteAssembly =
[]
type RewriteContext =
- { ccu : CcuThunk;
- g : TcGlobals;
- tlrS : Zset ;
- topValS : Zset ;
- arityM : Zmap ;
- fclassM : Zmap ;
- recShortCallS : Zset ;
- envPackM : Zmap;
+ { ccu : CcuThunk
+ g : TcGlobals
+ tlrS : Zset
+ topValS : Zset
+ arityM : Zmap
+ fclassM : Zmap
+ recShortCallS : Zset
+ envPackM : Zmap
/// The mapping from 'f' values to 'fHat' values
- fHatM : Zmap ;
+ fHatM : Zmap
}
@@ -898,9 +898,9 @@ module Pass4_RewriteAssembly =
/// Any TLR repr bindings under lambdas can be filtered out (and collected),
/// giving pre-declarations to insert before the outermost lambda expr.
type RewriteState =
- { rws_mustinline: bool;
+ { rws_mustinline: bool
/// counts level of enclosing "lambdas"
- rws_innerLevel : int;
+ rws_innerLevel : int
/// collected preDecs (fringe is in-order)
rws_preDecs : Tree
}
@@ -1345,7 +1345,7 @@ let MakeTLRDecisions ccu g expr =
let fHatM = CreateNewValuesForTLR g tlrS arityM fclassM envPackM
// pass4: rewrite
- if verboseTLR then dprintf "TransExpr(rw)------\n";
+ if verboseTLR then dprintf "TransExpr(rw)------\n"
let expr,_ =
let penv : Pass4_RewriteAssembly.RewriteContext =
{ccu=ccu; g=g; tlrS=tlrS; topValS=topValS; arityM=arityM; fclassM=fclassM; recShortCallS=recShortCallS; envPackM=envPackM; fHatM=fHatM}
@@ -1354,9 +1354,9 @@ let MakeTLRDecisions ccu g expr =
// pass5: copyExpr to restore "each bound is unique" property
// aka, copyExpr
- if verboseTLR then dprintf "copyExpr------\n";
+ if verboseTLR then dprintf "copyExpr------\n"
let expr = RecreateUniqueBounds g expr
- if verboseTLR then dprintf "TLR-done------\n";
+ if verboseTLR then dprintf "TLR-done------\n"
// Summary:
// GTL = genuine top-level
@@ -1370,5 +1370,5 @@ let MakeTLRDecisions ccu g expr =
// DONE
expr
with AbortTLR m ->
- warning(Error(FSComp.SR.tlrLambdaLiftingOptimizationsNotApplied(),m));
+ warning(Error(FSComp.SR.tlrLambdaLiftingOptimizationsNotApplied(),m))
expr
diff --git a/src/fsharp/LexFilter.fs b/src/fsharp/LexFilter.fs
index e4ef817ca77..5ef87ac8f58 100755
--- a/src/fsharp/LexFilter.fs
+++ b/src/fsharp/LexFilter.fs
@@ -534,7 +534,6 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer,
new LexbufState(lexbuf.StartPos, lexbuf.EndPos, lexbuf.IsPastEndOfStream)
let setLexbufState (p:LexbufState) =
- // if debug then dprintf "SET lex state to; %a\n" output_any p;
lexbuf.StartPos <- p.StartPos
lexbuf.EndPos <- p.EndPos
lexbuf.IsPastEndOfStream <- p.PastEOF
@@ -927,6 +926,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer,
| MINUS
| GLOBAL
| CONST
+ | KEYWORD_STRING _
| NULL
| INT8 _ | INT16 _ | INT32 _ | INT64 _ | NATIVEINT _
| UINT8 _ | UINT16 _ | UINT32 _ | UINT64 _ | UNATIVEINT _
diff --git a/src/fsharp/LowerCallsAndSeqs.fs b/src/fsharp/LowerCallsAndSeqs.fs
index 571997f761f..34289568ad8 100644
--- a/src/fsharp/LowerCallsAndSeqs.fs
+++ b/src/fsharp/LowerCallsAndSeqs.fs
@@ -58,9 +58,9 @@ let InterceptExpr g cont expr =
/// any known arguments. The results are later optimized by the peephole
/// optimizer in opt.fs
let LowerImplFile g ass =
- RewriteImplFile { PreIntercept = Some(InterceptExpr g);
+ RewriteImplFile { PreIntercept = Some(InterceptExpr g)
PreInterceptBinding=None
- PostTransform= (fun _ -> None);
+ PostTransform= (fun _ -> None)
IsUnderQuotations=false } ass
@@ -76,7 +76,7 @@ let mkUnitDelayLambda g m e =
let callNonOverloadedMethod g amap m methName ty args =
match TryFindIntrinsicMethInfo (InfoReader(g,amap)) m AccessibleFromSomeFSharpCode methName ty with
- | [] -> error(InternalError("No method called '"+methName+"' was found",m));
+ | [] -> error(InternalError("No method called '"+methName+"' was found",m))
| ILMeth(g,ilMethInfo,_) :: _ ->
// REVIEW: consider if this should ever be a constrained call. At the moment typecheck limitations in the F# typechecker
// ensure the enumerator type used within computation expressions is not a struct type
@@ -189,9 +189,9 @@ let LowerSeqExpr g amap overallExpr =
match expr with
| SeqYield(e,m) ->
// printfn "found Seq.singleton"
- //this.pc <- NEXT;
- //curr <- e;
- //return true;
+ //this.pc <- NEXT
+ //curr <- e
+ //return true
//NEXT:
let label = IL.generateCodeLabel()
Some { phase2 = (fun (pcv,currv,_nextv,pcMap) ->
@@ -211,9 +211,9 @@ let LowerSeqExpr g amap overallExpr =
mkCompGenSequential m
(Expr.Op(TOp.Label label,[],[],m))
(Expr.Op(TOp.Return,[],[mkBool g m (not (noDisposeContinuationLabel = currentDisposeContinuationLabel))],m))
- generate,dispose,checkDispose);
- labels=[label];
- stateVars=[];
+ generate,dispose,checkDispose)
+ labels=[label]
+ stateVars=[]
significantClose = false
}
@@ -233,8 +233,8 @@ let LowerSeqExpr g amap overallExpr =
// However leaving as is for now.
let dispose = mkCompGenSequential m dispose2 dispose1
let checkDispose = mkCompGenSequential m checkDispose2 checkDispose1
- generate,dispose,checkDispose);
- labels= res1.labels @ res2.labels;
+ generate,dispose,checkDispose)
+ labels= res1.labels @ res2.labels
stateVars = res1.stateVars @ res2.stateVars
significantClose = res1.significantClose || res2.significantClose }
| _ ->
@@ -248,8 +248,8 @@ let LowerSeqExpr g amap overallExpr =
let generate = mkWhile g (SequencePointAtWhileLoop e1.Range,NoSpecialWhileLoopMarker,e1,generate2,m)
let dispose = dispose2
let checkDispose = checkDispose2
- generate,dispose,checkDispose);
- labels = res2.labels;
+ generate,dispose,checkDispose)
+ labels = res2.labels
stateVars = res2.stateVars
significantClose = res2.significantClose }
| _ ->
@@ -312,8 +312,8 @@ let LowerSeqExpr g amap overallExpr =
(Expr.Op(TOp.Label innerDisposeContinuationLabel,[],[],m))
(Expr.Op(TOp.Return,[],[mkTrue g m (* yes, we must dispose!!! *) ],m)))
- generate,dispose,checkDispose);
- labels = innerDisposeContinuationLabel :: res1.labels;
+ generate,dispose,checkDispose)
+ labels = innerDisposeContinuationLabel :: res1.labels
stateVars = res1.stateVars
significantClose = true }
| _ ->
@@ -324,7 +324,7 @@ let LowerSeqExpr g amap overallExpr =
let generate = mkUnit g m
let dispose = Expr.Op(TOp.Goto currentDisposeContinuationLabel,[],[],m)
let checkDispose = Expr.Op(TOp.Goto currentDisposeContinuationLabel,[],[],m)
- generate,dispose,checkDispose);
+ generate,dispose,checkDispose)
labels = []
stateVars = []
significantClose = false }
@@ -376,7 +376,7 @@ let LowerSeqExpr g amap overallExpr =
(mkValSet m vref (mkDefault (m,vref.Type)))
let dispose = dispose2
let checkDispose = checkDispose2
- generate,dispose,checkDispose);
+ generate,dispose,checkDispose)
stateVars = vref::res2.stateVars }
| None ->
None
@@ -402,8 +402,8 @@ let LowerSeqExpr g amap overallExpr =
let generate = primMkMatch (spBind,exprm,pt,Array.ofList gtgs,m,ty)
let dispose = if isNil disposals then mkUnit g m else List.reduce (mkCompGenSequential m) disposals
let checkDispose = if isNil checkDisposes then mkFalse g m else List.reduce (mkCompGenSequential m) checkDisposes
- generate,dispose,checkDispose);
- labels=labs;
+ generate,dispose,checkDispose)
+ labels=labs
stateVars = stateVars
significantClose = significantClose }
else
@@ -418,7 +418,7 @@ let LowerSeqExpr g amap overallExpr =
// This can give rise to infinite iterator chains when implemented by the naive expansion to
// “for x in e yield e”. For example consider this:
//
- // let rec rwalk x = { yield x;
+ // let rec rwalk x = { yield x
// yield! rwalk (x + rand()) }
//
// This is the moral equivalent of a tailcall optimization. These also don’t compile well
@@ -439,9 +439,9 @@ let LowerSeqExpr g amap overallExpr =
// printfn "found yield!"
let inpElemTy = List.head (argsOfAppTy g ty)
if isTailCall then
- //this.pc <- NEXT;
- //nextEnumerator <- e;
- //return 2;
+ //this.pc <- NEXT
+ //nextEnumerator <- e
+ //return 2
//NEXT:
let label = IL.generateCodeLabel()
Some { phase2 = (fun (pcv,_currv,nextv,pcMap) ->
@@ -461,7 +461,7 @@ let LowerSeqExpr g amap overallExpr =
mkCompGenSequential m
(Expr.Op(TOp.Label label,[],[],m))
(Expr.Op(TOp.Return,[],[mkFalse g m],m))
- generate,dispose,checkDispose);
+ generate,dispose,checkDispose)
labels=[label]
stateVars=[]
significantClose = false }
diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs
index 43731c50ae2..14c41717483 100644
--- a/src/fsharp/MethodCalls.fs
+++ b/src/fsharp/MethodCalls.fs
@@ -62,15 +62,17 @@ type CalledArg =
{ Position: (int * int)
IsParamArray : bool
OptArgInfo : OptionalArgInfo
+ CallerInfoInfo : CallerInfoInfo
IsOutArg: bool
ReflArgInfo: ReflectedArgInfo
NameOpt: Ident option
CalledArgumentType : TType }
-let CalledArg(pos,isParamArray,optArgInfo,isOutArg,nameOpt,reflArgInfo,calledArgTy) =
+let CalledArg(pos,isParamArray,optArgInfo,callerInfoInfo,isOutArg,nameOpt,reflArgInfo,calledArgTy) =
{ Position=pos
IsParamArray=isParamArray
OptArgInfo =optArgInfo
+ CallerInfoInfo = callerInfoInfo
IsOutArg=isOutArg
ReflArgInfo=reflArgInfo
NameOpt=nameOpt
@@ -198,10 +200,11 @@ type CalledMethArgSet<'T> =
let MakeCalledArgs amap m (minfo:MethInfo) minst =
// Mark up the arguments with their position, so we can sort them back into order later
let paramDatas = minfo.GetParamDatas(amap, m, minst)
- paramDatas |> List.mapiSquared (fun i j (ParamData(isParamArrayArg,isOutArg,optArgInfo,nmOpt,reflArgInfo,typeOfCalledArg)) ->
+ paramDatas |> List.mapiSquared (fun i j (ParamData(isParamArrayArg,isOutArg,optArgInfo,callerInfoFlags,nmOpt,reflArgInfo,typeOfCalledArg)) ->
{ Position=(i,j)
IsParamArray=isParamArrayArg
OptArgInfo=optArgInfo
+ CallerInfoInfo = callerInfoFlags
IsOutArg=isOutArg
ReflArgInfo=reflArgInfo
NameOpt=nmOpt
diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs
index 9ebd2bafafe..74cedde7377 100755
--- a/src/fsharp/NameResolution.fs
+++ b/src/fsharp/NameResolution.fs
@@ -483,8 +483,8 @@ let AddFakeNameToNameEnv nm nenv item =
/// Add a set of F# values to the environment.
let AddValRefsToNameEnvWithPriority bulkAddMode pri nenv vrefs =
- {nenv with eUnqualifiedItems= AddValRefsToItems bulkAddMode nenv.eUnqualifiedItems vrefs;
- eIndexedExtensionMembers = (nenv.eIndexedExtensionMembers,vrefs) ||> Array.fold (AddValRefToExtensionMembers pri);
+ {nenv with eUnqualifiedItems= AddValRefsToItems bulkAddMode nenv.eUnqualifiedItems vrefs
+ eIndexedExtensionMembers = (nenv.eIndexedExtensionMembers,vrefs) ||> Array.fold (AddValRefToExtensionMembers pri)
ePatItems =
(nenv.ePatItems,vrefs) ||> Array.fold (fun acc vref ->
let ePatItems =
@@ -507,7 +507,7 @@ let AddValRefToNameEnv nenv vref =
let AddActivePatternResultTagsToNameEnv (apinfo: PrettyNaming.ActivePatternInfo) nenv ty m =
let nms = apinfo.Names
let apresl = nms |> List.mapi (fun j nm -> nm, j)
- { nenv with eUnqualifiedItems= (apresl,nenv.eUnqualifiedItems) ||> List.foldBack (fun (nm,j) acc -> acc.Add(nm, Item.ActivePatternResult(apinfo,ty,j, m))); }
+ { nenv with eUnqualifiedItems= (apresl,nenv.eUnqualifiedItems) ||> List.foldBack (fun (nm,j) acc -> acc.Add(nm, Item.ActivePatternResult(apinfo,ty,j, m))) }
/// Generalize a union case, from Cons --> List.Cons
let GeneralizeUnionCaseRef (ucref:UnionCaseRef) =
@@ -627,11 +627,11 @@ let AddTyconRefsToNameEnv bulkAddMode ownDefinition g amap m root nenv tcrefs =
let tcrefs = Array.ofList tcrefs
{ env with
eFullyQualifiedTyconsByDemangledNameAndArity=
- (if root then AddTyconsByDemangledNameAndArity bulkAddMode tcrefs nenv.eFullyQualifiedTyconsByDemangledNameAndArity else nenv.eFullyQualifiedTyconsByDemangledNameAndArity);
+ (if root then AddTyconsByDemangledNameAndArity bulkAddMode tcrefs nenv.eFullyQualifiedTyconsByDemangledNameAndArity else nenv.eFullyQualifiedTyconsByDemangledNameAndArity)
eFullyQualifiedTyconsByAccessNames=
- (if root then AddTyconByAccessNames bulkAddMode tcrefs nenv.eFullyQualifiedTyconsByAccessNames else nenv.eFullyQualifiedTyconsByAccessNames);
+ (if root then AddTyconByAccessNames bulkAddMode tcrefs nenv.eFullyQualifiedTyconsByAccessNames else nenv.eFullyQualifiedTyconsByAccessNames)
eTyconsByDemangledNameAndArity=
- AddTyconsByDemangledNameAndArity bulkAddMode tcrefs nenv.eTyconsByDemangledNameAndArity;
+ AddTyconsByDemangledNameAndArity bulkAddMode tcrefs nenv.eTyconsByDemangledNameAndArity
eTyconsByAccessNames=
AddTyconByAccessNames bulkAddMode tcrefs nenv.eTyconsByAccessNames }
@@ -679,7 +679,7 @@ let rec AddModuleOrNamespaceRefsToNameEnv g amap m root ad nenv (modrefs: Module
NameMap.layerAdditive add modrefsMap tab
let nenv =
{nenv with
- eModulesAndNamespaces= addModrefs nenv.eModulesAndNamespaces;
+ eModulesAndNamespaces= addModrefs nenv.eModulesAndNamespaces
eFullyQualifiedModulesAndNamespaces =
(if root
then addModrefs nenv.eFullyQualifiedModulesAndNamespaces
@@ -754,7 +754,7 @@ let AddDeclaredTyparsToNameEnv check nenv typars =
if Map.containsKey tp.Name sofar then errorR (Duplicate("type parameter",tp.DisplayName,tp.Range))
| NoCheckForDuplicateTypars ->
()
- end;
+ end
Map.add tp.Name tp sofar) typars Map.empty
{nenv with eTypars=NameMap.layer typarmap nenv.eTypars }
@@ -1507,8 +1507,8 @@ type ResolutionInfo =
static member SendToSink(sink, ncenv: NameResolver, nenv, occ, ad, ResolutionInfo(entityPath,warnings), typarChecker) =
entityPath |> List.iter (fun (m,eref:EntityRef) ->
- CheckEntityAttributes ncenv.g eref m |> CommitOperationResult;
- CheckTyconAccessible ncenv.amap m ad eref |> ignore;
+ CheckEntityAttributes ncenv.g eref m |> CommitOperationResult
+ CheckTyconAccessible ncenv.amap m ad eref |> ignore
let item =
if eref.IsModuleOrNamespace then
Item.ModuleOrNamespaces [eref]
@@ -1656,7 +1656,7 @@ let private ResolveObjectConstructorPrim (ncenv:NameResolver) edenv resInfo m ad
success (resInfo, Item.FakeInterfaceCtor typ)
else
let defaultStructCtorInfo =
- if (isStructTy g typ && not(isRecdTy g typ) && not(ctorInfos |> List.exists (fun x -> x.IsNullary))) then
+ if (isStructTy g typ && not (isRecdTy g typ) && not (isUnionTy g typ) && not(ctorInfos |> List.exists (fun x -> x.IsNullary))) then
[DefaultStructCtor(g,typ)]
else []
if (isNil defaultStructCtorInfo && isNil ctorInfos) || not (isAppTy g typ) then
@@ -1923,7 +1923,7 @@ let ResolveLongIdentInType sink ncenv nenv lookupKind m ad lid findFlag typeName
ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind ResolutionInfo.Empty 0 m ad lid findFlag typeNameResInfo typ
|> AtMostOneResult m
|> ForceRaise
- ResolutionInfo.SendToSink (sink,ncenv,nenv,ItemOccurence.UseInType,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item));
+ ResolutionInfo.SendToSink (sink,ncenv,nenv,ItemOccurence.UseInType,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item))
item,rest
let private ResolveLongIdentInTyconRef (ncenv:NameResolver) nenv lookupKind resInfo depth m ad lid typeNameResInfo tcref =
@@ -2063,7 +2063,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) fullyQualified m ad n
match AtMostOneResult m search with
| Result _ as res ->
let resInfo,item,rest = ForceRaise res
- ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item));
+ ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item))
Some(item,rest)
| _ ->
None
@@ -2088,7 +2088,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) fullyQualified m ad n
let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueOfConstructor,id,NoPredictions))
let search = ctorSearch +++ implicitOpSearch +++ failingCase
let resInfo,item,rest = ForceRaise (AtMostOneResult m search)
- ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item));
+ ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item))
item,rest
@@ -2144,7 +2144,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) fullyQualified m ad n
| _ ->
let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueNamespaceTypeOrModule,id,NoPredictions))
ForceRaise (AtMostOneResult m (search +++ moduleSearch AccessibleFromSomeFSharpCode +++ tyconSearch AccessibleFromSomeFSharpCode +++ failingCase))
- ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item));
+ ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item))
item,rest
let ResolveExprLongIdent sink (ncenv:NameResolver) m ad nenv typeNameResInfo lid =
@@ -2241,7 +2241,7 @@ let rec ResolvePatternLongIdentPrim sink (ncenv:NameResolver) fullyQualified war
(warnOnUpper = WarnOnUpperCase) &&
id.idText.Length >= 3 &&
System.Char.ToLowerInvariant id.idText.[0] <> id.idText.[0] then
- warning(UpperCaseIdentifierInPattern(m));
+ warning(UpperCaseIdentifierInPattern(m))
Item.NewDef id
// Long identifiers in patterns
@@ -2262,9 +2262,9 @@ let rec ResolvePatternLongIdentPrim sink (ncenv:NameResolver) fullyQualified war
| Result _ as res -> ForceRaise res
| _ ->
ForceRaise (AtMostOneResult m (tyconSearch AccessibleFromSomeFSharpCode +++ moduleSearch AccessibleFromSomeFSharpCode))
- ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> true));
+ ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> true))
- if nonNil rest then error(Error(FSComp.SR.nrIsNotConstructorOrLiteral(),(List.head rest).idRange));
+ if nonNil rest then error(Error(FSComp.SR.nrIsNotConstructorOrLiteral(),(List.head rest).idRange))
res
@@ -2326,7 +2326,7 @@ let rec ResolveTypeLongIdentInTyconRefPrim (ncenv:NameResolver) (typeNameResInfo
/// Resolve a long identifier representing a type name and report the result
let ResolveTypeLongIdentInTyconRef sink (ncenv:NameResolver) nenv typeNameResInfo ad m tcref (lid: Ident list) =
let resInfo,tcref = ForceRaise (ResolveTypeLongIdentInTyconRefPrim ncenv typeNameResInfo ad ResolutionInfo.Empty PermitDirectReferenceToGeneratedType.No 0 m tcref lid)
- ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> true));
+ ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> true))
let item = Item.Types(tcref.DisplayName,[FreshenTycon ncenv m tcref])
CallNameResolutionSink sink (rangeOfLid lid,nenv,item,item,ItemOccurence.UseInType,nenv.eDisplayEnv,ad)
tcref
@@ -2391,7 +2391,7 @@ let rec ResolveTypeLongIdentPrim (ncenv:NameResolver) fullyQualified m nenv ad (
match tcrefs with
| tcref :: _tcrefs ->
// Note: This path is only for error reporting
- //CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities tcref rest typeNameResInfo m;
+ //CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities tcref rest typeNameResInfo m
success(ResolutionInfo.Empty,tcref)
| [] ->
raze (UndefinedName(0,FSComp.SR.undefinedNameType,id,NoPredictions))
@@ -2442,7 +2442,7 @@ let ResolveTypeLongIdent sink (ncenv:NameResolver) occurence fullyQualified nenv
// Register the result as a name resolution
match res with
| Result (resInfo,tcref) ->
- ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.UseInType, ad,resInfo,ResultTyparChecker(fun () -> true));
+ ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.UseInType, ad,resInfo,ResultTyparChecker(fun () -> true))
let item = Item.Types(tcref.DisplayName,[FreshenTycon ncenv m tcref])
CallNameResolutionSink sink (m,nenv,item,item,occurence,nenv.eDisplayEnv,ad)
| _ -> ()
@@ -2591,7 +2591,7 @@ let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) allFields =
ResolveLongIndentAsModuleOrNamespaceThen ncenv.amap m OpenQualified nenv ad lid
(ResolveFieldInModuleOrNamespace ncenv nenv ad)
let resInfo,item,rest = ForceRaise (AtMostOneResult m (modulSearch ad +++ tyconSearch ad +++ modulSearch AccessibleFromSomeFSharpCode +++ tyconSearch AccessibleFromSomeFSharpCode))
- if nonNil rest then errorR(Error(FSComp.SR.nrInvalidFieldLabel(),(List.head rest).idRange));
+ if nonNil rest then errorR(Error(FSComp.SR.nrInvalidFieldLabel(),(List.head rest).idRange))
[(resInfo,item)]
let ResolveField sink ncenv nenv ad typ (mp,id) allFields =
@@ -2599,7 +2599,7 @@ let ResolveField sink ncenv nenv ad typ (mp,id) allFields =
// Register the results of any field paths "Module.Type" in "Module.Type.field" as a name resolution. (Note, the path resolution
// info is only non-empty if there was a unique resolution of the field)
for (resInfo,_rfref) in res do
- ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.UseInType, ad,resInfo,ResultTyparChecker(fun () -> true));
+ ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.UseInType, ad,resInfo,ResultTyparChecker(fun () -> true))
res |> List.map snd
/// Generate a new reference to a record field with a fresh type instantiation
@@ -2737,7 +2737,7 @@ let ResolveExprDotLongIdentAndComputeRange (sink:TcResultsSink) (ncenv:NameResol
resInfo,item,rest,itemRange
// "true" resolution
let resInfo,item,rest,itemRange = resolveExpr findFlag
- ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap itemRange item));
+ ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap itemRange item))
// Record the precise resolution of the field for intellisense/goto definition
let afterOverloadResolution =
diff --git a/src/fsharp/NicePrint.fs b/src/fsharp/NicePrint.fs
index 609134d68d3..e4dc8100c44 100755
--- a/src/fsharp/NicePrint.fs
+++ b/src/fsharp/NicePrint.fs
@@ -1193,7 +1193,7 @@ module InfoMemberPrinting =
/// Format the arguments of a method to a buffer.
///
/// This uses somewhat "old fashioned" printf-style buffer printing.
- let formatParamDataToBuffer denv os (ParamData(isParamArray, _isOutArg, optArgInfo, nmOpt, _reflArgInfo, pty)) =
+ let formatParamDataToBuffer denv os (ParamData(isParamArray, _isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty)) =
let isOptArg = optArgInfo.IsOptional
match isParamArray, nmOpt, isOptArg, tryDestOptionTy denv.g pty with
// Layout an optional argument
diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs
index 186113ed2a2..7867a3569dc 100644
--- a/src/fsharp/Optimizer.fs
+++ b/src/fsharp/Optimizer.fs
@@ -101,7 +101,7 @@ type ExprValueInfo =
| ConstExprValue of int * Expr
type ValInfo =
- { ValMakesNoCriticalTailcalls: bool;
+ { ValMakesNoCriticalTailcalls: bool
ValExprInfo: ExprValueInfo }
//-------------------------------------------------------------------------
@@ -140,7 +140,7 @@ type ValInfos(entries) =
member x.TryFindForFslib (v:ValRef) = valInfosForFslib.Force().TryFind(v.Deref.LinkagePartialKey)
type ModuleInfo =
- { ValInfos: ValInfos;
+ { ValInfos: ValInfos
ModuleOrNamespaceInfos: NameMap }
and LazyModuleInfo = Lazy
@@ -174,11 +174,11 @@ and valInfoL g (x:ValInfo) =
#endif
type Summary<'Info> =
- { Info: 'Info;
+ { Info: 'Info
/// What's the contribution to the size of this function?
- FunctionSize: int;
+ FunctionSize: int
/// What's the total contribution to the size of the assembly, including closure classes etc.?
- TotalSize: int;
+ TotalSize: int
/// Meaning: could mutate, could non-terminate, could raise exception
/// One use: an effect expr can not be eliminated as dead code (e.g. sequencing)
/// One use: an effect=false expr can not throw an exception? so try-catch is removed.
@@ -247,36 +247,36 @@ let [] localOptDefault = true
let [] crossModuleOptDefault = true
type OptimizationSettings =
- { abstractBigTargets : bool;
- jitOptUser : bool option;
- localOptUser : bool option;
- crossModuleOptUser : bool option;
+ { abstractBigTargets : bool
+ jitOptUser : bool option
+ localOptUser : bool option
+ crossModuleOptUser : bool option
/// size after which we start chopping methods in two, though only at match targets
bigTargetSize : int
/// size after which we start enforcing splitting sub-expressions to new methods, to avoid hitting .NET IL limitations
veryBigExprSize : int
/// The size after which we don't inline
- lambdaInlineThreshold : int;
+ lambdaInlineThreshold : int
/// For unit testing
reportingPhase : bool
- reportNoNeedToTailcall: bool;
+ reportNoNeedToTailcall: bool
reportFunctionSizes : bool
reportHasEffect : bool
reportTotalSizes : bool }
static member Defaults =
- { abstractBigTargets = false;
- jitOptUser = None;
+ { abstractBigTargets = false
+ jitOptUser = None
localOptUser = None
/// size after which we start chopping methods in two, though only at match targets
bigTargetSize = 100
/// size after which we start enforcing splitting sub-expressions to new methods, to avoid hitting .NET IL limitations
veryBigExprSize = 3000
- crossModuleOptUser = None;
+ crossModuleOptUser = None
/// The size after which we don't inline
- lambdaInlineThreshold = 6;
- reportingPhase = false;
- reportNoNeedToTailcall = false;
+ lambdaInlineThreshold = 6
+ reportingPhase = false
+ reportNoNeedToTailcall = false
reportFunctionSizes = false
reportHasEffect = false
reportTotalSizes = false
@@ -309,41 +309,41 @@ type OptimizationSettings =
#else
type cenv =
- { g: TcGlobals;
+ { g: TcGlobals
TcVal : ConstraintSolver.TcValF
- amap: Import.ImportMap;
- optimizing: bool;
- scope: CcuThunk;
+ amap: Import.ImportMap
+ optimizing: bool
+ scope: CcuThunk
localInternalVals: System.Collections.Generic.Dictionary
- settings: OptimizationSettings;
- emitTailcalls: bool;
+ settings: OptimizationSettings
+ emitTailcalls: bool
// cache methods with SecurityAttribute applied to them, to prevent unnecessary calls to ExistsInEntireHierarchyOfType
- casApplied : Dictionary;}
+ casApplied : Dictionary}
type IncrementalOptimizationEnv =
{ // An identifier to help with name generation
- latestBoundId: Ident option;
+ latestBoundId: Ident option
// The set of lambda IDs we've inlined to reach this point. Helps to prevent recursive inlining
- dontInline: Zset;
+ dontInline: Zset
// Recursively bound vars. If an sub-expression that is a candidate for method splitting
// contains any of these variables then don't split it, for fear of mucking up tailcalls.
// See FSharp 1.0 bug 2892
- dontSplitVars: ValMap;
+ dontSplitVars: ValMap
/// The Val for the function binding being generated, if any.
- functionVal: (Val * Tast.ValReprInfo) option;
- typarInfos: (Typar * TypeValueInfo) list;
- localExternalVals: LayeredMap;
- globalModuleInfos: LayeredMap; }
+ functionVal: (Val * Tast.ValReprInfo) option
+ typarInfos: (Typar * TypeValueInfo) list
+ localExternalVals: LayeredMap
+ globalModuleInfos: LayeredMap }
static member Empty =
- { latestBoundId = None;
- dontInline = Zset.empty Int64.order;
- typarInfos = [];
- functionVal = None;
- dontSplitVars = ValMap.Empty;
- localExternalVals = LayeredMap.Empty;
+ { latestBoundId = None
+ dontInline = Zset.empty Int64.order
+ typarInfos = []
+ functionVal = None
+ dontSplitVars = ValMap.Empty
+ localExternalVals = LayeredMap.Empty
globalModuleInfos = LayeredMap.Empty }
//-------------------------------------------------------------------------
@@ -368,7 +368,7 @@ let CheckInlineValueIsComplete (v:Val) res =
//System.Diagnostics.Debug.Assert(false,sprintf "Break for incomplete inline value %s" v.DisplayName)
let check (vref: ValRef) (res:ValInfo) =
- CheckInlineValueIsComplete vref.Deref res.ValExprInfo;
+ CheckInlineValueIsComplete vref.Deref res.ValExprInfo
(vref,res)
//-------------------------------------------------------------------------
@@ -423,15 +423,14 @@ let BindInternalLocalVal cenv (v:Val) vval env =
| UnknownValue -> env
| _ ->
#endif
- cenv.localInternalVals.[v.Stamp] <- vval;
+ cenv.localInternalVals.[v.Stamp] <- vval
env
let BindExternalLocalVal cenv (v:Val) vval env =
#if CHECKED
- CheckInlineValueIsComplete v vval;
+ CheckInlineValueIsComplete v vval
#endif
- if verboseOptimizationInfo then dprintn ("*** Binding "^v.LogicalName);
let vval = if v.IsMutable then {vval with ValExprInfo=UnknownValue } else vval
let env =
#if CHECKED
@@ -490,17 +489,10 @@ let BindTypeVarsToUnknown (tps:Typar list) env =
let nms = PrettyTypes.PrettyTyparNames (fun _ -> true) (env.typarInfos |> List.map (fun (tp,_) -> tp.Name) ) tps
(tps,nms) ||> List.iter2 (fun tp nm ->
if PrettyTypes.NeedsPrettyTyparName tp then
- tp.Data.typar_id <- ident (nm,tp.Range));
+ tp.Data.typar_id <- ident (nm,tp.Range))
List.fold (fun sofar arg -> BindTypeVar arg UnknownTypeValue sofar) env tps
-let BindCcu (ccu:Tast.CcuThunk) mval env (g:TcGlobals) =
-#if DEBUG
- if verboseOptimizationInfo then
- dprintf "*** Reloading optimization data for assembly %s, info = \n%s\n" ccu.AssemblyName (showL (Layout.squashTo 192 (moduleInfoL g mval)));
-#else
- ignore g
-#endif
-
+let BindCcu (ccu:Tast.CcuThunk) mval env (_g:TcGlobals) =
{ env with globalModuleInfos=env.globalModuleInfos.Add(ccu.AssemblyName,mval) }
@@ -521,9 +513,9 @@ let GetInfoForLocalValue cenv env (v:Val) m =
| Some vval -> vval
| None ->
if v.MustInline then
- errorR(Error(FSComp.SR.optValueMarkedInlineButWasNotBoundInTheOptEnv(fullDisplayTextOfValRef (mkLocalValRef v)), m));
+ errorR(Error(FSComp.SR.optValueMarkedInlineButWasNotBoundInTheOptEnv(fullDisplayTextOfValRef (mkLocalValRef v)), m))
#if CHECKED
- warning(Error(FSComp.SR.optLocalValueNotFoundDuringOptimization(v.DisplayName),m));
+ warning(Error(FSComp.SR.optLocalValueNotFoundDuringOptimization(v.DisplayName),m))
#endif
UnknownValInfo
@@ -532,10 +524,7 @@ let TryGetInfoForCcu env (ccu:CcuThunk) = env.globalModuleInfos.TryFind(ccu.Asse
let TryGetInfoForEntity sv n =
match sv.ModuleOrNamespaceInfos.TryFind n with
| Some info -> Some (info.Force())
- | None ->
- if verboseOptimizationInfo then
- dprintn ("\n\n*** Optimization info for submodule "^n^" not found in parent module which contains submodules: "^String.concat "," (NameMap.domainL sv.ModuleOrNamespaceInfos));
- None
+ | None -> None
let rec TryGetInfoForPath sv (p:_[]) i =
if i >= p.Length then Some sv else
@@ -558,7 +547,7 @@ let GetInfoForNonLocalVal cenv env (vref:ValRef) =
match structInfo.ValInfos.TryFind(vref) with
| Some ninfo -> snd ninfo
| None ->
- //dprintn ("\n\n*** Optimization info for value "^n^" from module "^(full_name_of_nlpath smv)^" not found, module contains values: "^String.concat "," (NameMap.domainL structInfo.ValInfos));
+ //dprintn ("\n\n*** Optimization info for value "+n+" from module "+(full_name_of_nlpath smv)+" not found, module contains values: "+String.concat "," (NameMap.domainL structInfo.ValInfos))
//System.Diagnostics.Debug.Assert(false,sprintf "Break for module %s, value %s" (full_name_of_nlpath smv) n)
if cenv.g.compilingFslib then
match structInfo.ValInfos.TryFindForFslib(vref) with
@@ -568,7 +557,7 @@ let GetInfoForNonLocalVal cenv env (vref:ValRef) =
else
UnknownValInfo
| None ->
- //dprintf "\n\n*** Optimization info for module %s from ccu %s not found." (full_name_of_nlpath smv) (ccu_of_nlpath smv).AssemblyName;
+ //dprintf "\n\n*** Optimization info for module %s from ccu %s not found." (full_name_of_nlpath smv) (ccu_of_nlpath smv).AssemblyName
//System.Diagnostics.Debug.Assert(false,sprintf "Break for module %s, ccu %s" (full_name_of_nlpath smv) (ccu_of_nlpath smv).AssemblyName)
UnknownValInfo
else
@@ -579,7 +568,7 @@ let GetInfoForVal cenv env m (vref:ValRef) =
match vref.IsLocalRef with
| true -> GetInfoForLocalValue cenv env vref.binding m
| false -> GetInfoForNonLocalVal cenv env vref
- check (* "its stored value was incomplete" m *) vref res |> ignore;
+ check (* "its stored value was incomplete" m *) vref res |> ignore
res
//-------------------------------------------------------------------------
@@ -639,9 +628,9 @@ let MakeValueInfoForValue g m vref vinfo =
| ValValue (vref2,detail) -> if valRefEq g vref vref2 then error(Error(FSComp.SR.optRecursiveValValue(showL(exprValueInfoL g vinfo)),m)) else check detail
| SizeValue (_n,detail) -> check detail
| _ -> ()
- check vinfo;
+ check vinfo
#else
- ignore g; ignore m;
+ ignore g; ignore m
#endif
ValValue (vref,vinfo) |> BoundValueInfoBySize
@@ -978,17 +967,17 @@ let NoFlatExprs : (FlatExprs * FlatList>) = FlatList.empt
//-------------------------------------------------------------------------
let CombineValueInfos einfos res =
- { TotalSize = AddTotalSizes einfos;
- FunctionSize = AddFunctionSizes einfos;
- HasEffect = OrEffects einfos;
- MightMakeCriticalTailcall = OrTailcalls einfos;
+ { TotalSize = AddTotalSizes einfos
+ FunctionSize = AddFunctionSizes einfos
+ HasEffect = OrEffects einfos
+ MightMakeCriticalTailcall = OrTailcalls einfos
Info = res }
let CombineFlatValueInfos einfos res =
- { TotalSize = AddTotalSizesFlat einfos;
- FunctionSize = AddFunctionSizesFlat einfos;
- HasEffect = OrEffectsFlat einfos;
- MightMakeCriticalTailcall = OrTailcallsFlat einfos;
+ { TotalSize = AddTotalSizesFlat einfos
+ FunctionSize = AddFunctionSizesFlat einfos
+ HasEffect = OrEffectsFlat einfos
+ MightMakeCriticalTailcall = OrTailcallsFlat einfos
Info = res }
let CombineValueInfosUnknown einfos = CombineValueInfos einfos UnknownValue
@@ -1011,7 +1000,6 @@ let AbstractLazyModulInfoByHiding isAssemblyBoundary mhi =
Zset.memberOf mhi.mhiUnionCases
let rec abstractExprInfo ivalue =
- if verboseOptimizationInfo then dprintf "abstractExprInfo\n";
match ivalue with
(* Check for escaping value. Revert to old info if possible *)
| ValValue (vref2,detail) ->
@@ -1057,11 +1045,10 @@ let AbstractLazyModulInfoByHiding isAssemblyBoundary mhi =
| CurriedLambdaValue _
| ConstValue _ -> ivalue
and abstractValInfo v =
- { ValExprInfo=abstractExprInfo v.ValExprInfo;
+ { ValExprInfo=abstractExprInfo v.ValExprInfo
ValMakesNoCriticalTailcalls=v.ValMakesNoCriticalTailcalls }
and abstractModulInfo ss =
- if verboseOptimizationInfo then dprintf "abstractModulInfo\n";
- { ModuleOrNamespaceInfos = NameMap.map abstractLazyModulInfo ss.ModuleOrNamespaceInfos;
+ { ModuleOrNamespaceInfos = NameMap.map abstractLazyModulInfo ss.ModuleOrNamespaceInfos
ValInfos =
ValInfos(ss.ValInfos.Entries
|> Seq.filter (fun (vref,_) -> not (hiddenVal vref.Deref))
@@ -1075,7 +1062,7 @@ let AbstractLazyModulInfoByHiding isAssemblyBoundary mhi =
let AbstractOptimizationInfoToEssentials =
let rec abstractModulInfo (ss:ModuleInfo) =
- { ModuleOrNamespaceInfos = NameMap.map (Lazy.force >> abstractModulInfo >> notlazy) ss.ModuleOrNamespaceInfos;
+ { ModuleOrNamespaceInfos = NameMap.map (Lazy.force >> abstractModulInfo >> notlazy) ss.ModuleOrNamespaceInfos
ValInfos = ss.ValInfos.Filter (fun (v,_) -> v.MustInline) }
and abstractLazyModulInfo ss = ss |> Lazy.force |> abstractModulInfo |> notlazy
@@ -1105,14 +1092,9 @@ let AbstractExprInfoByVars (boundVars:Val list,boundTyVars) ivalue =
let ftyvs = freeInVal CollectTypars v2
List.exists (Zset.memberOf ftyvs.FreeTypars) boundTyVars) ->
- if verboseOptimizationInfo then
- dprintf "hiding value '%s' when used in expression (see %a)\n" v2.LogicalName outputRange v2.Range;
- let ftyvs = freeInVal CollectTypars v2
- ftyvs.FreeTypars |> Zset.iter (fun v -> dprintf " -- ftyv %s @ %a\n" v.Name outputRange v.Range);
- boundVars |> List.iter (fun v -> dprintf " -- bv %s @ %a\n" v.LogicalName outputRange v.Range);
- boundTyVars |> List.iter (fun v -> dprintf " -- btyv %s @ %a\n" v.Name outputRange v.Range)
-
+ // hiding value when used in expression
abstractExprInfo detail
+
| ValValue (v2,detail) ->
let detail' = abstractExprInfo detail
ValValue (v2,detail')
@@ -1123,14 +1105,8 @@ let AbstractExprInfoByVars (boundVars:Val list,boundTyVars) ivalue =
(nonNil boundVars && List.exists (Zset.memberOf fvs.FreeLocals) boundVars) ||
(nonNil boundTyVars && List.exists (Zset.memberOf fvs.FreeTyvars.FreeTypars) boundTyVars) ||
(fvs.UsesMethodLocalConstructs )) ->
- if verboseOptimizationInfo then
- let fvs = freeInExpr (if isNil boundTyVars then CollectLocals else CollectTyparsAndLocals) expr
- dprintf "Trimming lambda @ %a, UsesMethodLocalConstructs = %b, exprL = %s\n" outputRange expr.Range fvs.UsesMethodLocalConstructs (showL (exprL expr));
- fvs.FreeLocals |> Zset.iter (fun v -> dprintf "fv %s @ %a\n" v.LogicalName outputRange v.Range);
- fvs.FreeTyvars.FreeTypars |> Zset.iter (fun v -> dprintf "ftyv %s @ %a\n" v.Name outputRange v.Range);
- boundVars |> List.iter (fun v -> dprintf "bv %s @ %a\n" v.LogicalName outputRange v.Range);
- boundTyVars |> List.iter (fun v -> dprintf "btyv %s @ %a\n" v.Name outputRange v.Range)
-
+
+ // Trimming lambda
UnknownValue
// Check for escape in generic constant
@@ -1151,14 +1127,13 @@ let AbstractExprInfoByVars (boundVars:Val list,boundTyVars) ivalue =
| SizeValue (_vdepth,vinfo) -> MakeSizedValueInfo (abstractExprInfo vinfo)
and abstractValInfo v =
- { ValExprInfo=abstractExprInfo v.ValExprInfo;
+ { ValExprInfo=abstractExprInfo v.ValExprInfo
ValMakesNoCriticalTailcalls=v.ValMakesNoCriticalTailcalls }
and abstractModulInfo ss =
- { ModuleOrNamespaceInfos = ss.ModuleOrNamespaceInfos |> NameMap.map (Lazy.force >> abstractModulInfo >> notlazy) ;
+ { ModuleOrNamespaceInfos = ss.ModuleOrNamespaceInfos |> NameMap.map (Lazy.force >> abstractModulInfo >> notlazy)
ValInfos = ss.ValInfos.Map (fun (vref,e) ->
- if verboseOptimizationInfo then dprintf "checking %s @ %a\n" vref.LogicalName outputRange (vref.Range);
- check (* "its implementation uses a private binding" m *) vref (abstractValInfo e) ) }
+ check vref (abstractValInfo e) ) }
abstractExprInfo ivalue
@@ -1169,7 +1144,6 @@ let AbstractExprInfoByVars (boundVars:Val list,boundTyVars) ivalue =
let RemapOptimizationInfo g tmenv =
let rec remapExprInfo ivalue =
- if verboseOptimizationInfo then dprintf "remapExprInfo\n";
match ivalue with
| ValValue (v,detail) -> ValValue (remapValRef tmenv v,remapExprInfo detail)
| TupleValue vinfos -> TupleValue (Array.map remapExprInfo vinfos)
@@ -1183,8 +1157,7 @@ let RemapOptimizationInfo g tmenv =
let remapValInfo v = { ValExprInfo=remapExprInfo v.ValExprInfo; ValMakesNoCriticalTailcalls=v.ValMakesNoCriticalTailcalls }
let rec remapModulInfo ss =
- if verboseOptimizationInfo then dprintf "remapModulInfo\n";
- { ModuleOrNamespaceInfos = ss.ModuleOrNamespaceInfos |> NameMap.map remapLazyModulInfo;
+ { ModuleOrNamespaceInfos = ss.ModuleOrNamespaceInfos |> NameMap.map remapLazyModulInfo
ValInfos = ss.ValInfos.Map (fun (vref,vinfo) ->
let vref' = remapValRef tmenv vref
let vinfo = remapValInfo vinfo
@@ -1204,17 +1177,17 @@ let RemapOptimizationInfo g tmenv =
let AbstractAndRemapModulInfo msg g m (repackage,hidden) info =
let mrpi = mkRepackageRemapping repackage
#if DEBUG
- if verboseOptimizationInfo then dprintf "%s - %a - Optimization data prior to trim: \n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info)));
+ if verboseOptimizationInfo then dprintf "%s - %a - Optimization data prior to trim: \n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info)))
#else
ignore (msg,m)
#endif
let info = info |> AbstractLazyModulInfoByHiding false hidden
#if DEBUG
- if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after trim:\n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info)));
+ if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after trim:\n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info)))
#endif
let info = info |> RemapOptimizationInfo g mrpi
#if DEBUG
- if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after remap:\n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info)));
+ if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after remap:\n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info)))
#endif
info
@@ -1254,6 +1227,7 @@ let ValueIsUsedOrHasEffect cenv fvs (b:Binding,binfo) =
not (cenv.settings.EliminateUnusedBindings()) ||
isSome v.MemberInfo ||
binfo.HasEffect ||
+ v.IsFixed ||
Zset.contains v (fvs())
let rec SplitValuesByIsUsedOrHasEffect cenv fvs x =
@@ -1320,7 +1294,8 @@ and OpHasEffect g op =
| TOp.ExnFieldGet(ecref,n) -> isExnFieldMutable ecref n
| TOp.RefAddrGet -> false
| TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some(true))
- | TOp.ValFieldGetAddr _rfref -> true (* check *)
+ | TOp.ValFieldGetAddr rfref -> rfref.RecdField.IsMutable (* data is immutable, so taking address is ok *)
+ | TOp.UnionCaseFieldGetAddr _ -> false (* data is immutable, so taking address is ok *)
| TOp.LValueOp (LGetAddr,lv) -> lv.IsMutable
| TOp.UnionCaseFieldSet _
| TOp.ExnFieldSet _
@@ -1344,6 +1319,7 @@ let TryEliminateBinding cenv _env (TBind(vspec1,e1,spBind)) e2 _m =
if not (cenv.optimizing && cenv.settings.EliminateImmediatelyConsumedLocals()) &&
not vspec1.IsCompilerGenerated then
None
+ elif vspec1.IsFixed then None
else
// Peephole on immediate consumption of single bindings, e.g. "let x = e in x" --> "e"
// REVIEW: enhance this by general elimination of bindings to
@@ -1453,7 +1429,7 @@ let ExpandStructuralBindingRaw cenv expr =
else
let argTys = destTupleTy cenv.g v.Type
let argBind i (arg:Expr) argTy =
- let name = v.LogicalName ^ "_" ^ string i
+ let name = v.LogicalName + "_" + string i
let v,ve = mkCompGenLocal arg.Range name argTy
ve,mkCompGenBind v arg
@@ -1730,10 +1706,10 @@ let rec OptimizeExpr cenv (env:IncrementalOptimizationEnv) expr =
| Expr.Quote(ast,splices,isFromQueryExpression,m,ty) ->
let splices = ref (splices.Value |> Option.map (map3Of4 (List.map (OptimizeExpr cenv env >> fst))))
Expr.Quote(ast,splices,isFromQueryExpression,m,ty),
- { TotalSize = 10;
- FunctionSize = 1;
- HasEffect = false;
- MightMakeCriticalTailcall=false;
+ { TotalSize = 10
+ FunctionSize = 1
+ HasEffect = false
+ MightMakeCriticalTailcall=false
Info=UnknownValue }
| Expr.Obj (_,typ,basev,expr,overrides,iimpls,m) -> OptimizeObjectExpr cenv env (typ,basev,expr,overrides,iimpls,m)
| Expr.Op (c,tyargs,args,m) -> OptimizeExprOp cenv env (c,tyargs,args,m)
@@ -1758,13 +1734,13 @@ let rec OptimizeExpr cenv (env:IncrementalOptimizationEnv) expr =
let e2',e2info = OptimizeExpr cenv env e2
let e3',e3info = OptimizeExpr cenv env e3
Expr.StaticOptimization(constraints,e2',e3',m),
- { TotalSize = min e2info.TotalSize e3info.TotalSize;
- FunctionSize = min e2info.FunctionSize e3info.FunctionSize;
- HasEffect = e2info.HasEffect || e3info.HasEffect;
+ { TotalSize = min e2info.TotalSize e3info.TotalSize
+ FunctionSize = min e2info.FunctionSize e3info.FunctionSize
+ HasEffect = e2info.HasEffect || e3info.HasEffect
MightMakeCriticalTailcall=e2info.MightMakeCriticalTailcall || e3info.MightMakeCriticalTailcall // seems conservative
Info= UnknownValue }
| Expr.Link _eref ->
- assert ("unexpected reclink" = "");
+ assert ("unexpected reclink" = "")
failwith "Unexpected reclink"
@@ -1773,15 +1749,14 @@ let rec OptimizeExpr cenv (env:IncrementalOptimizationEnv) expr =
//-------------------------------------------------------------------------
and OptimizeObjectExpr cenv env (typ,baseValOpt,basecall,overrides,iimpls,m) =
- if verboseOptimizations then dprintf "OptimizeObjectExpr\n";
let basecall',basecallinfo = OptimizeExpr cenv env basecall
let overrides',overrideinfos = OptimizeMethods cenv env baseValOpt overrides
let iimpls',iimplsinfos = OptimizeInterfaceImpls cenv env baseValOpt iimpls
let expr'=mkObjExpr(typ,baseValOpt,basecall',overrides',iimpls',m)
- expr', { TotalSize=closureTotalSize + basecallinfo.TotalSize + AddTotalSizes overrideinfos + AddTotalSizes iimplsinfos;
- FunctionSize=1 (* a newobj *) ;
- HasEffect=true;
- MightMakeCriticalTailcall=false; // creating an object is not a useful tailcall
+ expr', { TotalSize=closureTotalSize + basecallinfo.TotalSize + AddTotalSizes overrideinfos + AddTotalSizes iimplsinfos
+ FunctionSize=1 (* a newobj *)
+ HasEffect=true
+ MightMakeCriticalTailcall=false // creating an object is not a useful tailcall
Info=UnknownValue}
//-------------------------------------------------------------------------
@@ -1790,7 +1765,6 @@ and OptimizeObjectExpr cenv env (typ,baseValOpt,basecall,overrides,iimpls,m) =
and OptimizeMethods cenv env baseValOpt l = OptimizeList (OptimizeMethod cenv env baseValOpt) l
and OptimizeMethod cenv env baseValOpt (TObjExprMethod(slotsig, attribs, tps, vs, e, m) as tmethod) =
- if verboseOptimizations then dprintf "OptimizeMethod\n";
let env = {env with latestBoundId=Some tmethod.Id; functionVal = None}
let env = BindTypeVarsToUnknown tps env
let env = BindInternalValsToUnknown cenv vs env
@@ -1798,10 +1772,10 @@ and OptimizeMethod cenv env baseValOpt (TObjExprMethod(slotsig, attribs, tps, vs
let e',einfo = OptimizeExpr cenv env e
(* REVIEW: if we ever change this from being UnknownValue then we should call AbstractExprInfoByVars *)
TObjExprMethod(slotsig,attribs,tps,vs,e',m),
- { TotalSize = einfo.TotalSize;
- FunctionSize = 0;
- HasEffect = false;
- MightMakeCriticalTailcall=false;
+ { TotalSize = einfo.TotalSize
+ FunctionSize = 0
+ HasEffect = false
+ MightMakeCriticalTailcall=false
Info=UnknownValue}
//-------------------------------------------------------------------------
@@ -1810,13 +1784,12 @@ and OptimizeMethod cenv env baseValOpt (TObjExprMethod(slotsig, attribs, tps, vs
and OptimizeInterfaceImpls cenv env baseValOpt l = OptimizeList (OptimizeInterfaceImpl cenv env baseValOpt) l
and OptimizeInterfaceImpl cenv env baseValOpt (ty,overrides) =
- if verboseOptimizations then dprintf "OptimizeInterfaceImpl\n";
let overrides',overridesinfos = OptimizeMethods cenv env baseValOpt overrides
(ty, overrides'),
- { TotalSize = AddTotalSizes overridesinfos;
- FunctionSize = 1;
- HasEffect = false;
- MightMakeCriticalTailcall=false;
+ { TotalSize = AddTotalSizes overridesinfos
+ FunctionSize = 1
+ HasEffect = false
+ MightMakeCriticalTailcall=false
Info=UnknownValue}
//-------------------------------------------------------------------------
@@ -1825,7 +1798,6 @@ and OptimizeInterfaceImpl cenv env baseValOpt (ty,overrides) =
and OptimizeExprOp cenv env (op,tyargs,args,m) =
- if verboseOptimizations then dprintf "OptimizeExprOp\n";
(* Special cases *)
match op,tyargs,args with
| TOp.Coerce,[toty;fromty],[e] ->
@@ -1833,10 +1805,10 @@ and OptimizeExprOp cenv env (op,tyargs,args,m) =
if typeEquiv cenv.g toty fromty then e',einfo
else
mkCoerceExpr(e',toty,m,fromty),
- { TotalSize=einfo.TotalSize + 1;
- FunctionSize=einfo.FunctionSize + 1;
- HasEffect = true;
- MightMakeCriticalTailcall=false;
+ { TotalSize=einfo.TotalSize + 1
+ FunctionSize=einfo.FunctionSize + 1
+ HasEffect = true
+ MightMakeCriticalTailcall=false
Info=UnknownValue }
(* Handle addresses *)
| TOp.LValueOp (LGetAddr,lv),_,_ ->
@@ -1847,10 +1819,10 @@ and OptimizeExprOp cenv env (op,tyargs,args,m) =
| Expr.Val (v,_,_) when not v.IsCompiledAsTopLevel -> TOp.LValueOp (LGetAddr,v)
| _ -> op
Expr.Op (op',tyargs,args,m),
- { TotalSize = 1;
- FunctionSize = 1;
- HasEffect = OpHasEffect cenv.g op';
- MightMakeCriticalTailcall = false;
+ { TotalSize = 1
+ FunctionSize = 1
+ HasEffect = OpHasEffect cenv.g op'
+ MightMakeCriticalTailcall = false
Info = UnknownValue }
(* Handle these as special cases since mutables are allowed inside their bodies *)
| TOp.While (spWhile,marker),_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_)] -> OptimizeWhileLoop cenv env (spWhile,marker,e1,e2,m)
@@ -1928,6 +1900,7 @@ and OptimizeExprOpFallback cenv env (op,tyargs,args',m) arginfos valu =
| TOp.Array | TOp.For _ | TOp.While _ | TOp.TryCatch _ | TOp.TryFinally _
| TOp.ILCall _ | TOp.TraitCall _ | TOp.LValueOp _ | TOp.ValFieldSet _
| TOp.UnionCaseFieldSet _ | TOp.RefAddrGet | TOp.Coerce | TOp.Reraise
+ | TOp.UnionCaseFieldGetAddr _
| TOp.ExnFieldSet _ -> 1,valu
| TOp.Recd (ctorInfo,tcref) ->
let finfos = tcref.AllInstanceFieldsAsList
@@ -1948,10 +1921,10 @@ and OptimizeExprOpFallback cenv env (op,tyargs,args',m) arginfos valu =
| TOp.ILCall (virt,_,newobj,_,_,_,_,_,_,_,_) -> not newobj && virt
| _ -> false
- let vinfo = { TotalSize=argsTSize + cost;
- FunctionSize=argsFSize + cost;
- HasEffect=argEffects || effect;
- MightMakeCriticalTailcall= mayBeCriticalTailcall; // discard tailcall info for args - these are not in tailcall position
+ let vinfo = { TotalSize=argsTSize + cost
+ FunctionSize=argsFSize + cost
+ HasEffect=argEffects || effect
+ MightMakeCriticalTailcall= mayBeCriticalTailcall // discard tailcall info for args - these are not in tailcall position
Info=valu }
// Replace entire expression with known value?
@@ -1959,10 +1932,10 @@ and OptimizeExprOpFallback cenv env (op,tyargs,args',m) arginfos valu =
| Some res -> res,vinfo
| None ->
Expr.Op(op,tyargs,args',m),
- { TotalSize=argsTSize + cost;
- FunctionSize=argsFSize + cost;
- HasEffect=argEffects || effect;
- MightMakeCriticalTailcall= mayBeCriticalTailcall; // discard tailcall info for args - these are not in tailcall position
+ { TotalSize=argsTSize + cost
+ FunctionSize=argsFSize + cost
+ HasEffect=argEffects || effect
+ MightMakeCriticalTailcall= mayBeCriticalTailcall // discard tailcall info for args - these are not in tailcall position
Info=valu }
//-------------------------------------------------------------------------
@@ -1974,13 +1947,12 @@ and OptimizeConst cenv env expr (c,m,ty) =
| Some(e) ->
OptimizeExpr cenv env e
| None ->
- if verboseOptimizations then dprintf "OptimizeConst\n";
expr, { TotalSize=(match c with
| Const.String b -> b.Length/10
- | _ -> 0);
- FunctionSize=0;
- HasEffect=false;
- MightMakeCriticalTailcall=false;
+ | _ -> 0)
+ FunctionSize=0
+ HasEffect=false
+ MightMakeCriticalTailcall=false
Info=MakeValueInfoForConst c ty}
//-------------------------------------------------------------------------
@@ -1991,7 +1963,7 @@ and TryOptimizeRecordFieldGet cenv _env (e1info,r:RecdFieldRef,_tinst,m) =
match destRecdValue e1info.Info with
| Some finfos when cenv.settings.EliminateRecdFieldGet() && not e1info.HasEffect ->
let n = r.Index
- if n >= finfos.Length then errorR(InternalError( "TryOptimizeRecordFieldGet: term argument out of range",m));
+ if n >= finfos.Length then errorR(InternalError( "TryOptimizeRecordFieldGet: term argument out of range",m))
Some finfos.[n] (* Uses INVARIANT on record ValInfos that exprs are in defn order *)
| _ -> None
@@ -1999,15 +1971,15 @@ and TryOptimizeTupleFieldGet cenv _env (e1info,tys,n,m) =
match destTupleValue e1info.Info with
| Some tups when cenv.settings.EliminateTupleFieldGet() && not e1info.HasEffect ->
let len = tups.Length
- if len <> tys.Length then errorR(InternalError("error: tuple lengths don't match",m));
- if n >= len then errorR(InternalError("TryOptimizeTupleFieldGet: tuple index out of range",m));
+ if len <> tys.Length then errorR(InternalError("error: tuple lengths don't match",m))
+ if n >= len then errorR(InternalError("TryOptimizeTupleFieldGet: tuple index out of range",m))
Some tups.[n]
| _ -> None
and TryOptimizeUnionCaseGet cenv _env (e1info,cspec,_tys,n,m) =
match e1info.Info with
| StripUnionCaseValue(cspec2,args) when cenv.settings.EliminatUnionCaseFieldGet() && not e1info.HasEffect && cenv.g.unionCaseRefEq cspec cspec2 ->
- if n >= args.Length then errorR(InternalError( "TryOptimizeUnionCaseGet: term argument out of range",m));
+ if n >= args.Length then errorR(InternalError( "TryOptimizeUnionCaseGet: term argument out of range",m))
Some args.[n]
| _ -> None
@@ -2016,7 +1988,6 @@ and TryOptimizeUnionCaseGet cenv _env (e1info,cspec,_tys,n,m) =
//-------------------------------------------------------------------------
and OptimizeFastIntegerForLoop cenv env (spStart,v,e1,dir,e2,e3,m) =
- if verboseOptimizations then dprintf "OptimizeFastIntegerForLoop\n";
let e1',e1info = OptimizeExpr cenv env e1
let e2',e2info = OptimizeExpr cenv env e2
let env = BindInternalValToUnknown cenv v env
@@ -2027,8 +1998,7 @@ and OptimizeFastIntegerForLoop cenv env (spStart,v,e1,dir,e2,e3,m) =
let e2', dir =
match dir, e2' with
// detect upwards for loops with bounds of the form "arr.Length - 1" and convert them to a C#-style for loop
- | FSharpForLoopUp, Expr.Op(TOp.ILAsm([ (AI_sub | AI_sub_ovf)],_),_,[Expr.Op(TOp.ILAsm([ I_ldlen; (AI_conv DT_I4)],_),_,[arre],_);
- Expr.Const(Const.Int32 1,_,_)],_)
+ | FSharpForLoopUp, Expr.Op(TOp.ILAsm([ (AI_sub | AI_sub_ovf)],_),_,[Expr.Op(TOp.ILAsm([ I_ldlen; (AI_conv DT_I4)],_),_,[arre],_); Expr.Const(Const.Int32 1,_,_)],_)
when not (snd(OptimizeExpr cenv env arre)).HasEffect ->
mkLdlen cenv.g (e2'.Range) arre, CSharpForLoopUp
@@ -2048,10 +2018,10 @@ and OptimizeFastIntegerForLoop cenv env (spStart,v,e1,dir,e2,e3,m) =
mkUnit cenv.g m , { TotalSize=0; FunctionSize=0; HasEffect=false; MightMakeCriticalTailcall=false; Info=UnknownValue }
else
let expr' = mkFor cenv.g (spStart,v,e1',dir,e2',e3',m)
- expr', { TotalSize=AddTotalSizes einfos + forAndWhileLoopSize;
- FunctionSize=AddFunctionSizes einfos + forAndWhileLoopSize;
- HasEffect=eff;
- MightMakeCriticalTailcall=false;
+ expr', { TotalSize=AddTotalSizes einfos + forAndWhileLoopSize
+ FunctionSize=AddFunctionSizes einfos + forAndWhileLoopSize
+ HasEffect=eff
+ MightMakeCriticalTailcall=false
Info=UnknownValue }
//-------------------------------------------------------------------------
@@ -2059,7 +2029,6 @@ and OptimizeFastIntegerForLoop cenv env (spStart,v,e1,dir,e2,e3,m) =
//-------------------------------------------------------------------------
and OptimizeLetRec cenv env (binds,bodyExpr,m) =
- if verboseOptimizations then dprintf "OptimizeLetRec\n";
let vs = binds |> FlatList.map (fun v -> v.Var) in
let env = BindInternalValsToUnknown cenv vs env
let binds',env = OptimizeBindings cenv true env binds
@@ -2086,11 +2055,9 @@ and OptimizeLinearExpr cenv env expr contf =
let expr = DetectAndOptimizeForExpression cenv.g OptimizeAllForExpressions expr
- if verboseOptimizations then dprintf "OptimizeLinearExpr\n";
let expr = if cenv.settings.ExpandStructrualValues() then ExpandStructuralBinding cenv expr else expr
match expr with
| Expr.Sequential (e1,e2,flag,spSeq,m) ->
- if verboseOptimizations then dprintf "OptimizeLinearExpr: seq\n";
let e1',e1info = OptimizeExpr cenv env e1
OptimizeLinearExpr cenv env e2 (contf << (fun (e2',e2info) ->
if (flag = NormalSeq) &&
@@ -2101,14 +2068,13 @@ and OptimizeLinearExpr cenv env expr contf =
e2', e2info
else
Expr.Sequential(e1',e2',flag,spSeq,m),
- { TotalSize = e1info.TotalSize + e2info.TotalSize;
- FunctionSize = e1info.FunctionSize + e2info.FunctionSize;
- HasEffect = flag <> NormalSeq || e1info.HasEffect || e2info.HasEffect;
+ { TotalSize = e1info.TotalSize + e2info.TotalSize
+ FunctionSize = e1info.FunctionSize + e2info.FunctionSize
+ HasEffect = flag <> NormalSeq || e1info.HasEffect || e2info.HasEffect
MightMakeCriticalTailcall = (if flag = NormalSeq then e2info.MightMakeCriticalTailcall else e1info.MightMakeCriticalTailcall || e2info.MightMakeCriticalTailcall)
Info = UnknownValue (* can't propagate value: must access result of computation for its effects *) }))
| Expr.Let (bind,body,m,_) ->
- if verboseOptimizations then dprintf "OptimizeLinearExpr: let\n";
let (bind',bindingInfo),env = OptimizeBinding cenv false env bind
OptimizeLinearExpr cenv env body (contf << (fun (body',bodyInfo) ->
// PERF: This call to ValueIsUsedOrHasEffect/freeInExpr amounts to 9% of all optimization time.
@@ -2117,19 +2083,19 @@ and OptimizeLinearExpr cenv env expr contf =
(* Eliminate let bindings on the way back up *)
let expr',adjust = TryEliminateLet cenv env bind' body' m
expr',
- { TotalSize = bindingInfo.TotalSize + bodyInfo.TotalSize + adjust;
- FunctionSize = bindingInfo.FunctionSize + bodyInfo.FunctionSize + adjust;
- HasEffect=bindingInfo.HasEffect || bodyInfo.HasEffect;
- MightMakeCriticalTailcall = bodyInfo.MightMakeCriticalTailcall; // discard tailcall info from binding - not in tailcall position
+ { TotalSize = bindingInfo.TotalSize + bodyInfo.TotalSize + adjust
+ FunctionSize = bindingInfo.FunctionSize + bodyInfo.FunctionSize + adjust
+ HasEffect=bindingInfo.HasEffect || bodyInfo.HasEffect
+ MightMakeCriticalTailcall = bodyInfo.MightMakeCriticalTailcall // discard tailcall info from binding - not in tailcall position
Info = UnknownValue }
else
(* On the way back up: Trim out any optimization info that involves escaping values on the way back up *)
let evalue' = AbstractExprInfoByVars ([bind'.Var],[]) bodyInfo.Info
body',
- { TotalSize = bindingInfo.TotalSize + bodyInfo.TotalSize - localVarSize (* eliminated a local var *);
- FunctionSize = bindingInfo.FunctionSize + bodyInfo.FunctionSize - localVarSize (* eliminated a local var *);
- HasEffect=bindingInfo.HasEffect || bodyInfo.HasEffect;
- MightMakeCriticalTailcall = bodyInfo.MightMakeCriticalTailcall; // discard tailcall info from binding - not in tailcall position
+ { TotalSize = bindingInfo.TotalSize + bodyInfo.TotalSize - localVarSize (* eliminated a local var *)
+ FunctionSize = bindingInfo.FunctionSize + bodyInfo.FunctionSize - localVarSize (* eliminated a local var *)
+ HasEffect=bindingInfo.HasEffect || bodyInfo.HasEffect
+ MightMakeCriticalTailcall = bodyInfo.MightMakeCriticalTailcall // discard tailcall info from binding - not in tailcall position
Info = evalue' } ))
| LinearMatchExpr (spMatch,exprm,dtree,tg1,e2,spTarget2,m,ty) ->
@@ -2149,14 +2115,13 @@ and OptimizeLinearExpr cenv env expr contf =
//-------------------------------------------------------------------------
and OptimizeTryFinally cenv env (spTry,spFinally,e1,e2,m,ty) =
- if verboseOptimizations then dprintf "OptimizeTryFinally\n";
let e1',e1info = OptimizeExpr cenv env e1
let e2',e2info = OptimizeExpr cenv env e2
let info =
- { TotalSize = e1info.TotalSize + e2info.TotalSize + tryFinallySize;
- FunctionSize = e1info.FunctionSize + e2info.FunctionSize + tryFinallySize;
- HasEffect = e1info.HasEffect || e2info.HasEffect;
- MightMakeCriticalTailcall = false; // no tailcalls from inside in try/finally
+ { TotalSize = e1info.TotalSize + e2info.TotalSize + tryFinallySize
+ FunctionSize = e1info.FunctionSize + e2info.FunctionSize + tryFinallySize
+ HasEffect = e1info.HasEffect || e2info.HasEffect
+ MightMakeCriticalTailcall = false // no tailcalls from inside in try/finally
Info = UnknownValue }
(* try-finally, so no effect means no exception can be raised, so just sequence the finally *)
if cenv.settings.EliminateTryCatchAndTryFinally () && not e1info.HasEffect then
@@ -2175,7 +2140,6 @@ and OptimizeTryFinally cenv env (spTry,spFinally,e1,e2,m,ty) =
//-------------------------------------------------------------------------
and OptimizeTryCatch cenv env (e1,vf,ef,vh,eh,m,ty,spTry,spWith) =
- if verboseOptimizations then dprintf "OptimizeTryCatch\n";
let e1',e1info = OptimizeExpr cenv env e1
// try-catch, so no effect means no exception can be raised, so discard the catch
if cenv.settings.EliminateTryCatchAndTryFinally () && not e1info.HasEffect then
@@ -2185,10 +2149,10 @@ and OptimizeTryCatch cenv env (e1,vf,ef,vh,eh,m,ty,spTry,spWith) =
let ef',efinfo = OptimizeExpr cenv envinner ef
let eh',ehinfo = OptimizeExpr cenv envinner eh
let info =
- { TotalSize = e1info.TotalSize + efinfo.TotalSize+ ehinfo.TotalSize + tryCatchSize;
- FunctionSize = e1info.FunctionSize + efinfo.FunctionSize+ ehinfo.FunctionSize + tryCatchSize;
- HasEffect = e1info.HasEffect || efinfo.HasEffect || ehinfo.HasEffect;
- MightMakeCriticalTailcall = false;
+ { TotalSize = e1info.TotalSize + efinfo.TotalSize+ ehinfo.TotalSize + tryCatchSize
+ FunctionSize = e1info.FunctionSize + efinfo.FunctionSize+ ehinfo.FunctionSize + tryCatchSize
+ HasEffect = e1info.HasEffect || efinfo.HasEffect || ehinfo.HasEffect
+ MightMakeCriticalTailcall = false
Info = UnknownValue }
mkTryWith cenv.g (e1',vf,ef',vh,eh',m,ty,spTry,spWith),
info
@@ -2198,14 +2162,13 @@ and OptimizeTryCatch cenv env (e1,vf,ef,vh,eh,m,ty,spTry,spWith) =
//-------------------------------------------------------------------------
and OptimizeWhileLoop cenv env (spWhile,marker,e1,e2,m) =
- if verboseOptimizations then dprintf "OptimizeWhileLoop\n";
let e1',e1info = OptimizeExpr cenv env e1
let e2',e2info = OptimizeExpr cenv env e2
mkWhile cenv.g (spWhile,marker,e1',e2',m),
- { TotalSize = e1info.TotalSize + e2info.TotalSize + forAndWhileLoopSize;
- FunctionSize = e1info.FunctionSize + e2info.FunctionSize + forAndWhileLoopSize;
- HasEffect = true; (* may not terminate *)
- MightMakeCriticalTailcall = false;
+ { TotalSize = e1info.TotalSize + e2info.TotalSize + forAndWhileLoopSize
+ FunctionSize = e1info.FunctionSize + e2info.FunctionSize + forAndWhileLoopSize
+ HasEffect = true (* may not terminate *)
+ MightMakeCriticalTailcall = false
Info = UnknownValue }
//-------------------------------------------------------------------------
@@ -2246,10 +2209,8 @@ and TryOptimizeVal cenv env (mustInline,valInfoForVal,m) =
//If the more specific info didn't reveal an inline then use the value
| None -> Some(exprForValRef m v')
| ConstExprValue(_size,expr) ->
- if verboseOptimizations then dprintf "Inlining constant expression value at %a\n" outputRange m;
Some (remarkExpr m (copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated expr))
| CurriedLambdaValue (_,_,_,expr,_) when mustInline ->
- if verboseOptimizations then dprintf "Inlining mustinline-lambda at %a\n" outputRange m;
Some (remarkExpr m (copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated expr))
| TupleValue _ | UnionCaseValue _ | RecdValue _ when mustInline -> failwith "tuple, union and record values cannot be marked 'inline'"
| UnknownValue when mustInline -> warning(Error(FSComp.SR.optValueMarkedInlineHasUnexpectedValue(),m)); None
@@ -2284,22 +2245,22 @@ and OptimizeVal cenv env expr (v:ValRef,m) =
| Expr.TyLambda _
| Expr.Lambda _ ->
e, (AddValEqualityInfo cenv.g m v
- { Info=valInfoForVal.ValExprInfo;
- HasEffect=false;
- MightMakeCriticalTailcall = false;
- FunctionSize=10;
+ { Info=valInfoForVal.ValExprInfo
+ HasEffect=false
+ MightMakeCriticalTailcall = false
+ FunctionSize=10
TotalSize=10})
| _ ->
let e,einfo = OptimizeExpr cenv env e
e,AddValEqualityInfo cenv.g m v einfo
| None ->
- if v.MustInline then error(Error(FSComp.SR.optFailedToInlineValue(v.DisplayName),m));
+ if v.MustInline then error(Error(FSComp.SR.optFailedToInlineValue(v.DisplayName),m))
expr,(AddValEqualityInfo cenv.g m v
- { Info=valInfoForVal.ValExprInfo;
- HasEffect=false;
- MightMakeCriticalTailcall = false;
- FunctionSize=1;
+ { Info=valInfoForVal.ValExprInfo
+ HasEffect=false
+ MightMakeCriticalTailcall = false
+ FunctionSize=1
TotalSize=1})
//-------------------------------------------------------------------------
@@ -2536,21 +2497,21 @@ and TryDevirtualizeApplication cenv env (f,tyargs,args,m) =
// Don't fiddle with 'methodhandleof' calls - just remake the application
| Expr.Val(vref,_,_),_,_ when valRefEq cenv.g vref cenv.g.methodhandleof_vref ->
Some( MakeApplicationAndBetaReduce cenv.g (exprForValRef m vref,vref.Type,(if isNil tyargs then [] else [tyargs]),args,m),
- { TotalSize=1;
+ { TotalSize=1
FunctionSize=1
- HasEffect=false;
- MightMakeCriticalTailcall = false;
+ HasEffect=false
+ MightMakeCriticalTailcall = false
Info=UnknownValue})
| _ -> None
/// Attempt to inline an application of a known value at callsites
and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr list,m) =
- if verboseOptimizations then dprintf "Considering inlining app near %a\n" outputRange m;
+ // Considering inlining app
match finfo.Info with
| StripLambdaValue (lambdaId,arities,size,f2,f2ty) when
- (if verboseOptimizations then dprintf "Considering inlining lambda near %a, size = %d, finfo.HasEffect = %b\n" outputRange m size finfo.HasEffect;
+ (// Considering inlining lambda
cenv.optimizing &&
cenv.settings.InlineLambdas () &&
not finfo.HasEffect &&
@@ -2558,9 +2519,9 @@ and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr li
not (Zset.contains lambdaId env.dontInline) &&
(// Check the number of argument groups is enough to saturate the lambdas of the target.
(if tyargs |> List.filter (fun t -> match t with TType_measure _ -> false | _ -> true) |> isNil then 0 else 1) + args.Length = arities &&
- (if verboseOptimizations then dprintn "Enough args";
+ (// Enough args
(if size > cenv.settings.lambdaInlineThreshold + args.Length then
- if verboseOptimizations then dprintf "Not inlining lambda near %a because size = %d\n" outputRange m size;
+ // Not inlining lambda near, size too big
false
else true)))) ->
@@ -2595,18 +2556,18 @@ and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr li
if isBaseCall || isSecureMethod || isValFromLazyExtensions then None
else
- if verboseOptimizations then dprintf "Inlining lambda near %a\n" outputRange m;
- (* ---------- printf "Inlining lambda near %a = %s\n" outputRange m (showL (exprL f2)); (* JAMES: *) ----------*)
+ // Inlining lambda
+ (* ---------- printf "Inlining lambda near %a = %s\n" outputRange m (showL (exprL f2)) (* JAMES: *) ----------*)
let f2' = remarkExpr m (copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated f2)
- if verboseOptimizations then dprintf "--- TryInlineApplication, optimizing arguments\n";
+ // Optimizing arguments after inlining
// REVIEW: this is a cheapshot way of optimizing the arg expressions as well without the restriction of recursive
// inlining kicking into effect
let args' = args |> List.map (fun e -> let e',_einfo = OptimizeExpr cenv env e in e')
// Beta reduce. MakeApplicationAndBetaReduce cenv.g does all the hard work.
- if verboseOptimizations then dprintf "--- TryInlineApplication, beta reducing \n";
+ // Inlining: beta reducing
let expr' = MakeApplicationAndBetaReduce cenv.g (f2',f2ty,[tyargs],args',m)
- if verboseOptimizations then dprintf "--- TryInlineApplication, reoptimizing\n";
+ // Inlining: reoptimizing
Some (OptimizeExpr cenv {env with dontInline= Zset.add lambdaId env.dontInline} expr')
| _ -> None
@@ -2616,18 +2577,17 @@ and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr li
//-------------------------------------------------------------------------
and OptimizeApplication cenv env (f0,f0ty,tyargs,args,m) =
- if verboseOptimizations then dprintf "--> OptimizeApplication\n";
let f0',finfo = OptimizeExpr cenv env f0
- if verboseOptimizations then dprintf "--- OptimizeApplication, trying to devirtualize\n";
+ // trying to devirtualize
match TryDevirtualizeApplication cenv env (f0,tyargs,args,m) with
| Some res ->
- if verboseOptimizations then dprintf "<-- OptimizeApplication, devirtualized\n";
+ // devirtualized
res
| None ->
match TryInlineApplication cenv env (f0',finfo) (tyargs,args,m) with
| Some res ->
- if verboseOptimizations then dprintf "<-- OptimizeApplication, inlined\n";
+ // inlined
res
| None ->
@@ -2648,16 +2608,15 @@ and OptimizeApplication cenv env (f0,f0ty,tyargs,args,m) =
| _ -> args |> List.map (fun _ -> UnknownValue)
let args',arginfos = OptimizeExprsThenReshapeAndConsiderSplits cenv env (List.zip shapes args)
- if verboseOptimizations then dprintf "<-- OptimizeApplication, beta reducing\n";
+ // beta reducing
let expr' = MakeApplicationAndBetaReduce cenv.g (f0',f0ty, [tyargs],args',m)
match f0', expr' with
| (Expr.Lambda _ | Expr.TyLambda _), Expr.Let _ ->
// we beta-reduced, hence reoptimize
- if verboseOptimizations then dprintf "<-- OptimizeApplication, beta reduced\n";
OptimizeExpr cenv env expr'
| _ ->
- if verboseOptimizations then dprintf "<-- OptimizeApplication, regular\n";
+ // regular
// Determine if this application is a critical tailcall
let mayBeCriticalTailcall =
@@ -2686,10 +2645,10 @@ and OptimizeApplication cenv env (f0,f0ty,tyargs,args,m) =
// All indirect calls (calls to unknown functions) are assumed to be critical tailcalls
true
- expr', { TotalSize=finfo.TotalSize + AddTotalSizes arginfos;
- FunctionSize=finfo.FunctionSize + AddFunctionSizes arginfos;
- HasEffect=true;
- MightMakeCriticalTailcall = mayBeCriticalTailcall;
+ expr', { TotalSize=finfo.TotalSize + AddTotalSizes arginfos
+ FunctionSize=finfo.FunctionSize + AddFunctionSizes arginfos
+ HasEffect=true
+ MightMakeCriticalTailcall = mayBeCriticalTailcall
Info=ValueOfExpr expr' }
//-------------------------------------------------------------------------
@@ -2697,7 +2656,6 @@ and OptimizeApplication cenv env (f0,f0ty,tyargs,args,m) =
//-------------------------------------------------------------------------
and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety =
- if verboseOptimizations then dprintf "OptimizeLambdas, #argsl = %d, %a\n" topValInfo.NumCurriedArgs outputRange (e.Range) ;
match e with
| Expr.Lambda (lambdaId,_,_,_,_,m,_)
| Expr.TyLambda(lambdaId,_,_,m,_) ->
@@ -2714,8 +2672,6 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety =
let arities = vsl.Length
let arities = if isNil tps then arities else 1+arities
let bsize = bodyinfo.TotalSize
- if verboseOptimizations then dprintf "lambda @ %a, bsize = %d\n" outputRange m bsize;
-
/// Set the flag on the value indicating that direct calls can avoid a tailcall (which are expensive on .NET x86)
/// MightMakeCriticalTailcall is true whenever the body of the method may itself do a useful tailcall, e.g. has
@@ -2757,11 +2713,11 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety =
CurriedLambdaValue (lambdaId,arities,bsize,expr2,ety)
- expr', { TotalSize=bsize + (if isTopLevel then methodDefnTotalSize else closureTotalSize); (* estimate size of new syntactic closure - expensive, in contrast to a method *)
- FunctionSize=1;
- HasEffect=false;
- MightMakeCriticalTailcall = false;
- Info= valu; }
+ expr', { TotalSize=bsize + (if isTopLevel then methodDefnTotalSize else closureTotalSize) (* estimate size of new syntactic closure - expensive, in contrast to a method *)
+ FunctionSize=1
+ HasEffect=false
+ MightMakeCriticalTailcall = false
+ Info= valu }
| _ -> OptimizeExpr cenv env e
@@ -2832,7 +2788,8 @@ and ComputeSplitToMethodCondition flag threshold cenv env (e,einfo) =
// None of them should be local polymorphic constrained values
not (IsGenericValWithGenericContraints cenv.g v) &&
// None of them should be mutable
- not v.IsMutable))))
+ not v.IsMutable)))) &&
+ not (isByrefLikeTy cenv.g (tyOfExpr cenv.g e))
and ConsiderSplitToMethod flag threshold cenv env (e,einfo) =
if ComputeSplitToMethodCondition flag threshold cenv env (e,einfo) then
@@ -2841,7 +2798,7 @@ and ConsiderSplitToMethod flag threshold cenv env (e,einfo) =
let ty = tyOfExpr cenv.g e
let nm =
match env.latestBoundId with
- | Some id -> id.idText^suffixForVariablesThatMayNotBeEliminated
+ | Some id -> id.idText+suffixForVariablesThatMayNotBeEliminated
| None -> suffixForVariablesThatMayNotBeEliminated
let fv,fe = mkCompGenLocal m nm (cenv.g.unit_ty --> ty)
mkInvisibleLet m fv (mkLambda m uv (e,ty))
@@ -2855,17 +2812,16 @@ and ConsiderSplitToMethod flag threshold cenv env (e,einfo) =
//-------------------------------------------------------------------------
and OptimizeMatch cenv env (spMatch,exprm,dtree,targets,m, ty) =
- if verboseOptimizations then dprintf "OptimizeMatch\n";
// REVIEW: consider collecting, merging and using information flowing through each line of the decision tree to each target
let dtree',dinfo = OptimizeDecisionTree cenv env m dtree
let targets',tinfos = OptimizeDecisionTreeTargets cenv env m targets
RebuildOptimizedMatch (spMatch,exprm,m,ty,dtree',targets',dinfo,tinfos)
and CombineMatchInfos dinfo tinfo =
- { TotalSize = dinfo.TotalSize + tinfo.TotalSize;
- FunctionSize = dinfo.FunctionSize + tinfo.FunctionSize;
- HasEffect = dinfo.HasEffect || tinfo.HasEffect;
- MightMakeCriticalTailcall=tinfo.MightMakeCriticalTailcall; // discard tailcall info from decision tree since it's not in tailcall position
+ { TotalSize = dinfo.TotalSize + tinfo.TotalSize
+ FunctionSize = dinfo.FunctionSize + tinfo.FunctionSize
+ HasEffect = dinfo.HasEffect || tinfo.HasEffect
+ MightMakeCriticalTailcall=tinfo.MightMakeCriticalTailcall // discard tailcall info from decision tree since it's not in tailcall position
Info= UnknownValue }
and RebuildOptimizedMatch (spMatch,exprm,m,ty,dtree,tgs,dinfo,tinfos) =
@@ -2879,17 +2835,16 @@ and RebuildOptimizedMatch (spMatch,exprm,m,ty,dtree,tgs,dinfo,tinfos) =
//-------------------------------------------------------------------------
and OptimizeDecisionTreeTarget cenv env _m (TTarget(vs,e,spTarget)) =
- if verboseOptimizations then dprintf "OptimizeDecisionTreeTarget\n";
(* REVIEW: this is where we should be using information collected for each target *)
let env = BindInternalValsToUnknown cenv vs env
let e',einfo = OptimizeExpr cenv env e
let e',einfo = ConsiderSplitToMethod cenv.settings.abstractBigTargets cenv.settings.bigTargetSize cenv env (e',einfo)
let evalue' = AbstractExprInfoByVars (FlatList.toList vs,[]) einfo.Info
TTarget(vs,e',spTarget),
- { TotalSize=einfo.TotalSize;
- FunctionSize=einfo.FunctionSize;
- HasEffect=einfo.HasEffect;
- MightMakeCriticalTailcall = einfo.MightMakeCriticalTailcall;
+ { TotalSize=einfo.TotalSize
+ FunctionSize=einfo.FunctionSize
+ HasEffect=einfo.HasEffect
+ MightMakeCriticalTailcall = einfo.MightMakeCriticalTailcall
Info=evalue' }
//-------------------------------------------------------------------------
@@ -2943,7 +2898,6 @@ and TryOptimizeDecisionTreeTest cenv test vinfo =
/// Optimize/analyze a switch construct from pattern matching
and OptimizeSwitch cenv env (e,cases,dflt,m) =
- if verboseOptimizations then dprintf "OptimizeSwitch\n";
let e', einfo = OptimizeExpr cenv env e
let cases,dflt =
@@ -2972,7 +2926,6 @@ and OptimizeSwitchFallback cenv env (e', einfo, cases,dflt,m) =
and OptimizeBinding cenv isRec env (TBind(v,e,spBind)) =
try
- if verboseOptimizations then dprintf "OptimizeBinding\n";
// The aim here is to stop method splitting for direct-self-tailcalls. We do more than that: if an expression
// occurs in the body of recursively defined values RVS, then we refuse to split
@@ -2995,12 +2948,12 @@ and OptimizeBinding cenv isRec env (TBind(v,e,spBind)) =
match ivalue with
| CurriedLambdaValue (_, arities, size, body,_) ->
if size > (cenv.settings.lambdaInlineThreshold + arities + 2) then
- if verboseOptimizations then dprintf "Discarding lambda for binding %s, size = %d, m = %a\n" v.LogicalName size outputRange body.Range;
+ // Discarding lambda for binding v.LogicalName
UnknownValue (* trim large *)
else
let fvs = freeInExpr CollectLocals body
if fvs.UsesMethodLocalConstructs then
- if verboseOptimizations then dprintf "Discarding lambda for binding %s because uses protected members, m = %a\n" v.LogicalName outputRange body.Range;
+ // Discarding lambda for bindingbecause uses protected members
UnknownValue (* trim protected *)
else
ivalue
@@ -3061,15 +3014,12 @@ and OptimizeBinding cenv isRec env (TBind(v,e,spBind)) =
then {einfo with Info=UnknownValue}
else einfo
if v.MustInline && IsPartialExprVal einfo.Info then
- errorR(InternalError("the mustinline value '"^v.LogicalName^"' was not inferred to have a known value",v.Range));
-#if DEBUG
- if verboseOptimizations then dprintf "val %s gets opt info %s\n" (showL(valL v)) (showL(exprValueInfoL cenv.g einfo.Info));
-#endif
+ errorR(InternalError("the mustinline value '"+v.LogicalName+"' was not inferred to have a known value",v.Range))
let env = BindInternalLocalVal cenv v (mkValInfo einfo v) env
(TBind(v,repr',spBind), einfo), env
with exn ->
- errorRecovery exn v.Range;
+ errorRecovery exn v.Range
raise (ReportedError (Some exn))
and OptimizeBindings cenv isRec env xs = FlatList.mapFold (OptimizeBinding cenv isRec) env xs
@@ -3102,7 +3052,7 @@ and OptimizeModuleExpr cenv env x =
// Check the thing is not compiled as a static field or property, since reflected definitions and other reflective stuff might need it
not (IsCompiledAsStaticProperty cenv.g bind.Var))
- if verboseOptimizations then dead |> List.iter (fun (bind,_) -> dprintf "dead, hidden, buried, gone: %s\n" (showL (vspecAtBindL bind.Var)));
+
let deadSet = Zset.addList (dead |> List.map (fun (bind,_) -> bind.Var)) (Zset.empty valOrder)
// Eliminate dead private bindings from a module type by mutation. Note that the optimizer doesn't
@@ -3120,7 +3070,7 @@ and OptimizeModuleExpr cenv env x =
vals= (mtyp.AllValsAndMembers |> QueueList.filter (Zset.memberOf deadSet >> not)),
entities= mtyp.AllEntities)
mtyp.ModuleAndNamespaceDefinitions |> List.iter (fun mspec -> elimModSpec mspec)
- mty;
+ mty
and elimModSpec (mspec:ModuleOrNamespace) =
let mtyp = elimModTy mspec.ModuleOrNamespaceType
mspec.Data.entity_modul_contents <- notlazy mtyp
@@ -3167,7 +3117,7 @@ and OptimizeModuleDef cenv (env,bindInfosColl) x =
(* REVIEW: Eliminate let bindings on the way back up *)
(TMDefRec(isRec,tycons,mbinds,m),
- notlazy { ValInfos= ValInfos(FlatList.map2 (fun bind binfo -> mkValBind bind (mkValInfo binfo bind.Var)) binds binfos);
+ notlazy { ValInfos= ValInfos(FlatList.map2 (fun bind binfo -> mkValBind bind (mkValInfo binfo bind.Var)) binds binfos)
ModuleOrNamespaceInfos = NameMap.ofList minfos}),
(env,bindInfosColl)
| TMAbstract(mexpr) ->
@@ -3178,7 +3128,7 @@ and OptimizeModuleDef cenv (env,bindInfosColl) x =
let ((bind',binfo) as bindInfo),env = OptimizeBinding cenv false env bind
(* REVIEW: Eliminate unused let bindings from modules *)
(TMDefLet(bind',m),
- notlazy { ValInfos=ValInfos [mkValBind bind (mkValInfo binfo bind.Var)];
+ notlazy { ValInfos=ValInfos [mkValBind bind (mkValInfo binfo bind.Var)]
ModuleOrNamespaceInfos = NameMap.ofList []}),
(env ,([bindInfo]::bindInfosColl))
@@ -3205,7 +3155,6 @@ and OptimizeModuleBinding cenv (env,bindInfosColl) x =
(env,bindInfosColl)
and OptimizeModuleDefs cenv (env,bindInfosColl) defs =
- if verboseOptimizations then dprintf "OptimizeModuleDefs\n";
let defs,(env,bindInfosColl) = List.mapFold (OptimizeModuleDef cenv) (env,bindInfosColl) defs
let defs,minfos = List.unzip defs
(defs,UnionOptimizationInfos minfos),(env,bindInfosColl)
@@ -3237,14 +3186,14 @@ and OptimizeImplFileInternal cenv env isIncrementalFragment hidden (TImplFile(qn
let OptimizeImplFile(settings,ccu,tcGlobals,tcVal, importMap,optEnv,isIncrementalFragment,emitTailcalls,hidden,mimpls) =
let cenv =
- { settings=settings;
- scope=ccu;
+ { settings=settings
+ scope=ccu
TcVal = tcVal
- g=tcGlobals;
- amap=importMap;
- optimizing=true;
- localInternalVals=new System.Collections.Generic.Dictionary(10000);
- emitTailcalls=emitTailcalls;
+ g=tcGlobals
+ amap=importMap
+ optimizing=true
+ localInternalVals=new System.Collections.Generic.Dictionary(10000)
+ emitTailcalls=emitTailcalls
casApplied=new Dictionary() }
OptimizeImplFileInternal cenv optEnv isIncrementalFragment hidden mimpls
diff --git a/src/fsharp/PatternMatchCompilation.fs b/src/fsharp/PatternMatchCompilation.fs
index 0dae5cdfbf2..55632d51a68 100644
--- a/src/fsharp/PatternMatchCompilation.fs
+++ b/src/fsharp/PatternMatchCompilation.fs
@@ -310,7 +310,7 @@ let ShowCounterExample g denv m refuted =
match refutations with
| [] -> raise CannotRefute
| h :: t ->
- if verbose then dprintf "h = %s\n" (Layout.showL (exprL h));
+ if verbose then dprintf "h = %s\n" (Layout.showL (exprL h))
List.fold (CombineRefutations g) h t
let text = Layout.showL (NicePrint.dataExprL denv counterExample)
let failingWhenClause = refuted |> List.exists (function RefutedWhenClause -> true | _ -> false)
@@ -320,7 +320,7 @@ let ShowCounterExample g denv m refuted =
| CannotRefute ->
None
| e ->
- warning(InternalError(sprintf "" (e.ToString()),m));
+ warning(InternalError(sprintf "" (e.ToString()),m))
None
//---------------------------------------------------------------------------
@@ -375,7 +375,7 @@ let getDiscrimOfPattern g tpinst t =
| TPat_array (args,ty,_m) ->
Some(Test.ArrayLength (args.Length,ty))
| TPat_query ((pexp,resTys,apatVrefOpt,idx,apinfo),_,_m) ->
- Some(Test.ActivePatternCase (pexp, instTypes tpinst resTys, apatVrefOpt,idx,apinfo))
+ Some(Test.ActivePatternCase (pexp, instTypes tpinst resTys, apatVrefOpt, idx, apinfo))
| _ -> None
let constOfDiscrim discrim =
@@ -493,8 +493,8 @@ let (|ListEmptyDiscrim|_|) g = function
/// - Compact integer switches become a single switch. Non-compact integer
/// switches, string switches and floating point switches are treated in the
/// same way as Test.IsInst.
-let rec BuildSwitch resPreBindOpt g expr edges dflt m =
- if verbose then dprintf "--> BuildSwitch@%a, #edges = %A, dflt.IsSome = %A\n" outputRange m (List.length edges) (Option.isSome dflt);
+let rec BuildSwitch inpExprOpt g expr edges dflt m =
+ if verbose then dprintf "--> BuildSwitch@%a, #edges = %A, dflt.IsSome = %A\n" outputRange m (List.length edges) (Option.isSome dflt)
match edges,dflt with
| [], None -> failwith "internal error: no edges and no default"
| [], Some dflt -> dflt (* NOTE: first time around, edges<>[] *)
@@ -505,12 +505,12 @@ let rec BuildSwitch resPreBindOpt g expr edges dflt m =
// 'isinst' tests where we have stored the result of the 'isinst' in a variable
// In this case the 'expr' already holds the result of the 'isinst' test.
- | (TCase(Test.IsInst _,success)):: edges, dflt when isSome resPreBindOpt ->
+ | (TCase(Test.IsInst _,success)):: edges, dflt when isSome inpExprOpt ->
TDSwitch(expr,[TCase(Test.IsNull,BuildSwitch None g expr edges dflt m)],Some success,m)
// isnull and isinst tests
| (TCase((Test.IsNull | Test.IsInst _),_) as edge):: edges, dflt ->
- TDSwitch(expr,[edge],Some (BuildSwitch resPreBindOpt g expr edges dflt m),m)
+ TDSwitch(expr,[edge],Some (BuildSwitch inpExprOpt g expr edges dflt m),m)
#if OPTIMIZE_LIST_MATCHING
// 'cons/nil' tests where we have stored the result of the cons test in an 'isinst' in a variable
@@ -519,7 +519,7 @@ let rec BuildSwitch resPreBindOpt g expr edges dflt m =
| [TCase(ListEmptyDiscrim g tinst, emptyCase)], Some consCase
| [TCase(ListEmptyDiscrim g _, emptyCase); TCase(ListConsDiscrim g tinst, consCase)], None
| [TCase(ListConsDiscrim g tinst, consCase); TCase(ListEmptyDiscrim g _, emptyCase)], None
- when isSome resPreBindOpt ->
+ when isSome inpExprOpt ->
TDSwitch(expr, [TCase(Test.IsNull, emptyCase)], Some consCase, m)
#endif
@@ -562,7 +562,6 @@ let rec BuildSwitch resPreBindOpt g expr edges dflt m =
| _ -> failwith "illtyped term during pattern compilation"
let edges' = List.sortWith edgeCompare edges
let rec compactify curr edges =
- if debug then dprintf "--> compactify@%a\n" outputRange m;
match curr,edges with
| None,[] -> []
| Some last,[] -> [List.rev last]
@@ -592,7 +591,7 @@ let rec BuildSwitch resPreBindOpt g expr edges dflt m =
// For a total pattern match, run the active pattern, bind the result and
// recursively build a switch in the choice type
| (TCase(Test.ActivePatternCase _,_)::_), _ ->
- error(InternalError("Test.ActivePatternCase should have been eliminated",m));
+ error(InternalError("Test.ActivePatternCase should have been eliminated",m))
// For a complete match, optimize one test to be the default
| (TCase(_,tree)::rest), None -> TDSwitch (expr,rest,Some tree,m)
@@ -602,7 +601,6 @@ let rec BuildSwitch resPreBindOpt g expr edges dflt m =
#if DEBUG
let rec layoutPat pat =
- if debug then dprintf "--> layoutPat\n";
match pat with
| TPat_query (_,pat,_) -> Layout.(--) (Layout.wordL "query") (layoutPat pat)
| TPat_wild _ -> Layout.wordL "wild"
@@ -696,9 +694,9 @@ let CompilePatternBasic
if warnOnIncomplete then
match actionOnFailure with
| ThrowIncompleteMatchException ->
- warning (MatchIncomplete (false,ShowCounterExample g denv matchm refuted, matchm));
+ warning (MatchIncomplete (false,ShowCounterExample g denv matchm refuted, matchm))
| IgnoreWithWarning ->
- warning (MatchIncomplete (true,ShowCounterExample g denv matchm refuted, matchm));
+ warning (MatchIncomplete (true,ShowCounterExample g denv matchm refuted, matchm))
| _ ->
()
@@ -722,8 +720,8 @@ let CompilePatternBasic
| ThrowIncompleteMatchException ->
mkThrow matchm resultTy
(mkExnExpr(mk_MFCore_tcref g.fslibCcu "MatchFailureException",
- [ mkString g matchm matchm.FileName;
- mkInt g matchm matchm.StartLine;
+ [ mkString g matchm matchm.FileName
+ mkInt g matchm matchm.StartLine
mkInt g matchm matchm.StartColumn],matchm))
| IgnoreWithWarning ->
@@ -737,9 +735,9 @@ let CompilePatternBasic
// will run the handler and hit the sequence point there.
// That sequence point will have the pattern variables bound, which is exactly what we want.
let tg = TTarget(FlatList.empty,throwExpr,SuppressSequencePointAtTarget )
- mbuilder.AddTarget tg |> ignore;
+ mbuilder.AddTarget tg |> ignore
let clause = TClause(TPat_wild matchm,None,tg,matchm)
- incompleteMatchClauseOnce := Some(clause);
+ incompleteMatchClauseOnce := Some(clause)
clause
| Some c -> c
@@ -769,7 +767,6 @@ let CompilePatternBasic
// The main recursive loop of the pattern match compiler
let rec InvestigateFrontiers refuted frontiers =
- if debug then dprintf "frontiers = %s\n" (String.concat ";" (List.map (getRuleIndex >> string) frontiers));
match frontiers with
| [] -> failwith "CompilePattern:compile - empty clauses: at least the final clause should always succeed"
| (Frontier (i,active,valMap)) :: rest ->
@@ -779,7 +776,6 @@ let CompilePatternBasic
| [] -> CompileSuccessPointAndGuard i refuted valMap rest
| _ ->
- if debug then dprintf "Investigating based on rule %d, #active = %d\n" i (List.length active);
(* Otherwise choose a point (i.e. a path) to investigate. *)
let (Active(path,subexpr,pat)) = ChooseInvestigationPointLeftToRight frontiers
match pat with
@@ -789,21 +785,14 @@ let CompilePatternBasic
// Leaving the ones where we have real work to do
| _ ->
- if debug then dprintf "chooseSimultaneousEdgeSet\n";
let simulSetOfEdgeDiscrims,fallthroughPathFrontiers = ChooseSimultaneousEdges frontiers path
- let resPreBindOpt, bindOpt = ChoosePreBinder simulSetOfEdgeDiscrims subexpr
+ let inpExprOpt, bindOpt = ChoosePreBinder simulSetOfEdgeDiscrims subexpr
// For each case, recursively compile the residue decision trees that result if that case successfully matches
- let simulSetOfCases, _ = CompileSimultaneousSet frontiers path refuted subexpr simulSetOfEdgeDiscrims resPreBindOpt
+ let simulSetOfCases, _ = CompileSimultaneousSet frontiers path refuted subexpr simulSetOfEdgeDiscrims inpExprOpt
- assert (nonNil(simulSetOfCases));
-
- if debug then
- dprintf "#fallthroughPathFrontiers = %d, #simulSetOfEdgeDiscrims = %d\n" (List.length fallthroughPathFrontiers) (List.length simulSetOfEdgeDiscrims);
- dprintf "Making cases for each discriminator...\n";
- dprintf "#edges = %d\n" (List.length simulSetOfCases);
- dprintf "Checking for completeness of edge set from earlier investigation of rule %d, #active = %d\n" i (List.length active);
+ assert (nonNil(simulSetOfCases))
// Work out what the default/fall-through tree looks like, is any
// Check if match is complete, if so optimize the default case away.
@@ -812,8 +801,8 @@ let CompilePatternBasic
// OK, build the whole tree and whack on the binding if any
let finalDecisionTree =
- let inpExprToSwitch = (match resPreBindOpt with Some vexp -> vexp | None -> GetSubExprOfInput subexpr)
- let tree = BuildSwitch resPreBindOpt g inpExprToSwitch simulSetOfCases defaultTreeOpt matchm
+ let inpExprToSwitch = (match inpExprOpt with Some vexp -> vexp | None -> GetSubExprOfInput subexpr)
+ let tree = BuildSwitch inpExprOpt g inpExprToSwitch simulSetOfCases defaultTreeOpt matchm
match bindOpt with
| None -> tree
| Some bind -> TDBind (bind,tree)
@@ -822,7 +811,6 @@ let CompilePatternBasic
and CompileSuccessPointAndGuard i refuted valMap rest =
- if debug then dprintf "generating success node for rule %d\n" i;
let vs2 = GetValsBoundByClause i refuted
let es2 =
vs2 |> FlatList.map (fun v ->
@@ -832,7 +820,6 @@ let CompilePatternBasic
let rhs' = TDSuccess(es2, i)
match GetWhenGuardOfClause i refuted with
| Some whenExpr ->
- if debug then dprintf "generating success node for rule %d, with 'when' clause\n" i;
let m = whenExpr.Range
@@ -856,16 +843,14 @@ let CompilePatternBasic
/// Record the rule numbers so we know which rule the TPat_query cam from, so that when we project through
/// the frontier we only project the right rule.
and ChooseSimultaneousEdges frontiers path =
- if debug then dprintf "chooseSimultaneousEdgeSet\n";
frontiers |> chooseSimultaneousEdgeSet None (fun prevOpt (Frontier (i',active',_)) ->
if isMemOfActives path active' then
let p = lookupActive path active' |> snd
match getDiscrimOfPattern p with
| Some discrim ->
- if (match prevOpt with None -> true | Some (EdgeDiscrim(_,discrimPrev,_)) -> discrimsHaveSameSimultaneousClass g discrim discrimPrev) then (
- if debug then dprintf "taking rule %d\n" i';
+ if (match prevOpt with None -> true | Some (EdgeDiscrim(_,discrimPrev,_)) -> discrimsHaveSameSimultaneousClass g discrim discrimPrev) then
Some (EdgeDiscrim(i',discrim,p.Range)),true
- ) else
+ else
None,false
| None ->
@@ -892,11 +877,26 @@ let CompilePatternBasic
let v,vexp = mkCompGenLocal m "typeTestResult" tgty
if topv.IsMemberOrModuleBinding then
- AdjustValToTopVal v topv.ActualParent ValReprInfo.emptyValData;
+ AdjustValToTopVal v topv.ActualParent ValReprInfo.emptyValData
let argexp = GetSubExprOfInput subexpr
let appexp = mkIsInst tgty argexp matchm
Some(vexp),Some(mkInvisibleBind v appexp)
+ // Any match on a struct union must take the address of its input
+ | EdgeDiscrim(_i',(Test.UnionCase (ucref, _)),_) :: _rest
+ when (isNil topgtvs && ucref.Tycon.IsStructRecordOrUnionTycon) ->
+
+ let argexp = GetSubExprOfInput subexpr
+ let vOpt,addrexp = mkExprAddrOfExprAux g true false NeverMutates argexp None matchm
+ match vOpt with
+ | None -> Some addrexp, None
+ | Some (v,e) ->
+ if topv.IsMemberOrModuleBinding then
+ AdjustValToTopVal v topv.ActualParent ValReprInfo.emptyValData
+ Some addrexp, Some (mkInvisibleBind v e)
+
+
+
#if OPTIMIZE_LIST_MATCHING
| [EdgeDiscrim(_, ListConsDiscrim g tinst,m); EdgeDiscrim(_, ListEmptyDiscrim g _, _)]
| [EdgeDiscrim(_, ListEmptyDiscrim g _, _); EdgeDiscrim(_, ListConsDiscrim g tinst, m)]
@@ -908,21 +908,20 @@ let CompilePatternBasic
let ucaseTy = (mkProvenUnionCaseTy g.cons_ucref tinst)
let v,vexp = mkCompGenLocal m "unionTestResult" ucaseTy
if topv.IsMemberOrModuleBinding then
- AdjustValToTopVal v topv.ActualParent ValReprInfo.emptyValData;
+ AdjustValToTopVal v topv.ActualParent ValReprInfo.emptyValData
let argexp = GetSubExprOfInput subexpr
let appexp = mkIsInst ucaseTy argexp matchm
Some vexp,Some (mkInvisibleBind v appexp)
#endif
// Active pattern matches: create a variable to hold the results of executing the active pattern.
- | (EdgeDiscrim(_,(Test.ActivePatternCase(pexp,resTys,_resPreBindOpt,_,apinfo)),m) :: _) ->
- if debug then dprintf "Building result var for active pattern...\n";
+ | (EdgeDiscrim(_,(Test.ActivePatternCase(pexp,resTys,_,_,apinfo)),m) :: _) ->
- if nonNil topgtvs then error(InternalError("Unexpected generalized type variables when compiling an active pattern",m));
+ if nonNil topgtvs then error(InternalError("Unexpected generalized type variables when compiling an active pattern",m))
let rty = apinfo.ResultType g m resTys
let v,vexp = mkCompGenLocal m "activePatternResult" rty
if topv.IsMemberOrModuleBinding then
- AdjustValToTopVal v topv.ActualParent ValReprInfo.emptyValData;
+ AdjustValToTopVal v topv.ActualParent ValReprInfo.emptyValData
let argexp = GetSubExprOfInput subexpr
let appexp = mkApps g ((pexp,tyOfExpr g pexp), [], [argexp],m)
@@ -930,7 +929,7 @@ let CompilePatternBasic
| _ -> None,None
- and CompileSimultaneousSet frontiers path refuted subexpr simulSetOfEdgeDiscrims (resPreBindOpt: Expr option) =
+ and CompileSimultaneousSet frontiers path refuted subexpr simulSetOfEdgeDiscrims (inpExprOpt: Expr option) =
([],simulSetOfEdgeDiscrims) ||> List.collectFold (fun taken (EdgeDiscrim(i',discrim,m)) ->
// Check to see if we've already collected the edge for this case, in which case skip it.
@@ -953,17 +952,18 @@ let CompilePatternBasic
match discrim with
| Test.UnionCase (ucref, tinst) when
#if OPTIMIZE_LIST_MATCHING
- isNone resPreBindOpt &&
+ isNone inpExprOpt &&
#endif
(isNil topgtvs &&
not topv.IsMemberOrModuleBinding &&
+ not ucref.Tycon.IsStructRecordOrUnionTycon &&
ucref.UnionCase.RecdFields.Length >= 1 &&
ucref.Tycon.UnionCasesArray.Length > 1) ->
let v,vexp = mkCompGenLocal m "unionCase" (mkProvenUnionCaseTy ucref tinst)
let argexp = GetSubExprOfInput subexpr
- let appexp = mkUnionCaseProof(argexp, ucref,tinst,m)
- Some(vexp),Some(mkInvisibleBind v appexp)
+ let appexp = mkUnionCaseProof (argexp, ucref,tinst,m)
+ Some vexp,Some(mkInvisibleBind v appexp)
| _ ->
None,None
@@ -974,7 +974,7 @@ let CompilePatternBasic
let aparity = apinfo.Names.Length
let total = apinfo.IsTotal
if not total && aparity > 1 then
- error(Error(FSComp.SR.patcPartialActivePatternsGenerateOneResult(),m));
+ error(Error(FSComp.SR.patcPartialActivePatternsGenerateOneResult(),m))
if not total then Test.UnionCase(mkSomeCase g,resTys)
elif aparity <= 1 then Test.Const(Const.Unit)
@@ -984,7 +984,7 @@ let CompilePatternBasic
// Project a successful edge through the frontiers.
let investigation = Investigation(i',discrim,path)
- let frontiers = frontiers |> List.collect (GenerateNewFrontiersAfterSucccessfulInvestigation resPreBindOpt resPostBindOpt investigation)
+ let frontiers = frontiers |> List.collect (GenerateNewFrontiersAfterSucccessfulInvestigation inpExprOpt resPostBindOpt investigation)
let tree = InvestigateFrontiers refuted frontiers
// Bind the resVar for the union case, if we have one
let tree =
@@ -1017,7 +1017,6 @@ let CompilePatternBasic
(* Add to the refuted set *)
let refuted = (RefutedInvestigation(path,simulSetOfDiscrims)) :: refuted
- if debug then dprintf "Edge set was incomplete. Compiling remaining cases\n";
match fallthroughPathFrontiers with
| [] ->
None
@@ -1026,12 +1025,10 @@ let CompilePatternBasic
// Build a new frontier that represents the result of a successful investigation
// at rule point (i',discrim,path)
- and GenerateNewFrontiersAfterSucccessfulInvestigation resPreBindOpt resPostBindOpt (Investigation(i',discrim,path)) (Frontier (i, active,valMap) as frontier) =
- if debug then dprintf "projecting success of investigation encompassing rule %d through rule %d \n" i' i;
+ and GenerateNewFrontiersAfterSucccessfulInvestigation inpExprOpt resPostBindOpt (Investigation(i',discrim,path)) (Frontier (i, active,valMap) as frontier) =
if (isMemOfActives path active) then
let (SubExpr(accessf,ve)),pat = lookupActive path active
- if debug then dprintf "active...\n";
let mkSubFrontiers path accessf' active' argpats pathBuilder =
let mkSubActive j p =
@@ -1052,11 +1049,14 @@ let CompilePatternBasic
if (hasParam && i = i') || (discrimsEq g discrim (Option.get (getDiscrimOfPattern pat))) then
let aparity = apinfo.Names.Length
let accessf' j tpinst _e' =
+ assert inpExprOpt.IsSome
if aparity <= 1 then
- Option.get resPreBindOpt
+ Option.get inpExprOpt
else
let ucref = mkChoiceCaseRef g m aparity idx
- mkUnionCaseFieldGetUnproven(Option.get resPreBindOpt,ucref,instTypes tpinst resTys,j,exprm)
+ // TODO: In the future we will want active patterns to be able to return struct-unions
+ // In that eventuality, we need to check we are taking the address correctly
+ mkUnionCaseFieldGetUnprovenViaExprAddr (Option.get inpExprOpt,ucref,instTypes tpinst resTys,j,exprm)
mkSubFrontiers path accessf' active' [p] (fun path j -> PathQuery(path,int64 j))
elif hasParam then
@@ -1068,7 +1068,9 @@ let CompilePatternBasic
else
if i = i' then
let accessf' _j tpinst _ =
- mkUnionCaseFieldGetUnproven(Option.get resPreBindOpt, mkSomeCase g, instTypes tpinst resTys, 0, exprm)
+ // TODO: In the future we will want active patterns to be able to return struct-unions
+ // In that eventuality, we need to check we are taking the address correctly
+ mkUnionCaseFieldGetUnprovenViaExprAddr (Option.get inpExprOpt, mkSomeCase g, instTypes tpinst resTys, 0, exprm)
mkSubFrontiers path accessf' active' [p] (fun path j -> PathQuery(path,int64 j))
else
// Successful active patterns don't refute other patterns
@@ -1077,15 +1079,15 @@ let CompilePatternBasic
| TPat_unioncase (ucref1, tyargs, argpats,_) ->
match discrim with
| Test.UnionCase (ucref2, tinst) when g.unionCaseRefEq ucref1 ucref2 ->
- let accessf' j tpinst e' =
-#if OPTIMIZE_LIST_MATCHING
- match resPreBindOpt with
- | Some e -> mkUnionCaseFieldGetProven(e,ucref1,tinst,j,exprm)
- | None ->
-#endif
+ let accessf' j tpinst exprIn =
match resPostBindOpt with
- | Some e -> mkUnionCaseFieldGetProven(e,ucref1,tinst,j,exprm)
- | None -> mkUnionCaseFieldGetUnproven(accessf tpinst e',ucref1,instTypes tpinst tyargs,j,exprm)
+ | Some e -> mkUnionCaseFieldGetProvenViaExprAddr (e,ucref1,tinst,j,exprm)
+ | None ->
+ let exprIn =
+ match inpExprOpt with
+ | Some addrexp -> addrexp
+ | None -> accessf tpinst exprIn
+ mkUnionCaseFieldGetUnprovenViaExprAddr (exprIn,ucref1,instTypes tpinst tyargs,j,exprm)
mkSubFrontiers path accessf' active' argpats (fun path j -> PathUnionConstr(path,ucref1,tyargs,j))
| Test.UnionCase _ ->
@@ -1098,7 +1100,7 @@ let CompilePatternBasic
| TPat_array (argpats,ty,_) ->
match discrim with
| Test.ArrayLength (n,_) when List.length argpats = n ->
- let accessf' j tpinst e' = mkCallArrayGet g exprm ty (accessf tpinst e') (mkInt g exprm j)
+ let accessf' j tpinst exprIn = mkCallArrayGet g exprm ty (accessf tpinst exprIn) (mkInt g exprm j)
mkSubFrontiers path accessf' active' argpats (fun path j -> PathArray(path,ty,List.length argpats,j))
// Successful length tests refute all other lengths
| Test.ArrayLength _ ->
@@ -1109,7 +1111,7 @@ let CompilePatternBasic
| TPat_exnconstr (ecref, argpats,_) ->
match discrim with
| Test.IsInst (_srcTy,tgtTy) when typeEquiv g (mkAppTy ecref []) tgtTy ->
- let accessf' j tpinst e' = mkExnCaseFieldGet(accessf tpinst e',ecref,j,exprm)
+ let accessf' j tpinst exprIn = mkExnCaseFieldGet(accessf tpinst exprIn,ecref,j,exprm)
mkSubFrontiers path accessf' active' argpats (fun path j -> PathExnConstr(path,ecref,j))
| _ ->
// Successful type tests against one sealed type refute all other sealed types
@@ -1121,16 +1123,16 @@ let CompilePatternBasic
| Test.IsInst (_srcTy,tgtTy2) when typeEquiv g tgtTy1 tgtTy2 ->
match pbindOpt with
| Some pbind ->
- let accessf' tpinst e' =
+ let accessf' tpinst exprIn =
// Fetch the result from the place where we saved it, if possible
- match resPreBindOpt with
+ match inpExprOpt with
| Some e -> e
| _ ->
// Otherwise call the helper
- mkCallUnboxFast g exprm (instType tpinst tgtTy1) (accessf tpinst e')
+ mkCallUnboxFast g exprm (instType tpinst tgtTy1) (accessf tpinst exprIn)
- let (v,e') = BindSubExprOfInput g amap topgtvs pbind exprm (SubExpr(accessf',ve))
- [Frontier (i, active', valMap.Add v e' )]
+ let (v,exprIn) = BindSubExprOfInput g amap topgtvs pbind exprm (SubExpr(accessf',ve))
+ [Frontier (i, active', valMap.Add v exprIn )]
| None ->
[Frontier (i, active', valMap)]
@@ -1169,17 +1171,17 @@ let CompilePatternBasic
| TPat_wild _ ->
BindProjectionPatterns [] s
| TPat_as(p',pbind,m) ->
- let (v,e') = BindSubExprOfInput g amap topgtvs pbind m subExpr
- BindProjectionPattern (Active(path,subExpr,p')) (accActive,accValMap.Add v e' )
+ let (v,subExpr') = BindSubExprOfInput g amap topgtvs pbind m subExpr
+ BindProjectionPattern (Active(path,subExpr,p')) (accActive,accValMap.Add v subExpr' )
| TPat_tuple(ps,tyargs,_m) ->
- let accessf' j tpinst e' = mkTupleFieldGet(accessf tpinst e',instTypes tpinst tyargs,j,exprm)
+ let accessf' j tpinst exprIn = mkTupleFieldGet(accessf tpinst exprIn,instTypes tpinst tyargs,j,exprm)
let pathBuilder path j = PathTuple(path,tyargs,j)
let newActives = List.mapi (mkSubActive pathBuilder accessf') ps
BindProjectionPatterns newActives s
| TPat_recd(tcref,tinst,ps,_m) ->
let newActives =
(ps,tcref.TrueInstanceFieldsAsRefList) ||> List.mapi2 (fun j p fref ->
- let accessf' fref _j tpinst e' = mkRecdFieldGet g (accessf tpinst e',fref,instTypes tpinst tinst,exprm)
+ let accessf' fref _j tpinst exprIn = mkRecdFieldGet g (accessf tpinst exprIn,fref,instTypes tpinst tinst,exprm)
let pathBuilder path j = PathRecd(path,tcref,tinst,j)
mkSubActive pathBuilder (accessf' fref) j p)
BindProjectionPatterns newActives s
@@ -1252,7 +1254,6 @@ let rec CompilePattern g denv amap exprm matchm warnOnUnused actionOnFailure (t
let warnOnIncomplete = false
let rec atMostOnePartialAtATime clauses =
- if debug then dprintf "atMostOnePartialAtATime: #clauses = %A\n" clauses;
match List.takeUntil isPartialOrWhenClause clauses with
| l,[] ->
CompilePatternBasic g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (topv,topgtvs) l inputTy resultTy
@@ -1261,7 +1262,6 @@ let rec CompilePattern g denv amap exprm matchm warnOnUnused actionOnFailure (t
doGroupWithAtMostOnePartial (l @ [h]) t
and doGroupWithAtMostOnePartial group rest =
- if debug then dprintf "doGroupWithAtMostOnePartial: #group = %A\n" group;
// Compile the remaining clauses
let dtree,targets = atMostOnePartialAtATime rest
diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs
index d9ea90e1715..8b5987bb899 100644
--- a/src/fsharp/PostInferenceChecks.fs
+++ b/src/fsharp/PostInferenceChecks.fs
@@ -133,11 +133,11 @@ type env =
{ boundTyparNames: string list
boundTypars: TyparMap
/// "module remap info", i.e. hiding information down the signature chain, used to compute what's hidden by a signature
- sigToImplRemapInfo: (Remap * SignatureHidingInfo) list;
+ sigToImplRemapInfo: (Remap * SignatureHidingInfo) list
/// Constructor limited - are we in the prelude of a constructor, prior to object initialization
- limited: bool;
+ limited: bool
/// Are we in a quotation?
- quote : bool;
+ quote : bool
/// Are we under []?
reflect : bool }
@@ -153,21 +153,21 @@ let BindTypars g env (tps:Typar list) =
let nms = PrettyTypes.PrettyTyparNames (fun _ -> true) env.boundTyparNames tps
(tps,nms) ||> List.iter2 (fun tp nm ->
if PrettyTypes.NeedsPrettyTyparName tp then
- tp.Data.typar_id <- ident (nm,tp.Range));
+ tp.Data.typar_id <- ident (nm,tp.Range))
List.fold BindTypar env tps
type cenv =
- { boundVals: Dictionary; // really a hash set
- mutable potentialUnboundUsesOfVals: StampMap;
- g: TcGlobals;
- amap: Import.ImportMap;
+ { boundVals: Dictionary // really a hash set
+ mutable potentialUnboundUsesOfVals: StampMap
+ g: TcGlobals
+ amap: Import.ImportMap
/// For reading metadata
- infoReader: InfoReader;
- internalsVisibleToPaths : CompilationPath list;
- denv: DisplayEnv;
- viewCcu : CcuThunk;
- reportErrors: bool;
- isLastCompiland : bool*bool;
+ infoReader: InfoReader
+ internalsVisibleToPaths : CompilationPath list
+ denv: DisplayEnv
+ viewCcu : CcuThunk
+ reportErrors: bool
+ isLastCompiland : bool*bool
// outputs
mutable usesQuotations : bool
mutable entryPointGiven:bool }
@@ -220,7 +220,7 @@ let rec CheckTypeDeep ((visitTyp,visitTyconRefOpt,visitByrefsOfByrefsOpt,visitTr
match typ with
| TType_forall (tps,body) ->
let env = BindTypars g env tps
- CheckTypeDeep f g env body;
+ CheckTypeDeep f g env body
tps |> List.iter (fun tp -> tp.Constraints |> List.iter (CheckTypeConstraintDeep f g env))
| TType_measure _ -> ()
@@ -261,9 +261,9 @@ and CheckTypeConstraintDeep f g env x =
| TyparConstraint.IsReferenceType _
| TyparConstraint.RequiresDefaultConstructor _ -> ()
and CheckTraitInfoDeep ((_,_,_,visitTraitSolutionOpt,_) as f) g env (TTrait(typs,_,_,argtys,rty,soln)) =
- CheckTypesDeep f g env typs;
- CheckTypesDeep f g env argtys;
- Option.iter (CheckTypeDeep f g env) rty;
+ CheckTypesDeep f g env typs
+ CheckTypesDeep f g env argtys
+ Option.iter (CheckTypeDeep f g env) rty
match visitTraitSolutionOpt, !soln with
| Some visitTraitSolution, Some sln -> visitTraitSolution sln
| _ -> ()
@@ -465,29 +465,30 @@ let rec CheckExpr (cenv:cenv) (env:env) expr =
and CheckVal (cenv:cenv) (env:env) v m context =
if cenv.reportErrors then
- if is_splice cenv.g v && not env.quote then errorR(Error(FSComp.SR.chkSplicingOnlyInQuotations(), m));
- if is_splice cenv.g v then errorR(Error(FSComp.SR.chkNoFirstClassSplicing(), m));
- if valRefEq cenv.g v cenv.g.addrof_vref then errorR(Error(FSComp.SR.chkNoFirstClassAddressOf(), m));
- if valRefEq cenv.g v cenv.g.reraise_vref then errorR(Error(FSComp.SR.chkNoFirstClassRethrow(), m));
+ if is_splice cenv.g v && not env.quote then errorR(Error(FSComp.SR.chkSplicingOnlyInQuotations(), m))
+ if is_splice cenv.g v then errorR(Error(FSComp.SR.chkNoFirstClassSplicing(), m))
+ if valRefEq cenv.g v cenv.g.addrof_vref then errorR(Error(FSComp.SR.chkNoFirstClassAddressOf(), m))
+ if valRefEq cenv.g v cenv.g.reraise_vref then errorR(Error(FSComp.SR.chkNoFirstClassRethrow(), m))
if isByrefLikeTy cenv.g v.Type then
// byref typed val can only occur in permitting contexts
if context <> DirectArg then errorR(Error(FSComp.SR.chkNoByrefAtThisPoint(v.DisplayName), m))
CheckTypePermitByrefs cenv env m v.Type
and CheckExprInContext (cenv:cenv) (env:env) expr (context:ByrefCallContext) =
- // dprintf "CheckExpr: %s\n" (showL(exprL expr));
let expr = stripExpr expr
match expr with
| Expr.Sequential (e1,e2,dir,_,_) ->
- CheckExpr cenv env e1;
+ CheckExpr cenv env e1
match dir with
| NormalSeq -> CheckExprInContext cenv env e2 context // carry context into _;RHS (normal sequencing only)
| ThenDoSeq -> CheckExpr cenv {env with limited=false} e2
+
| Expr.Let (bind,body,_,_) ->
- CheckBinding cenv env false bind ;
+ CheckBinding cenv env false bind
BindVal cenv bind.Var
- CheckExpr cenv env body
+ CheckExprInContext cenv env body context
+
| Expr.Const (_,m,ty) ->
CheckTypePermitByrefs cenv env m ty
@@ -498,12 +499,12 @@ and CheckExprInContext (cenv:cenv) (env:env) expr (context:ByrefCallContext) =
if (match vFlags with NormalValUse -> true | _ -> false) &&
v.IsConstructor &&
(match v.ActualParent with Parent tcref -> isAbstractTycon tcref.Deref | _ -> false) then
- errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(),m));
+ errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(),m))
CheckVal cenv env v m context
| Expr.Quote(ast,savedConv,_isFromQueryExpression,m,ty) ->
- CheckExpr cenv {env with quote=true} ast;
+ CheckExpr cenv {env with quote=true} ast
if cenv.reportErrors then
cenv.usesQuotations <- true
try
@@ -519,9 +520,9 @@ and CheckExprInContext (cenv:cenv) (env:env) expr (context:ByrefCallContext) =
CheckTypeNoByrefs cenv env m ty
| Expr.Obj (_,typ,basev,superInitCall,overrides,iimpls,m) ->
- CheckExpr cenv env superInitCall;
- CheckMethods cenv env basev overrides ;
- CheckInterfaceImpls cenv env basev iimpls;
+ CheckExpr cenv env superInitCall
+ CheckMethods cenv env basev overrides
+ CheckInterfaceImpls cenv env basev iimpls
CheckTypePermitByrefs cenv env m typ
let interfaces =
[ if isInterfaceTy cenv.g typ then
@@ -538,12 +539,12 @@ and CheckExprInContext (cenv:cenv) (env:env) expr (context:ByrefCallContext) =
// dprintfn "GOT BASE VAL USE"
let memberInfo = Option.get v.MemberInfo
if memberInfo.MemberFlags.IsDispatchSlot then
- errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(v.DisplayName),m));
+ errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(v.DisplayName),m))
else
CheckVal cenv env v m GeneralContext
CheckVal cenv env baseVal m GeneralContext
- CheckTypePermitByrefs cenv env m fty;
- CheckTypeInstPermitByrefs cenv env m tyargs;
+ CheckTypePermitByrefs cenv env m fty
+ CheckTypeInstPermitByrefs cenv env m tyargs
CheckExprsInContext cenv env rest (argAritiesOfFunExpr f)
// Allow base calls to IL methods
@@ -560,13 +561,13 @@ and CheckExprInContext (cenv:cenv) (env:env) expr (context:ByrefCallContext) =
// equality. It would be better to make this check in tc.fs when we have the Abstract IL metadata for the method to hand.
let mdef = resolveILMethodRef tcref.ILTyconRawMetadata mref
if mdef.IsAbstract then
- errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(mdef.Name),m));
+ errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(mdef.Name),m))
with _ -> () // defensive coding
| _ -> ()
- CheckTypeInstNoByrefs cenv env m tyargs;
- CheckTypeInstNoByrefs cenv env m enclTypeArgs;
- CheckTypeInstNoByrefs cenv env m methTypeArgs;
- CheckTypeInstNoByrefs cenv env m tys;
+ CheckTypeInstNoByrefs cenv env m tyargs
+ CheckTypeInstNoByrefs cenv env m enclTypeArgs
+ CheckTypeInstNoByrefs cenv env m methTypeArgs
+ CheckTypeInstNoByrefs cenv env m tys
CheckVal cenv env baseVal m GeneralContext
CheckExprDirectArgs cenv env rest
@@ -582,7 +583,7 @@ and CheckExprInContext (cenv:cenv) (env:env) expr (context:ByrefCallContext) =
// Allow '%expr' in quotations
| Expr.App(Expr.Val(vref,_,_),_,tinst,[arg],m) when is_splice cenv.g vref && env.quote ->
- CheckTypeInstPermitByrefs cenv env m tinst;
+ CheckTypeInstPermitByrefs cenv env m tinst
CheckExpr cenv env arg
@@ -619,10 +620,10 @@ and CheckExprInContext (cenv:cenv) (env:env) expr (context:ByrefCallContext) =
| _ ->
()
- CheckTypeInstNoByrefs cenv env m tyargs;
- CheckTypePermitByrefs cenv env m fty;
- CheckTypeInstPermitByrefs cenv env m tyargs;
- CheckExpr cenv env f;
+ CheckTypeInstNoByrefs cenv env m tyargs
+ CheckTypePermitByrefs cenv env m fty
+ CheckTypeInstPermitByrefs cenv env m tyargs
+ CheckExpr cenv env f
CheckExprsInContext cenv env argsl (argAritiesOfFunExpr f)
(* REVIEW: fold the next two cases together *)
@@ -641,19 +642,19 @@ and CheckExprInContext (cenv:cenv) (env:env) expr (context:ByrefCallContext) =
CheckExpr cenv env e1
| Expr.Match(_,_,dtree,targets,m,ty) ->
- CheckTypeNoByrefs cenv env m ty;
- CheckDecisionTree cenv env dtree;
- CheckDecisionTreeTargets cenv env targets;
+ CheckTypePermitByrefs cenv env m ty // computed byrefs allowed at each branch
+ CheckDecisionTree cenv env dtree
+ CheckDecisionTreeTargets cenv env targets context
| Expr.LetRec (binds,e,_,_) ->
BindVals cenv (valsOfBinds binds)
- CheckBindings cenv env binds;
+ CheckBindings cenv env binds
CheckExpr cenv env e
| Expr.StaticOptimization (constraints,e2,e3,m) ->
- CheckExpr cenv env e2;
- CheckExpr cenv env e3;
+ CheckExpr cenv env e2
+ CheckExpr cenv env e3
constraints |> List.iter (function
| TTyconEqualsTycon(ty1,ty2) ->
- CheckTypeNoByrefs cenv env m ty1;
+ CheckTypeNoByrefs cenv env m ty1
CheckTypeNoByrefs cenv env m ty2
| TTyconIsStruct(ty1) ->
CheckTypeNoByrefs cenv env m ty1)
@@ -666,8 +667,8 @@ and CheckMethods cenv env baseValOpt l =
and CheckMethod cenv env baseValOpt (TObjExprMethod(_,attribs,tps,vs,e,m)) =
let env = BindTypars cenv.g env tps
let vs = List.concat vs
- CheckAttribs cenv env attribs;
- CheckNoReraise cenv None e;
+ CheckAttribs cenv env attribs
+ CheckNoReraise cenv None e
CheckEscapes cenv true m (match baseValOpt with Some x -> x:: vs | None -> vs) e |> ignore
CheckExpr cenv env e
@@ -680,41 +681,41 @@ and CheckInterfaceImpl cenv env baseValOpt (_ty,overrides) =
and CheckExprOp cenv env (op,tyargs,args,m) context =
let limitedCheck() =
- if env.limited then errorR(Error(FSComp.SR.chkObjCtorsCantUseExceptionHandling(), m));
- List.iter (CheckTypePermitByrefs cenv env m) tyargs;
+ if env.limited then errorR(Error(FSComp.SR.chkObjCtorsCantUseExceptionHandling(), m))
+ List.iter (CheckTypePermitByrefs cenv env m) tyargs
(* Special cases *)
match op,tyargs,args,context with
// Handle these as special cases since mutables are allowed inside their bodies
| TOp.While _,_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_)],_ ->
- CheckTypeInstNoByrefs cenv env m tyargs;
+ CheckTypeInstNoByrefs cenv env m tyargs
CheckExprs cenv env [e1;e2]
| TOp.TryFinally _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],e2,_,_)],_ ->
- CheckTypeInstNoByrefs cenv env m tyargs;
- limitedCheck();
+ CheckTypeInstNoByrefs cenv env m tyargs
+ limitedCheck()
CheckExprs cenv env [e1;e2]
| TOp.For(_),_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_);Expr.Lambda(_,_,_,[_],e3,_,_)],_ ->
- CheckTypeInstNoByrefs cenv env m tyargs;
+ CheckTypeInstNoByrefs cenv env m tyargs
CheckExprs cenv env [e1;e2;e3]
| TOp.TryCatch _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],_e2,_,_); Expr.Lambda(_,_,_,[_],e3,_,_)],_ ->
- CheckTypeInstNoByrefs cenv env m tyargs;
- limitedCheck();
+ CheckTypeInstNoByrefs cenv env m tyargs
+ limitedCheck()
CheckExprs cenv env [e1;(* e2; -- don't check filter body - duplicates logic in 'catch' body *) e3]
| TOp.ILCall (_,_,_,_,_,_,_,_,enclTypeArgs,methTypeArgs,tys),_,_,_ ->
- CheckTypeInstNoByrefs cenv env m tyargs;
- CheckTypeInstNoByrefs cenv env m enclTypeArgs;
- CheckTypeInstNoByrefs cenv env m methTypeArgs;
- CheckTypeInstNoByrefs cenv env m tys;
+ CheckTypeInstNoByrefs cenv env m tyargs
+ CheckTypeInstNoByrefs cenv env m enclTypeArgs
+ CheckTypeInstNoByrefs cenv env m methTypeArgs
+ CheckTypeInstNoByrefs cenv env m tys
CheckExprDirectArgs cenv env args
// Tuple expression in known tuple context
| TOp.Tuple,_,_,KnownArityTuple nArity ->
if cenv.reportErrors then
if args.Length <> nArity then
- errorR(InternalError("Tuple arity does not correspond to planned function argument arity",m));
+ errorR(InternalError("Tuple arity does not correspond to planned function argument arity",m))
// This tuple should not be generated. The known function arity
// means it just bundles arguments.
CheckExprDirectArgs cenv env args
@@ -726,36 +727,55 @@ and CheckExprOp cenv env (op,tyargs,args,m) context =
if cenv.reportErrors then
errorR(Error(FSComp.SR.chkNoAddressOfAtThisPoint(v.DisplayName), m))
| TOp.ValFieldGet _rf,_,[arg1],_arity ->
- CheckTypeInstNoByrefs cenv env m tyargs;
+ CheckTypeInstNoByrefs cenv env m tyargs
CheckExprDirectArgs cenv env [arg1] (* See mkRecdFieldGetViaExprAddr -- byref arg1 when #args =1 *)
(* Property getters on mutable structs come through here. *)
| TOp.ValFieldSet _rf,_,[arg1;arg2],_arity ->
- CheckTypeInstNoByrefs cenv env m tyargs;
- CheckExprDirectArgs cenv env [arg1]; (* See mkRecdFieldSetViaExprAddr -- byref arg1 when #args=2 *)
+ CheckTypeInstNoByrefs cenv env m tyargs
+ CheckExprDirectArgs cenv env [arg1] (* See mkRecdFieldSetViaExprAddr -- byref arg1 when #args=2 *)
CheckExprs cenv env [arg2] (* Property setters on mutable structs come through here (TBC). *)
+
| TOp.Coerce,[_ty1;_ty2],[x],_arity ->
- CheckTypeInstNoByrefs cenv env m tyargs;
+ CheckTypeInstNoByrefs cenv env m tyargs
CheckExprInContext cenv env x context
+
| TOp.Reraise,[_ty1],[],_arity ->
CheckTypeInstNoByrefs cenv env m tyargs
+
| TOp.ValFieldGetAddr rfref,tyargs,[],_ ->
if context <> DirectArg && cenv.reportErrors then
- errorR(Error(FSComp.SR.chkNoAddressStaticFieldAtThisPoint(rfref.FieldName), m));
+ errorR(Error(FSComp.SR.chkNoAddressStaticFieldAtThisPoint(rfref.FieldName), m))
CheckTypeInstNoByrefs cenv env m tyargs
(* NOTE: there are no arg exprs to check in this case *)
+
| TOp.ValFieldGetAddr rfref,tyargs,[rx],_ ->
if context <> DirectArg && cenv.reportErrors then
- errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(rfref.FieldName), m));
+ errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(rfref.FieldName), m))
(* This construct is used for &(rx.rfield) and &(rx->rfield). Relax to permit byref types for rx. [See Bug 1263]. *)
- CheckTypeInstNoByrefs cenv env m tyargs;
+ CheckTypeInstNoByrefs cenv env m tyargs
CheckExprInContext cenv env rx DirectArg (* allow rx to be byref here *)
+
+ | TOp.UnionCaseFieldGet _,_,[arg1],_arity ->
+ CheckTypeInstNoByrefs cenv env m tyargs
+ CheckExprInContext cenv env arg1 DirectArg
+
+ | TOp.UnionCaseTagGet _,_,[arg1],_arity ->
+ CheckTypeInstNoByrefs cenv env m tyargs
+ CheckExprInContext cenv env arg1 DirectArg
+
+ | TOp.UnionCaseFieldGetAddr (uref, _idx),tyargs,[rx],_ ->
+ if context <> DirectArg && cenv.reportErrors then
+ errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(uref.CaseName), m))
+ CheckTypeInstNoByrefs cenv env m tyargs
+ CheckExprInContext cenv env rx DirectArg // allow rx to be byref here
+
| TOp.ILAsm (instrs,tys),_,_,_ ->
- CheckTypeInstPermitByrefs cenv env m tys;
- CheckTypeInstNoByrefs cenv env m tyargs;
+ CheckTypeInstPermitByrefs cenv env m tys
+ CheckTypeInstNoByrefs cenv env m tyargs
begin
match instrs,args with
| [ I_stfld (_alignment,_vol,_fspec) ],[lhs;rhs] ->
- CheckExprInContext cenv env lhs DirectArg; (* permit byref for lhs lvalue *)
+ CheckExprInContext cenv env lhs DirectArg (* permit byref for lhs lvalue *)
CheckExpr cenv env rhs
| [ I_ldfld (_alignment,_vol,_fspec) ],[lhs] ->
CheckExprInContext cenv env lhs DirectArg (* permit byref for lhs lvalue *)
@@ -763,19 +783,21 @@ and CheckExprOp cenv env (op,tyargs,args,m) context =
CheckExprInContext cenv env lhs DirectArg (* permit byref for lhs lvalue of readonly value *)
| [ I_ldflda (fspec) | I_ldsflda (fspec) ],[lhs] ->
if context <> DirectArg && cenv.reportErrors then
- errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(fspec.Name), m));
+ errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(fspec.Name), m))
CheckExprInContext cenv env lhs DirectArg (* permit byref for lhs lvalue *)
| [ I_ldelema (_,isNativePtr,_,_) ],lhsArray::indices ->
if not(isNativePtr) && context <> DirectArg && cenv.reportErrors then
- errorR(Error(FSComp.SR.chkNoAddressOfArrayElementAtThisPoint(), m));
+ errorR(Error(FSComp.SR.chkNoAddressOfArrayElementAtThisPoint(), m))
CheckExprInContext cenv env lhsArray DirectArg (* permit byref for lhs lvalue *)
CheckExprs cenv env indices
+ | [ AI_conv _ ],_ ->
+ CheckExprDirectArgs cenv env args (* permit byref for args to conv *)
| _instrs ->
CheckExprs cenv env args
end
| TOp.TraitCall _,_,_,_ ->
- CheckTypeInstNoByrefs cenv env m tyargs;
+ CheckTypeInstNoByrefs cenv env m tyargs
CheckExprDirectArgs cenv env args (* allow args to be byref here *)
| ( TOp.Tuple
@@ -796,7 +818,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context =
| TOp.RefAddrGet
| _ (* catch all! *)
),_,_,_ ->
- CheckTypeInstNoByrefs cenv env m tyargs;
+ CheckTypeInstNoByrefs cenv env m tyargs
CheckExprs cenv env args
and CheckLambdas (memInfo: ValMemberInfo option) cenv env inlined topValInfo alwaysCheckNoReraise e m ety =
@@ -828,18 +850,18 @@ and CheckLambdas (memInfo: ValMemberInfo option) cenv env inlined topValInfo alw
// any byRef arguments are considered used, as they may be 'out's
restArgs |> List.iter (fun arg -> if isByrefTy cenv.g arg.Type then arg.SetHasBeenReferenced())
- syntacticArgs |> List.iter (CheckValSpec cenv env);
- syntacticArgs |> List.iter (BindVal cenv);
+ syntacticArgs |> List.iter (CheckValSpec cenv env)
+ syntacticArgs |> List.iter (BindVal cenv)
// Allow access to protected things within members
match memInfo with
| None -> ()
| Some membInfo ->
- testHookMemberBody membInfo body;
+ testHookMemberBody membInfo body
- let freesOpt = CheckEscapes cenv (isSome(memInfo)) m syntacticArgs body;
- CheckNoReraise cenv freesOpt body; (* no reraise under lambda expression *)
- CheckExpr cenv env body;
+ let freesOpt = CheckEscapes cenv (isSome(memInfo)) m syntacticArgs body
+ CheckNoReraise cenv freesOpt body (* no reraise under lambda expression *)
+ CheckExpr cenv env body
if cenv.reportErrors then
if not inlined then
CheckForByrefLikeType cenv env bodyty (fun () ->
@@ -852,13 +874,13 @@ and CheckLambdas (memInfo: ValMemberInfo option) cenv env inlined topValInfo alw
errorR(Error(FSComp.SR.chkTyparMultipleClassConstraints(), m))
| _ ->
- CheckTypePermitByrefs cenv env m ety;
+ CheckTypePermitByrefs cenv env m ety
if not inlined && isByrefLikeTy cenv.g ety then
CheckExprInContext cenv env e DirectArg (* allow byref to occur as RHS of byref binding. *)
else
CheckExpr cenv env e
if alwaysCheckNoReraise then
- CheckNoReraise cenv None e; (* no reraise *)
+ CheckNoReraise cenv None e (* no reraise *)
and CheckExprsInContext cenv env exprs arities =
let arities = Array.ofList arities
@@ -874,24 +896,24 @@ and CheckFlatExprs cenv env exprs =
and CheckExprDirectArgs cenv env exprs =
exprs |> List.iter (fun x -> CheckExprInContext cenv env x DirectArg)
-and CheckDecisionTreeTargets cenv env targets =
- targets |> Array.iter (CheckDecisionTreeTarget cenv env)
+and CheckDecisionTreeTargets cenv env targets context =
+ targets |> Array.iter (CheckDecisionTreeTarget cenv env context )
-and CheckDecisionTreeTarget cenv env (TTarget(vs,e,_)) =
+and CheckDecisionTreeTarget cenv env context (TTarget(vs,e,_)) =
BindVals cenv vs
vs |> FlatList.iter (CheckValSpec cenv env)
- CheckExpr cenv env e
+ CheckExprInContext cenv env e context
and CheckDecisionTree cenv env x =
match x with
- | TDSuccess (es,_) -> CheckFlatExprs cenv env es;
+ | TDSuccess (es,_) -> CheckFlatExprs cenv env es
| TDBind(bind,rest) -> CheckBinding cenv env false bind; CheckDecisionTree cenv env rest
| TDSwitch (e,cases,dflt,m) -> CheckDecisionTreeSwitch cenv env (e,cases,dflt,m)
and CheckDecisionTreeSwitch cenv env (e,cases,dflt,m) =
- CheckExpr cenv env e;
- List.iter (fun (TCase(discrim,e)) -> CheckDecisionTreeTest cenv env m discrim; CheckDecisionTree cenv env e) cases;
- Option.iter (CheckDecisionTree cenv env) dflt
+ CheckExprInContext cenv env e DirectArg // can be byref for struct union switch
+ cases |> List.iter (fun (TCase(discrim,e)) -> CheckDecisionTreeTest cenv env m discrim; CheckDecisionTree cenv env e)
+ dflt |> Option.iter (CheckDecisionTree cenv env)
and CheckDecisionTreeTest cenv env m discrim =
match discrim with
@@ -903,13 +925,13 @@ and CheckDecisionTreeTest cenv env m discrim =
| Test.ActivePatternCase (exp,_,_,_,_) -> CheckExpr cenv env exp
and CheckAttrib cenv env (Attrib(_,_,args,props,_,_,_)) =
- props |> List.iter (fun (AttribNamedArg(_,_,_,expr)) -> CheckAttribExpr cenv env expr);
+ props |> List.iter (fun (AttribNamedArg(_,_,_,expr)) -> CheckAttribExpr cenv env expr)
args |> List.iter (CheckAttribExpr cenv env)
and CheckAttribExpr cenv env (AttribExpr(expr,vexpr)) =
- CheckExpr cenv env expr;
- CheckExpr cenv env vexpr;
- CheckNoReraise cenv None expr;
+ CheckExpr cenv env expr
+ CheckExpr cenv env vexpr
+ CheckNoReraise cenv None expr
CheckAttribArgExpr cenv env vexpr
and CheckAttribArgExpr cenv env expr =
@@ -948,7 +970,7 @@ and CheckAttribArgExpr cenv env expr =
| EnumExpr cenv.g arg1 ->
CheckAttribArgExpr cenv env arg1
| AttribBitwiseOrExpr cenv.g (arg1,arg2) ->
- CheckAttribArgExpr cenv env arg1;
+ CheckAttribArgExpr cenv env arg1
CheckAttribArgExpr cenv env arg2
| _ ->
if cenv.reportErrors then
@@ -975,15 +997,15 @@ and CheckAttribs cenv env (attribs: Attribs) =
attribs |> List.iter (CheckAttrib cenv env)
and CheckValInfo cenv env (ValReprInfo(_,args,ret)) =
- args |> List.iterSquared (CheckArgInfo cenv env);
- ret |> CheckArgInfo cenv env;
+ args |> List.iterSquared (CheckArgInfo cenv env)
+ ret |> CheckArgInfo cenv env
and CheckArgInfo cenv env (argInfo : ArgReprInfo) =
CheckAttribs cenv env argInfo.Attribs
and CheckValSpec cenv env (v:Val) =
- v.Attribs |> CheckAttribs cenv env;
- v.ValReprInfo |> Option.iter (CheckValInfo cenv env);
+ v.Attribs |> CheckAttribs cenv env
+ v.ValReprInfo |> Option.iter (CheckValInfo cenv env)
v.Type |> CheckTypePermitByrefs cenv env v.Range
and AdjustAccess isHidden (cpath: unit -> CompilationPath) access =
@@ -1009,9 +1031,9 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,e,_) as bind) =
let nm = v.DisplayName
errorR(Error(FSComp.SR.chkMemberUsedInInvalidWay(nm, nm, stringOfRange m), v.Range))
- v.Type |> CheckTypePermitByrefs cenv env v.Range;
- v.Attribs |> CheckAttribs cenv env;
- v.ValReprInfo |> Option.iter (CheckValInfo cenv env);
+ v.Type |> CheckTypePermitByrefs cenv env v.Range
+ v.Attribs |> CheckAttribs cenv env
+ v.ValReprInfo |> Option.iter (CheckValInfo cenv env)
if (v.IsMemberOrModuleBinding || v.IsMember) && not v.IsIncrClassGeneratedMember then
let access = AdjustAccess (IsHiddenVal env.sigToImplRemapInfo v) (fun () -> v.TopValActualParent.CompilationPath) v.Accessibility
CheckTypeForAccess cenv env (fun () -> NicePrint.stringOfQualifiedValOrMember cenv.denv v) access v.Range v.Type
@@ -1020,7 +1042,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,e,_) as bind) =
if cenv.reportErrors then
if isByrefLikeTy cenv.g v.Type && isSome bind.Var.ValReprInfo then
- errorR(Error(FSComp.SR.chkNoByrefAsTopValue(), v.Range));
+ errorR(Error(FSComp.SR.chkNoByrefAsTopValue(), v.Range))
// Check top-level let-bound values (arity=0 so not compiled not method) for byref types (not allowed)
match bind.Var.ValReprInfo with
@@ -1090,7 +1112,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,e,_) as bind) =
let inlined = v.MustInline
// certain inline functions are permitted to have byref return types
// e.g. for the byref operator itself, &.
- CheckLambdas v.MemberInfo cenv env inlined topValInfo alwaysCheckNoReraise e v.Range v.Type;
+ CheckLambdas v.MemberInfo cenv env inlined topValInfo alwaysCheckNoReraise e v.Range v.Type
and CheckBindings cenv env xs = FlatList.iter (CheckBinding cenv env false) xs
@@ -1098,7 +1120,7 @@ and CheckBindings cenv env xs = FlatList.iter (CheckBinding cenv env false) xs
let CheckModuleBinding cenv env (TBind(v,e,_) as bind) =
let isExplicitEntryPoint = HasFSharpAttribute cenv.g cenv.g.attrib_EntryPointAttribute v.Attribs
if isExplicitEntryPoint then
- cenv.entryPointGiven <- true;
+ cenv.entryPointGiven <- true
let isLastCompiland = fst cenv.isLastCompiland
if not isLastCompiland && cenv.reportErrors then
errorR(Error(FSComp.SR.chkEntryPointUsage(), v.Range))
@@ -1143,20 +1165,20 @@ let CheckModuleBinding cenv env (TBind(v,e,_) as bind) =
tcref.ModuleOrNamespaceType.AllValsByLogicalName.ContainsKey(nm) &&
not (valEq tcref.ModuleOrNamespaceType.AllValsByLogicalName.[nm] v) then
- error(Duplicate(kind,v.DisplayName,v.Range));
+ error(Duplicate(kind,v.DisplayName,v.Range))
#if CASES_IN_NESTED_CLASS
if tcref.IsUnionTycon && nm = "Cases" then
- errorR(NameClash(nm,kind,v.DisplayName,v.Range, "generated type","Cases",tcref.Range));
+ errorR(NameClash(nm,kind,v.DisplayName,v.Range, "generated type","Cases",tcref.Range))
#endif
if tcref.IsUnionTycon then
match nm with
- | "Tag" -> errorR(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.typeInfoGeneratedProperty(),"Tag",tcref.Range));
- | "Tags" -> errorR(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.typeInfoGeneratedType(),"Tags",tcref.Range));
+ | "Tag" -> errorR(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.typeInfoGeneratedProperty(),"Tag",tcref.Range))
+ | "Tags" -> errorR(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.typeInfoGeneratedType(),"Tags",tcref.Range))
| _ ->
if hasDefaultAugmentation then
match tcref.GetUnionCaseByName(nm) with
- | Some(uc) -> error(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.typeInfoUnionCase(),uc.DisplayName,uc.Range));
+ | Some(uc) -> error(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.typeInfoUnionCase(),uc.DisplayName,uc.Range))
| None -> ()
let hasNoArgs =
@@ -1168,24 +1190,24 @@ let CheckModuleBinding cenv env (TBind(v,e,_) as bind) =
if tcref.UnionCasesArray.Length = 1 && hasNoArgs then
let ucase1 = tcref.UnionCasesArray.[0]
for f in ucase1.RecdFieldsArray do
- if f.Name = nm then error(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.typeInfoGeneratedProperty(),f.Name,ucase1.Range));
+ if f.Name = nm then error(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.typeInfoGeneratedProperty(),f.Name,ucase1.Range))
// Default augmentation contains the nasty 'Case' etc.
let prefix = "New"
if nm.StartsWith prefix then
match tcref.GetUnionCaseByName(nm.[prefix.Length ..]) with
- | Some(uc) -> error(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.chkUnionCaseCompiledForm(),uc.DisplayName,uc.Range));
+ | Some(uc) -> error(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.chkUnionCaseCompiledForm(),uc.DisplayName,uc.Range))
| None -> ()
// Default augmentation contains the nasty 'Is' etc.
let prefix = "Is"
if nm.StartsWith prefix && hasDefaultAugmentation then
match tcref.GetUnionCaseByName(nm.[prefix.Length ..]) with
- | Some(uc) -> error(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.chkUnionCaseDefaultAugmentation(),uc.DisplayName,uc.Range));
+ | Some(uc) -> error(NameClash(nm,kind,v.DisplayName,v.Range, FSComp.SR.chkUnionCaseDefaultAugmentation(),uc.DisplayName,uc.Range))
| None -> ()
match tcref.GetFieldByName(nm) with
- | Some(rf) -> error(NameClash(nm,kind,v.DisplayName,v.Range,"field",rf.Name,rf.Range));
+ | Some(rf) -> error(NameClash(nm,kind,v.DisplayName,v.Range,"field",rf.Name,rf.Range))
| None -> ()
check false v.CoreDisplayName
@@ -1215,7 +1237,7 @@ let CheckModuleBinding cenv env (TBind(v,e,_) as bind) =
match TryChopPropertyName v.DisplayName with
| Some res -> check true res
| None -> ()
- with e -> errorRecovery e v.Range;
+ with e -> errorRecovery e v.Range
end
CheckBinding cenv env true bind
@@ -1232,10 +1254,10 @@ let CheckRecdField isUnion cenv env (tycon:Tycon) (rfield:RecdField) =
IsHiddenTyconRepr env.sigToImplRemapInfo tycon ||
(not isUnion && IsHiddenRecdField env.sigToImplRemapInfo ((mkLocalTyconRef tycon).MakeNestedRecdFieldRef rfield))
let access = AdjustAccess isHidden (fun () -> tycon.CompilationPath) rfield.Accessibility
- CheckTypeForAccess cenv env (fun () -> rfield.Name) access rfield.Range rfield.FormalType;
- CheckTypePermitByrefs cenv env rfield.Range rfield.FormalType;
- CheckAttribs cenv env rfield.PropertyAttribs;
- CheckAttribs cenv env rfield.FieldAttribs;
+ CheckTypeForAccess cenv env (fun () -> rfield.Name) access rfield.Range rfield.FormalType
+ CheckTypePermitByrefs cenv env rfield.Range rfield.FormalType
+ CheckAttribs cenv env rfield.PropertyAttribs
+ CheckAttribs cenv env rfield.FieldAttribs
if cenv.reportErrors then
CheckForByrefLikeType cenv env rfield.FormalType (fun () -> errorR(Error(FSComp.SR.chkCantStoreByrefValue(), tycon.Range)))
@@ -1246,7 +1268,7 @@ let CheckEntityDefn cenv env (tycon:Entity) =
let env = { env with reflect = env.reflect || HasFSharpAttribute cenv.g cenv.g.attrib_ReflectedDefinitionAttribute tycon.Attribs }
let m = tycon.Range
let env = BindTypars cenv.g env (tycon.Typars(m))
- CheckAttribs cenv env tycon.Attribs;
+ CheckAttribs cenv env tycon.Attribs
if cenv.reportErrors then begin
if not tycon.IsTypeAbbrev then
@@ -1315,15 +1337,42 @@ let CheckEntityDefn cenv env (tycon:Entity) =
else
errorR(Error(FSComp.SR.chkDuplicateMethodWithSuffix(nm),m))
- if minfo.NumArgs.Length > 1 && others |> List.exists (fun minfo2 -> not (IsAbstractDefaultPair2 minfo minfo2)) then
+ let numCurriedArgSets = minfo.NumArgs.Length
+
+ if numCurriedArgSets > 1 && others |> List.exists (fun minfo2 -> not (IsAbstractDefaultPair2 minfo minfo2)) then
errorR(Error(FSComp.SR.chkDuplicateMethodCurried nm,m))
- if minfo.NumArgs.Length > 1 &&
+ if numCurriedArgSets > 1 &&
(minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst)
- |> List.existsSquared (fun (ParamData(isParamArrayArg, isOutArg, optArgInfo, _, reflArgInfo, ty)) ->
- isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || isByrefTy cenv.g ty)) then
+ |> List.existsSquared (fun (ParamData(isParamArrayArg, isOutArg, optArgInfo, callerInfoInfo, _, reflArgInfo, ty)) ->
+ isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefTy cenv.g ty)) then
errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m))
+ if numCurriedArgSets = 1 then
+ minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst)
+ |> List.iterSquared (fun (ParamData(_, _, optArgInfo, callerInfoInfo, _, _, ty)) ->
+ match (optArgInfo, callerInfoInfo) with
+ | _, NoCallerInfo -> ()
+ | NotOptional, _ -> errorR(Error(FSComp.SR.tcCallerInfoNotOptional(callerInfoInfo.ToString()),m))
+ | CallerSide(_), CallerLineNumber ->
+ if not (typeEquiv cenv.g cenv.g.int32_ty ty) then
+ errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "int", NicePrint.minimalStringOfType cenv.denv ty),m))
+ | CalleeSide, CallerLineNumber ->
+ if not ((isOptionTy cenv.g ty) && (typeEquiv cenv.g cenv.g.int32_ty (destOptionTy cenv.g ty))) then
+ errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "int", NicePrint.minimalStringOfType cenv.denv (destOptionTy cenv.g ty)),m))
+ | CallerSide(_), CallerFilePath ->
+ if not (typeEquiv cenv.g cenv.g.string_ty ty) then
+ errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv ty),m))
+ | CalleeSide, CallerFilePath ->
+ if not ((isOptionTy cenv.g ty) && (typeEquiv cenv.g cenv.g.string_ty (destOptionTy cenv.g ty))) then
+ errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy cenv.g ty)),m))
+ | CallerSide(_), CallerMemberName ->
+ if not (typeEquiv cenv.g cenv.g.string_ty ty) then
+ errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv ty),m))
+ | CalleeSide, CallerMemberName ->
+ if not ((isOptionTy cenv.g ty) && (typeEquiv cenv.g cenv.g.string_ty (destOptionTy cenv.g ty))) then
+ errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy cenv.g ty)),m)))
+
for pinfo in immediateProps do
let nm = pinfo.PropertyName
let m = (match pinfo.ArbitraryValRef with None -> m | Some vref -> vref.DefinitionRange)
@@ -1407,23 +1456,23 @@ let CheckEntityDefn cenv env (tycon:Entity) =
else
errorR(Error(FSComp.SR.chkDuplicateMethodInheritedTypeWithSuffix(nm),m))
- end;
+ end
// Considers TFSharpObjectRepr, TRecdRepr and TUnionRepr.
// [Review] are all cases covered: TILObjectRepr,TAsmRepr. [Yes - these are FSharp.Core.dll only]
- tycon.AllFieldsArray |> Array.iter (CheckRecdField false cenv env tycon);
- abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> CheckTypePermitByrefs cenv env m); (* check vslots = abstract slots *)
- tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (CheckTypePermitByrefs cenv env m); (* check implemented interface types *)
- superOfTycon cenv.g tycon |> CheckTypePermitByrefs cenv env m; (* check super type *)
+ tycon.AllFieldsArray |> Array.iter (CheckRecdField false cenv env tycon)
+ abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> CheckTypePermitByrefs cenv env m) (* check vslots = abstract slots *)
+ tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (CheckTypePermitByrefs cenv env m) (* check implemented interface types *)
+ superOfTycon cenv.g tycon |> CheckTypePermitByrefs cenv env m (* check super type *)
if tycon.IsUnionTycon then (* This covers finite unions. *)
tycon.UnionCasesAsList |> List.iter (fun uc ->
- CheckAttribs cenv env uc.Attribs;
+ CheckAttribs cenv env uc.Attribs
uc.RecdFields |> List.iter (CheckRecdField true cenv env tycon))
let access = AdjustAccess (IsHiddenTycon env.sigToImplRemapInfo tycon) (fun () -> tycon.CompilationPath) tycon.Accessibility
let visitType ty = CheckTypeForAccess cenv env (fun () -> tycon.DisplayNameWithStaticParametersAndUnderscoreTypars) access tycon.Range ty
- abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> visitType); (* check vslots = abstract slots *)
+ abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> visitType) (* check vslots = abstract slots *)
superOfTycon cenv.g tycon |> visitType
// We do not have to check access of interface implementations. See FSharp 1.0 5042
//implements_of_tycon cenv.g tycon |> List.iter visitType
@@ -1434,7 +1483,7 @@ let CheckEntityDefn cenv env (tycon:Entity) =
| TTyconDelegate ss ->
//ss.ClassTypars
//ss.MethodTypars
- ss.FormalReturnType |> Option.iter visitType;
+ ss.FormalReturnType |> Option.iter visitType
ss.FormalParams |> List.iterSquared (fun (TSlotParam(_,ty,_,_,_,_)) -> visitType ty)
| _ -> ()
| _ -> ()
@@ -1464,7 +1513,7 @@ let CheckEntityDefn cenv env (tycon:Entity) =
if zeroInitUnsafe = Some(true) then
let ty' = generalizedTyconRef (mkLocalTyconRef tycon)
if not (TypeHasDefaultValue cenv.g m ty') then
- errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m));
+ errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m))
)
match tycon.TypeAbbrev with (* And type abbreviations *)
| None -> ()
@@ -1505,7 +1554,7 @@ and CheckDefnInModule cenv env x =
BindVal cenv bind.Var
| TMDefDo(e,m) ->
CheckNothingAfterEntryPoint cenv m
- CheckNoReraise cenv None e;
+ CheckNoReraise cenv None e
CheckExpr cenv env e
| TMAbstract(def) -> CheckModuleExpr cenv env def
| TMDefs(defs) -> CheckDefnsInModule cenv env defs
@@ -1516,23 +1565,23 @@ and CheckModuleSpec cenv env x =
BindVals cenv (valsOfBinds [bind])
CheckModuleBinding cenv env bind
| ModuleOrNamespaceBinding.Module (mspec, rhs) ->
- CheckEntityDefn cenv env mspec;
+ CheckEntityDefn cenv env mspec
let env = { env with reflect = env.reflect || HasFSharpAttribute cenv.g cenv.g.attrib_ReflectedDefinitionAttribute mspec.Attribs }
CheckDefnInModule cenv env rhs
let CheckTopImpl (g,amap,reportErrors,infoReader,internalsVisibleToPaths,viewCcu,denv ,mexpr,extraAttribs,(isLastCompiland:bool*bool)) =
let cenv =
- { g =g ;
- reportErrors=reportErrors;
- boundVals= new Dictionary<_,_>(100, HashIdentity.Structural);
- potentialUnboundUsesOfVals=Map.empty;
- usesQuotations=false;
- infoReader=infoReader;
- internalsVisibleToPaths=internalsVisibleToPaths;
- amap=amap;
- denv=denv;
- viewCcu= viewCcu;
- isLastCompiland=isLastCompiland;
+ { g =g
+ reportErrors=reportErrors
+ boundVals= new Dictionary<_,_>(100, HashIdentity.Structural)
+ potentialUnboundUsesOfVals=Map.empty
+ usesQuotations=false
+ infoReader=infoReader
+ internalsVisibleToPaths=internalsVisibleToPaths
+ amap=amap
+ denv=denv
+ viewCcu= viewCcu
+ isLastCompiland=isLastCompiland
entryPointGiven=false}
// Certain type equality checks go faster if these TyconRefs are pre-resolved.
@@ -1554,8 +1603,8 @@ let CheckTopImpl (g,amap,reportErrors,infoReader,internalsVisibleToPaths,viewCcu
boundTypars= TyparMap.Empty
reflect=false }
- CheckModuleExpr cenv env mexpr;
- CheckAttribs cenv env extraAttribs;
+ CheckModuleExpr cenv env mexpr
+ CheckAttribs cenv env extraAttribs
if cenv.usesQuotations && QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat(cenv.g) = QuotationTranslator.QuotationSerializationFormat.FSharp_20_Plus then
viewCcu.UsesFSharp20PlusQuotations <- true
cenv.entryPointGiven
diff --git a/src/fsharp/QuotationTranslator.fs b/src/fsharp/QuotationTranslator.fs
index 22090236d4b..8b1dd7e1889 100644
--- a/src/fsharp/QuotationTranslator.fs
+++ b/src/fsharp/QuotationTranslator.fs
@@ -38,9 +38,9 @@ type QuotationSerializationFormat =
| FSharp_20_Plus
type QuotationGenerationScope =
- { g: TcGlobals;
- amap: Import.ImportMap;
- scope: CcuThunk;
+ { g: TcGlobals
+ amap: Import.ImportMap
+ scope: CcuThunk
// Accumulate the references to type definitions
referencedTypeDefs: ResizeArray
referencedTypeDefsTable: Dictionary
@@ -78,10 +78,10 @@ type QuotationGenerationScope =
type QuotationTranslationEnv =
{ //Map from Val to binding index
- vs: ValMap;
- nvs: int;
+ vs: ValMap
+ nvs: int
//Map from typar stamps to binding index
- tyvs: StampMap;
+ tyvs: StampMap
// Map for values bound by the
// 'let v = isinst e in .... if nonnull v then ...v .... '
// construct arising out the compilation of pattern matching. We decode these back to the form
@@ -90,9 +90,9 @@ type QuotationTranslationEnv =
substVals: ValMap }
static member Empty =
- { vs=ValMap<_>.Empty;
- nvs=0;
- tyvs = Map.empty ;
+ { vs=ValMap<_>.Empty
+ nvs=0
+ tyvs = Map.empty
isinstVals = ValMap<_>.Empty
substVals = ValMap<_>.Empty }
@@ -182,11 +182,11 @@ let rec EmitDebugInfoIfNecessary cenv env m astExpr : QP.ExprData =
let rangeExpr =
mk_tuple cenv.g m
- [ mkString cenv.g m m.FileName;
- mkInt cenv.g m m.StartLine;
- mkInt cenv.g m m.StartColumn;
- mkInt cenv.g m m.EndLine;
- mkInt cenv.g m m.EndColumn; ]
+ [ mkString cenv.g m m.FileName
+ mkInt cenv.g m m.StartLine
+ mkInt cenv.g m m.StartColumn
+ mkInt cenv.g m m.EndLine
+ mkInt cenv.g m m.EndColumn; ]
let attrExpr =
mk_tuple cenv.g m
[ mkString cenv.g m "DebugRange"; rangeExpr ]
@@ -224,7 +224,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.
match (freeInExpr CollectTyparsAndLocalsNoCaching x0).FreeLocals |> Seq.tryPick (fun v -> if env.vs.ContainsVal v then Some(v) else None) with
| Some v -> errorR(Error(FSComp.SR.crefBoundVarUsedInSplice(v.DisplayName), v.Range))
| None -> ()
- cenv.exprSplices.Add((x0, m));
+ cenv.exprSplices.Add((x0, m))
let hole = QP.mkHole(ConvType cenv env m ty,idx)
(hole, rest) ||> List.fold (fun fR arg -> QP.mkApp (fR,ConvExpr cenv env arg))
@@ -345,7 +345,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.
// Simple applications
| Expr.App(f,_fty,tyargs,args,m) ->
- if nonNil tyargs then wfail(Error(FSComp.SR.crefQuotationsCantContainGenericExprs(), m));
+ if nonNil tyargs then wfail(Error(FSComp.SR.crefQuotationsCantContainGenericExprs(), m))
List.fold (fun fR arg -> QP.mkApp (fR,ConvExpr cenv env arg)) (ConvExpr cenv env f) args
// REVIEW: what is the quotation view of literals accessing enumerations? Currently they show up as integers.
@@ -433,6 +433,9 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.
| TOp.ValFieldGetAddr(_rfref),_tyargs,_ ->
wfail(Error(FSComp.SR.crefQuotationsCantContainAddressOf(), m))
+ | TOp.UnionCaseFieldGetAddr _,_tyargs,_ ->
+ wfail(Error(FSComp.SR.crefQuotationsCantContainAddressOf(), m))
+
| TOp.ValFieldGet(_rfref),_tyargs,[] ->
wfail(Error(FSComp.SR.crefQuotationsCantContainStaticFieldRef(),m))
@@ -475,8 +478,8 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.
let methArgTypesR = ConvTypes cenv env m argtys
let argsR = ConvExprs cenv env args
let objR =
- QP.mkCtorCall( { ctorParent = parentTyconR;
- ctorArgTypes = methArgTypesR },
+ QP.mkCtorCall( { ctorParent = parentTyconR
+ ctorArgTypes = methArgTypesR },
[], argsR)
let exnTypeR = ConvType cenv env m cenv.g.exn_ty
QP.mkCoerce(exnTypeR, objR)
@@ -684,17 +687,19 @@ and ConvObjectModelCallCore cenv env m (isPropGet,isPropSet,isNewObj,parentTycon
QP.mkPropSet( (parentTyconR, propName,propTy,args),tyargsR, callArgsR)
elif isNewObj then
- QP.mkCtorCall( { ctorParent = parentTyconR;
- ctorArgTypes = methArgTypesR },
- tyargsR, callArgsR)
+ let ctorR : QuotationPickler.CtorData =
+ { ctorParent = parentTyconR
+ ctorArgTypes = methArgTypesR }
+ QP.mkCtorCall(ctorR, tyargsR, callArgsR)
else
- QP.mkMethodCall( { methParent = parentTyconR;
- methArgTypes = methArgTypesR;
- methRetType = methRetTypeR;
- methName = methName;
- numGenericArgs=numGenericArgs },
- tyargsR, callArgsR)
+ let methR : QuotationPickler.MethodData =
+ { methParent = parentTyconR
+ methArgTypes = methArgTypesR
+ methRetType = methRetTypeR
+ methName = methName
+ numGenericArgs=numGenericArgs }
+ QP.mkMethodCall(methR, tyargsR, callArgsR)
and ConvModuleValueApp cenv env m (vref:ValRef) tyargs (args: Expr list list) =
EmitDebugInfoIfNecessary cenv env m (ConvModuleValueAppCore cenv env m vref tyargs args)
@@ -724,7 +729,7 @@ and private ConvValRefCore holeOk cenv env m (vref:ValRef) tyargs =
let e = env.substVals.[v]
ConvExpr cenv env e
elif env.vs.ContainsVal v then
- if nonNil tyargs then wfail(InternalError("ignoring generic application of local quoted variable",m));
+ if nonNil tyargs then wfail(InternalError("ignoring generic application of local quoted variable",m))
QP.mkVar(env.vs.[v])
elif v.BaseOrThisInfo = CtorThisVal && cenv.isReflectedDefinition = IsReflectedDefinition.Yes then
QP.mkThisVar(ConvType cenv env m v.Type)
@@ -735,7 +740,7 @@ and private ConvValRefCore holeOk cenv env m (vref:ValRef) tyargs =
// References to local values are embedded by value
if not holeOk then wfail(Error(FSComp.SR.crefNoSetOfHole(),m))
let idx = cenv.exprSplices.Count
- cenv.exprSplices.Add((mkCallLiftValueWithName cenv.g m vty v.LogicalName (exprForValRef m vref), m));
+ cenv.exprSplices.Add((mkCallLiftValueWithName cenv.g m vty v.LogicalName (exprForValRef m vref), m))
QP.mkHole(ConvType cenv env m vty,idx)
| Parent _ ->
ConvModuleValueApp cenv env m vref tyargs []
@@ -769,7 +774,7 @@ and ConvTyparRef cenv env m (tp:Typar) =
| Some idx -> idx
| None ->
let idx = cenv.typeSplices.Count
- cenv.typeSplices.Add((tp, m));
+ cenv.typeSplices.Add((tp, m))
idx
and FilterMeasureTyargs tys =
@@ -1019,14 +1024,14 @@ let ConvMethodBase cenv env (methName, v:Val) =
if isNewObj then
QP.MethodBaseData.Ctor
- { ctorParent = parentTyconR;
+ { ctorParent = parentTyconR
ctorArgTypes = methArgTypesR }
else
QP.MethodBaseData.Method
- { methParent = parentTyconR;
- methArgTypes = methArgTypesR;
- methRetType = methRetTypeR;
- methName = methName;
+ { methParent = parentTyconR
+ methArgTypes = methArgTypesR
+ methRetType = methRetTypeR
+ methName = methName
numGenericArgs=numGenericArgs }
| _ when v.IsExtensionMember ->
@@ -1047,8 +1052,8 @@ let ConvMethodBase cenv env (methName, v:Val) =
| _ ->
QP.MethodBaseData.ModuleDefn
- { Name = methName;
- Module = parentTyconR;
+ { Name = methName
+ Module = parentTyconR
IsProperty = IsCompiledAsStaticProperty cenv.g v }
diff --git a/src/fsharp/ReferenceResolution.fs b/src/fsharp/ReferenceResolution.fs
index 7340b8a429f..6c0685349b1 100644
--- a/src/fsharp/ReferenceResolution.fs
+++ b/src/fsharp/ReferenceResolution.fs
@@ -39,7 +39,6 @@ module internal MSBuildResolver =
open Microsoft.Build.Tasks
open Microsoft.Build.Utilities
open Microsoft.Build.Framework
- open Microsoft.Build.BuildEngine
open System.IO
type ResolvedFile =
diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs
index 57320d2205e..2be517b27dd 100755
--- a/src/fsharp/TastOps.fs
+++ b/src/fsharp/TastOps.fs
@@ -536,7 +536,7 @@ let rec sizeMeasure g ms =
// Some basic type builders
//---------------------------------------------------------------------------
-let mkNativePtrType g ty = TType_app (g.nativeptr_tcr, [ty])
+let mkNativePtrTy g ty = TType_app (g.nativeptr_tcr, [ty])
let mkByrefTy g ty = TType_app (g.byref_tcr, [ty])
let mkArrayTy g rank ty m =
@@ -1181,24 +1181,34 @@ let mkStaticRecdFieldGetAddr(fref,tinst,m) = Expr.Op (TOp.ValFieldGetAd
let mkStaticRecdFieldGet(fref,tinst,m) = Expr.Op (TOp.ValFieldGet(fref), tinst, [],m)
let mkStaticRecdFieldSet(fref,tinst,e,m) = Expr.Op (TOp.ValFieldSet(fref), tinst, [e],m)
-let mkRecdFieldSetViaExprAddr(e1,fref,tinst,e2,m) = Expr.Op (TOp.ValFieldSet(fref), tinst, [e1;e2],m)
+let mkArrayElemAddress g (readonly,isNativePtr,shape,elemTy,aexpr,nexpr,m) = Expr.Op (TOp.ILAsm ([IL.I_ldelema(readonly,isNativePtr,shape,mkILTyvarTy 0us)],[mkByrefTy g elemTy]), [elemTy],[aexpr;nexpr],m)
-let mkUnionCaseTagGet(e1,cref,tinst,m) = Expr.Op (TOp.UnionCaseTagGet(cref), tinst, [e1],m)
-let mkUnionCaseProof(e1,cref,tinst,m) = Expr.Op (TOp.UnionCaseProof(cref), tinst, [e1],m)
+let mkRecdFieldSetViaExprAddr (e1,fref,tinst,e2,m) = Expr.Op (TOp.ValFieldSet(fref), tinst, [e1;e2],m)
-/// Build a 'get' expression for something we've already determined to be a particular union case, and where the
-/// input expression has 'TType_ucase', which is an F# compiler internal "type"
-let mkUnionCaseFieldGetProven(e1,cref,tinst,j,m) = Expr.Op (TOp.UnionCaseFieldGet(cref,j), tinst, [e1],m)
+let mkUnionCaseTagGetViaExprAddr (e1,cref,tinst,m) = Expr.Op (TOp.UnionCaseTagGet(cref), tinst, [e1],m)
+
+/// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions)
+let mkUnionCaseProof (e1,cref:UnionCaseRef,tinst,m) = if cref.Tycon.IsStructOrEnumTycon then e1 else Expr.Op (TOp.UnionCaseProof(cref), tinst, [e1],m)
+
+/// Build a 'TOp.UnionCaseFieldGet' expression for something we've already determined to be a particular union case. For ref-unions,
+/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions,
+/// the input should be the address of the expression.
+let mkUnionCaseFieldGetProvenViaExprAddr (e1,cref,tinst,j,m) = Expr.Op (TOp.UnionCaseFieldGet(cref,j), tinst, [e1],m)
+
+/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions,
+/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions,
+/// the input should be the address of the expression.
+let mkUnionCaseFieldGetAddrProvenViaExprAddr (e1,cref,tinst,j,m) = Expr.Op (TOp.UnionCaseFieldGetAddr(cref,j), tinst, [e1],m)
/// Build a 'get' expression for something we've already determined to be a particular union case, but where
/// the static type of the input is not yet proven to be that particular union case. This requires a type
/// cast to 'prove' the condition.
-let mkUnionCaseFieldGetUnproven(e1,cref,tinst,j,m) = mkUnionCaseFieldGetProven(mkUnionCaseProof(e1,cref,tinst,m),cref,tinst,j,m)
+let mkUnionCaseFieldGetUnprovenViaExprAddr (e1,cref,tinst,j,m) = mkUnionCaseFieldGetProvenViaExprAddr(mkUnionCaseProof(e1,cref,tinst,m),cref,tinst,j,m)
-let mkUnionCaseFieldSet(e1,cref,tinst,j,e2,m) = Expr.Op (TOp.UnionCaseFieldSet(cref,j), tinst, [e1;e2],m)
+let mkUnionCaseFieldSet (e1,cref,tinst,j,e2,m) = Expr.Op (TOp.UnionCaseFieldSet(cref,j), tinst, [e1;e2],m)
-let mkExnCaseFieldGet(e1,ecref,j,m) = Expr.Op (TOp.ExnFieldGet(ecref,j), [],[e1],m)
-let mkExnCaseFieldSet(e1,ecref,j,e2,m) = Expr.Op (TOp.ExnFieldSet(ecref,j), [],[e1;e2],m)
+let mkExnCaseFieldGet (e1,ecref,j,m) = Expr.Op (TOp.ExnFieldGet(ecref,j), [],[e1],m)
+let mkExnCaseFieldSet (e1,ecref,j,e2,m) = Expr.Op (TOp.ExnFieldSet(ecref,j), [],[e1;e2],m)
let mkDummyLambda g (e:Expr,ety) =
let m = e.Range
@@ -1310,6 +1320,9 @@ let actualTyOfRecdFieldForTycon tycon tinst (fspec:RecdField) =
let actualTyOfRecdFieldRef (fref:RecdFieldRef) tinst =
actualTyOfRecdFieldForTycon fref.Tycon tinst fref.RecdField
+let actualTyOfUnionFieldRef (fref:UnionCaseRef) n tinst =
+ actualTyOfRecdFieldForTycon fref.Tycon tinst (fref.FieldByIndex(n))
+
//---------------------------------------------------------------------------
// Apply type functions to types
@@ -1456,6 +1469,7 @@ let isUnitTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref,_) -> t
let isObjTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref,_) -> tyconRefEq g g.system_Object_tcref tcref | _ -> false)
let isVoidTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref,_) -> tyconRefEq g g.system_Void_tcref tcref | _ -> false)
let isILAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref,_) -> tcref.IsILTycon | _ -> false)
+let isNativePtrTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref,_) -> tyconRefEq g g.nativeptr_tcr tcref | _ -> false)
let isByrefTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref,_) -> tyconRefEq g g.byref_tcr tcref | _ -> false)
let isByrefLikeTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref,_) -> isByrefLikeTyconRef g tcref | _ -> false)
#if EXTENSIONTYPING
@@ -2651,6 +2665,7 @@ let TyconRefHasAttribute g m attribSpec tcref =
//-------------------------------------------------------------------------
let destByrefTy g ty = if isByrefTy g ty then List.head (argsOfAppTy g ty) else failwith "destByrefTy: not a byref type"
+let destNativePtrTy g ty = if isNativePtrTy g ty then List.head (argsOfAppTy g ty) else failwith "destNativePtrTy: not a native ptr type"
let isRefCellTy g ty =
match tryDestAppTy g ty with
@@ -4138,6 +4153,7 @@ and accFreeInOp opts op acc =
// Things containing just a union case reference
| TOp.UnionCaseProof cr
| TOp.UnionCase cr
+ | TOp.UnionCaseFieldGetAddr (cr,_)
| TOp.UnionCaseFieldGet (cr,_)
| TOp.UnionCaseFieldSet (cr,_) -> accFreeUnionCaseRef opts cr acc
@@ -4549,7 +4565,7 @@ and remapExpr g (compgen:ValCopyFlag) (tmenv:Remap) x =
List.map (remapMethod g compgen tmenvinner) overrides,
List.map (remapInterfaceImpl g compgen tmenvinner) iimpls,m)
- // Addresses of immutable field may "leak" across assembly boundaries - see CanTakeAddressOfRecdField below.
+ // Addresses of immutable field may "leak" across assembly boundaries - see CanTakeAddressOfRecdFieldRef below.
// This is "ok", in the sense that it is always valid to fix these up to be uses
// of a temporary local, e.g.
// &(E.RF) --> let mutable v = E.RF in &v
@@ -4563,6 +4579,15 @@ and remapExpr g (compgen:ValCopyFlag) (tmenv:Remap) x =
let tmp,_ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfRecdFieldRef rfref tinst)
mkCompGenLet m tmp (mkRecdFieldGetViaExprAddr(arg,rfref,tinst,m)) (mkValAddr m (mkLocalValRef tmp))
+ | Expr.Op (TOp.UnionCaseFieldGetAddr (uref,cidx),tinst,[arg],m) when
+ not (uref.FieldByIndex(cidx).IsMutable) &&
+ not (entityRefInThisAssembly g.compilingFslib uref.TyconRef) ->
+
+ let tinst = remapTypes tmenv tinst
+ let arg = remapExpr g compgen tmenv arg
+ let tmp,_ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfUnionFieldRef uref cidx tinst)
+ mkCompGenLet m tmp (mkUnionCaseFieldGetProvenViaExprAddr(arg,uref,tinst,cidx,m)) (mkValAddr m (mkLocalValRef tmp))
+
| Expr.Op (op,tinst,args,m) ->
let op' = remapOp tmenv op
let tinst' = remapTypes tmenv tinst
@@ -5020,14 +5045,14 @@ and remarkBind m (TBind(v,repr,_)) =
//--------------------------------------------------------------------------
let isRecdOrStructFieldAllocObservable (f:RecdField) = not f.IsStatic && f.IsMutable
-let ucaseAllocObservable (uc:UnionCase) = uc.FieldTable.FieldsByIndex |> Array.exists isRecdOrStructFieldAllocObservable
-let isUnionCaseAllocObservable (uc:UnionCaseRef) = uc.UnionCase |> ucaseAllocObservable
+let isUnionCaseAllocObservable (uc:UnionCase) = uc.FieldTable.FieldsByIndex |> Array.exists isRecdOrStructFieldAllocObservable
+let isUnionCaseRefAllocObservable (uc:UnionCaseRef) = uc.UnionCase |> isUnionCaseAllocObservable
let isRecdOrUnionOrStructTyconAllocObservable (_g:TcGlobals) (tycon:Tycon) =
- if tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then
+ if tycon.IsUnionTycon then
+ tycon.UnionCasesArray |> Array.exists isUnionCaseAllocObservable
+ elif tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then
tycon.AllFieldsArray |> Array.exists isRecdOrStructFieldAllocObservable
- elif tycon.IsUnionTycon then
- tycon.UnionCasesArray |> Array.exists ucaseAllocObservable
else
false
@@ -5122,6 +5147,7 @@ let rec tyOfExpr g e =
| TOp.ValFieldGet(fref) -> actualTyOfRecdFieldRef fref tinst
| (TOp.ValFieldSet _ | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ | TOp.LValueOp ((LSet | LByrefSet),_)) ->g.unit_ty
| TOp.UnionCaseTagGet _ -> g.int_ty
+ | TOp.UnionCaseFieldGetAddr(cref,j) -> mkByrefTy g (actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j))
| TOp.UnionCaseFieldGet(cref,j) -> actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j)
| TOp.ExnFieldGet(ecref,j) -> recdFieldTyOfExnDefRefByIdx ecref j
| TOp.LValueOp (LByrefGet, v) -> destByrefTy g v.Type
@@ -5346,13 +5372,13 @@ let mkAndSimplifyMatch spBind exprm matchm ty tree targets =
//-------------------------------------------------------------------------
-// mkExprAddrOfExpr
+// mkExprAddrOfExprAux
//-------------------------------------------------------------------------
type Mutates = DefinitelyMutates | PossiblyMutates | NeverMutates
exception DefensiveCopyWarning of string * range
-let isRecdOrStuctTyImmutable g ty =
+let isRecdOrStructTyImmutable g ty =
match tryDestAppTy g ty with
| None -> false
| Some tcref ->
@@ -5371,7 +5397,7 @@ let isRecdOrStuctTyImmutable g ty =
// let g1 = A.G(1)
// (fun () -> g1.x1)
//
-// Note: isRecdOrStuctTyImmutable implies PossiblyMutates or NeverMutates
+// Note: isRecdOrStructTyImmutable implies PossiblyMutates or NeverMutates
//
// We only do this for true local or closure fields because we can't take adddresses of immutable static
// fields across assemblies.
@@ -5382,7 +5408,7 @@ let CanTakeAddressOfImmutableVal g (v:ValRef) mut =
not v.IsMemberOrModuleBinding &&
(match mut with
| NeverMutates -> true
- | PossiblyMutates -> isRecdOrStuctTyImmutable g v.Type
+ | PossiblyMutates -> isRecdOrStructTyImmutable g v.Type
| DefinitelyMutates -> false)
let MustTakeAddressOfVal g (v:ValRef) =
@@ -5390,48 +5416,61 @@ let MustTakeAddressOfVal g (v:ValRef) =
// We can only take the address of mutable values in the same assembly
valRefInThisAssembly g.compilingFslib v
-let MustTakeAddressOfRecdField (rfref: RecdFieldRef) =
+let MustTakeAddressOfRecdField (rf: RecdField) =
// Static mutable fields must be private, hence we don't have to take their address
- not rfref.RecdField.IsStatic &&
- rfref.RecdField.IsMutable
+ not rf.IsStatic &&
+ rf.IsMutable
-let CanTakeAddressOfRecdField g (rfref: RecdFieldRef) mut tinst =
+let MustTakeAddressOfRecdFieldRef (rfref: RecdFieldRef) = MustTakeAddressOfRecdField rfref.RecdField
+
+let CanTakeAddressOfRecdFieldRef g (rfref: RecdFieldRef) mut tinst =
mut <> DefinitelyMutates &&
// We only do this if the field is defined in this assembly because we can't take adddresses across assemblies for immutable fields
entityRefInThisAssembly g.compilingFslib rfref.TyconRef &&
- isRecdOrStuctTyImmutable g (actualTyOfRecdFieldRef rfref tinst)
+ isRecdOrStructTyImmutable g (actualTyOfRecdFieldRef rfref tinst)
+
+let CanTakeAddressOfUnionFieldRef g (uref: UnionCaseRef) mut tinst cidx =
+ mut <> DefinitelyMutates &&
+ // We only do this if the field is defined in this assembly because we can't take adddresses across assemblies for immutable fields
+ entityRefInThisAssembly g.compilingFslib uref.TyconRef &&
+ isRecdOrStructTyImmutable g (actualTyOfUnionFieldRef uref cidx tinst)
-let rec mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m =
- if not mustTakeAddress then (fun x -> x),e else
+let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m =
+ if not mustTakeAddress then None,e else
match e with
// LVALUE: "x" where "x" is byref
| Expr.Op (TOp.LValueOp (LByrefGet, v), _,[], m) ->
- (fun x -> x), exprForValRef m v
+ None, exprForValRef m v
// LVALUE: "x" where "x" is mutable local, mutable intra-assembly module/static binding, or operation doesn't mutate
// Note: we can always take the address of mutable values
| Expr.Val(v, _,m) when MustTakeAddressOfVal g v || CanTakeAddressOfImmutableVal g v mut ->
- (fun x -> x), mkValAddr m v
- // LVALUE: "x" where "e.x" is mutable record field. "e" may be an lvalue
- | Expr.Op (TOp.ValFieldGet rfref, tinst,[e],m) when MustTakeAddressOfRecdField rfref || CanTakeAddressOfRecdField g rfref mut tinst ->
+ None, mkValAddr m v
+ // LVALUE: "x" where "e.x" is record field.
+ | Expr.Op (TOp.ValFieldGet rfref, tinst,[e],m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g rfref mut tinst ->
let exprty = tyOfExpr g e
- let wrap,expra = mkExprAddrOfExpr g (isStructTy g exprty) false mut e None m
+ let wrap,expra = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m
wrap, mkRecdFieldGetAddrViaExprAddr(expra,rfref,tinst,m)
+ // LVALUE: "x" where "e.x" is union field
+ | Expr.Op (TOp.UnionCaseFieldGet (uref,cidx), tinst,[e],m) when MustTakeAddressOfRecdField (uref.FieldByIndex(cidx)) || CanTakeAddressOfUnionFieldRef g uref mut tinst cidx ->
+ let exprty = tyOfExpr g e
+ let wrap,expra = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m
+ wrap, mkUnionCaseFieldGetAddrProvenViaExprAddr(expra,uref,tinst,cidx,m)
// LVALUE: "x" where "e.x" is a .NET static field.
| Expr.Op (TOp.ILAsm ([IL.I_ldsfld(_vol,fspec)],[ty2]), tinst,[],m) ->
- (fun x -> x),Expr.Op (TOp.ILAsm ([IL.I_ldsflda(fspec)],[mkByrefTy g ty2]), tinst,[],m)
+ None,Expr.Op (TOp.ILAsm ([IL.I_ldsflda(fspec)],[mkByrefTy g ty2]), tinst,[],m)
// LVALUE: "x" where "e.x" is a .NET instance field. "e" may be an lvalue
| Expr.Op (TOp.ILAsm ([IL.I_ldfld(_align,_vol,fspec)],[ty2]), tinst,[e],m)
->
let exprty = tyOfExpr g e
- let wrap,expra = mkExprAddrOfExpr g (isStructTy g exprty) false mut e None m
+ let wrap,expra = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m
wrap,Expr.Op (TOp.ILAsm ([IL.I_ldflda(fspec)],[mkByrefTy g ty2]), tinst,[expra],m)
// LVALUE: "x" where "x" is mutable static field.
- | Expr.Op (TOp.ValFieldGet rfref, tinst,[],m) when MustTakeAddressOfRecdField rfref || CanTakeAddressOfRecdField g rfref mut tinst ->
- (fun x -> x), mkStaticRecdFieldGetAddr(rfref,tinst,m)
+ | Expr.Op (TOp.ValFieldGet rfref, tinst,[],m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g rfref mut tinst ->
+ None, mkStaticRecdFieldGetAddr(rfref,tinst,m)
// LVALUE: "e.[n]" where e is an array of structs
| Expr.App(Expr.Val(vf,_,_),_,[elemTy],[aexpr;nexpr],_)
@@ -5443,7 +5482,7 @@ let rec mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut
match addrExprVal with
| Some(vf) -> valRefEq g vf g.addrof2_vref
| _ -> false
- (fun x -> x), Expr.Op (TOp.ILAsm ([IL.I_ldelema(readonly,isNativePtr,shape,mkILTyvarTy 0us)],[mkByrefTy g elemTy]), [elemTy],[aexpr;nexpr],m)
+ None, mkArrayElemAddress g (readonly,isNativePtr,shape,elemTy,aexpr,nexpr,m)
// LVALUE: "e.[n1,n2]", "e.[n1,n2,n3]", "e.[n1,n2,n3,n4]" where e is an array of structs
| Expr.App(Expr.Val(vf,_,_),_,[elemTy],(aexpr::args),_)
@@ -5456,7 +5495,7 @@ let rec mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut
| Some(vf) -> valRefEq g vf g.addrof2_vref
| _ -> false
- (fun x -> x), Expr.Op (TOp.ILAsm ([IL.I_ldelema(readonly,isNativePtr,shape,mkILTyvarTy 0us)],[mkByrefTy g elemTy]), [elemTy],(aexpr::args),m)
+ None, Expr.Op (TOp.ILAsm ([IL.I_ldelema(readonly,isNativePtr,shape,mkILTyvarTy 0us)],[mkByrefTy g elemTy]), [elemTy],(aexpr::args),m)
// Give a nice error message for DefinitelyMutates on immutable values, or mutable values in other assemblies
| Expr.Val(v, _,m) when mut = DefinitelyMutates
@@ -5476,16 +5515,28 @@ let rec mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut
errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(),m));
| PossiblyMutates ->
warning(DefensiveCopyWarning(FSComp.SR.tastValueHasBeenCopied(),m));
- let tmp,_ = mkMutableCompGenLocal m "copyOfStruct" ty
- (fun rest -> mkCompGenLet m tmp e rest), (mkValAddr m (mkLocalValRef tmp))
+ let tmp,_ =
+ match mut with
+ | NeverMutates -> mkCompGenLocal m "copyOfStruct" ty
+ | _ -> mkMutableCompGenLocal m "copyOfStruct" ty
+ Some (tmp,e), (mkValAddr m (mkLocalValRef tmp))
+
+let mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m =
+ let optBind, addre = mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m
+ match optBind with
+ | None -> (fun x -> x), addre
+ | Some (tmp,rval) -> (fun x -> mkCompGenLet m tmp rval x), addre
let mkRecdFieldGet g (e,fref:RecdFieldRef,tinst,m) =
+ assert (not (isByrefTy g (tyOfExpr g e)))
let wrap,e' = mkExprAddrOfExpr g fref.Tycon.IsStructOrEnumTycon false NeverMutates e None m
wrap (mkRecdFieldGetViaExprAddr(e',fref,tinst,m))
-let mkRecdFieldSet g (e,fref:RecdFieldRef,tinst,e2,m) =
- let wrap,e' = mkExprAddrOfExpr g fref.Tycon.IsStructOrEnumTycon false DefinitelyMutates e None m
- wrap (mkRecdFieldSetViaExprAddr(e',fref,tinst,e2,m))
+let mkUnionCaseFieldGetUnproven g (e,cref:UnionCaseRef,tinst,j,m) =
+ assert (not (isByrefTy g (tyOfExpr g e)))
+ let wrap,e' = mkExprAddrOfExpr g cref.Tycon.IsStructOrEnumTycon false NeverMutates e None m
+ wrap (mkUnionCaseFieldGetUnprovenViaExprAddr (e',cref,tinst,j,m))
+
let mkArray (argty, args, m) = Expr.Op(TOp.Array, [argty],args,m)
@@ -5525,12 +5576,13 @@ let rec IterateRecursiveFixups g (selfv : Val option) rvs ((access : Expr),set)
| Expr.Op (TOp.UnionCase (c),tinst,args,m) ->
args |> List.iteri (fun n ->
IterateRecursiveFixups g None rvs
- (mkUnionCaseFieldGetUnproven(access,c,tinst,n,m),
+ (mkUnionCaseFieldGetUnprovenViaExprAddr (access,c,tinst,n,m),
(fun e ->
// NICE: it would be better to do this check in the type checker
let tcref = c.TyconRef
- errorR(Error(FSComp.SR.tastRecursiveValuesMayNotAppearInConstructionOfType(tcref.LogicalName),m));
- mkUnionCaseFieldSet(access,c,tinst,n,e,m))))
+ if not (c.FieldByIndex(n)).IsMutable && not (entityRefInThisAssembly g.compilingFslib tcref) then
+ errorR(Error(FSComp.SR.tastRecursiveValuesMayNotAppearInConstructionOfType(tcref.LogicalName),m));
+ mkUnionCaseFieldSet (access,c,tinst,n,e,m))))
| Expr.Op (TOp.Recd (_,tcref),tinst,args,m) ->
(tcref.TrueInstanceFieldsAsRefList, args) ||> List.iter2 (fun fref arg ->
@@ -5541,7 +5593,7 @@ let rec IterateRecursiveFixups g (selfv : Val option) rvs ((access : Expr),set)
// NICE: it would be better to do this check in the type checker
if not fspec.IsMutable && not (entityRefInThisAssembly g.compilingFslib tcref) then
errorR(Error(FSComp.SR.tastRecursiveValuesMayNotBeAssignedToNonMutableField(fspec.rfield_id.idText, tcref.LogicalName),m));
- mkRecdFieldSet g (access,fref,tinst,e,m))) arg )
+ mkRecdFieldSetViaExprAddr (access,fref,tinst,e,m))) arg )
| Expr.Val _
| Expr.Lambda _
| Expr.Obj _
@@ -5872,8 +5924,8 @@ let mkRecordExpr g (lnk,tcref,tinst,rfrefs:RecdFieldRef list,args,m) =
//-------------------------------------------------------------------------
let mkRefCell g m ty e = mkRecordExpr g (RecdExpr,g.refcell_tcr_canon,[ty],[mkRefCellContentsRef g],[e],m)
-let mkRefCellGet g m ty e = mkRecdFieldGet g (e,mkRefCellContentsRef g,[ty],m)
-let mkRefCellSet g m ty e1 e2 = mkRecdFieldSet g (e1,mkRefCellContentsRef g,[ty],e2,m)
+let mkRefCellGet g m ty e = mkRecdFieldGetViaExprAddr (e,mkRefCellContentsRef g,[ty],m)
+let mkRefCellSet g m ty e1 e2 = mkRecdFieldSetViaExprAddr (e1,mkRefCellContentsRef g,[ty],e2,m)
let mkNil g m ty = mkUnionCaseExpr (g.nil_ucref,[ty],[],m)
let mkCons g ty h t = mkUnionCaseExpr (g.cons_ucref,[ty],[h;t],unionRanges h.Range t.Range)
@@ -7868,8 +7920,8 @@ let DetectAndOptimizeForExpression g option expr =
let elemTy = destListTy g enumerableTy
let guardExpr = mkNonNullTest g m nextExpr
- let headOrDefaultExpr = mkUnionCaseFieldGetUnproven(currentExpr,g.cons_ucref,[elemTy],IndexHead,m)
- let tailOrNullExpr = mkUnionCaseFieldGetUnproven(currentExpr,g.cons_ucref,[elemTy],IndexTail,mBody)
+ let headOrDefaultExpr = mkUnionCaseFieldGetUnprovenViaExprAddr (currentExpr,g.cons_ucref,[elemTy],IndexHead,m)
+ let tailOrNullExpr = mkUnionCaseFieldGetUnprovenViaExprAddr (currentExpr,g.cons_ucref,[elemTy],IndexTail,mBody)
let bodyExpr =
mkCompGenLet m elemVar headOrDefaultExpr
(mkCompGenSequential mBody
diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi
index e4719f1b86f..ad0ce3d440e 100755
--- a/src/fsharp/TastOps.fsi
+++ b/src/fsharp/TastOps.fsi
@@ -188,14 +188,39 @@ val mkStaticRecdFieldGet : RecdFieldRef * TypeInst
val mkStaticRecdFieldSet : RecdFieldRef * TypeInst * Expr * range -> Expr
val mkStaticRecdFieldGetAddr : RecdFieldRef * TypeInst * range -> Expr
val mkRecdFieldSetViaExprAddr : Expr * RecdFieldRef * TypeInst * Expr * range -> Expr
-val mkUnionCaseTagGet : Expr * TyconRef * TypeInst * range -> Expr
+val mkUnionCaseTagGetViaExprAddr : Expr * TyconRef * TypeInst * range -> Expr
+
+/// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions)
val mkUnionCaseProof : Expr * UnionCaseRef * TypeInst * range -> Expr
-val mkUnionCaseFieldGetProven : Expr * UnionCaseRef * TypeInst * int * range -> Expr
-val mkUnionCaseFieldGetUnproven : Expr * UnionCaseRef * TypeInst * int * range -> Expr
-val mkExnCaseFieldGet : Expr * TyconRef * int * range -> Expr
+
+/// Build a 'TOp.UnionCaseFieldGet' expression for something we've already determined to be a particular union case. For ref-unions,
+/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions,
+/// the input should be the address of the expression.
+val mkUnionCaseFieldGetProvenViaExprAddr : Expr * UnionCaseRef * TypeInst * int * range -> Expr
+
+/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions,
+/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions,
+/// the input should be the address of the expression.
+val mkUnionCaseFieldGetAddrProvenViaExprAddr : Expr * UnionCaseRef * TypeInst * int * range -> Expr
+
+/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions,
+/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions,
+/// the input should be the address of the expression.
+val mkUnionCaseFieldGetUnprovenViaExprAddr : Expr * UnionCaseRef * TypeInst * int * range -> Expr
+
+/// Build a 'TOp.UnionCaseFieldSet' expression. For ref-unions, the input expression has 'TType_ucase', which is
+/// an F# compiler internal "type" corresponding to the union case. For struct-unions,
+/// the input should be the address of the expression.
val mkUnionCaseFieldSet : Expr * UnionCaseRef * TypeInst * int * Expr * range -> Expr
+
+/// Like mkUnionCaseFieldGetUnprovenViaExprAddr, but for struct-unions, the input should be a copy of the expression.
+val mkUnionCaseFieldGetUnproven : TcGlobals -> Expr * UnionCaseRef * TypeInst * int * range -> Expr
+
+val mkExnCaseFieldGet : Expr * TyconRef * int * range -> Expr
val mkExnCaseFieldSet : Expr * TyconRef * int * Expr * range -> Expr
+val mkArrayElemAddress : TcGlobals -> ILReadonly * bool * ILArrayShape * TType * Expr * Expr * range -> Expr
+
//-------------------------------------------------------------------------
// Compiled view of tuples
//-------------------------------------------------------------------------
@@ -217,6 +242,7 @@ val mkGetTupleItemN : TcGlobals -> range -> int -> ILType -> Expr -> TType -> Ex
exception DefensiveCopyWarning of string * range
type Mutates = DefinitelyMutates | PossiblyMutates | NeverMutates
+val mkExprAddrOfExprAux : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Val * Expr) option * Expr
val mkExprAddrOfExpr : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Expr -> Expr) * Expr
//-------------------------------------------------------------------------
@@ -811,7 +837,6 @@ val mkValAddr : range -> ValRef -> Expr
//-------------------------------------------------------------------------
val mkRecdFieldGet : TcGlobals -> Expr * RecdFieldRef * TypeInst * range -> Expr
-val mkRecdFieldSet : TcGlobals -> Expr * RecdFieldRef * TypeInst * Expr * range -> Expr
//-------------------------------------------------------------------------
// Get the targets used in a decision graph (for reporting warnings)
@@ -907,7 +932,7 @@ val ExprStats : Expr -> string
// Make some common types
//-------------------------------------------------------------------------
-val mkNativePtrType : TcGlobals -> TType -> TType
+val mkNativePtrTy : TcGlobals -> TType -> TType
val mkArrayType : TcGlobals -> TType -> TType
val isOptionTy : TcGlobals -> TType -> bool
val destOptionTy : TcGlobals -> TType -> TType
@@ -1023,7 +1048,7 @@ val TypeHasDefaultValue : TcGlobals -> range -> TType -> bool
val isAbstractTycon : Tycon -> bool
-val isUnionCaseAllocObservable : UnionCaseRef -> bool
+val isUnionCaseRefAllocObservable : UnionCaseRef -> bool
val isRecdOrUnionOrStructTyconRefAllocObservable : TcGlobals -> TyconRef -> bool
val isExnAllocObservable : TyconRef -> bool
val isUnionCaseFieldMutable : TcGlobals -> UnionCaseRef -> int -> bool
@@ -1256,7 +1281,9 @@ val mkCompilerGeneratedAttr : TcGlobals -> int -> ILAtt
//-------------------------------------------------------------------------
val isByrefTy : TcGlobals -> TType -> bool
+val isNativePtrTy : TcGlobals -> TType -> bool
val destByrefTy : TcGlobals -> TType -> TType
+val destNativePtrTy : TcGlobals -> TType -> TType
val isByrefLikeTyconRef : TcGlobals -> TyconRef -> bool
val isByrefLikeTy : TcGlobals -> TType -> bool
diff --git a/src/fsharp/TastPickle.fs b/src/fsharp/TastPickle.fs
index 2b68fbb7c57..cf37fbfc193 100755
--- a/src/fsharp/TastPickle.fs
+++ b/src/fsharp/TastPickle.fs
@@ -2315,6 +2315,7 @@ and p_op x st =
| TOp.ValFieldGetAddr (a) -> p_byte 25 st; p_rfref a st
| TOp.UInt16s arr -> p_byte 26 st; p_array p_uint16 arr st
| TOp.Reraise -> p_byte 27 st
+ | TOp.UnionCaseFieldGetAddr (a,b) -> p_byte 28 st; p_tup2 p_ucref p_int (a,b) st
| TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST"
#endif
@@ -2376,6 +2377,9 @@ and u_op st =
TOp.ValFieldGetAddr a
| 26 -> TOp.UInt16s (u_array u_uint16 st)
| 27 -> TOp.Reraise
+ | 28 -> let a = u_ucref st
+ let b = u_int st
+ TOp.UnionCaseFieldGetAddr (a,b)
| _ -> ufailwith st "u_op"
#if INCLUDE_METADATA_WRITER
diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs
index a02124d5e42..6d23531256f 100755
--- a/src/fsharp/TcGlobals.fs
+++ b/src/fsharp/TcGlobals.fs
@@ -218,6 +218,7 @@ type public TcGlobals =
system_Array_typ : TType
system_Object_typ : TType
system_IDisposable_typ : TType
+ system_RuntimeHelpers_typ : TType
system_Value_typ : TType
system_Delegate_typ : TType
system_MulticastDelegate_typ : TType
@@ -298,6 +299,10 @@ type public TcGlobals =
attrib_PreserveSigAttribute : BuiltinAttribInfo option
attrib_MethodImplAttribute : BuiltinAttribInfo
attrib_ExtensionAttribute : BuiltinAttribInfo
+ attrib_CallerLineNumberAttribute : BuiltinAttribInfo
+ attrib_CallerFilePathAttribute : BuiltinAttribInfo
+ attrib_CallerMemberNameAttribute : BuiltinAttribInfo
+
tcref_System_Collections_Generic_IList : TyconRef
tcref_System_Collections_Generic_IReadOnlyList : TyconRef
tcref_System_Collections_Generic_ICollection : TyconRef
@@ -616,6 +621,7 @@ let mkTcGlobals (compilingFslib,sysCcu,ilg,fslibCcu,directoryToResolveRelativePa
let sysLinq = ["System";"Linq"]
let sysCollections = ["System";"Collections"]
let sysGenerics = ["System";"Collections";"Generic"]
+ let sysCompilerServices = ["System";"Runtime";"CompilerServices"]
let lazy_tcr = mkSysTyconRef sys "Lazy`1"
let fslib_IEvent2_tcr = mk_MFControl_tcref fslibCcu "IEvent`2"
@@ -666,7 +672,7 @@ let mkTcGlobals (compilingFslib,sysCcu,ilg,fslibCcu,directoryToResolveRelativePa
(* local helpers to build value infos *)
let mkNullableTy ty = TType_app(nullable_tcr, [ty])
let mkByrefTy ty = TType_app(byref_tcr, [ty])
- let mkNativePtrType ty = TType_app(nativeptr_tcr, [ty])
+ let mkNativePtrTy ty = TType_app(nativeptr_tcr, [ty])
let mkFunTy d r = TType_fun (d,r)
let (-->) d r = mkFunTy d r
let mkIteratedFunTy dl r = List.foldBack (-->) dl r
@@ -845,7 +851,7 @@ let mkTcGlobals (compilingFslib,sysCcu,ilg,fslibCcu,directoryToResolveRelativePa
let and_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "&" ,None ,None ,[], mk_rel_sig bool_ty)
let addrof_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "~&" ,None ,None ,[vara], ([[varaTy]], mkByrefTy varaTy))
- let addrof2_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "~&&" ,None ,None ,[vara], ([[varaTy]], mkNativePtrType varaTy))
+ let addrof2_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "~&&" ,None ,None ,[vara], ([[varaTy]], mkNativePtrTy varaTy))
let and2_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "&&" ,None ,None ,[], mk_rel_sig bool_ty)
let or_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, "or" ,None ,Some "Or" ,[], mk_rel_sig bool_ty)
let or2_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "||" ,None ,None ,[], mk_rel_sig bool_ty)
@@ -1099,6 +1105,7 @@ let mkTcGlobals (compilingFslib,sysCcu,ilg,fslibCcu,directoryToResolveRelativePa
system_Array_typ = mkSysNonGenericTy sys "Array"
system_Object_typ = mkSysNonGenericTy sys "Object"
system_IDisposable_typ = mkSysNonGenericTy sys "IDisposable"
+ system_RuntimeHelpers_typ = mkSysNonGenericTy sysCompilerServices "RuntimeHelpers"
system_Value_typ = mkSysNonGenericTy sys "ValueType"
system_Delegate_typ = mkSysNonGenericTy sys "Delegate"
system_MulticastDelegate_typ = mkSysNonGenericTy sys "MulticastDelegate"
@@ -1200,7 +1207,10 @@ let mkTcGlobals (compilingFslib,sysCcu,ilg,fslibCcu,directoryToResolveRelativePa
attrib_PreserveSigAttribute = mkSystemRuntimeInteropServicesAttribute "System.Runtime.InteropServices.PreserveSigAttribute"
attrib_MethodImplAttribute = mkSystemRuntimeAttrib "System.Runtime.CompilerServices.MethodImplAttribute"
attrib_ExtensionAttribute = mkSystemRuntimeAttrib "System.Runtime.CompilerServices.ExtensionAttribute"
-
+ attrib_CallerLineNumberAttribute = mkSystemRuntimeAttrib "System.Runtime.CompilerServices.CallerLineNumberAttribute"
+ attrib_CallerFilePathAttribute = mkSystemRuntimeAttrib "System.Runtime.CompilerServices.CallerFilePathAttribute"
+ attrib_CallerMemberNameAttribute = mkSystemRuntimeAttrib "System.Runtime.CompilerServices.CallerMemberNameAttribute"
+
attrib_ProjectionParameterAttribute = mk_MFCore_attrib "ProjectionParameterAttribute"
attrib_CustomOperationAttribute = mk_MFCore_attrib "CustomOperationAttribute"
attrib_NonSerializedAttribute = if ilg.traits.NonSerializedAttributeScopeRef.IsSome then Some(mkSystemRuntimeAttrib "System.NonSerializedAttribute") else None
diff --git a/src/fsharp/TraceCall.fs b/src/fsharp/TraceCall.fs
deleted file mode 100644
index db24974fece..00000000000
--- a/src/fsharp/TraceCall.fs
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-namespace Internal.Utilities.Debug
-
-open System
-open System.IO
-open System.Threading
-open System.Diagnostics
-open System.Runtime.InteropServices
-
-
-module internal TraceInterop =
- type MessageBeepType =
- | Default = -1
- | Ok = 0x00000000
- | Error = 0x00000010
- | Question = 0x00000020
- | Warning = 0x00000030
- | Information = 0x00000040
-
- []
- let MessageBeep(_mbt:MessageBeepType):bool=failwith ""
-
-[]
-[]
-type internal Trace private() =
- static let mutable log = ""
-#if DEBUG_WITH_TIME_AND_THREAD_INFO
- static let TMinusZero = DateTime.Now
-#endif
- static let noopDisposable =
- { new IDisposable with
- member this.Dispose() = ()
- }
- static let mutable out = Console.Out
- [] [] static val mutable private indent:int
- [] [] static val mutable private threadName:string
-
- /// Set to the semicolon-delimited names of the logging classes to be reported.
- /// Use * to mean all.
- static member Log
- with get() = log
- and set(value) = log<-value
-
- /// Output destination.
- static member Out
- with get() = out
- and set(value:TextWriter) = out<-value
-
- /// True if the given logging class should be logged.
- static member ShouldLog(loggingClass) =
- let result = Trace.Log = "*" || Trace.Log.Contains(loggingClass^";") || Trace.Log.EndsWith(loggingClass,StringComparison.Ordinal)
- result
-
- /// Description of the current thread.
- static member private CurrentThreadInfo() =
- if String.IsNullOrEmpty(Trace.threadName) then sprintf "(id=%d)" Thread.CurrentThread.ManagedThreadId
- else sprintf "(id=%d,name=%s)" Thread.CurrentThread.ManagedThreadId Trace.threadName
-
- /// Report the elapsed time since start.
- static member private ElapsedTime(start) =
- let elapsed : TimeSpan = (DateTime.Now-start)
- sprintf "%A ms" elapsed.TotalMilliseconds
-
- /// Get a string with spaces for indention.
- static member private IndentSpaces() = new string(' ', Trace.indent)
-
- /// Log a message.
- static member private LogMessage(msg:string) =
- Trace.Out.Write(sprintf "%s%s" (Trace.IndentSpaces()) msg)
- Trace.Out.Flush()
- if Trace.Out<>Console.Out then
- // Always log to console.
- Console.Out.Write(sprintf "%s%s" (Trace.IndentSpaces()) msg)
-
- /// Name the current thread.
- static member private NameCurrentThread(threadName) =
- match threadName with
- | Some(threadName)->
- let current = Trace.threadName
- if String.IsNullOrEmpty(current) then Trace.threadName <- threadName
- else if not(current.Contains(threadName)) then Trace.threadName <- current^","^threadName
- | None -> ()
-
- /// Base implementation of the call function.
- static member private CallImpl(loggingClass,functionName,descriptionFunc,threadName:string option) : IDisposable =
- #if DEBUG
- if Trace.ShouldLog(loggingClass) then
- Trace.NameCurrentThread(threadName)
-
- let description = try descriptionFunc() with e->"No description because of exception"
-
-#if DEBUG_WITH_TIME_AND_THREAD_INFO
- let threadInfo = Trace.CurrentThreadInfo()
- let indent = Trace.IndentSpaces()
- let start = DateTime.Now
- Trace.LogMessage(sprintf "Entering %s(%s) %s t-plus %fms %s\n"
- functionName
- loggingClass
- threadInfo
- (start-TMinusZero).TotalMilliseconds
- description)
-#else
- Trace.LogMessage(sprintf "Entering %s(%s) %s\n"
- functionName
- loggingClass
- description)
-#endif
- Trace.indent<-Trace.indent+1
-
- {new IDisposable with
- member d.Dispose() =
- Trace.indent<-Trace.indent-1
-#if DEBUG_WITH_TIME_AND_THREAD_INFO
- Trace.LogMessage(sprintf "Exitting %s %s %s\n"
- functionName
- threadInfo
- (Trace.ElapsedTime(start)))}
-#else
- Trace.LogMessage(sprintf "Exiting %s\n"
- functionName)}
-#endif
- else
- noopDisposable : IDisposable
- #else
- ignore(loggingClass,functionName,descriptionFunc,threadName)
- noopDisposable : IDisposable
- #endif
-
- /// Log a method as it's called.
- static member Call(loggingClass:string,functionName:string,descriptionFunc:unit->string) = Trace.CallImpl(loggingClass,functionName,descriptionFunc,None)
- /// Log a method as it's called. Expected always to be called on the same thread which will be named 'threadName'.
- static member CallByThreadNamed(loggingClass:string,functionName:string,threadName:string,descriptionFunc:unit->string) = Trace.CallImpl(loggingClass,functionName,descriptionFunc,Some(threadName))
- /// Log a message by logging class.
- static member PrintLine(loggingClass:string, messageFunc:unit->string) =
- #if DEBUG
- if Trace.ShouldLog(loggingClass) then
- let message = try messageFunc() with _-> "No message because of exception.\n"
- Trace.LogMessage(sprintf "%s%s" message System.Environment.NewLine)
- #else
- ignore(loggingClass,messageFunc)
- #endif
-
- /// Log a message by logging class.
- static member Print(loggingClass:string, messageFunc:unit->string) =
- #if DEBUG
- if Trace.ShouldLog(loggingClass) then
- let message = try messageFunc() with _-> "No message because of exception.\n"
- Trace.LogMessage(message)
- #else
- ignore(loggingClass,messageFunc)
- #endif
-
- /// Make a beep when the given loggingClass is matched.
- static member private BeepHelper(loggingClass,beeptype) =
- #if DEBUG
- if Trace.ShouldLog(loggingClass) then
- TraceInterop.MessageBeep(beeptype) |> ignore
- #else
- ignore(loggingClass,beeptype)
- #endif
-
- /// Make the "OK" sound when the given loggingClass is matched.
- static member BeepOk(loggingClass:string) = Trace.BeepHelper(loggingClass,TraceInterop.MessageBeepType.Ok)
-
- /// Make the "Error" sound when the given loggingClass is matched.
- static member BeepError(loggingClass:string) = Trace.BeepHelper(loggingClass,TraceInterop.MessageBeepType.Error)
-
- /// Make the default sound when the given loggingClass is matched.
- static member Beep(loggingClass:string) = Trace.BeepHelper(loggingClass,TraceInterop.MessageBeepType.Default)
-
-
diff --git a/src/fsharp/TraceCall.fsi b/src/fsharp/TraceCall.fsi
deleted file mode 100644
index 609d1d1bb0e..00000000000
--- a/src/fsharp/TraceCall.fsi
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-namespace Internal.Utilities.Debug
- module internal TraceInterop =
- type MessageBeepType =
- | Default = -1
- | Ok = 0
- | Error = 16
- | Question = 32
- | Warning = 48
- | Information = 64
- val MessageBeep : MessageBeepType -> bool
- []
- type internal Trace =
- static member Beep : loggingClass:string -> unit
- static member BeepError : loggingClass:string -> unit
- static member BeepOk : loggingClass:string -> unit
- static member Call : loggingClass:string * functionName:string * descriptionFunc:(unit->string) -> System.IDisposable
- static member CallByThreadNamed : loggingClass:string * functionName:string * threadName:string * descriptionFunc:(unit->string) -> System.IDisposable
- static member Print : loggingClass:string * messageFunc:(unit->string) -> unit
- static member PrintLine : loggingClass:string * messageFunc:(unit->string) -> unit
- static member ShouldLog : loggingClass:string -> bool
- static member Log : string with get, set
- static member Out : System.IO.TextWriter with get, set
-
diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs
index c8cfc054800..c77de8b545f 100755
--- a/src/fsharp/TypeChecker.fs
+++ b/src/fsharp/TypeChecker.fs
@@ -277,6 +277,8 @@ type TcEnv =
// Information to enforce special restrictions on valid expressions
// for .NET constructors.
eCtorInfo : CtorInfo option
+
+ eCallerMemberName : string option
}
member tenv.DisplayEnv = tenv.eNameResEnv.DisplayEnv
member tenv.NameEnv = tenv.eNameResEnv
@@ -298,7 +300,8 @@ let emptyTcEnv g =
eContextInfo=ContextInfo.NoContext
eModuleOrNamespaceTypeAccumulator= ref (NewEmptyModuleOrNamespaceType Namespace)
eFamilyType=None
- eCtorInfo=None }
+ eCtorInfo=None
+ eCallerMemberName=None}
//-------------------------------------------------------------------------
// Helpers related to determining if we're in a constructor and/or a class
@@ -1048,7 +1051,7 @@ type DeclKind =
| IntrinsicExtensionBinding
/// Extensions to a type in a different assembly
| ExtrinsicExtensionBinding
- | ClassLetBinding
+ | ClassLetBinding of (* isStatic *) bool
| ObjectExpressionOverrideBinding
| ExpressionBinding
@@ -1057,7 +1060,7 @@ type DeclKind =
| ModuleOrMemberBinding -> true
| IntrinsicExtensionBinding -> true
| ExtrinsicExtensionBinding -> true
- | ClassLetBinding -> false
+ | ClassLetBinding _ -> false
| ObjectExpressionOverrideBinding -> false
| ExpressionBinding -> false
@@ -1068,7 +1071,7 @@ type DeclKind =
| ModuleOrMemberBinding -> true
| IntrinsicExtensionBinding -> true
| ExtrinsicExtensionBinding -> true
- | ClassLetBinding -> true
+ | ClassLetBinding _ -> true
| ObjectExpressionOverrideBinding -> false
| ExpressionBinding -> false
@@ -1088,7 +1091,7 @@ type DeclKind =
| None -> AttributeTargets.Field ||| AttributeTargets.Method ||| AttributeTargets.Property
| IntrinsicExtensionBinding -> AttributeTargets.Method ||| AttributeTargets.Property
| ExtrinsicExtensionBinding -> AttributeTargets.Method ||| AttributeTargets.Property
- | ClassLetBinding -> AttributeTargets.Field ||| AttributeTargets.Method
+ | ClassLetBinding _ -> AttributeTargets.Field ||| AttributeTargets.Method
| ExpressionBinding -> enum 0 // indicates attributes not allowed on expression 'let' bindings
// Note: now always true
@@ -1097,7 +1100,7 @@ type DeclKind =
| ModuleOrMemberBinding -> true
| IntrinsicExtensionBinding -> true
| ExtrinsicExtensionBinding -> true
- | ClassLetBinding -> true
+ | ClassLetBinding _ -> true
| ObjectExpressionOverrideBinding -> true
| ExpressionBinding -> true
@@ -1106,7 +1109,7 @@ type DeclKind =
| ModuleOrMemberBinding -> true
| IntrinsicExtensionBinding -> true
| ExtrinsicExtensionBinding -> true
- | ClassLetBinding -> true
+ | ClassLetBinding _ -> true
| ObjectExpressionOverrideBinding -> true
| ExpressionBinding -> false
@@ -1115,7 +1118,7 @@ type DeclKind =
| ModuleOrMemberBinding -> OverridesOK
| IntrinsicExtensionBinding -> WarnOnOverrides
| ExtrinsicExtensionBinding -> ErrorOnOverrides
- | ClassLetBinding -> ErrorOnOverrides
+ | ClassLetBinding _ -> ErrorOnOverrides
| ObjectExpressionOverrideBinding -> OverridesOK
| ExpressionBinding -> ErrorOnOverrides
@@ -1196,7 +1199,6 @@ type TcPatPhase2Input =
type CheckedBindingInfo =
| CheckedBindingInfo of
ValInline *
- bool * (* immutable? *)
Tast.Attribs *
XmlDoc *
(TcPatPhase2Input -> PatternMatchCompilation.Pattern) *
@@ -1207,10 +1209,11 @@ type CheckedBindingInfo =
TType *
range *
SequencePointInfoForBinding *
- bool * (* compiler generated? *)
- Const option (* literal value? *)
- member x.Expr = let (CheckedBindingInfo(_,_,_,_,_,_,_,expr,_,_,_,_,_,_)) = x in expr
- member x.SeqPoint = let (CheckedBindingInfo(_,_,_,_,_,_,_,_,_,_,_,spBind,_,_)) = x in spBind
+ bool * // compiler generated?
+ Const option * // literal value?
+ bool // fixed?
+ member x.Expr = let (CheckedBindingInfo(_,_,_,_,_,_,expr,_,_,_,_,_,_,_)) = x in expr
+ member x.SeqPoint = let (CheckedBindingInfo(_,_,_,_,_,_,_,_,_,_,spBind,_,_,_)) = x in spBind
//-------------------------------------------------------------------------
// Helpers related to type schemes
@@ -2037,7 +2040,7 @@ module GeneralizationHelpers =
| Expr.Op(op,_,args,_) ->
match op with
| TOp.Tuple -> true
- | TOp.UnionCase uc -> not (isUnionCaseAllocObservable uc)
+ | TOp.UnionCase uc -> not (isUnionCaseRefAllocObservable uc)
| TOp.Recd(ctorInfo,tcref) ->
match ctorInfo with
| RecdExpr -> not (isRecdOrUnionOrStructTyconRefAllocObservable g tcref)
@@ -2174,7 +2177,7 @@ module GeneralizationHelpers =
let ComputeAndGeneralizeGenericTypars (cenv,
denv:DisplayEnv,
m,
- immut,
+ canGeneralize,
freeInEnv:FreeTypars,
canInferTypars,
genConstrainedTyparFlag,
@@ -2187,7 +2190,7 @@ module GeneralizationHelpers =
let allDeclaredTypars = NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g allDeclaredTypars
let typarsToAttemptToGeneralize =
- if immut && (match exprOpt with None -> true | Some e -> IsGeneralizableValue cenv.g e)
+ if canGeneralize && (match exprOpt with None -> true | Some e -> IsGeneralizableValue cenv.g e)
then (ListSet.unionFavourLeft typarEq allDeclaredTypars maxInferredTypars)
else allDeclaredTypars
@@ -2945,6 +2948,17 @@ let BuildDisposableCleanup cenv env m (v:Val) =
let inpe = mkCoerceExpr(exprForVal v.Range v,cenv.g.obj_ty,m,v.Type)
mkIsInstConditional cenv.g m cenv.g.system_IDisposable_typ inpe disposeObjVar disposeExpr (mkUnit cenv.g m)
+/// Build call to get_OffsetToStringData as part of 'fixed'
+let BuildOffsetToStringData cenv env m =
+ let ad = env.eAccessRights
+ let offsetToStringDataMethod =
+ match TryFindIntrinsicOrExtensionMethInfo cenv env m ad "get_OffsetToStringData" cenv.g.system_RuntimeHelpers_typ with
+ | [x] -> x
+ | _ -> error(Error(FSComp.SR.tcCouldNotFindOffsetToStringData(),m))
+
+ let offsetExpr,_ = BuildPossiblyConditionalMethodCall cenv env NeverMutates m false offsetToStringDataMethod NormalValUse [] [] []
+ offsetExpr
+
let BuildILFieldGet g amap m objExpr (finfo:ILFieldInfo) =
let fref = finfo.ILFieldRef
let isValueType = finfo.IsValueType
@@ -3000,7 +3014,8 @@ let BuildRecdFieldSet g m objExpr (rfinfo:RecdFieldInfo) argExpr =
let tgty = rfinfo.EnclosingType
let valu = isStructTy g tgty
let objExpr = if valu then objExpr else mkCoerceExpr(objExpr,tgty,m,tyOfExpr g objExpr)
- mkRecdFieldSet g (objExpr,rfinfo.RecdFieldRef,rfinfo.TypeInst,argExpr,m)
+ let wrap,objExpr = mkExprAddrOfExpr g valu false DefinitelyMutates objExpr None m
+ wrap (mkRecdFieldSetViaExprAddr (objExpr,rfinfo.RecdFieldRef,rfinfo.TypeInst,argExpr,m) )
//-------------------------------------------------------------------------
@@ -3448,7 +3463,7 @@ module MutRecShapes =
| MutRecShape.Tycon a -> MutRecShape.Tycon (f2 parent a)
| MutRecShape.Lets b -> MutRecShape.Lets (f3 parent b)
| MutRecShape.Module (c,d) ->
- let c2, parent2 = f1 parent c
+ let c2, parent2 = f1 parent c d
MutRecShape.Module (c2, mapWithParent parent2 f1 f2 f3 d))
let rec computeEnvs f1 f2 (env: 'Env) xs =
@@ -3774,7 +3789,7 @@ let CheckAndRewriteObjectCtor g env (ctorLambaExpr:Expr) =
let thisTy = tyOfExpr g recdExpr
let thisExpr = mkGetArg0 m thisTy
let thisTyInst = argsOfAppTy g thisTy
- let setExpr = mkRecdFieldSet g (thisExpr, rfref, thisTyInst, mkOne g m, m)
+ let setExpr = mkRecdFieldSetViaExprAddr (thisExpr, rfref, thisTyInst, mkOne g m, m)
Expr.Sequential(recdExpr,setExpr,ThenDoSeq,SuppressSequencePointOnExprOfSequential,m)
recdExpr
@@ -5499,6 +5514,9 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) =
| SynExpr.Assert (x,m) ->
TcAssertExpr cenv overallTy env m tpenv x
+ | SynExpr.Fixed (_,m) ->
+ error(Error(FSComp.SR.tcFixedNotAllowed(),m))
+
// e : ty
| SynExpr.Typed (e,cty,m) ->
let tgty,tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv cty
@@ -5823,7 +5841,7 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) =
| SynExpr.LibraryOnlyUnionCaseFieldGet (e1,c,n,m) ->
let e1',ty1,tpenv = TcExprOfUnknownType cenv env tpenv e1
let mkf,ty2 = TcUnionCaseOrExnField cenv env ty1 m c n
- ((fun (a,b) n -> mkUnionCaseFieldGetUnproven(e1',a,b,n,m)),
+ ((fun (a,b) n -> mkUnionCaseFieldGetUnproven cenv.g (e1',a,b,n,m)),
(fun a n -> mkExnCaseFieldGet(e1',a,n,m)))
UnifyTypes cenv env m overallTy ty2
mkf n,tpenv
@@ -6109,18 +6127,19 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m =
(fname,fieldExpr),tpenv)
// Add rebindings for unbound field when an "old value" is available
- let oldFldsList =
+ // Effect order: mutable fields may get modified by other bindings...
+ let oldFldsList, wrap =
match optOrigExpr with
- | None -> []
- | Some (_,_,oldve') ->
- // When we have an "old" value, append bindings for the unbound fields.
- // Effect order - mutable fields may get modified by other bindings...
- let fieldNameUnbound nom = List.forall (fun (name,_) -> name <> nom) fldsList
- fspecs
- |> List.choose (fun rfld ->
+ | None -> [], id
+ | Some (_,_,oldve) ->
+ let wrap,oldveaddr = mkExprAddrOfExpr cenv.g tycon.IsStructOrEnumTycon false NeverMutates oldve None m
+ let fieldNameUnbound nom = List.forall (fun (name,_) -> name <> nom) fldsList
+ let flds =
+ fspecs |> List.choose (fun rfld ->
if fieldNameUnbound rfld.Name && not rfld.IsZeroInit
- then Some(rfld.Name, mkRecdFieldGet cenv.g (oldve',tcref.MakeNestedRecdFieldRef rfld,tinst,m))
+ then Some(rfld.Name, mkRecdFieldGetViaExprAddr (oldveaddr,tcref.MakeNestedRecdFieldRef rfld,tinst,m))
else None)
+ flds, wrap
let fldsList = fldsList @ oldFldsList
@@ -6153,7 +6172,7 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m =
let args = List.map snd fldsList
- let expr = mkRecordExpr cenv.g (GetRecdInfo env, tcref, tinst, rfrefs, args, m)
+ let expr = wrap (mkRecordExpr cenv.g (GetRecdInfo env, tcref, tinst, rfrefs, args, m))
let expr =
match optOrigExpr with
@@ -6161,10 +6180,10 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m =
// '{ recd fields }'. //
expr
- | Some (old',oldv',_) ->
+ | Some (old,oldv,_) ->
// '{ recd with fields }'.
// Assign the first object to a tmp and then construct
- mkCompGenLet m oldv' old' expr
+ mkCompGenLet m oldv old expr
expr, tpenv
@@ -6262,9 +6281,9 @@ and TcObjectExprBinding cenv (env: TcEnv) implty tpenv (absSlotInfo,bind) =
| _ ->
implty --> NewInferenceType ()
- let (CheckedBindingInfo(inlineFlag,immut,bindingAttribs,_,_,ExplicitTyparInfo(_,declaredTypars,_),nameToPrelimValSchemeMap,rhsExpr,_,_,m,_,_,_),tpenv) =
+ let (CheckedBindingInfo(inlineFlag,bindingAttribs,_,_,ExplicitTyparInfo(_,declaredTypars,_),nameToPrelimValSchemeMap,rhsExpr,_,_,m,_,_,_,_),tpenv) =
let flex, tpenv = TcNonrecBindingTyparDecls cenv env tpenv bind
- TcNormalizedBinding ObjectExpressionOverrideBinding cenv env tpenv bindingTy None NoSafeInitInfo ([],flex) bind
+ TcNormalizedBinding ObjectExpressionOverrideBinding cenv env tpenv false bindingTy None NoSafeInitInfo ([],flex) bind
// 4c. generalize the binding - only relevant when implementing a generic virtual method
@@ -6283,7 +6302,7 @@ and TcObjectExprBinding cenv (env: TcEnv) implty tpenv (absSlotInfo,bind) =
let freeInEnv = GeneralizationHelpers.ComputeUngeneralizableTypars env
- let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars(cenv,denv,m,immut,freeInEnv,false,CanGeneralizeConstrainedTypars,inlineFlag,Some(rhsExpr),declaredTypars,[],bindingTy,false)
+ let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars(cenv,denv,m,true,freeInEnv,false,CanGeneralizeConstrainedTypars,inlineFlag,Some(rhsExpr),declaredTypars,[],bindingTy,false)
let declaredTypars = ChooseCanonicalDeclaredTyparsAfterInference cenv.g env.DisplayEnv declaredTypars m
let generalizedTypars = PlaceTyparsInDeclarationOrder declaredTypars generalizedTypars
@@ -6603,13 +6622,13 @@ and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr
let optOrigExpr,tpenv =
match optOrigExpr with
| None -> None, tpenv
- | Some (e, _) ->
+ | Some (origExpr, _) ->
match inherits with
| Some (_,_,mInherits, _, _) -> error(Error(FSComp.SR.tcInvalidRecordConstruction(),mInherits))
| None ->
- let e',tpenv = TcExpr cenv overallTy env tpenv e
- let v',ve' = mkCompGenLocal mWholeExpr "inputRecord" overallTy
- Some (e',v',ve'), tpenv
+ let olde,tpenv = TcExpr cenv overallTy env tpenv origExpr
+ let oldv,oldve = mkCompGenLocal mWholeExpr "inputRecord" overallTy
+ Some (olde,oldv,oldve), tpenv
let fldsList =
let flds =
@@ -8902,8 +8921,8 @@ and TcMethodApplication
let denv = env.DisplayEnv
- let isSimpleFormalArg (isParamArrayArg, isOutArg, optArgInfo: OptionalArgInfo, _reflArgInfo: ReflectedArgInfo) =
- not isParamArrayArg && not isOutArg && not optArgInfo.IsOptional
+ let isSimpleFormalArg (isParamArrayArg, isOutArg, optArgInfo: OptionalArgInfo, callerInfoInfo: CallerInfoInfo, _reflArgInfo: ReflectedArgInfo) =
+ not isParamArrayArg && not isOutArg && not optArgInfo.IsOptional && callerInfoInfo = NoCallerInfo
let callerObjArgTys = objArgs |> List.map (tyOfExpr cenv.g)
@@ -9260,7 +9279,7 @@ and TcMethodApplication
if HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_Dictionary finalCalledMethInfo.EnclosingType &&
finalCalledMethInfo.IsConstructor &&
not (finalCalledMethInfo.GetParamDatas(cenv.amap, mItem, finalCalledMeth.CallerTyArgs)
- |> List.existsSquared (fun (ParamData(_,_,_,_,_,ty)) ->
+ |> List.existsSquared (fun (ParamData(_,_,_,_,_,_,ty)) ->
HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_IEqualityComparer ty)) then
match argsOfAppTy cenv.g finalCalledMethInfo.EnclosingType with
@@ -9389,7 +9408,16 @@ and TcMethodApplication
| ByrefTy cenv.g inst ->
build inst (PassByRef(inst, currDfltVal))
| _ ->
- emptyPreBinder,Expr.Const(TcFieldInit mMethExpr fieldInit,mMethExpr,currCalledArgTy)
+ match calledArg.CallerInfoInfo, env.eCallerMemberName with
+ | CallerLineNumber, _ when typeEquiv cenv.g currCalledArgTy cenv.g.int_ty ->
+ emptyPreBinder,Expr.Const(Const.Int32(mMethExpr.StartLine), mMethExpr, currCalledArgTy)
+ | CallerFilePath, _ when typeEquiv cenv.g currCalledArgTy cenv.g.string_ty ->
+ emptyPreBinder,Expr.Const(Const.String(System.IO.Path.GetFullPath(mMethExpr.FileName)), mMethExpr, currCalledArgTy)
+ | CallerMemberName, Some(callerName) when (typeEquiv cenv.g currCalledArgTy cenv.g.string_ty) ->
+ emptyPreBinder,Expr.Const(Const.String(callerName), mMethExpr, currCalledArgTy)
+ | _ ->
+ emptyPreBinder,Expr.Const(TcFieldInit mMethExpr fieldInit,mMethExpr,currCalledArgTy)
+
| WrapperForIDispatch ->
match cenv.g.ilg.traits.SystemRuntimeInteropServicesScopeRef.Value with
| None -> error(Error(FSComp.SR.fscSystemRuntimeInteropServicesIsRequired(), mMethExpr))
@@ -9411,13 +9439,25 @@ and TcMethodApplication
let wrapper2,rhs = build currCalledArgTy dfltVal2
(wrapper2 >> mkCompGenLet mMethExpr v rhs), mkValAddr mMethExpr (mkLocalValRef v)
build calledArgTy dfltVal
- | CalleeSide ->
+ | CalleeSide ->
let calledNonOptTy =
if isOptionTy cenv.g calledArgTy then
destOptionTy cenv.g calledArgTy
else
calledArgTy // should be unreachable
- emptyPreBinder,mkUnionCaseExpr(mkNoneCase cenv.g,[calledNonOptTy],[],mMethExpr)
+
+ match calledArg.CallerInfoInfo, env.eCallerMemberName with
+ | CallerLineNumber, _ when typeEquiv cenv.g calledNonOptTy cenv.g.int_ty ->
+ let lineExpr = Expr.Const(Const.Int32(mMethExpr.StartLine), mMethExpr, calledNonOptTy)
+ emptyPreBinder,mkUnionCaseExpr(mkSomeCase cenv.g,[calledNonOptTy],[lineExpr],mMethExpr)
+ | CallerFilePath, _ when typeEquiv cenv.g calledNonOptTy cenv.g.string_ty ->
+ let filePathExpr = Expr.Const(Const.String(System.IO.Path.GetFullPath(mMethExpr.FileName)), mMethExpr, calledNonOptTy)
+ emptyPreBinder,mkUnionCaseExpr(mkSomeCase cenv.g,[calledNonOptTy],[filePathExpr],mMethExpr)
+ | CallerMemberName, Some(callerName) when typeEquiv cenv.g calledNonOptTy cenv.g.string_ty ->
+ let memberNameExpr = Expr.Const(Const.String(callerName), mMethExpr, calledNonOptTy)
+ emptyPreBinder,mkUnionCaseExpr(mkSomeCase cenv.g,[calledNonOptTy],[memberNameExpr],mMethExpr)
+ | _ ->
+ emptyPreBinder,mkUnionCaseExpr(mkNoneCase cenv.g,[calledNonOptTy],[],mMethExpr)
// Combine the variable allocators (if any)
let wrapper = (wrapper >> wrapper2)
@@ -9427,18 +9467,19 @@ and TcMethodApplication
// Handle optional arguments
let wrapOptionalArg (assignedArg: AssignedCalledArg<_>) =
- let (CallerArg(callerArgTy,m,isOptCallerArg,expr)) = assignedArg.CallerArg
+ let (CallerArg(callerArgTy,m,isOptCallerArg,expr)) = assignedArg.CallerArg
match assignedArg.CalledArg.OptArgInfo with
| NotOptional ->
if isOptCallerArg then errorR(Error(FSComp.SR.tcFormalArgumentIsNotOptional(),m))
assignedArg
-
| _ ->
let expr =
match assignedArg.CalledArg.OptArgInfo with
| CallerSide _ ->
if isOptCallerArg then
- mkUnionCaseFieldGetUnproven(expr,mkSomeCase cenv.g,[destOptionTy cenv.g callerArgTy],0,m)
+ // STRUCT OPTIONS: if we allow struct options as optional arguments then we should take
+ // the address correctly.
+ mkUnionCaseFieldGetUnprovenViaExprAddr (expr,mkSomeCase cenv.g,[destOptionTy cenv.g callerArgTy],0,m)
else
expr
| CalleeSide ->
@@ -9727,8 +9768,7 @@ and TcLinearLetExprs bodyChecker cenv env overallTy builder tpenv (processUseBin
// TcLinearLetExprs processes multiple 'let' bindings in a tail recursive way
// We process one binding, then look for additional linear bindings and accumulate the builder continuation.
// Don't processes 'use' bindings (e.g. in sequence expressions) unless directed to.
- let mkf,envinner,tpenv =
- TcLetBinding cenv isUse env ExprContainerInfo ExpressionBinding tpenv (binds,m,body.Range)
+ let mkf,envinner,tpenv = TcLetBinding cenv isUse env ExprContainerInfo ExpressionBinding tpenv (binds,m,body.Range)
let builder' x = builder (mkf x)
match body with
| SynExpr.LetOrUse (isRec',isUse',binds',bodyExpr,m') when (not isUse' || processUseBindings) ->
@@ -9772,18 +9812,118 @@ and TcStaticOptimizationConstraint cenv env tpenv c =
let tp',tpenv = TcTypar cenv env NewTyparsOK tpenv tp
TTyconIsStruct(mkTyparTy tp'),tpenv
+/// Emit a conv.i instruction
+and mkConvToNativeInt g e m = Expr.Op (TOp.ILAsm ([ AI_conv ILBasicType.DT_I], [ g.nativeint_ty ]),[],[e],m)
+
+/// Fix up the r.h.s. of a 'use x = fixed expr'
+and TcAndBuildFixedExpr cenv env (overallPatTy, fixedExpr, overallExprTy, mBinding) =
+ warning(PossibleUnverifiableCode(mBinding))
+ match overallExprTy with
+ | ty when isByrefTy cenv.g ty ->
+ let okByRef =
+ match stripExpr fixedExpr with
+ | Expr.Op (op,tyargs,args,_) ->
+ match op,tyargs,args with
+ | TOp.ValFieldGetAddr rfref,_,[_] -> not rfref.Tycon.IsStructOrEnumTycon
+ | TOp.ILAsm ([ I_ldflda (fspec)],_),_,_ -> fspec.EnclosingType.Boxity = ILBoxity.AsObject
+ | TOp.ILAsm ([ I_ldelema _],_),_,_ -> true
+ | TOp.RefAddrGet _,_,_ -> true
+ | _ -> false
+ | _ -> false
+ if not okByRef then
+ error(Error(FSComp.SR.tcFixedNotAllowed(),mBinding))
+
+ let elemTy = destByrefTy cenv.g overallExprTy
+ UnifyTypes cenv env mBinding (mkNativePtrTy cenv.g elemTy) overallPatTy
+ mkCompGenLetIn mBinding "pinnedByref" ty fixedExpr (fun (v,ve) ->
+ v.SetIsFixed()
+ mkConvToNativeInt cenv.g ve mBinding)
+
+ | ty when isStringTy cenv.g ty ->
+ let charPtrTy = mkNativePtrTy cenv.g cenv.g.char_ty
+ UnifyTypes cenv env mBinding charPtrTy overallPatTy
+ //
+ // let ptr : nativeptr =
+ // let pinned s = str
+ // (nativeptr)s + get_OffsettoStringData()
+
+ mkCompGenLetIn mBinding "pinnedString" cenv.g.string_ty fixedExpr (fun (v,ve) ->
+ v.SetIsFixed()
+ let addrOffset = BuildOffsetToStringData cenv env mBinding
+ let stringAsNativeInt = mkConvToNativeInt cenv.g ve mBinding
+ let plusOffset = Expr.Op (TOp.ILAsm ([ AI_add ], [ cenv.g.nativeint_ty ]),[],[stringAsNativeInt; addrOffset],mBinding)
+ // check for non-null
+ mkNullTest cenv.g mBinding ve plusOffset ve)
+
+ | ty when isArray1DTy cenv.g ty ->
+ let elemTy = destArrayTy cenv.g overallExprTy
+ let elemPtrTy = mkNativePtrTy cenv.g elemTy
+ UnifyTypes cenv env mBinding elemPtrTy overallPatTy
+
+ // let ptr : nativeptr =
+ // let tmpArray : elem[] = arr
+ // if nonNull tmpArray then
+ // if tmpArray.Length <> 0 then
+ // let pinned tmpArrayByref : byref = &arr.[0]
+ // (nativeint) tmpArrayByref
+ // else
+ // (nativeint) 0
+ // else
+ // (nativeint) 0
+ //
+ mkCompGenLetIn mBinding "tmpArray" overallExprTy fixedExpr (fun (_,ve) ->
+ // This is &arr.[0]
+ let elemZeroAddress = mkArrayElemAddress cenv.g (ILReadonly.NormalAddress,false,ILArrayShape.SingleDimensional,elemTy,ve,mkInt32 cenv.g mBinding 0,mBinding)
+ // check for non-null and non-empty
+ let zero = mkConvToNativeInt cenv.g (mkInt32 cenv.g mBinding 0) mBinding
+ // This is arr.Length
+ let arrayLengthExpr = mkCallArrayLength cenv.g mBinding elemTy ve
+ mkNullTest cenv.g mBinding ve
+ (mkNullTest cenv.g mBinding arrayLengthExpr
+ (mkCompGenLetIn mBinding "pinnedByref" (mkByrefTy cenv.g elemTy) elemZeroAddress (fun (v,ve) ->
+ v.SetIsFixed()
+ (mkConvToNativeInt cenv.g ve mBinding)))
+ zero)
+ zero)
+
+ | _ -> error(Error(FSComp.SR.tcFixedNotAllowed(),mBinding))
+
+
/// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and
-and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars,(ExplicitTyparInfo(_,declaredTypars,_) as flex)) bind =
+and TcNormalizedBinding declKind (cenv:cenv) env tpenv isUse overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars,(ExplicitTyparInfo(_,declaredTypars,_) as flex)) bind =
let envinner = AddDeclaredTypars NoCheckForDuplicateTypars (enclosingDeclaredTypars@declaredTypars) env
match bind with
| NormalizedBinding(vis,bkind,isInline,isMutable,attrs,doc,_,valSynData,pat,NormalizedBindingRhs(spatsL,rtyOpt,rhsExpr),mBinding,spBind) ->
-
let (SynValData(memberFlagsOpt,valSynInfo,_)) = valSynData
+ let callerName =
+ match declKind, bkind, pat with
+ | ExpressionBinding, _, _ -> envinner.eCallerMemberName
+ | _, _, SynPat.Named(_,name,_,_,_) ->
+ match memberFlagsOpt with
+ | Some(memberFlags) ->
+ match memberFlags.MemberKind with
+ | MemberKind.PropertyGet | MemberKind.PropertySet | MemberKind.PropertyGetSet -> Some(name.idText.Substring(4))
+ | MemberKind.ClassConstructor -> Some(".ctor")
+ | MemberKind.Constructor -> Some(".ctor")
+ | _ -> Some(name.idText)
+ | _ -> Some(name.idText)
+ | ClassLetBinding(false), DoBinding, _ -> Some(".ctor")
+ | ClassLetBinding(true), DoBinding, _ -> Some(".cctor")
+ | ModuleOrMemberBinding, StandaloneExpression, _ -> Some(".cctor")
+ | _, _, _ -> envinner.eCallerMemberName
+
+ let envinner = {envinner with eCallerMemberName = callerName }
+
let attrTgt = DeclKind.AllowedAttribTargets memberFlagsOpt declKind
+ let isFixed,rhsExpr,overallPatTy,overallExprTy =
+ match rhsExpr with
+ | SynExpr.Fixed (e,_) -> true, e, NewInferenceType(), overallTy
+ | e -> false, e, overallTy, overallTy
+
// Check the attributes of the binding, parameters or return value
let TcAttrs tgt attrs =
let attrs = TcAttributes cenv envinner tgt attrs
@@ -9798,6 +9938,7 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt
let argAttribs =
spatsL |> List.map (SynInfo.InferSynArgInfoFromSimplePats >> List.map (SynInfo.AttribsOfArgData >> TcAttrs AttributeTargets.Parameter))
+
let retAttribs =
match rtyOpt with
| Some (SynBindingReturnInfo(_,_,retAttrs)) -> TcAttrs AttributeTargets.ReturnValue retAttrs
@@ -9812,11 +9953,20 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt
if isThreadStatic then errorR(DeprecatedThreadStaticBindingWarning(mBinding))
if isVolatile then
- if declKind <> ClassLetBinding then
- errorR(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(),mBinding))
+ match declKind with
+ | ClassLetBinding(_) -> ()
+ | _ -> errorR(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(),mBinding))
+
if (not isMutable || isThreadStatic) then
errorR(Error(FSComp.SR.tcVolatileFieldsMustBeMutable(),mBinding))
+ if isFixed then
+ if declKind <> ExpressionBinding || isInline || isMutable then
+ errorR(Error(FSComp.SR.tcFixedNotAllowed(),mBinding))
+
+ if isUse && isMutable then
+ warning(Error(FSComp.SR.tcUseMayNotBeMutable(),mBinding))
+
if HasFSharpAttributeOpt cenv.g cenv.g.attrib_DllImportAttribute valAttribs then
if not declKind.CanBeDllImport || (match memberFlagsOpt with Some memberFlags -> memberFlags.IsInstance | _ -> false) then
errorR(Error(FSComp.SR.tcDllImportNotAllowed(),mBinding))
@@ -9828,12 +9978,16 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt
if isSome(memberFlagsOpt) then
errorR(Error(FSComp.SR.tcEntryPointAttributeRequiresFunctionInModule(),mBinding))
else
- UnifyTypes cenv env mBinding overallTy (mkArrayType cenv.g cenv.g.string_ty --> cenv.g.int_ty)
+ UnifyTypes cenv env mBinding overallPatTy (mkArrayType cenv.g cenv.g.string_ty --> cenv.g.int_ty)
if isMutable && isInline then errorR(Error(FSComp.SR.tcMutableValuesCannotBeInline(),mBinding))
+
if isMutable && nonNil declaredTypars then errorR(Error(FSComp.SR.tcMutableValuesMayNotHaveGenericParameters(),mBinding))
+
let flex = if isMutable then dontInferTypars else flex
+
if isMutable && nonNil spatsL then errorR(Error(FSComp.SR.tcMutableValuesSyntax(),mBinding))
+
let isInline =
if isInline && isNil spatsL && isNil declaredTypars then
errorR(Error(FSComp.SR.tcOnlyFunctionsCanBeInline(),mBinding))
@@ -9848,7 +10002,7 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt
// Check the pattern of the l.h.s. of the binding
let tcPatPhase2,(tpenv,nameToPrelimValSchemeMap,_) =
- TcPat AllIdsOK cenv envinner (Some(partialValReprInfo)) (inlineFlag,flex,argAndRetAttribs,isMutable,vis,compgen) (tpenv,NameMap.empty,Set.empty) overallTy pat
+ TcPat AllIdsOK cenv envinner (Some(partialValReprInfo)) (inlineFlag,flex,argAndRetAttribs,isMutable,vis,compgen) (tpenv,NameMap.empty,Set.empty) overallPatTy pat
// Add active pattern result names to the environment
@@ -9879,22 +10033,26 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt
// If binding a ctor then set the ugly counter that permits us to write ctor expressions on the r.h.s.
let isCtor = (match memberFlagsOpt with Some memberFlags -> memberFlags.MemberKind = MemberKind.Constructor | _ -> false)
- let tc =
- if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo)
- else TcExprThatCantBeCtorBody
-
// At each module binding, dive into the expression to check for syntax errors and suppress them if they show.
// Don't do this for lambdas, because we always check for suppression for all lambda bodies in TcIteratedLambdas
- let rhsExpr',tpenv =
+ let rhsExprChecked,tpenv =
let atTopNonLambdaDefn =
DeclKind.IsModuleOrMemberOrExtensionBinding declKind &&
(match rhsExpr with SynExpr.Lambda _ -> false | _ -> true) &&
synExprContainsError rhsExpr
+
conditionallySuppressErrorReporting atTopNonLambdaDefn (fun () ->
- tc cenv overallTy envinner tpenv rhsExpr)
+
+ if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo) cenv overallExprTy envinner tpenv rhsExpr
+ else TcExprThatCantBeCtorBody cenv overallExprTy envinner tpenv rhsExpr)
if bkind = StandaloneExpression && not cenv.isScript then
- UnifyUnitType cenv env.DisplayEnv mBinding overallTy (Some rhsExpr') |> ignore
+ UnifyUnitType cenv env.DisplayEnv mBinding overallPatTy (Some rhsExprChecked) |> ignore
+
+ // Fix up the r.h.s. expression for 'fixed'
+ let rhsExprChecked =
+ if isFixed then TcAndBuildFixedExpr cenv env (overallPatTy, rhsExprChecked, overallExprTy, mBinding)
+ else rhsExprChecked
// Assert the return type of an active pattern
match apinfoOpt with
@@ -9906,7 +10064,7 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt
()
// Check other attributes
- let hasLiteralAttr,konst = TcLiteral cenv overallTy env tpenv (valAttribs,rhsExpr)
+ let hasLiteralAttr,konst = TcLiteral cenv overallExprTy env tpenv (valAttribs,rhsExpr)
if hasLiteralAttr && isThreadStatic then
errorR(Error(FSComp.SR.tcIllegalAttributesForLiteral(),mBinding))
if hasLiteralAttr && isMutable then
@@ -9916,7 +10074,7 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt
if hasLiteralAttr && nonNil declaredTypars then
errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(),mBinding))
- CheckedBindingInfo(inlineFlag,true,valAttribs,doc,tcPatPhase2,flex,nameToPrelimValSchemeMap,rhsExpr',argAndRetAttribs,overallTy,mBinding,spBind,compgen,konst),tpenv
+ CheckedBindingInfo(inlineFlag,valAttribs,doc,tcPatPhase2,flex,nameToPrelimValSchemeMap,rhsExprChecked,argAndRetAttribs,overallPatTy,mBinding,spBind,compgen,konst,isFixed),tpenv
and TcLiteral cenv overallTy env tpenv (attrs,synLiteralValExpr) =
let hasLiteralAttr = HasFSharpAttribute cenv.g cenv.g.attrib_LiteralAttribute attrs
@@ -9958,10 +10116,10 @@ and TcNonrecBindingTyparDecls cenv env tpenv bind =
let (NormalizedBinding(_,_,_,_,_,_,synTyparDecls,_,_,_,_,_)) = bind
TcBindingTyparDecls true cenv env tpenv synTyparDecls
-and TcNonRecursiveBinding declKind cenv env tpenv ty b =
+and TcNonRecursiveBinding declKind cenv env tpenv isUse ty b =
let b = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env b
let flex, tpenv = TcNonrecBindingTyparDecls cenv env tpenv b
- TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([],flex) b
+ TcNormalizedBinding declKind cenv env tpenv isUse ty None NoSafeInitInfo ([],flex) b
//-------------------------------------------------------------------------
// TcAttribute*
@@ -10164,14 +10322,14 @@ and TcAttributes cenv env attrTgt synAttribs =
and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds,bindsm,scopem) =
// Typecheck all the bindings...
- let binds',tpenv = List.mapFold (fun tpenv b -> TcNonRecursiveBinding declKind cenv env tpenv (NewInferenceType ()) b) tpenv binds
+ let binds',tpenv = List.mapFold (fun tpenv b -> TcNonRecursiveBinding declKind cenv env tpenv isUse (NewInferenceType ()) b) tpenv binds
let (ContainerInfo(altActualParent,_)) = containerInfo
// Canonicalize constraints prior to generalization
let denv = env.DisplayEnv
GeneralizationHelpers.CanonicalizePartialInferenceProblem (cenv,denv,bindsm)
(binds' |> List.collect (fun tbinfo ->
- let (CheckedBindingInfo(_,_,_,_,_,flex,_,_,_,tauTy,_,_,_,_)) = tbinfo
+ let (CheckedBindingInfo(_,_,_,_,flex,_,_,_,tauTy,_,_,_,_,_)) = tbinfo
let (ExplicitTyparInfo(_,declaredTypars,_)) = flex
let maxInferredTypars = (freeInTypeLeftToRight cenv.g false tauTy)
declaredTypars @ maxInferredTypars))
@@ -10180,7 +10338,7 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds,bindsm,scope
// Generalize the bindings...
(((fun x -> x), env, tpenv), binds') ||> List.fold (fun (mkf_sofar,env,tpenv) tbinfo ->
- let (CheckedBindingInfo(inlineFlag,immut,attrs,doc,tcPatPhase2,flex,nameToPrelimValSchemeMap,rhsExpr,_,tauTy,m,spBind,_,konst)) = tbinfo
+ let (CheckedBindingInfo(inlineFlag,attrs,doc,tcPatPhase2,flex,nameToPrelimValSchemeMap,rhsExpr,_,tauTy,m,spBind,_,konst,isFixed)) = tbinfo
let enclosingDeclaredTypars = []
let (ExplicitTyparInfo(_,declaredTypars,canInferTypars)) = flex
let allDeclaredTypars = enclosingDeclaredTypars @ declaredTypars
@@ -10194,7 +10352,7 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds,bindsm,scope
[]
else
let freeInEnv = lazyFreeInEnv.Force()
- GeneralizationHelpers.ComputeAndGeneralizeGenericTypars(cenv,denv, m, immut, freeInEnv, canInferTypars, GeneralizationHelpers.CanGeneralizeConstrainedTyparsForDecl(declKind), inlineFlag, Some rhsExpr, allDeclaredTypars, maxInferredTypars,tauTy,false)
+ GeneralizationHelpers.ComputeAndGeneralizeGenericTypars(cenv,denv, m, true, freeInEnv, canInferTypars, GeneralizationHelpers.CanGeneralizeConstrainedTyparsForDecl(declKind), inlineFlag, Some rhsExpr, allDeclaredTypars, maxInferredTypars,tauTy,false)
let prelimValSchemes2 = GeneralizeVals cenv denv enclosingDeclaredTypars generalizedTypars nameToPrelimValSchemeMap
@@ -10209,13 +10367,13 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds,bindsm,scope
let prelimRecValues = NameMap.map fst values
// Now bind the r.h.s. to the l.h.s.
- let rhse = mkTypeLambda m generalizedTypars (rhsExpr,tauTy)
+ let rhsExpr = mkTypeLambda m generalizedTypars (rhsExpr,tauTy)
match pat' with
// Don't introduce temporary or 'let' for 'match against wild' or 'match against unit'
- | (TPat_wild _ | TPat_const (Const.Unit,_)) when not isUse && isNil generalizedTypars ->
- let mk_seq_bind (tm,tmty) = (mkSequential SequencePointsAtSeq m rhse tm, tmty)
+ | (TPat_wild _ | TPat_const (Const.Unit,_)) when not isUse && not isFixed && isNil generalizedTypars ->
+ let mk_seq_bind (tm,tmty) = (mkSequential SequencePointsAtSeq m rhsExpr tm, tmty)
(mk_seq_bind << mkf_sofar,env,tpenv)
| _ ->
@@ -10226,38 +10384,42 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds,bindsm,scope
// nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to
| TPat_as (pat1,PBind(v,TypeScheme(generalizedTypars',_)),_)
when List.lengthsEqAndForall2 typarRefEq generalizedTypars generalizedTypars' ->
+
v, pat1
| _ when mustinline(inlineFlag) -> error(Error(FSComp.SR.tcInvalidInlineSpecification(),m))
| _ ->
let tmp,_ = mkCompGenLocal m "patternInput" (generalizedTypars +-> tauTy)
- if isUse then
+ if isUse || isFixed then
errorR(Error(FSComp.SR.tcInvalidUseBinding(),m))
// This assignment forces representation as module value, to maintain the invariant from the
// type checker that anything related to binding module-level values is marked with an
// val_repr_info, val_actual_parent and is_topbind
if (DeclKind.MustHaveArity declKind) then
- AdjustValToTopVal tmp altActualParent (InferArityOfExprBinding cenv.g tmp rhse)
+ AdjustValToTopVal tmp altActualParent (InferArityOfExprBinding cenv.g tmp rhsExpr)
tmp,pat'
- let mkRhsBind (tm,tmty) = (mkLet spBind m tmp rhse tm),tmty
+ let mkRhsBind (bodyExpr,bodyExprTy) =
+ let letExpr = mkLet spBind m tmp rhsExpr bodyExpr
+ letExpr,bodyExprTy
+
let allValsDefinedByPattern = (NameMap.range prelimRecValues |> FlatList.ofList)
- let mkPatBind (tm,tmty) =
+ let mkPatBind (bodyExpr,bodyExprTy) =
let valsDefinedByMatching = FlatListSet.remove valEq tmp allValsDefinedByPattern
- let matchx = CompilePatternForMatch cenv env m m true ThrowIncompleteMatchException (tmp,generalizedTypars) [TClause(pat'',None,TTarget(valsDefinedByMatching,tm,SuppressSequencePointAtTarget),m)] tauTy tmty
+ let matchx = CompilePatternForMatch cenv env m m true ThrowIncompleteMatchException (tmp,generalizedTypars) [TClause(pat'',None,TTarget(valsDefinedByMatching,bodyExpr,SuppressSequencePointAtTarget),m)] tauTy bodyExprTy
let matchx = if (DeclKind.ConvertToLinearBindings declKind) then LinearizeTopMatch cenv.g altActualParent matchx else matchx
- matchx,tmty
+ matchx,bodyExprTy
- let mkCleanup (tm,tmty) =
- if isUse then
- (allValsDefinedByPattern,(tm,tmty)) ||> FlatList.foldBack (fun v (tm,tmty) ->
+ let mkCleanup (bodyExpr,bodyExprTy) =
+ if isUse && not isFixed then
+ (allValsDefinedByPattern,(bodyExpr,bodyExprTy)) ||> FlatList.foldBack (fun v (bodyExpr,bodyExprTy) ->
AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css v.Range NoTrace cenv.g.system_IDisposable_typ v.Type
let cleanupE = BuildDisposableCleanup cenv env m v
- mkTryFinally cenv.g (tm,cleanupE,m,tmty,SequencePointInBodyOfTry,NoSequencePointAtFinally),tmty)
+ mkTryFinally cenv.g (bodyExpr,cleanupE,m,bodyExprTy,SequencePointInBodyOfTry,NoSequencePointAtFinally),bodyExprTy)
else
- (tm,tmty)
+ (bodyExpr,bodyExprTy)
((mkRhsBind << mkPatBind << mkCleanup << mkf_sofar),
AddLocalValMap cenv.tcSink scopem prelimRecValues env,
@@ -10809,7 +10971,7 @@ and TcLetrecBinding
let envRec = MakeInnerEnvForMember cenv envRec vspec
let checkedBind,tpenv =
- TcNormalizedBinding declKind cenv envRec tpenv tau safeThisValOpt safeInitInfo (enclosingDeclaredTypars,flex) rbind.SyntacticBinding
+ TcNormalizedBinding declKind cenv envRec tpenv false tau safeThisValOpt safeInitInfo (enclosingDeclaredTypars,flex) rbind.SyntacticBinding
(try UnifyTypes cenv envRec vspec.Range (allDeclaredTypars +-> tau) vspec.Type
with e -> error (Recursion(envRec.DisplayEnv,vspec.Id,tau,vspec.Type,vspec.Range)))
@@ -11026,7 +11188,7 @@ and TcLetrecComputeAndGeneralizeGenericTyparsForBinding cenv denv freeInEnv (pgr
let rbinfo = pgrbind.RecBindingInfo
let vspec = rbinfo.Val
- let (CheckedBindingInfo(inlineFlag,immut,_,_,_,_,_,expr,_,_,m,_,_,_)) = pgrbind.CheckedBinding
+ let (CheckedBindingInfo(inlineFlag,_,_,_,_,_,expr,_,_,m,_,_,_,_)) = pgrbind.CheckedBinding
let (ExplicitTyparInfo(rigidCopyOfDeclaredTypars,declaredTypars,_)) = rbinfo.ExplicitTyparInfo
let allDeclaredTypars = rbinfo.EnclosingDeclaredTypars @ declaredTypars
@@ -11047,7 +11209,7 @@ and TcLetrecComputeAndGeneralizeGenericTyparsForBinding cenv denv freeInEnv (pgr
let maxInferredTypars = freeInTypeLeftToRight cenv.g false tau
let canGeneralizeConstrained = GeneralizationHelpers.CanGeneralizeConstrainedTyparsForDecl rbinfo.DeclKind
- let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars (cenv,denv,m,immut,freeInEnv,canInferTypars,canGeneralizeConstrained,inlineFlag, Some(expr), allDeclaredTypars, maxInferredTypars,tau,isCtor)
+ let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars (cenv,denv,m,true,freeInEnv,canInferTypars,canGeneralizeConstrained,inlineFlag, Some(expr), allDeclaredTypars, maxInferredTypars,tau,isCtor)
generalizedTypars
/// Compute the type variables which may have member constraints that need to be canonicalized prior to generalization
@@ -11065,8 +11227,11 @@ and TcLetrecComputeSupportForBinding cenv (pgrbind : PreGeneralizationRecursiveB
and TcLetrecGeneralizeBinding cenv denv generalizedTypars (pgrbind : PreGeneralizationRecursiveBinding) : PostGeneralizationRecursiveBinding =
let (RBInfo(_,_,enclosingDeclaredTypars,_,vspec,flex,partialValReprInfo,memberInfoOpt,_,_,_,vis,_,declKind)) = pgrbind.RecBindingInfo
- let (CheckedBindingInfo(inlineFlag,_,_,_,_,_,_,expr,argAttribs,_,_,_,compgen,_)) = pgrbind.CheckedBinding
+ let (CheckedBindingInfo(inlineFlag,_,_,_,_,_,expr,argAttribs,_,_,_,compgen,_,isFixed)) = pgrbind.CheckedBinding
+ if isFixed then
+ errorR(Error(FSComp.SR.tcFixedNotAllowed(),expr.Range))
+
let _,tau = vspec.TypeScheme
let pvalscheme1 = PrelimValScheme1(vspec.Id,flex,tau,Some(partialValReprInfo),memberInfoOpt,false,inlineFlag,NormalVal,argAttribs,vis,compgen)
@@ -11095,7 +11260,7 @@ and MakeCheckSafeInitField g tinst thisValOpt rfref reqExpr (expr:Expr) =
| None -> mkStaticRecdFieldGet (rfref, tinst, m)
| Some thisVar ->
// This is an instance method, it must have a 'this' var
- mkRecdFieldGet g (exprForVal m thisVar, rfref, tinst, m)
+ mkRecdFieldGetViaExprAddr (exprForVal m thisVar, rfref, tinst, m)
let failureExpr = match thisValOpt with None -> mkCallFailStaticInit g m | Some _ -> mkCallFailInit g m
mkCompGenSequential m (mkIfThen g m (mkILAsmClt g m availExpr reqExpr) failureExpr) expr
@@ -11696,7 +11861,7 @@ module IncrClassChecking =
// --- Create this for use inside constructor
let thisId = ident ("this",m)
let thisValScheme = ValScheme(thisId,NonGenericTypeScheme(thisTy),None,None,false,ValInline.Never,CtorThisVal,None,true,false,false,false)
- let thisVal = MakeAndPublishVal cenv env (ParentNone,false,ClassLetBinding,ValNotInRecScope,thisValScheme,[],XmlDoc.Empty,None,false)
+ let thisVal = MakeAndPublishVal cenv env (ParentNone,false,ClassLetBinding(false),ValNotInRecScope,thisValScheme,[],XmlDoc.Empty,None,false)
thisVal
{TyconRef = tcref
@@ -12239,7 +12404,7 @@ module IncrClassChecking =
let binders =
[ match ctorInfo.InstanceCtorSafeInitInfo with
| SafeInitField (rfref, _) ->
- let setExpr = mkRecdFieldSet cenv.g (exprForVal m thisVal, rfref, thisTyInst, mkOne cenv.g m, m)
+ let setExpr = mkRecdFieldSetViaExprAddr (exprForVal m thisVal, rfref, thisTyInst, mkOne cenv.g m, m)
let setExpr = reps.FixupIncrClassExprPhase2C (Some(thisVal)) safeStaticInitInfo thisTyInst setExpr
let binder = (fun e -> mkSequential SequencePointsAtSeq setExpr.Range setExpr e)
let isPriorToSuperInit = false
@@ -12490,81 +12655,79 @@ module MutRecBindingChecking =
if tcref.IsEnumTycon && (declKind <> ExtrinsicExtensionBinding) then error(Error(FSComp.SR.tcEnumerationsMayNotHaveMembers(),(trimRangeToLine m))) // ideally we'd have the 'm' of the type declaration stored here, to avoid needing to trim to line to approx
match classMemberDef, containerInfo with
-
- | SynMemberDefn.ImplicitCtor (vis,attrs,spats,thisIdOpt, m), ContainerInfo(_,Some(MemberOrValContainerInfo(tcref, _, baseValOpt, safeInitInfo, _))) ->
- match tcref.TypeOrMeasureKind with TyparKind.Measure -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) | _ -> ()
+ | SynMemberDefn.ImplicitCtor (vis,attrs,spats,thisIdOpt, m), ContainerInfo(_,Some(MemberOrValContainerInfo(tcref, _, baseValOpt, safeInitInfo, _))) ->
+ if tcref.TypeOrMeasureKind = TyparKind.Measure then
+ error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m))
- // Phase2A: make incrClassCtorLhs - ctorv, thisVal etc, type depends on argty(s)
- let incrClassCtorLhs = TcImplictCtorLhs_Phase2A(cenv,envForTycon,tpenv,tcref,vis,attrs,spats,thisIdOpt,baseValOpt,safeInitInfo,m,copyOfTyconTypars,objTy,thisTy)
- // Phase2A: Add copyOfTyconTypars from incrClassCtorLhs - or from tcref
- let envForTycon = AddDeclaredTypars CheckForDuplicateTypars incrClassCtorLhs.InstanceCtorDeclaredTypars envForTycon
- let innerState = (Some incrClassCtorLhs, envForTycon, tpenv, recBindIdx, uncheckedBindsRev)
+ // Phase2A: make incrClassCtorLhs - ctorv, thisVal etc, type depends on argty(s)
+ let incrClassCtorLhs = TcImplictCtorLhs_Phase2A(cenv,envForTycon,tpenv,tcref,vis,attrs,spats,thisIdOpt,baseValOpt,safeInitInfo,m,copyOfTyconTypars,objTy,thisTy)
+ // Phase2A: Add copyOfTyconTypars from incrClassCtorLhs - or from tcref
+ let envForTycon = AddDeclaredTypars CheckForDuplicateTypars incrClassCtorLhs.InstanceCtorDeclaredTypars envForTycon
+ let innerState = (Some incrClassCtorLhs, envForTycon, tpenv, recBindIdx, uncheckedBindsRev)
- [Phase2AIncrClassCtor incrClassCtorLhs],innerState
-
- | SynMemberDefn.ImplicitInherit (typ,arg,_baseIdOpt,m),_ ->
- match tcref.TypeOrMeasureKind with TyparKind.Measure -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) | _ -> ()
- // Phase2A: inherit typ(arg) as base - pass through
- // Phase2A: pick up baseValOpt!
- let baseValOpt = incrClassCtorLhsOpt |> Option.bind (fun x -> x.InstanceCtorBaseValOpt)
- let innerState = (incrClassCtorLhsOpt,envForTycon,tpenv,recBindIdx,uncheckedBindsRev)
- [Phase2AInherit (typ,arg,baseValOpt,m); Phase2AIncrClassCtorJustAfterSuperInit], innerState
-
+ [Phase2AIncrClassCtor incrClassCtorLhs],innerState
+ | SynMemberDefn.ImplicitInherit (typ,arg,_baseIdOpt,m),_ ->
+ if tcref.TypeOrMeasureKind = TyparKind.Measure then
+ error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m))
+
+ // Phase2A: inherit typ(arg) as base - pass through
+ // Phase2A: pick up baseValOpt!
+ let baseValOpt = incrClassCtorLhsOpt |> Option.bind (fun x -> x.InstanceCtorBaseValOpt)
+ let innerState = (incrClassCtorLhsOpt,envForTycon,tpenv,recBindIdx,uncheckedBindsRev)
+ [Phase2AInherit (typ,arg,baseValOpt,m); Phase2AIncrClassCtorJustAfterSuperInit], innerState
+
+ | SynMemberDefn.LetBindings (letBinds,isStatic,isRec,m),_ ->
+ match tcref.TypeOrMeasureKind,isStatic with
+ | TyparKind.Measure,false -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m))
+ | _ -> ()
- | SynMemberDefn.LetBindings (letBinds,isStatic,isRec,m),_ ->
- match tcref.TypeOrMeasureKind,isStatic with
- | TyparKind.Measure,false -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m))
- | _,_ -> ()
-
- if tcref.IsStructOrEnumTycon && not isStatic then
- let allDo = letBinds |> List.forall (function (Binding(_,DoBinding,_,_,_,_,_,_,_,_,_,_)) -> true | _ -> false)
- // Code for potential future design change to allow functions-compiled-as-members in structs
- //let allFun = letBinds |> List.forall (function (Binding(_,NormalBinding,_,_,_,_,SynValData(_,info,_),_,_,_,_,_)) -> not (SynInfo.HasNoArgs info) | _ -> false)
- if allDo then
- errorR(Deprecated(FSComp.SR.tcStructsMayNotContainDoBindings(),(trimRangeToLine m)))
- else
- // Code for potential future design change to allow functions-compiled-as-members in structs
- //elif not allFun then
- errorR(Error(FSComp.SR.tcStructsMayNotContainLetBindings(),(trimRangeToLine m)))
-
- if isStatic && isNone incrClassCtorLhsOpt then
- errorR(Error(FSComp.SR.tcStaticLetBindingsRequireClassesWithImplicitConstructors(),m))
+ if tcref.IsStructOrEnumTycon && not isStatic then
+ let allDo = letBinds |> List.forall (function (Binding(_,DoBinding,_,_,_,_,_,_,_,_,_,_)) -> true | _ -> false)
+ // Code for potential future design change to allow functions-compiled-as-members in structs
+ if allDo then
+ errorR(Deprecated(FSComp.SR.tcStructsMayNotContainDoBindings(),(trimRangeToLine m)))
+ else
+ // Code for potential future design change to allow functions-compiled-as-members in structs
+ errorR(Error(FSComp.SR.tcStructsMayNotContainLetBindings(),(trimRangeToLine m)))
+
+ if isStatic && isNone incrClassCtorLhsOpt then
+ errorR(Error(FSComp.SR.tcStaticLetBindingsRequireClassesWithImplicitConstructors(),m))
- // Phase2A: let-bindings - pass through
- let innerState = (incrClassCtorLhsOpt,envForTycon,tpenv,recBindIdx,uncheckedBindsRev)
- [Phase2AIncrClassBindings (tcref,letBinds,isStatic,isRec,m)], innerState
+ // Phase2A: let-bindings - pass through
+ let innerState = (incrClassCtorLhsOpt,envForTycon,tpenv,recBindIdx,uncheckedBindsRev)
+ [Phase2AIncrClassBindings (tcref,letBinds,isStatic,isRec,m)], innerState
- | SynMemberDefn.Member (bind,m),_ ->
- // Phase2A: member binding - create prelim valspec (for recursive reference) and RecursiveBindingInfo
- let (NormalizedBinding(_,_,_,_,_,_,_,valSynData,_,_,_,_)) as bind = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv envForTycon bind
- let (SynValData(memberFlagsOpt,_,_)) = valSynData
- match tcref.TypeOrMeasureKind with
- | TyparKind.Type -> ()
- | TyparKind.Measure ->
- match memberFlagsOpt with
- | None -> ()
- | Some memberFlags ->
- if memberFlags.IsInstance then error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m))
- match memberFlags.MemberKind with
- | MemberKind.Constructor -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembersNotConstructors(), m))
- | _ -> ()
- let rbind = NormalizedRecBindingDefn(containerInfo,newslotsOK,declKind,bind)
- let overridesOK = DeclKind.CanOverrideOrImplement(declKind)
- let (binds,_values),(tpenv,recBindIdx) = AnalyzeAndMakeAndPublishRecursiveValue overridesOK false cenv envForTycon (tpenv,recBindIdx) rbind
- let cbinds = [ for rbind in binds -> Phase2AMember rbind ]
-
- let innerState = (incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, List.rev binds @ uncheckedBindsRev)
- cbinds,innerState
+ | SynMemberDefn.Member (bind,m),_ ->
+ // Phase2A: member binding - create prelim valspec (for recursive reference) and RecursiveBindingInfo
+ let (NormalizedBinding(_,_,_,_,_,_,_,valSynData,_,_,_,_)) as bind = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv envForTycon bind
+ let (SynValData(memberFlagsOpt,_,_)) = valSynData
+ match tcref.TypeOrMeasureKind with
+ | TyparKind.Type -> ()
+ | TyparKind.Measure ->
+ match memberFlagsOpt with
+ | None -> ()
+ | Some memberFlags ->
+ if memberFlags.IsInstance then error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m))
+ match memberFlags.MemberKind with
+ | MemberKind.Constructor -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembersNotConstructors(), m))
+ | _ -> ()
+ let rbind = NormalizedRecBindingDefn(containerInfo,newslotsOK,declKind,bind)
+ let overridesOK = DeclKind.CanOverrideOrImplement(declKind)
+ let (binds,_values),(tpenv,recBindIdx) = AnalyzeAndMakeAndPublishRecursiveValue overridesOK false cenv envForTycon (tpenv,recBindIdx) rbind
+ let cbinds = [ for rbind in binds -> Phase2AMember rbind ]
+
+ let innerState = (incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, List.rev binds @ uncheckedBindsRev)
+ cbinds,innerState
#if OPEN_IN_TYPE_DECLARATIONS
- | SynMemberDefn.Open (mp,m),_ ->
- let innerState = (incrClassCtorLhsOpt,env,tpenv,recBindIdx,prelimRecValuesRev,uncheckedBindsRev)
- [ Phase2AOpen (mp,m) ], innerState
+ | SynMemberDefn.Open (mp,m),_ ->
+ let innerState = (incrClassCtorLhsOpt,env,tpenv,recBindIdx,prelimRecValuesRev,uncheckedBindsRev)
+ [ Phase2AOpen (mp,m) ], innerState
#endif
- | _ ->
- error(InternalError("Unexpected definition",m)))
+ | _ ->
+ error(InternalError("Unexpected definition",m)))
// If no constructor call, insert Phase2AIncrClassCtorJustAfterSuperInit at start
let defnAs =
@@ -12716,14 +12879,14 @@ module MutRecBindingChecking =
if isRec then
// Type check local recursive binding
- let binds = binds |> List.map (fun bind -> RecDefnBindingInfo(ExprContainerInfo,NoNewSlots,ClassLetBinding,bind))
+ let binds = binds |> List.map (fun bind -> RecDefnBindingInfo(ExprContainerInfo,NoNewSlots,ClassLetBinding(isStatic),bind))
let binds,env,tpenv = TcLetrec ErrorOnOverrides cenv envForBinding tpenv (binds,scopem(*bindsm*),scopem)
let bindRs = [IncrClassBindingGroup(binds,isStatic,true)]
binds,bindRs,env,tpenv
else
// Type check local binding
- let binds,env,tpenv = TcLetBindings cenv envForBinding ExprContainerInfo ClassLetBinding tpenv (binds,bindsm,scopem)
+ let binds,env,tpenv = TcLetBindings cenv envForBinding ExprContainerInfo (ClassLetBinding(isStatic)) tpenv (binds,bindsm,scopem)
let binds,bindRs =
binds
|> List.map (function
@@ -13880,7 +14043,7 @@ module EstablishTypeDefinitionCores =
if hasClassAttr && not (match k with TyconClass -> true | _ -> false) ||
hasMeasureAttr && not (match k with TyconClass | TyconAbbrev | TyconHiddenRepr -> true | _ -> false) ||
hasInterfaceAttr && not (match k with TyconInterface -> true | _ -> false) ||
- hasStructAttr && not (match k with TyconStruct | TyconRecord -> true | _ -> false) then
+ hasStructAttr && not (match k with TyconStruct | TyconRecord | TyconUnion -> true | _ -> false) then
error(Error(FSComp.SR.tcKindOfTypeSpecifiedDoesNotMatchDefinition(),m))
k
@@ -13907,13 +14070,14 @@ module EstablishTypeDefinitionCores =
[ match synTyconRepr with
| SynTypeDefnSimpleRepr.None _ -> ()
| SynTypeDefnSimpleRepr.Union (_,unionCases,_) ->
+
for (UnionCase (_,_,args,_,_,m)) in unionCases do
- match args with
- | UnionCaseFields flds ->
+ match args with
+ | UnionCaseFields flds ->
for (Field(_,_,_,ty,_,_,_,m)) in flds do
let ty',_ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty
yield (ty',m)
- | UnionCaseFullType (ty,arity) ->
+ | UnionCaseFullType (ty,arity) ->
let ty',_ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty
let argtysl,_ = GetTopTauTypeInFSharpForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv env) |> TranslatePartialArity []).ArgInfos ty' m
if argtysl.Length > 1 then
@@ -13947,19 +14111,28 @@ module EstablishTypeDefinitionCores =
| _ ->
() ]
- let ComputeModuleOrNamespaceKind g isModule attribs =
+ let ComputeModuleOrNamespaceKind g isModule typeNames attribs nm =
if not isModule then Namespace
- elif ModuleNameIsMangled g attribs then FSharpModuleWithSuffix
+ elif ModuleNameIsMangled g attribs || Set.contains nm typeNames then FSharpModuleWithSuffix
else ModuleOrType
let AdjustModuleName modKind nm = (match modKind with FSharpModuleWithSuffix -> nm+FSharpModuleSuffix | _ -> nm)
- let TcTyconDefnCore_Phase1A_BuildInitialModule cenv envInitial parent compInfo =
+ let TypeNamesInMutRecDecls (compDecls: MutRecShapes) =
+ [ for d in compDecls do
+ match d with
+ | MutRecShape.Tycon (MutRecDefnsPhase1DataForTycon(ComponentInfo(_,_,_,ids,_,_,_,_),_,_,_,_,isAtOriginalTyconDefn),_) ->
+ if isAtOriginalTyconDefn then
+ yield (List.last ids).idText
+ | _ -> () ]
+ |> set
+
+ let TcTyconDefnCore_Phase1A_BuildInitialModule cenv envInitial parent typeNames compInfo compDecls =
let (ComponentInfo(attribs,_parms, _constraints,longPath,xml,_,vis,im)) = compInfo
let id = ComputeModuleName longPath
let modAttrs = TcAttributes cenv envInitial AttributeTargets.ModuleDecl attribs
- let modKind = ComputeModuleOrNamespaceKind cenv.g true modAttrs
+ let modKind = ComputeModuleOrNamespaceKind cenv.g true typeNames modAttrs id.idText
let modName = AdjustModuleName modKind id.idText
let vis,_ = ComputeAccessAndCompPath envInitial None id.idRange vis parent
@@ -13972,14 +14145,15 @@ module EstablishTypeDefinitionCores =
let envForDecls, mtypeAcc = MakeInnerEnv envInitial id modKind
let mspec = NewModuleOrNamespace (Some envInitial.eCompPath) vis id (xml.ToXmlDoc()) modAttrs (notlazy (NewEmptyModuleOrNamespaceType modKind))
let innerParent = Parent (mkLocalModRef mspec)
- MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), (innerParent, envForDecls)
+ let typeNames = TypeNamesInMutRecDecls compDecls
+ MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), (innerParent, typeNames, envForDecls)
/// Establish 'type C < T1... TN > = ...' including
/// - computing the mangled name for C
/// but
/// - we don't yet 'properly' establish constraints on type parameters
let private TcTyconDefnCore_Phase1A_BuildInitialTycon cenv env parent (MutRecDefnsPhase1DataForTycon(synTyconInfo,synTyconRepr,_,preEstablishedHasDefaultCtor,hasSelfReferentialCtor, _)) =
- let (ComponentInfo(_, synTypars, _, id, doc, preferPostfix, synVis, _)) = synTyconInfo
+ let (ComponentInfo (_, synTypars, _,id, doc, preferPostfix, synVis,_)) = synTyconInfo
let checkedTypars = TcTyparDecls cenv env synTypars
id |> List.iter (CheckNamespaceModuleOrTypeName cenv.g)
match synTyconRepr with
@@ -13990,7 +14164,6 @@ module EstablishTypeDefinitionCores =
// Augmentations of type definitions are allowed within the same file as long as no new type representation or abbreviation is given
CheckForDuplicateConcreteType env id.idText id.idRange
- CheckForDuplicateModule env id.idText id.idRange
let vis,cpath = ComputeAccessAndCompPath env None id.idRange synVis parent
// Establish the visibility of the representation, e.g.
@@ -14036,12 +14209,15 @@ module EstablishTypeDefinitionCores =
let attrs, getFinalAttrs = TcAttributesCanFail cenv envinner AttributeTargets.TyconDecl synAttrs
let hasMeasureAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute attrs
- let isStructRecordType =
+ let isStructRecordOrUnionType =
match synTyconRepr with
- | SynTypeDefnSimpleRepr.Record _ -> HasFSharpAttribute cenv.g cenv.g.attrib_StructAttribute attrs
- | _ -> false
+ | SynTypeDefnSimpleRepr.Record _
+ | SynTypeDefnSimpleRepr.Union _ ->
+ HasFSharpAttribute cenv.g cenv.g.attrib_StructAttribute attrs
+ | _ ->
+ false
- tycon.SetIsStructRecordType isStructRecordType
+ tycon.SetIsStructRecordOrUnion isStructRecordOrUnionType
// Set the compiled name, if any
tycon.Data.entity_compiled_name <- TryFindFSharpStringAttribute cenv.g cenv.g.attrib_CompiledNameAttribute attrs
@@ -14438,10 +14614,10 @@ module EstablishTypeDefinitionCores =
| SynTypeDefnSimpleRepr.Exception _ -> Some cenv.g.exn_ty
| SynTypeDefnSimpleRepr.None _ -> None
| SynTypeDefnSimpleRepr.TypeAbbrev _ -> None
- | SynTypeDefnSimpleRepr.Union _ -> None
| SynTypeDefnSimpleRepr.LibraryOnlyILAssembly _ -> None
+ | SynTypeDefnSimpleRepr.Union _
| SynTypeDefnSimpleRepr.Record _ ->
- if tycon.IsStructRecordTycon then Some(cenv.g.system_Value_typ)
+ if tycon.IsStructRecordOrUnionTycon then Some(cenv.g.system_Value_typ)
else None
| SynTypeDefnSimpleRepr.General (kind,_,slotsigs,fields,isConcrete,_,_,_) ->
let kind = InferTyconKind cenv.g (kind,attrs,slotsigs,fields,inSig,isConcrete,m)
@@ -14639,6 +14815,10 @@ module EstablishTypeDefinitionCores =
noAllowNullLiteralAttributeCheck()
structLayoutAttributeCheck(false)
let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy tpenv unionCases
+
+ if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then
+ errorR(Error(FSComp.SR.tcStructUnionMultiCase(),m))
+
writeFakeUnionCtorsToSink unionCases
MakeUnionRepr unionCases, None, NoSafeInitInfo
@@ -14976,11 +15156,18 @@ module EstablishTypeDefinitionCores =
else
// Only collect once from each type instance.
let doneTypes = ty :: doneTypes
- let fspecs = structTycon.AllFieldsAsList |> List.filter (fun fspec -> includeStaticFields || not fspec.IsStatic)
+ let fspecs =
+ if structTycon.IsUnionTycon then
+ [ for uc in structTycon.UnionCasesArray do
+ for c in uc.FieldTable.AllFieldsAsList do
+ yield c]
+ else
+ structTycon.AllFieldsAsList
+ let fspecs = fspecs |> List.filter (fun fspec -> includeStaticFields || not fspec.IsStatic)
let doneTypes,acc = List.foldBack (accStructField structTycon tinst) fspecs (doneTypes,acc)
doneTypes,acc
and accStructInstanceFields ty structTycon tinst (doneTypes,acc) = accStructFields false ty structTycon tinst (doneTypes,acc)
- and accStructAllFields ty structTycon tinst (doneTypes,acc) = accStructFields true ty structTycon tinst (doneTypes,acc)
+ and accStructAllFields ty (structTycon: Tycon) tinst (doneTypes,acc) = accStructFields true ty structTycon tinst (doneTypes,acc)
let acc = []
let acc =
@@ -15024,20 +15211,20 @@ module EstablishTypeDefinitionCores =
| _ -> ())
- let TcMutRecDefns_Phase1 mkLetInfo cenv envInitial parent inSig tpenv m scopem mutRecNSInfo (typeDefCores:MutRecShapes) =
+ let TcMutRecDefns_Phase1 mkLetInfo cenv envInitial parent inSig tpenv m scopem mutRecNSInfo (mutRecDefns:MutRecShapes) =
// Phase1A - build Entity for type definitions, exception definitions and module definitions.
// Also for abbreviations of any of these. Augmentations are skipped in this phase.
let withEntities =
- typeDefCores
+ mutRecDefns
|> MutRecShapes.mapWithParent
- (parent, envInitial)
+ (parent, TypeNamesInMutRecDecls mutRecDefns, envInitial)
// Build the initial entity for each module definition
- (fun (innerParent, envForDecls) compInfo ->
- TcTyconDefnCore_Phase1A_BuildInitialModule cenv envForDecls innerParent compInfo)
+ (fun (innerParent, typeNames, envForDecls) compInfo decls ->
+ TcTyconDefnCore_Phase1A_BuildInitialModule cenv envForDecls innerParent typeNames compInfo decls)
// Build the initial Tycon for each type definition
- (fun (innerParent, envForDecls) (typeDefCore,tyconMemberInfo) ->
+ (fun (innerParent, _, envForDecls) (typeDefCore,tyconMemberInfo) ->
let (MutRecDefnsPhase1DataForTycon(_,_,_,_,_,isAtOriginalTyconDefn)) = typeDefCore
let tyconOpt =
if isAtOriginalTyconDefn then
@@ -15047,7 +15234,7 @@ module EstablishTypeDefinitionCores =
(typeDefCore, tyconMemberInfo, innerParent), tyconOpt)
// Bundle up the data for each 'val', 'member' or 'let' definition (just package up the data, no processing yet)
- (fun (innerParent,_) synBinds ->
+ (fun (innerParent, _, _) synBinds ->
let containerInfo = ModuleOrNamespaceContainerInfo(match innerParent with Parent p -> p | _ -> failwith "unreachable")
mkLetInfo containerInfo synBinds)
@@ -15068,7 +15255,6 @@ module EstablishTypeDefinitionCores =
tyconOpt |> Option.iter (fun tycon ->
// recheck these in case type is a duplicate in a mutually recursive set
CheckForDuplicateConcreteType envAbove tycon.LogicalName tycon.Range
- CheckForDuplicateModule envAbove tycon.LogicalName tycon.Range
PublishTypeDefn cenv envAbove tycon))
// Updates the types of the modules to contain the contents so far
@@ -15479,7 +15665,7 @@ module TcDeclarations =
| SynTypeDefnRepr.Simple(repr,_) ->
let members = []
- let isAtOriginalTyconDefn = not (isAugmentationTyconDefnRepr repr)
+ let isAtOriginalTyconDefn = true
let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, repr, implements1, false, false, isAtOriginalTyconDefn)
core, members @ extraMembers
@@ -15560,8 +15746,10 @@ module TcDeclarations =
/// Separates the signature declaration into core (shape) and body.
let rec private SplitTyconSignature (TypeDefnSig(synTyconInfo,trepr,extraMembers,_)) =
+
let implements1 =
extraMembers |> List.choose (function SynMemberSig.Interface (f,m) -> Some(f,m) | _ -> None)
+
match trepr with
| SynTypeDefnSigRepr.ObjectModel(kind,cspec,m) ->
let fields = cspec |> List.choose (function SynMemberSig.ValField (f,_) -> Some(f) | _ -> None)
@@ -15669,7 +15857,7 @@ module TcDeclarations =
// Bind module types
//-------------------------------------------------------------------------
-let rec TcSignatureElementNonMutRec cenv parent endm (env: TcEnv) synSigDecl : Eventually =
+let rec TcSignatureElementNonMutRec cenv parent typeNames endm (env: TcEnv) synSigDecl : Eventually =
eventually {
try
match synSigDecl with
@@ -15710,10 +15898,9 @@ let rec TcSignatureElementNonMutRec cenv parent endm (env: TcEnv) synSigDecl : E
let vis,_ = ComputeAccessAndCompPath env None im vis parent
let attribs = TcAttributes cenv env AttributeTargets.ModuleDecl attribs
CheckNamespaceModuleOrTypeName cenv.g id
- let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true attribs
+ let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true typeNames attribs id.idText
let modName = EstablishTypeDefinitionCores.AdjustModuleName modKind id.idText
CheckForDuplicateConcreteType env modName id.idRange
- CheckForDuplicateModule env id.idText id.idRange
// Now typecheck the signature, accumulating and then recording the submodule description.
let id = ident (modName, id.idRange)
@@ -15821,7 +16008,19 @@ and TcSignatureElements cenv parent endm env xml mutRecNSInfo defs =
and TcSignatureElementsNonMutRec cenv parent endm env defs =
eventually {
- return! Eventually.fold (TcSignatureElementNonMutRec cenv parent endm ) env defs
+ // Collect the type names so we can implicitly add the compilation suffix to module names
+ let typeNames =
+ [ for def in defs do
+ match def with
+ | SynModuleSigDecl.Types (typeSpecs,_) ->
+ for (TypeDefnSig(ComponentInfo(_,_,_,ids,_,_,_,_),trepr,extraMembers,_)) in typeSpecs do
+ match trepr with
+ | SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _),_) when nonNil extraMembers -> ()
+ | _ -> yield (List.last ids).idText
+ | _ -> () ]
+ |> set
+
+ return! Eventually.fold (TcSignatureElementNonMutRec cenv parent typeNames endm) env defs
}
and TcSignatureElementsMutRec cenv parent endm mutRecNSInfo envInitial (defs: SynModuleSigDecl list) =
@@ -15938,7 +16137,7 @@ let CheckLetOrDoInNamespace binds m =
error(NumberedError(FSComp.SR.tcNamespaceCannotContainValues(),binds.Head.RangeOfHeadPat))
/// The non-mutually recursive case for a declaration
-let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent scopem env synDecl =
+let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent typeNames scopem env synDecl =
eventually {
cenv.synArgNameGenerator.Reset()
let tpenv = emptyUnscopedTyparEnv
@@ -16010,7 +16209,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent scopem env synDec
let id = ComputeModuleName longPath
let modAttrs = TcAttributes cenv env AttributeTargets.ModuleDecl attribs
- let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true modAttrs
+ let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true typeNames modAttrs id.idText
let modName = EstablishTypeDefinitionCores.AdjustModuleName modKind id.idText
CheckForDuplicateConcreteType env modName im
CheckForDuplicateModule env id.idText id.idRange
@@ -16114,7 +16313,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent scopem env synDec
}
/// The non-mutually recursive case for a sequence of declarations
-and TcModuleOrNamespaceElementsNonMutRec cenv parent endm (defsSoFar, env, envAtEnd) (moreDefs: SynModuleDecl list) =
+and TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm (defsSoFar, env, envAtEnd) (moreDefs: SynModuleDecl list) =
eventually {
match moreDefs with
| (firstDef :: otherDefs) ->
@@ -16126,9 +16325,9 @@ and TcModuleOrNamespaceElementsNonMutRec cenv parent endm (defsSoFar, env, envAt
// Possibly better:
//let scopem = unionRanges h1.Range.EndRange endm
- let! firstDef',env', envAtEnd' = TcModuleOrNamespaceElementNonMutRec cenv parent scopem env firstDef
+ let! firstDef',env', envAtEnd' = TcModuleOrNamespaceElementNonMutRec cenv parent typeNames scopem env firstDef
// tail recursive
- return! TcModuleOrNamespaceElementsNonMutRec cenv parent endm ( (firstDef' :: defsSoFar), env', envAtEnd') otherDefs
+ return! TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ( (firstDef' :: defsSoFar), env', envAtEnd') otherDefs
| [] ->
return List.rev defsSoFar, envAtEnd
}
@@ -16238,7 +16437,19 @@ and TcModuleOrNamespaceElements cenv parent endm env xml mutRecNSInfo defs =
return (mexpr, topAttrsNew, envAtEnd)
| None ->
- let! compiledDefs, envAtEnd = TcModuleOrNamespaceElementsNonMutRec cenv parent endm ([], env, env) defs
+ // Collect the type names so we can implicitly add the compilation suffix to module names
+ let typeNames =
+ [ for def in defs do
+ match def with
+ | SynModuleDecl.Types (typeSpecs,_) ->
+ for (TypeDefn(ComponentInfo(_,_,_,ids,_,_,_,_),trepr,_,_)) in typeSpecs do
+ match trepr with
+ | SynTypeDefnRepr.ObjectModel(TyconAugmentation,_,_) -> ()
+ | _ -> yield (List.last ids).idText
+ | _ -> () ]
+ |> set
+
+ let! compiledDefs, envAtEnd = TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ([], env, env) defs
// Apply the functions for each declaration to build the overall expression-builder
let mexpr = TMDefs(List.foldBack (fun (f,_) x -> f x) compiledDefs [])
diff --git a/src/fsharp/ast.fs b/src/fsharp/ast.fs
index afae87233d0..657d32c41f5 100644
--- a/src/fsharp/ast.fs
+++ b/src/fsharp/ast.fs
@@ -683,6 +683,10 @@ and
/// Inserted for error recovery when there is "expr." and missing tokens or error recovery after the dot
| DiscardAfterMissingQualificationAfterDot of SynExpr * range
+
+ /// 'use x = fixed expr'
+ | Fixed of SynExpr * range
+
/// Get the syntactic range of source code covered by this construct.
member e.Range =
match e with
@@ -742,6 +746,7 @@ and
| SynExpr.YieldOrReturnFrom (_,_,m)
| SynExpr.LetOrUseBang (_,_,_,_,_,_,m)
| SynExpr.DoBang (_,m) -> m
+ | SynExpr.Fixed (_,m) -> m
| SynExpr.Ident id -> id.idRange
/// range ignoring any (parse error) extra trailing dots
member e.RangeSansAnyExtraDot =
@@ -802,6 +807,7 @@ and
| SynExpr.DotGet (expr,_,lidwd,m) -> if lidwd.ThereIsAnExtraDotAtTheEnd then unionRanges expr.Range lidwd.RangeSansAnyExtraDot else m
| SynExpr.LongIdent (_,lidwd,_,_) -> lidwd.RangeSansAnyExtraDot
| SynExpr.DiscardAfterMissingQualificationAfterDot (expr,_) -> expr.Range
+ | SynExpr.Fixed (_,m) -> m
| SynExpr.Ident id -> id.idRange
/// Attempt to get the range of the first token or initial portion only - this is extremely ad-hoc, just a cheap way to improve a certain 'query custom operation' error range
member e.RangeOfFirstPortion =
@@ -869,6 +875,7 @@ and
let e = (pat.Range : range).Start
mkRange m.FileName start e
| SynExpr.Ident id -> id.idRange
+ | SynExpr.Fixed (_,m) -> m
and
@@ -993,7 +1000,7 @@ and SynAttributes = SynAttribute list
and
[]
SynAttribute =
- { TypeName: LongIdentWithDots;
+ { TypeName: LongIdentWithDots
ArgExpr: SynExpr
/// Target specifier, e.g. "assembly","module",etc.
Target: Ident option
@@ -1039,10 +1046,10 @@ and
and
[]
MemberFlags =
- { IsInstance: bool;
- IsDispatchSlot: bool;
- IsOverrideOrExplicitImpl: bool;
- IsFinal: bool;
+ { IsInstance: bool
+ IsDispatchSlot: bool
+ IsOverrideOrExplicitImpl: bool
+ IsFinal: bool
MemberKind: MemberKind }
/// Note the member kind is actually computed partially by a syntax tree transformation in tc.fs
@@ -2234,8 +2241,9 @@ let rec synExprContainsError inpExpr =
| SynExpr.TraitCall(_,_,e,_)
| SynExpr.YieldOrReturn (_,e,_)
| SynExpr.YieldOrReturnFrom (_,e,_)
- | SynExpr.DoBang (e,_)
- | SynExpr.Paren(e,_,_,_) ->
+ | SynExpr.DoBang (e,_)
+ | SynExpr.Fixed (e,_)
+ | SynExpr.Paren (e,_,_,_) ->
walkExpr e
| SynExpr.NamedIndexedPropertySet (_,e1,e2,_)
diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs
index 344fc582482..82d0b3a35f9 100755
--- a/src/fsharp/fsc.fs
+++ b/src/fsharp/fsc.fs
@@ -130,9 +130,8 @@ let ConsoleErrorLoggerThatQuitsAfterMaxErrors (tcConfigB:TcConfigBuilder, exiter
member this.HandleIssue(tcConfigB, err, isWarning) =
DoWithErrorColor isWarning (fun () ->
- (writeViaBufferWithEnvironmentNewLines stderr (OutputErrorOrWarning (tcConfigB.implicitIncludeDir,tcConfigB.showFullPaths,tcConfigB.flatErrors,tcConfigB.errorStyle,isWarning)) err;
- stderr.WriteLine())
- )
+ (writeViaBufferWithEnvironmentNewLines stderr (OutputErrorOrWarning (tcConfigB.implicitIncludeDir,tcConfigB.showFullPaths,tcConfigB.flatErrors,tcConfigB.errorStyle,isWarning)) err
+ stderr.WriteLine()))
} :> _
/// This error logger delays the messages it receives. At the end, call ForwardDelayedErrorsAndWarnings
@@ -541,22 +540,22 @@ module XmlDocWriter =
| Some "" -> Some mspec.LogicalName
| Some p -> Some (p+"."+mspec.LogicalName)
let ptext = match path with None -> "" | Some t -> t
- if mspec.IsModule then doModuleMemberSig ptext mspec;
+ if mspec.IsModule then doModuleMemberSig ptext mspec
let vals =
mtype.AllValsAndMembers
|> Seq.toList
|> List.filter (fun x -> not x.IsCompilerGenerated)
|> List.filter (fun x -> x.MemberInfo.IsNone || x.IsExtensionMember)
- List.iter (doModuleSig path) mtype.ModuleAndNamespaceDefinitions;
- List.iter (doTyconSig ptext) mtype.ExceptionDefinitions;
- List.iter (doValSig ptext) vals;
+ List.iter (doModuleSig path) mtype.ModuleAndNamespaceDefinitions
+ List.iter (doTyconSig ptext) mtype.ExceptionDefinitions
+ List.iter (doValSig ptext) vals
List.iter (doTyconSig ptext) mtype.TypeDefinitions
- doModuleSig None generatedCcu.Contents;
+ doModuleSig None generatedCcu.Contents
let writeXmlDoc (assemblyName,generatedCcu:CcuThunk,xmlfile) =
if not (Filename.hasSuffixCaseInsensitive "xml" xmlfile ) then
- error(Error(FSComp.SR.docfileNoXmlSuffix(), Range.rangeStartup));
+ error(Error(FSComp.SR.docfileNoXmlSuffix(), Range.rangeStartup))
(* the xmlDocSigOf* functions encode type into string to be used in "id" *)
let members = ref []
let addMember id xmlDoc =
@@ -567,7 +566,7 @@ module XmlDocWriter =
let doUnionCase (uc:UnionCase) = addMember uc.XmlDocSig uc.XmlDoc
let doField (rf:RecdField) = addMember rf.XmlDocSig rf.XmlDoc
let doTycon (tc:Tycon) =
- addMember tc.XmlDocSig tc.XmlDoc;
+ addMember tc.XmlDocSig tc.XmlDoc
for vref in tc.MembersOfFSharpTyconSorted do
doVal vref.Deref
for uc in tc.UnionCasesAsList do
@@ -580,31 +579,31 @@ module XmlDocWriter =
(* moduleSpec - recurses *)
let rec doModule (mspec:ModuleOrNamespace) =
let mtype = mspec.ModuleOrNamespaceType
- if mspec.IsModule then modulMember mspec;
+ if mspec.IsModule then modulMember mspec
let vals =
mtype.AllValsAndMembers
|> Seq.toList
|> List.filter (fun x -> not x.IsCompilerGenerated)
|> List.filter (fun x -> x.MemberInfo.IsNone || x.IsExtensionMember)
- List.iter doModule mtype.ModuleAndNamespaceDefinitions;
- List.iter doTycon mtype.ExceptionDefinitions;
- List.iter doVal vals;
+ List.iter doModule mtype.ModuleAndNamespaceDefinitions
+ List.iter doTycon mtype.ExceptionDefinitions
+ List.iter doVal vals
List.iter doTycon mtype.TypeDefinitions
- doModule generatedCcu.Contents;
+ doModule generatedCcu.Contents
use os = File.CreateText(xmlfile)
- fprintfn os ("");
- fprintfn os ("");
- fprintfn os ("%s") assemblyName;
- fprintfn os ("");
+ fprintfn os ("")
+ fprintfn os ("")
+ fprintfn os ("%s") assemblyName
+ fprintfn os ("")
!members |> List.iter (fun (id,doc) ->
fprintfn os "" id
fprintfn os "%s" doc
- fprintfn os "");
- fprintfn os "";
- fprintfn os "";
+ fprintfn os "")
+ fprintfn os ""
+ fprintfn os ""
//----------------------------------------------------------------------------
@@ -635,13 +634,13 @@ type ILResource with
let EncodeInterfaceData(tcConfig:TcConfig,tcGlobals,exportRemapping,generatedCcu,outfile,isIncrementalBuild) =
if GenerateInterfaceData(tcConfig) then
- if verbose then dprintfn "Generating interface data attribute...";
+ if verbose then dprintfn "Generating interface data attribute..."
let resource = WriteSignatureData (tcConfig,tcGlobals,exportRemapping,generatedCcu,outfile)
- if verbose then dprintf "Generated interface data attribute!\n";
+ if verbose then dprintf "Generated interface data attribute!\n"
// REVIEW: need a better test for this
if (tcConfig.useOptimizationDataFile || tcGlobals.compilingFslib) && not isIncrementalBuild then
let sigDataFileName = (Filename.chopExtension outfile)+".sigdata"
- File.WriteAllBytes(sigDataFileName,resource.Bytes);
+ File.WriteAllBytes(sigDataFileName,resource.Bytes)
let sigAttr = mkSignatureDataVersionAttr tcGlobals (IL.parseILVersion Internal.Utilities.FSharpEnvironment.FSharpBinaryMetadataFormatRevision)
// The resource gets written to a file for FSharp.Core
let resources =
@@ -663,13 +662,13 @@ let GenerateOptimizationData(tcConfig) =
let EncodeOptimizationData(tcGlobals,tcConfig,outfile,exportRemapping,data) =
if GenerateOptimizationData tcConfig then
let data = map2Of2 (Optimizer.RemapOptimizationInfo tcGlobals exportRemapping) data
- if verbose then dprintn "Generating optimization data attribute...";
+ if verbose then dprintn "Generating optimization data attribute..."
// REVIEW: need a better test for this
if tcConfig.useOptimizationDataFile || tcGlobals.compilingFslib then
let ccu,modulInfo = data
let bytes = TastPickle.pickleObjWithDanglingCcus outfile tcGlobals ccu Optimizer.p_CcuOptimizationInfo modulInfo
let optDataFileName = (Filename.chopExtension outfile)+".optdata"
- File.WriteAllBytes(optDataFileName,bytes);
+ File.WriteAllBytes(optDataFileName,bytes)
// As with the sigdata file, the optdata gets written to a file for FSharp.Core
if tcGlobals.compilingFslib then
[]
@@ -729,7 +728,7 @@ module VersionResourceFormat =
open BinaryGenerationUtilities
let VersionInfoNode(data:byte[]) =
- [| yield! i16 (data.Length + 2) // wLength : int16; // Specifies the length, in bytes, of the VS_VERSION_INFO structure. This length does not include any padding that aligns any subsequent version resource data on a 32-bit boundary.
+ [| yield! i16 (data.Length + 2) // wLength : int16 // Specifies the length, in bytes, of the VS_VERSION_INFO structure. This length does not include any padding that aligns any subsequent version resource data on a 32-bit boundary.
yield! data |]
let VersionInfoElement(wType, szKey, valueOpt: byte[] option, children:byte[][], isString) =
@@ -737,7 +736,7 @@ module VersionResourceFormat =
let wValueLength = (match valueOpt with None -> 0 | Some value -> (if isString then value.Length / 2 else value.Length))
VersionInfoNode
[| yield! i16 wValueLength // wValueLength: int16. Specifies the length, in words, of the Value member. This value is zero if there is no Value member associated with the current version structure.
- yield! i16 wType // wType : int16; Specifies the type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.
+ yield! i16 wType // wType : int16 Specifies the type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.
yield! Padded 2 szKey
match valueOpt with
| None -> yield! []
@@ -746,8 +745,8 @@ module VersionResourceFormat =
yield! child |]
let Version((v1,v2,v3,v4):ILVersionInfo) =
- [| yield! i32 (int32 v1 <<< 16 ||| int32 v2) // DWORD dwFileVersionMS; // Specifies the most significant 32 bits of the file's binary version number. This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons.
- yield! i32 (int32 v3 <<< 16 ||| int32 v4) // DWORD dwFileVersionLS; // Specifies the least significant 32 bits of the file's binary version number. This member is used with dwFileVersionMS to form a 64-bit value used for numeric comparisons.
+ [| yield! i32 (int32 v1 <<< 16 ||| int32 v2) // DWORD dwFileVersionMS // Specifies the most significant 32 bits of the file's binary version number. This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons.
+ yield! i32 (int32 v3 <<< 16 ||| int32 v4) // DWORD dwFileVersionLS // Specifies the least significant 32 bits of the file's binary version number. This member is used with dwFileVersionMS to form a 64-bit value used for numeric comparisons.
|]
let String(string,value) =
@@ -793,12 +792,12 @@ module VersionResourceFormat =
dwFileType,dwFileSubtype,
lwFileDate:int64) =
let dwStrucVersion = 0x00010000
- [| yield! i32 0xFEEF04BD // DWORD dwSignature; // Contains the value 0xFEEFO4BD. This is used with the szKey member of the VS_VERSION_INFO structure when searching a file for the VS_FIXEDFILEINFO structure.
- yield! i32 dwStrucVersion // DWORD dwStrucVersion; // Specifies the binary version number of this structure. The high-order word of this member contains the major version number, and the low-order word contains the minor version number.
- yield! Version fileVersion // DWORD dwFileVersionMS,dwFileVersionLS; // Specifies the most/least significant 32 bits of the file's binary version number. This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons.
- yield! Version productVersion // DWORD dwProductVersionMS,dwProductVersionLS; // Specifies the most/least significant 32 bits of the file's binary version number. This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons.
- yield! i32 dwFileFlagsMask // DWORD dwFileFlagsMask; // Contains a bitmask that specifies the valid bits in dwFileFlags. A bit is valid only if it was defined when the file was created.
- yield! i32 dwFileFlags // DWORD dwFileFlags; // Contains a bitmask that specifies the Boolean attributes of the file. This member can include one or more of the following values:
+ [| yield! i32 0xFEEF04BD // DWORD dwSignature // Contains the value 0xFEEFO4BD. This is used with the szKey member of the VS_VERSION_INFO structure when searching a file for the VS_FIXEDFILEINFO structure.
+ yield! i32 dwStrucVersion // DWORD dwStrucVersion // Specifies the binary version number of this structure. The high-order word of this member contains the major version number, and the low-order word contains the minor version number.
+ yield! Version fileVersion // DWORD dwFileVersionMS,dwFileVersionLS // Specifies the most/least significant 32 bits of the file's binary version number. This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons.
+ yield! Version productVersion // DWORD dwProductVersionMS,dwProductVersionLS // Specifies the most/least significant 32 bits of the file's binary version number. This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons.
+ yield! i32 dwFileFlagsMask // DWORD dwFileFlagsMask // Contains a bitmask that specifies the valid bits in dwFileFlags. A bit is valid only if it was defined when the file was created.
+ yield! i32 dwFileFlags // DWORD dwFileFlags // Contains a bitmask that specifies the Boolean attributes of the file. This member can include one or more of the following values:
// VS_FF_DEBUG 0x1L The file contains debugging information or is compiled with debugging features enabled.
// VS_FF_INFOINFERRED The file's version structure was created dynamically; therefore, some of the members in this structure may be empty or incorrect. This flag should never be set in a file's VS_VERSION_INFO data.
// VS_FF_PATCHED The file has been modified and is not identical to the original shipping file of the same version number.
@@ -907,7 +906,7 @@ module AttributeHelpers =
| Some versionString ->
try Some(IL.parseILVersion versionString)
with e ->
- warning(Error(FSComp.SR.fscBadAssemblyVersion(attribName, versionString),Range.rangeStartup));
+ warning(Error(FSComp.SR.fscBadAssemblyVersion(attribName, versionString),Range.rangeStartup))
None
| _ -> None
@@ -927,27 +926,27 @@ let injectedCompatTypes =
"System.Collections.IStructuralEquatable" ]
let typesForwardedToMscorlib =
- set [ "System.AggregateException";
- "System.Threading.CancellationTokenRegistration";
- "System.Threading.CancellationToken";
- "System.Threading.CancellationTokenSource";
- "System.Lazy`1";
- "System.IObservable`1";
- "System.IObserver`1";
+ set [ "System.AggregateException"
+ "System.Threading.CancellationTokenRegistration"
+ "System.Threading.CancellationToken"
+ "System.Threading.CancellationTokenSource"
+ "System.Lazy`1"
+ "System.IObservable`1"
+ "System.IObserver`1"
]
let typesForwardedToSystemNumerics =
- set [ "System.Numerics.BigInteger"; ]
+ set [ "System.Numerics.BigInteger" ]
let createMscorlibExportList tcGlobals =
// We want to write forwarders out for all injected types except for System.ITuple, which is internal
// Forwarding System.ITuple will cause FxCop failures on 4.0
Set.union (Set.filter (fun t -> t <> "System.ITuple") injectedCompatTypes) typesForwardedToMscorlib |>
Seq.map (fun t ->
- { ScopeRef = tcGlobals.sysCcu.ILScopeRef ;
- Name = t ;
- IsForwarder = true ;
- Access = ILTypeDefAccess.Public ;
- Nested = mkILNestedExportedTypes List.empty ;
+ { ScopeRef = tcGlobals.sysCcu.ILScopeRef
+ Name = t
+ IsForwarder = true
+ Access = ILTypeDefAccess.Public
+ Nested = mkILNestedExportedTypes List.empty
CustomAttrs = mkILCustomAttrs List.empty }) |>
Seq.toList
@@ -957,10 +956,10 @@ let createSystemNumericsExportList tcGlobals =
typesForwardedToSystemNumerics |>
Seq.map (fun t ->
{ ScopeRef = ILScopeRef.Assembly(systemNumericsAssemblyRef)
- Name = t;
- IsForwarder = true ;
- Access = ILTypeDefAccess.Public ;
- Nested = mkILNestedExportedTypes List.empty ;
+ Name = t
+ IsForwarder = true
+ Access = ILTypeDefAccess.Public
+ Nested = mkILNestedExportedTypes List.empty
CustomAttrs = mkILCustomAttrs List.empty }) |>
Seq.toList
@@ -1005,7 +1004,7 @@ module MainModuleBuilder =
codegenResults,assemVerFromAttrib,metadataVersion,secDecls) =
- if !progress then dprintf "Creating main module...\n";
+ if !progress then dprintf "Creating main module...\n"
let ilTypeDefs =
//let topTypeDef = mkILTypeDefForGlobalFunctions tcGlobals.ilg (mkILMethods [], emptyILFields)
mkILTypeDefs codegenResults.ilTypeDefs
@@ -1039,9 +1038,9 @@ module MainModuleBuilder =
| QuotationTranslator.QuotationSerializationFormat.FSharp_20_Plus ->
[ ]
let reflectedDefinitionResource =
- { Name=reflectedDefinitionResourceName;
- Location = ILResourceLocation.Local (fun () -> reflectedDefinitionBytes);
- Access= ILResourceAccess.Public;
+ { Name=reflectedDefinitionResourceName
+ Location = ILResourceLocation.Local (fun () -> reflectedDefinitionBytes)
+ Access= ILResourceAccess.Public
CustomAttrs = emptyILCustomAttrs }
reflectedDefinitionAttrs, reflectedDefinitionResource)
|> List.unzip
@@ -1067,9 +1066,9 @@ module MainModuleBuilder =
match assemVerFromAttrib with
| None -> tcVersion
| Some v -> v
- Some { man with Version= Some ver;
- CustomAttrs = manifestAttrs;
- DisableJitOptimizations=disableJitOptimizations;
+ Some { man with Version= Some ver
+ CustomAttrs = manifestAttrs
+ DisableJitOptimizations=disableJitOptimizations
SecurityDecls=secDecls }
let resources =
@@ -1091,7 +1090,7 @@ module MainModuleBuilder =
let writeResources((r:(string * obj) list),(f:string)) =
use writer = new System.Resources.ResourceWriter(f)
r |> List.iter (fun (k,v) -> writer.AddResource(k,v))
- writeResources(readResX(file),outfile);
+ writeResources(readResX(file),outfile)
let file,name,pub = TcConfigBuilder.SplitCommandLineResourceInfo outfile
let file = tcConfig.ResolveSourceFile(rangeStartup,file,tcConfig.implicitIncludeDir)
let bytes = FileSystem.ReadAllBytesShim file
@@ -1103,9 +1102,9 @@ module MainModuleBuilder =
let file = tcConfig.ResolveSourceFile(rangeStartup,file,tcConfig.implicitIncludeDir)
let bytes = FileSystem.ReadAllBytesShim file
name,bytes,pub
- yield { Name=name;
- Location=ILResourceLocation.Local (fun () -> bytes);
- Access=pub;
+ yield { Name=name
+ Location=ILResourceLocation.Local (fun () -> bytes)
+ Access=pub
CustomAttrs=emptyILCustomAttrs }
yield! reflectedDefinitionResources
@@ -1113,9 +1112,9 @@ module MainModuleBuilder =
yield! optDataResources
for ri in tcConfig.linkResources do
let file,name,pub = TcConfigBuilder.SplitCommandLineResourceInfo ri
- yield { Name=name;
- Location=ILResourceLocation.File(ILModuleRef.Create(name=file, hasMetadata=false, hash=Some (sha1HashBytes (FileSystem.ReadAllBytesShim file))), 0);
- Access=pub;
+ yield { Name=name
+ Location=ILResourceLocation.File(ILModuleRef.Create(name=file, hasMetadata=false, hash=Some (sha1HashBytes (FileSystem.ReadAllBytesShim file))), 0)
+ Access=pub
CustomAttrs=emptyILCustomAttrs } ]
let assemblyVersion =
@@ -1208,7 +1207,7 @@ module MainModuleBuilder =
// a user cannot specify both win32res and win32manifest
if not(tcConfig.win32manifest = "") && not(tcConfig.win32res = "") then
- error(Error(FSComp.SR.fscTwoResourceManifests(),rangeCmdArgs));
+ error(Error(FSComp.SR.fscTwoResourceManifests(),rangeCmdArgs))
let win32Manifest =
// use custom manifest if provided
@@ -1234,32 +1233,28 @@ module MainModuleBuilder =
yield Lazy<_>.CreateFromValue av
if not(tcConfig.win32res = "") then
yield Lazy<_>.CreateFromValue (FileSystem.ReadAllBytesShim tcConfig.win32res)
-#if ENABLE_MONO_SUPPORT
- if tcConfig.includewin32manifest && not(win32Manifest = "") && not(runningOnMono) then
-#else
- if tcConfig.includewin32manifest && not(win32Manifest = "") then
-#endif
+ if tcConfig.includewin32manifest && not(win32Manifest = "") && not runningOnMono then
yield Lazy<_>.CreateFromValue [| yield! ResFileFormat.ResFileHeader()
yield! (ManifestResourceFormat.VS_MANIFEST_RESOURCE((FileSystem.ReadAllBytesShim win32Manifest), tcConfig.target = Dll)) |]]
// Add attributes, version number, resources etc.
{mainModule with
StackReserveSize = tcConfig.stackReserveSize
- Name = (if tcConfig.target = Module then Filename.fileNameOfPath outfile else mainModule.Name);
- SubSystemFlags = (if tcConfig.target = WinExe then 2 else 3) ;
- Resources= resources;
- ImageBase = (match tcConfig.baseAddress with None -> 0x00400000l | Some b -> b);
- IsDLL=(tcConfig.target = Dll || tcConfig.target=Module);
- Platform = tcConfig.platform ;
- Is32Bit=(match tcConfig.platform with Some X86 -> true | _ -> false);
- Is64Bit=(match tcConfig.platform with Some AMD64 | Some IA64 -> true | _ -> false);
- Is32BitPreferred = if tcConfig.prefer32Bit && not tcConfig.target.IsExe then (error(Error(FSComp.SR.invalidPlatformTarget(),rangeCmdArgs))) else tcConfig.prefer32Bit;
+ Name = (if tcConfig.target = Module then Filename.fileNameOfPath outfile else mainModule.Name)
+ SubSystemFlags = (if tcConfig.target = WinExe then 2 else 3)
+ Resources= resources
+ ImageBase = (match tcConfig.baseAddress with None -> 0x00400000l | Some b -> b)
+ IsDLL=(tcConfig.target = Dll || tcConfig.target=Module)
+ Platform = tcConfig.platform
+ Is32Bit=(match tcConfig.platform with Some X86 -> true | _ -> false)
+ Is64Bit=(match tcConfig.platform with Some AMD64 | Some IA64 -> true | _ -> false)
+ Is32BitPreferred = if tcConfig.prefer32Bit && not tcConfig.target.IsExe then (error(Error(FSComp.SR.invalidPlatformTarget(),rangeCmdArgs))) else tcConfig.prefer32Bit
CustomAttrs=
mkILCustomAttrs
[ if tcConfig.target = Module then
yield! iattrs
- yield! codegenResults.ilNetModuleAttrs ];
- NativeResources=nativeResources;
+ yield! codegenResults.ilNetModuleAttrs ]
+ NativeResources=nativeResources
Manifest = manifest }
@@ -1276,7 +1271,7 @@ module StaticLinker =
// Check no dependent assemblies use quotations
let dependentCcuUsingQuotations = dependentILModules |> List.tryPick (function (Some ccu,_) when ccu.UsesFSharp20PlusQuotations -> Some ccu | _ -> None)
match dependentCcuUsingQuotations with
- | Some ccu -> error(Error(FSComp.SR.fscQuotationLiteralsStaticLinking(ccu.AssemblyName),rangeStartup));
+ | Some ccu -> error(Error(FSComp.SR.fscQuotationLiteralsStaticLinking(ccu.AssemblyName),rangeStartup))
| None -> ()
// Check we're not static linking a .EXE
@@ -1360,10 +1355,10 @@ module StaticLinker =
let ilxMainModule =
{ ilxMainModule with
- Manifest = (let m = ilxMainModule.ManifestOfAssembly in Some {m with CustomAttrs = mkILCustomAttrs (m.CustomAttrs.AsList @ savedManifestAttrs) });
- CustomAttrs = mkILCustomAttrs [ for m in moduls do yield! m.CustomAttrs.AsList ];
- TypeDefs = mkILTypeDefs (topTypeDef :: List.concat normalTypeDefs);
- Resources = mkILResources (savedResources @ ilxMainModule.Resources.AsList);
+ Manifest = (let m = ilxMainModule.ManifestOfAssembly in Some {m with CustomAttrs = mkILCustomAttrs (m.CustomAttrs.AsList @ savedManifestAttrs) })
+ CustomAttrs = mkILCustomAttrs [ for m in moduls do yield! m.CustomAttrs.AsList ]
+ TypeDefs = mkILTypeDefs (topTypeDef :: List.concat normalTypeDefs)
+ Resources = mkILResources (savedResources @ ilxMainModule.Resources.AsList)
NativeResources = savedNativeResources }
ilxMainModule, rewriteExternalRefsToLocalRefs
@@ -1379,8 +1374,8 @@ module StaticLinker =
let ilBinaryReader =
let ilGlobals = mkILGlobals (IL.mkMscorlibBasedTraits ILScopeRef.Local) (Some ilGlobals.primaryAssemblyName) tcConfig.noDebugData
let opts = { ILBinaryReader.mkDefault (ilGlobals) with
- optimizeForMemory=tcConfig.optimizeForMemory;
- pdbPath = None; }
+ optimizeForMemory=tcConfig.optimizeForMemory
+ pdbPath = None }
ILBinaryReader.OpenILModuleReader mscorlib40 opts
let tdefs1 = ilxMainModule.TypeDefs.AsList |> List.filter (fun td -> not (injectedCompatTypes.Contains(td.Name)))
@@ -1420,16 +1415,16 @@ module StaticLinker =
let ilxMainModule =
{ ilxMainModule with
- TypeDefs = mkILTypeDefs (tdefs1 @ tdefs2); }
+ TypeDefs = mkILTypeDefs (tdefs1 @ tdefs2) }
ilxMainModule
[]
type Node =
- { name: string;
- data: ILModuleDef;
- ccu: option;
- refs: ILReferences;
- mutable edges: list;
+ { name: string
+ data: ILModuleDef
+ ccu: option
+ refs: ILReferences
+ mutable edges: list
mutable visited: bool }
// Find all IL modules that are to be statically linked given the static linking roots.
@@ -1440,11 +1435,11 @@ module StaticLinker =
// Recursively find all referenced modules and add them to a module graph
let depModuleTable = HashMultiMap(0, HashIdentity.Structural)
let dummyEntry nm =
- { refs = IL.emptyILRefs ;
- name=nm;
- ccu=None;
- data=ilxMainModule; // any old module
- edges = [];
+ { refs = IL.emptyILRefs
+ name=nm
+ ccu=None
+ data=ilxMainModule // any old module
+ edges = []
visited = true }
let assumedIndependentSet = set [ "mscorlib"; "System"; "System.Core"; "System.Xml"; "Microsoft.Build.Framework"; "Microsoft.Build.Utilities" ]
@@ -1452,7 +1447,7 @@ module StaticLinker =
let remaining = ref (computeILRefs ilxMainModule).AssemblyReferences
while nonNil !remaining do
let ilAssemRef = List.head !remaining
- remaining := List.tail !remaining;
+ remaining := List.tail !remaining
if assumedIndependentSet.Contains ilAssemRef.Name || (ilAssemRef.PublicKey = Some ecmaPublicKey) then
depModuleTable.[ilAssemRef.Name] <- dummyEntry ilAssemRef.Name
else
@@ -1473,27 +1468,27 @@ module StaticLinker =
warning(Error(FSComp.SR.fscIgnoringMixedWhenLinking ilAssemRef.Name,rangeStartup))
IL.emptyILRefs
else
- { AssemblyReferences = dllInfo.ILAssemblyRefs;
+ { AssemblyReferences = dllInfo.ILAssemblyRefs
ModuleReferences = [] }
depModuleTable.[ilAssemRef.Name] <-
- { refs=refs;
- name=ilAssemRef.Name;
- ccu=ccu;
- data=modul;
- edges = [];
- visited = false };
+ { refs=refs
+ name=ilAssemRef.Name
+ ccu=ccu
+ data=modul
+ edges = []
+ visited = false }
// Push the new work items
- remaining := refs.AssemblyReferences @ !remaining;
+ remaining := refs.AssemblyReferences @ !remaining
| None ->
- warning(Error(FSComp.SR.fscAssumeStaticLinkContainsNoDependencies(ilAssemRef.Name),rangeStartup));
+ warning(Error(FSComp.SR.fscAssumeStaticLinkContainsNoDependencies(ilAssemRef.Name),rangeStartup))
depModuleTable.[ilAssemRef.Name] <- dummyEntry ilAssemRef.Name
- done;
- end;
+ done
+ end
- ReportTime tcConfig "Find dependencies";
+ ReportTime tcConfig "Find dependencies"
// Add edges from modules to the modules that depend on them
for (KeyValue(_,n)) in depModuleTable do
@@ -1508,18 +1503,18 @@ module StaticLinker =
for n in tcConfig.extraStaticLinkRoots do
match depModuleTable.TryFind n with
| Some x -> yield x
- | None -> error(Error(FSComp.SR.fscAssemblyNotFoundInDependencySet(n),rangeStartup));
+ | None -> error(Error(FSComp.SR.fscAssemblyNotFoundInDependencySet(n),rangeStartup))
]
let remaining = ref roots
[ while nonNil !remaining do
let n = List.head !remaining
- remaining := List.tail !remaining;
+ remaining := List.tail !remaining
if not n.visited then
- if verbose then dprintn ("Module "+n.name+" depends on "+GetFSharpCoreLibraryName());
- n.visited <- true;
+ if verbose then dprintn ("Module "+n.name+" depends on "+GetFSharpCoreLibraryName())
+ n.visited <- true
remaining := n.edges @ !remaining
- yield (n.ccu, n.data); ]
+ yield (n.ccu, n.data) ]
// Add all provider-generated assemblies into the static linking set
let FindProviderGeneratedILModules (tcImports:TcImports, providerGeneratedAssemblies: (ImportedBinary * _) list) =
@@ -1563,11 +1558,11 @@ module StaticLinker =
(fun ilxMainModule -> ilxMainModule)
else
(fun ilxMainModule ->
- ReportTime tcConfig "Find assembly references";
+ ReportTime tcConfig "Find assembly references"
let dependentILModules = FindDependentILModulesForStaticLinking (tcConfig, tcImports,ilxMainModule)
- ReportTime tcConfig "Static link";
+ ReportTime tcConfig "Static link"
#if EXTENSIONTYPING
Morphs.enableMorphCustomAttributeData()
@@ -1606,7 +1601,7 @@ module StaticLinker =
// Build a dictionary of all IL type defs, mapping ilOrigTyRef --> ilTypeDef
let allTypeDefsInProviderGeneratedAssemblies =
let rec loop ilOrigTyRef (ilTypeDef:ILTypeDef) =
- seq { yield (ilOrigTyRef,ilTypeDef);
+ seq { yield (ilOrigTyRef,ilTypeDef)
for ntdef in ilTypeDef.NestedTypes do
yield! loop (mkILTyRefInTyRef (ilOrigTyRef, ntdef.Name)) ntdef }
dict [
@@ -1741,7 +1736,7 @@ let GetSigner signingInfo =
module FileWriter =
let EmitIL (tcConfig:TcConfig, ilGlobals, errorLogger:ErrorLogger, outfile, pdbfile, ilxMainModule, signingInfo:SigningInfo, exiter:Exiter) =
try
- if !progress then dprintn "Writing assembly...";
+ if !progress then dprintn "Writing assembly..."
try
ILBinaryWriter.WriteILBinary
(outfile,
@@ -1774,7 +1769,7 @@ let ValidateKeySigningAttributes (tcConfig : TcConfig,tcGlobals,topAttrs) =
match delaySignAttrib with
| Some delaysign ->
if tcConfig.delaysign then
- warning(Error(FSComp.SR.fscDelaySignWarning(),rangeCmdArgs)) ;
+ warning(Error(FSComp.SR.fscDelaySignWarning(),rangeCmdArgs))
tcConfig.delaysign
else
delaysign
@@ -1785,7 +1780,7 @@ let ValidateKeySigningAttributes (tcConfig : TcConfig,tcGlobals,topAttrs) =
match signerAttrib with
| Some signer ->
if tcConfig.signer.IsSome && tcConfig.signer <> Some signer then
- warning(Error(FSComp.SR.fscKeyFileWarning(),rangeCmdArgs)) ;
+ warning(Error(FSComp.SR.fscKeyFileWarning(),rangeCmdArgs))
tcConfig.signer
else
Some signer
@@ -1798,7 +1793,7 @@ let ValidateKeySigningAttributes (tcConfig : TcConfig,tcGlobals,topAttrs) =
match containerAttrib with
| Some container ->
if tcConfig.container.IsSome && tcConfig.container <> Some container then
- warning(Error(FSComp.SR.fscKeyNameWarning(),rangeCmdArgs)) ;
+ warning(Error(FSComp.SR.fscKeyNameWarning(),rangeCmdArgs))
tcConfig.container
else
Some container
@@ -1922,9 +1917,9 @@ let main1(tcGlobals, tcImports: TcImports, frameworkTcImports, generatedCcu, typ
// write interface, xmldoc
begin
- ReportTime tcConfig ("Write Interface File");
+ ReportTime tcConfig ("Write Interface File")
use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind (BuildPhase.Output)
- if tcConfig.printSignature then InterfaceFileWriter.WriteInterfaceFile (tcGlobals,tcConfig, InfoReader(tcGlobals,tcImports.GetImportMap()), typedAssembly);
+ if tcConfig.printSignature then InterfaceFileWriter.WriteInterfaceFile (tcGlobals,tcConfig, InfoReader(tcGlobals,tcImports.GetImportMap()), typedAssembly)
ReportTime tcConfig ("Write XML document signatures")
if tcConfig.xmlDocOutputFile.IsSome then
XmlDocWriter.computeXmlDocSigs (tcGlobals,generatedCcu)
@@ -1944,7 +1939,7 @@ let main1(tcGlobals, tcImports: TcImports, frameworkTcImports, generatedCcu, typ
let main2(Args(tcConfig, tcImports, frameworkTcImports: TcImports, tcGlobals, errorLogger: ErrorLogger, generatedCcu: CcuThunk, outfile, typedAssembly, topAttrs, pdbfile, assemblyName, assemVerFromAttrib, signingInfo, exiter: Exiter)) =
- ReportTime tcConfig ("Encode Interface Data");
+ ReportTime tcConfig ("Encode Interface Data")
let exportRemapping = MakeExportRemapping generatedCcu generatedCcu.Contents
let sigDataAttributes,sigDataResources =
@@ -1956,7 +1951,7 @@ let main2(Args(tcConfig, tcImports, frameworkTcImports: TcImports, tcGlobals, er
exiter.Exit 1
if !progress && tcConfig.optSettings.jitOptUser = Some false then
- dprintf "Note, optimizations are off.\n";
+ dprintf "Note, optimizations are off.\n"
(* optimize *)
use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind (BuildPhase.Optimize)
@@ -1971,7 +1966,7 @@ let main2(Args(tcConfig, tcImports, frameworkTcImports: TcImports, tcGlobals, er
AbortOnError(errorLogger,tcConfig,exiter)
- ReportTime tcConfig ("Encoding OptData");
+ ReportTime tcConfig ("Encoding OptData")
let optDataResources = EncodeOptimizationData(tcGlobals,tcConfig,outfile,exportRemapping,(generatedCcu,optimizationData))
let sigDataResources, _optimizationData =
@@ -2002,10 +1997,10 @@ let main2b(Args(tcConfig: TcConfig, tcImports, tcGlobals, errorLogger, generated
// Compute a static linker.
let ilGlobals = tcGlobals.ilg
if tcConfig.standalone && generatedCcu.UsesFSharp20PlusQuotations then
- error(Error(FSComp.SR.fscQuotationLiteralsStaticLinking0(),rangeStartup));
+ error(Error(FSComp.SR.fscQuotationLiteralsStaticLinking0(),rangeStartup))
let staticLinker = StaticLinker.StaticLink (tcConfig,tcImports,ilGlobals)
- ReportTime tcConfig "TAST -> ILX";
+ ReportTime tcConfig "TAST -> ILX"
use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind (BuildPhase.IlxGen)
let ilxGenerator = CreateIlxAssemblyGenerator (tcConfig,tcImports,tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), generatedCcu)
diff --git a/src/fsharp/fsharp.core.netcore.nuget/Microsoft.FSharp.Core.netcore.nuspec b/src/fsharp/fsharp.core.netcore.nuget/Microsoft.FSharp.Core.netcore.nuspec
index ddcb33421ab..f4dcefd9a8c 100644
--- a/src/fsharp/fsharp.core.netcore.nuget/Microsoft.FSharp.Core.netcore.nuspec
+++ b/src/fsharp/fsharp.core.netcore.nuget/Microsoft.FSharp.Core.netcore.nuspec
@@ -3,8 +3,8 @@
Microsoft.FSharp.Core.netcore
- netcore compatible version of the fsharp core library fsharp.core.dll
- Supported Platforms: - .NET Core (netstandard1.5)
+ .NET Core compatible version of the fsharp core library fsharp.core.dll
+ Supported Platforms: - .NET Core (netstandard1.6)
en-US
true
@@ -14,28 +14,28 @@
$projectUrl$
$tags$
-
-