diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index f1c9aeec80..8a59a1999d 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -8,9 +8,9 @@
-
+
https://github.com/dotnet/arcade
- 28a6403ee97077256fcdc60f599f0ad9e38e3cfa
+ 685c1a4fa207d81e881a402a32ffa1c0fb191b42
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index 5619c7aaee..4b25520324 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -378,7 +378,16 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements =
}
$msbuildVersionDir = if ([int]$vsMajorVersion -lt 16) { "$vsMajorVersion.0" } else { "Current" }
- return $global:_MSBuildExe = Join-Path $vsInstallDir "MSBuild\$msbuildVersionDir\Bin\msbuild.exe"
+
+ $local:BinFolder = Join-Path $vsInstallDir "MSBuild\$msbuildVersionDir\Bin"
+ $local:Prefer64bit = if (Get-Member -InputObject $vsRequirements -Name 'Prefer64bit') { $vsRequirements.Prefer64bit } else { $false }
+ if ($local:Prefer64bit -and (Test-Path(Join-Path $local:BinFolder "amd64"))) {
+ $global:_MSBuildExe = Join-Path $local:BinFolder "amd64\msbuild.exe"
+ } else {
+ $global:_MSBuildExe = Join-Path $local:BinFolder "msbuild.exe"
+ }
+
+ return $global:_MSBuildExe
}
function InitializeVisualStudioEnvironmentVariables([string] $vsInstallDir, [string] $vsMajorVersion) {
diff --git a/eng/source-build-patches/0005-Fix-package-downgrade-warning.patch b/eng/source-build-patches/0005-Fix-package-downgrade-warning.patch
deleted file mode 100644
index e13b98068f..0000000000
--- a/eng/source-build-patches/0005-Fix-package-downgrade-warning.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 7f0d25bfaa9a38da2097c9420461232a08951165 Mon Sep 17 00:00:00 2001
-From: Chris Rummel
-Date: Thu, 3 Sep 2020 19:02:07 -0500
-Subject: [PATCH 5/5] Fix package downgrade warning
-
----
- .../FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj | 4 ++--
- .../Microsoft.FSharp.Compiler.nuspec | 4 ++--
- src/fsharp/fsc/fsc.fsproj | 1 +
- 3 files changed, 7 insertions(+), 6 deletions(-)
-
-diff --git a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
-index aced6e1b4..fcdacc30b 100644
---- a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
-+++ b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
-@@ -770,8 +770,8 @@
-
-
-
--
--
-+
-+
-
-
-
-diff --git a/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec b/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec
-index b96f90d2a..366488b47 100644
---- a/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec
-+++ b/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec
-@@ -22,8 +22,8 @@
-
-
-
--
--
-+
-+
-
-
-
-diff --git a/src/fsharp/fsc/fsc.fsproj b/src/fsharp/fsc/fsc.fsproj
-index 776cddc78..df16c1554 100644
---- a/src/fsharp/fsc/fsc.fsproj
-+++ b/src/fsharp/fsc/fsc.fsproj
-@@ -45,6 +45,7 @@
-
-
-
-+
-
-
-
---
-2.18.0
-
diff --git a/global.json b/global.json
index 0884f406b3..fd94b4b71a 100644
--- a/global.json
+++ b/global.json
@@ -13,7 +13,7 @@
}
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "6.0.0-beta.21321.2",
+ "Microsoft.DotNet.Arcade.Sdk": "6.0.0-beta.21328.2",
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2"
}
}
diff --git a/src/fsharp/CheckExpressions.fs b/src/fsharp/CheckExpressions.fs
index c2bca99665..10e4807a72 100644
--- a/src/fsharp/CheckExpressions.fs
+++ b/src/fsharp/CheckExpressions.fs
@@ -6906,28 +6906,38 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn
UnifyTypes cenv env m printerTupleTy printerTupleTyRequired
// Type check the expressions filling the holes
- let flexes = argTys |> List.map (fun _ -> false)
- let fillExprs, tpenv = TcExprsWithFlexes cenv env m tpenv flexes argTys synFillExprs
- let fillExprsBoxed = (argTys, fillExprs) ||> List.map2 (mkCallBox g m)
+ if List.isEmpty synFillExprs then
+ let str = mkString g m printfFormatString
- let argsExpr = mkArray (g.obj_ty, fillExprsBoxed, m)
- let percentATysExpr =
- if percentATys.Length = 0 then
- mkNull m (mkArrayType g g.system_Type_ty)
+ if isString then
+ str, tpenv
else
- let tyExprs = percentATys |> Array.map (mkCallTypeOf g m) |> Array.toList
- mkArray (g.system_Type_ty, tyExprs, m)
+ mkCallNewFormat cenv.g m printerTy printerArgTy printerResidueTy printerResultTy printerTupleTy str, tpenv
+ else
+ // Type check the expressions filling the holes
+ let flexes = argTys |> List.map (fun _ -> false)
+ let fillExprs, tpenv = TcExprsWithFlexes cenv env m tpenv flexes argTys synFillExprs
- let fmtExpr = MakeMethInfoCall cenv.amap m newFormatMethod [] [mkString g m printfFormatString; argsExpr; percentATysExpr]
+ let fillExprsBoxed = (argTys, fillExprs) ||> List.map2 (mkCallBox g m)
- if isString then
- TcPropagatingExprLeafThenConvert cenv overallTy g.string_ty env (* true *) m (fun () ->
- // Make the call to sprintf
- mkCall_sprintf g m printerTy fmtExpr [], tpenv
- )
- else
- fmtExpr, tpenv
+ let argsExpr = mkArray (g.obj_ty, fillExprsBoxed, m)
+ let percentATysExpr =
+ if percentATys.Length = 0 then
+ mkNull m (mkArrayType g g.system_Type_ty)
+ else
+ let tyExprs = percentATys |> Array.map (mkCallTypeOf g m) |> Array.toList
+ mkArray (g.system_Type_ty, tyExprs, m)
+
+ let fmtExpr = MakeMethInfoCall cenv.amap m newFormatMethod [] [mkString g m printfFormatString; argsExpr; percentATysExpr]
+
+ if isString then
+ TcPropagatingExprLeafThenConvert cenv overallTy g.string_ty env (* true *) m (fun () ->
+ // Make the call to sprintf
+ mkCall_sprintf g m printerTy fmtExpr [], tpenv
+ )
+ else
+ fmtExpr, tpenv
// The case for $"..." used as type FormattableString or IFormattable
| Choice2Of2 createFormattableStringMethod ->
diff --git a/src/fsharp/CompilerConfig.fs b/src/fsharp/CompilerConfig.fs
index c7dd623fad..0bdc81698c 100644
--- a/src/fsharp/CompilerConfig.fs
+++ b/src/fsharp/CompilerConfig.fs
@@ -270,6 +270,11 @@ type LStatus =
| Unprocessed
| Processed
+type TokenizeOption =
+ | AndCompile
+ | Only
+ | Unfiltered
+
type PackageManagerLine =
{ Directive: Directive
LineStatus: LStatus
@@ -367,7 +372,7 @@ type TcConfigBuilder =
mutable importAllReferencesOnly: bool
mutable simulateException: string option
mutable printAst: bool
- mutable tokenizeOnly: bool
+ mutable tokenize: TokenizeOption
mutable testInteractionParser: bool
mutable reportNumDecls: bool
mutable printSignature: bool
@@ -573,7 +578,7 @@ type TcConfigBuilder =
importAllReferencesOnly = false
simulateException = None
printAst = false
- tokenizeOnly = false
+ tokenize = TokenizeOption.AndCompile
testInteractionParser = false
reportNumDecls = false
printSignature = false
@@ -960,7 +965,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member x.simulateException = data.simulateException
member x.printAst = data.printAst
member x.targetFrameworkVersion = targetFrameworkVersionValue
- member x.tokenizeOnly = data.tokenizeOnly
+ member x.tokenize = data.tokenize
member x.testInteractionParser = data.testInteractionParser
member x.reportNumDecls = data.reportNumDecls
member x.printSignature = data.printSignature
diff --git a/src/fsharp/CompilerConfig.fsi b/src/fsharp/CompilerConfig.fsi
index 4c8831e6ba..acb5f140b3 100644
--- a/src/fsharp/CompilerConfig.fsi
+++ b/src/fsharp/CompilerConfig.fsi
@@ -121,6 +121,11 @@ type LStatus =
| Unprocessed
| Processed
+type TokenizeOption =
+ | AndCompile
+ | Only
+ | Unfiltered
+
type PackageManagerLine =
{ Directive: Directive
LineStatus: LStatus
@@ -182,7 +187,7 @@ type TcConfigBuilder =
mutable importAllReferencesOnly: bool
mutable simulateException: string option
mutable printAst: bool
- mutable tokenizeOnly: bool
+ mutable tokenize: TokenizeOption
mutable testInteractionParser: bool
mutable reportNumDecls: bool
mutable printSignature: bool
@@ -374,7 +379,7 @@ type TcConfig =
member importAllReferencesOnly: bool
member simulateException: string option
member printAst: bool
- member tokenizeOnly: bool
+ member tokenize: TokenizeOption
member testInteractionParser: bool
member reportNumDecls: bool
member printSignature: bool
diff --git a/src/fsharp/CompilerOptions.fs b/src/fsharp/CompilerOptions.fs
index b04c13031a..51339cb845 100644
--- a/src/fsharp/CompilerOptions.fs
+++ b/src/fsharp/CompilerOptions.fs
@@ -1139,9 +1139,14 @@ let internalFlags (tcConfigB:TcConfigBuilder) =
CompilerOption
("tokenize", tagNone,
- OptionUnit (fun () -> tcConfigB.tokenizeOnly <- true),
+ OptionUnit (fun () -> tcConfigB.tokenize <- TokenizeOption.Only),
Some(InternalCommandLineOption("--tokenize", rangeCmdArgs)), None)
+ CompilerOption
+ ("tokenize-unfiltered", tagNone,
+ OptionUnit (fun () -> tcConfigB.tokenize <- TokenizeOption.Unfiltered),
+ Some(InternalCommandLineOption("--tokenize-unfiltered", rangeCmdArgs)), None)
+
CompilerOption
("testInteractionParser", tagNone,
OptionUnit (fun () -> tcConfigB.testInteractionParser <- true),
diff --git a/src/fsharp/DependencyManager/NativeDllResolveHandler.fs b/src/fsharp/DependencyManager/NativeDllResolveHandler.fs
index 29d591393b..9397a04eb3 100644
--- a/src/fsharp/DependencyManager/NativeDllResolveHandler.fs
+++ b/src/fsharp/DependencyManager/NativeDllResolveHandler.fs
@@ -111,25 +111,26 @@ type NativeDllResolveHandler (nativeProbingRoots: NativeResolutionProbe) =
else
None
- let appendSemiColon (p: string) =
- if not(p.EndsWith(";", StringComparison.OrdinalIgnoreCase)) then
- p + ";"
+ let appendPathSeparator (p: string) =
+ let separator = string System.IO.Path.PathSeparator
+ if not(p.EndsWith(separator, StringComparison.OrdinalIgnoreCase)) then
+ p + separator
else
p
let addedPaths = ConcurrentBag()
let addProbeToProcessPath probePath =
- let probe = appendSemiColon probePath
- let path = appendSemiColon (Environment.GetEnvironmentVariable("PATH"))
+ let probe = appendPathSeparator probePath
+ let path = appendPathSeparator (Environment.GetEnvironmentVariable("PATH"))
if not (path.Contains(probe)) then
Environment.SetEnvironmentVariable("PATH", path + probe)
addedPaths.Add probe
let removeProbeFromProcessPath probePath =
if not(String.IsNullOrWhiteSpace(probePath)) then
- let probe = appendSemiColon probePath
- let path = appendSemiColon (Environment.GetEnvironmentVariable("PATH"))
+ let probe = appendPathSeparator probePath
+ let path = appendPathSeparator (Environment.GetEnvironmentVariable("PATH"))
if path.Contains(probe) then Environment.SetEnvironmentVariable("PATH", path.Replace(probe, ""))
member internal _.RefreshPathsInEnvironment(roots: string seq) =
diff --git a/src/fsharp/DetupleArgs.fs b/src/fsharp/DetupleArgs.fs
index 2ff48082fa..609ab4c202 100644
--- a/src/fsharp/DetupleArgs.fs
+++ b/src/fsharp/DetupleArgs.fs
@@ -715,7 +715,7 @@ let fixupApp (penv: penv) (fx, fty, tys, args, m) =
// Is it a val app, where the val has a transform?
match fx with
- | Expr.Val (vref, _, m) ->
+ | Expr.Val (vref, _, vm) ->
let f = vref.Deref
match hasTransfrom penv f with
| Some trans ->
@@ -723,7 +723,7 @@ let fixupApp (penv: penv) (fx, fty, tys, args, m) =
let callPattern = trans.transformCallPattern
let transformedVal = trans.transformedVal
let fCty = transformedVal.Type
- let fCx = exprForVal m transformedVal
+ let fCx = exprForVal vm transformedVal
(* [[f tps args ]] -> transformedVal tps [[COLLAPSED: args]] *)
let env = {prefix = "arg";m = m;eg=penv.g}
let bindings = []
diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt
index 032c1f001c..ff48ded92f 100644
--- a/src/fsharp/FSComp.txt
+++ b/src/fsharp/FSComp.txt
@@ -1233,6 +1233,7 @@ featureExpandedMeasurables,"more types support units of measure"
featurePrintfBinaryFormat,"binary formatting for integers"
featureDiscardUseValue,"discard pattern in use binding"
featureNonVariablePatternsToRightOfAsPatterns,"non-variable patterns to the right of 'as' patterns"
+featureAttributesToRightOfModuleKeyword,"attributes to the right of the 'module' keyword"
3090,tcIfThenElseMayNotBeUsedWithinQueries,"An if/then/else expression may not be used within queries. Consider using either an if/then expression, or use a sequence expression instead."
3091,ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen,"Invalid argument to 'methodhandleof' during codegen"
3092,etProvidedTypeReferenceMissingArgument,"A reference to a provided type was missing a value for the static parameter '%s'. You may need to recompile one or more referenced assemblies."
diff --git a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
index dd96b7da59..ff2d0cd077 100644
--- a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
+++ b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
@@ -112,18 +112,6 @@
Facilities\LanguageFeatures.fs
-
- LexYaccRuntime\prim-lexing.fsi
-
-
- LexYaccRuntime\prim-lexing.fs
-
-
- LexYaccRuntime\prim-parsing.fsi
-
-
- LexYaccRuntime\prim-parsing.fs
-
Utilities\ResizeArray.fsi
@@ -202,6 +190,12 @@
Utilities\lib.fs
+
+ Utilities\block.fsi
+
+
+ Utilities\block.fs
+
Utilities\rational.fsi
@@ -247,6 +241,18 @@
ErrorLogging\ErrorResolutionHints.fs
+
+ LexYaccRuntime\prim-lexing.fsi
+
+
+ LexYaccRuntime\prim-lexing.fs
+
+
+ LexYaccRuntime\prim-parsing.fsi
+
+
+ LexYaccRuntime\prim-parsing.fs
+
--unicode --lexlib Internal.Utilities.Text.Lexing
AbsIL\illex.fsl
diff --git a/src/fsharp/FSharp.Core/quotations.fs b/src/fsharp/FSharp.Core/quotations.fs
index aabae7bfda..94e6d36fe0 100644
--- a/src/fsharp/FSharp.Core/quotations.fs
+++ b/src/fsharp/FSharp.Core/quotations.fs
@@ -1856,7 +1856,7 @@ module Patterns =
|> List.iter (fun (resourceName, defns) ->
defns |> List.iter (fun (methodBase, exprBuilder) ->
reflectedDefinitionTable.[ReflectedDefinitionTableKey.GetKey methodBase] <- Entry exprBuilder)
- decodedTopResources.Add((assem, resourceName), 0))
+ decodedTopResources.[(assem, resourceName)] <- 0)
// we know it's in the table now, if it's ever going to be there
reflectedDefinitionTable.TryGetValue key
)
diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs
index 6cefacd50c..01e5eaac8e 100644
--- a/src/fsharp/IlxGen.fs
+++ b/src/fsharp/IlxGen.fs
@@ -829,14 +829,14 @@ type ValStorage =
| Method of ValReprInfo * ValRef * ILMethodSpec * ILMethodSpec * range * Typars * Typars * CurriedArgInfos * ArgReprInfo list * TraitWitnessInfos * TType list * ArgReprInfo
/// Indicates the value is stored at the given position in the closure environment accessed via "ldarg 0"
- | Env of ILType * ILFieldSpec * NamedLocalIlxClosureInfo ref option
+ | Env of ILType * ILFieldSpec * (FreeTyvars * NamedLocalIlxClosureInfo ref) option
/// Indicates that the value is an argument of a method being generated
| Arg of int
/// Indicates that the value is stored in local of the method being generated. NamedLocalIlxClosureInfo is normally empty.
/// It is non-empty for 'local type functions', see comments on definition of NamedLocalIlxClosureInfo.
- | Local of idx: int * realloc: bool * NamedLocalIlxClosureInfo ref option
+ | Local of idx: int * realloc: bool * (FreeTyvars * NamedLocalIlxClosureInfo ref) option
/// Indicates if there is a shadow local storage for a local, to make sure it gets a good name in debugging
and OptionalShadowLocal =
@@ -4883,16 +4883,25 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) eenvouter takenNames ex
// Partition the free variables when some can be accessed from places besides the immediate environment
// Also filter out the current value being bound, if any, as it is available from the "this"
// pointer which gives the current closure itself. This is in the case e.g. let rec f = ... f ...
+ let freeLocals = cloFreeVarResults.FreeLocals |> Zset.elements
let cloFreeVars =
- cloFreeVarResults.FreeLocals
- |> Zset.elements
+ freeLocals
|> List.filter (fun fv ->
(thisVars |> List.forall (fun v -> not (valRefEq g (mkLocalValRef fv) v))) &&
(match StorageForVal cenv.g m fv eenvouter with
| (StaticField _ | StaticProperty _ | Method _ | Null) -> false
| _ -> true))
- let cloFreeTyvars = cloFreeVarResults.FreeTyvars.FreeTypars |> Zset.elements
+ // Any closure using values represented as local type functions also captures the type variables captured
+ // by that local type function
+ let cloFreeTyvars =
+ (cloFreeVarResults.FreeTyvars, freeLocals) ||> List.fold (fun ftyvs fv ->
+ match StorageForVal cenv.g m fv eenvouter with
+ | Env (_, _, Some (moreFtyvs, _))
+ | Local (_, _, Some (moreFtyvs, _)) -> unionFreeTyvars ftyvs moreFtyvs
+ | _ -> ftyvs)
+
+ let cloFreeTyvars = cloFreeTyvars.FreeTypars |> Zset.elements
let cloAttribs = []
@@ -6629,10 +6638,10 @@ and GenSetStorage m cgbuf storage =
and CommitGetStorageSequel cenv cgbuf eenv m ty localCloInfo storeSequel =
match localCloInfo, storeSequel with
- | Some {contents =NamedLocalIlxClosureInfoGenerator _cloinfo}, _ ->
+ | Some (_, {contents =NamedLocalIlxClosureInfoGenerator _cloinfo}), _ ->
error(InternalError("Unexpected generator", m))
- | Some {contents =NamedLocalIlxClosureInfoGenerated cloinfo}, Some (tyargs, args, m, sequel) when not (isNil tyargs) ->
+ | Some (_, {contents =NamedLocalIlxClosureInfoGenerated cloinfo}), Some (tyargs, args, m, sequel) when not (isNil tyargs) ->
let actualRetTy = GenNamedLocalTyFuncCall cenv cgbuf eenv ty cloinfo tyargs m
CommitGetStorageSequel cenv cgbuf eenv m actualRetTy None (Some ([], args, m, sequel))
@@ -6729,16 +6738,17 @@ and AllocLocalVal cenv cgbuf v eenv repr scopeMarks =
else
match repr with
| Some r when IsNamedLocalTypeFuncVal g v r ->
+ let ftyvs = (freeInExpr CollectTypars r).FreeTyvars
// known, named, non-escaping type functions
let cloinfoGenerate eenv =
let eenvinner =
{eenv with
letBoundVars=(mkLocalValRef v) :: eenv.letBoundVars}
- let cloinfo, _, _ = GetIlxClosureInfo cenv v.Range true true [] eenvinner (Option.get repr)
+ let cloinfo, _, _ = GetIlxClosureInfo cenv v.Range true true [] eenvinner r
cloinfo
let idx, realloc, eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName g.CompilerGlobalState, g.ilg.typ_Object, false) scopeMarks
- Local (idx, realloc, Some(ref (NamedLocalIlxClosureInfoGenerator cloinfoGenerate))), eenv
+ Local (idx, realloc, Some(ftyvs, ref (NamedLocalIlxClosureInfoGenerator cloinfoGenerate))), eenv
| _ ->
// normal local
let idx, realloc, eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName g.CompilerGlobalState, GenTypeOfVal cenv eenv v, v.IsFixed) scopeMarks
@@ -6759,8 +6769,8 @@ and AllocStorageForBinds cenv cgbuf scopeMarks eenv binds =
match reprOpt with
| Some repr ->
match repr with
- | Local(_, _, Some g)
- | Env(_, _, Some g) ->
+ | Local(_, _, Some (_, g))
+ | Env(_, _, Some (_, g)) ->
match !g with
| NamedLocalIlxClosureInfoGenerator f -> g := NamedLocalIlxClosureInfoGenerated (f eenv)
| NamedLocalIlxClosureInfoGenerated _ -> ()
diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fs b/src/fsharp/InnerLambdasToTopLevelFuncs.fs
index 7721d0ccba..fb070b6617 100644
--- a/src/fsharp/InnerLambdasToTopLevelFuncs.fs
+++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fs
@@ -967,13 +967,14 @@ module Pass4_RewriteAssembly =
// pass4: lowertop - convert_vterm_bind on TopLevel binds
//-------------------------------------------------------------------------
- let ConvertBind g (TBind(v, repr, _) as bind) =
+ let AdjustBindToTopVal g (TBind(v, repr, _)) =
match v.ValReprInfo with
- | None -> v.SetValReprInfo (Some (InferArityOfExprBinding g AllowTypeDirectedDetupling.Yes v repr ))
+ | None ->
+ v.SetValReprInfo (Some (InferArityOfExprBinding g AllowTypeDirectedDetupling.Yes v repr ))
+ // Things that don't have an arity from type inference but are top-level are compiler-generated
+ v.SetIsCompilerGenerated(true)
| Some _ -> ()
- bind
-
//-------------------------------------------------------------------------
// pass4: transBind (translate)
//-------------------------------------------------------------------------
@@ -1035,6 +1036,9 @@ module Pass4_RewriteAssembly =
| None -> List.empty // no env for this mutual binding
| Some envp -> envp.ep_pack // environment pack bindings
+ let forceTopBindToHaveArity penv (bind: Binding) =
+ if penv.topValS.Contains(bind.Var) then AdjustBindToTopVal penv.g bind
+
let TransBindings xisRec penv (binds: Bindings) =
let tlrBs, nonTlrBs = binds |> List.partition (fun b -> Zset.contains b.Var penv.tlrS)
let fclass = BindingGroupSharingSameReqdItems tlrBs
@@ -1045,12 +1049,9 @@ module Pass4_RewriteAssembly =
// QUERY: we repeat this logic in LowerCallsAndSeqs. Do we really need to do this here?
// QUERY: yes and no - if we don't, we have an unrealizable term, and many decisions must
// QUERY: correlate with LowerCallsAndSeqs.
- let forceTopBindToHaveArity (bind: Binding) =
- if penv.topValS.Contains(bind.Var) then ConvertBind penv.g bind
- else bind
- let nonTlrBs = nonTlrBs |> List.map forceTopBindToHaveArity
- let tlrRebinds = tlrRebinds |> List.map forceTopBindToHaveArity
+ nonTlrBs |> List.iter (forceTopBindToHaveArity penv)
+ tlrRebinds |> List.iter (forceTopBindToHaveArity penv)
// assemble into replacement bindings
let bindAs, rebinds =
match xisRec with
@@ -1067,7 +1068,7 @@ module Pass4_RewriteAssembly =
// Is it a val app, where the val f is TLR with arity wf?
// CLEANUP NOTE: should be using a mkApps to make all applications
match fx with
- | Expr.Val (fvref: ValRef, _, m) when
+ | Expr.Val (fvref: ValRef, _, vm) when
(Zset.contains fvref.Deref penv.tlrS) &&
(let wf = Zmap.force fvref.Deref penv.arityM ("TransApp - wf", nameOfVal)
IsArityMet fvref wf tys args) ->
@@ -1078,9 +1079,9 @@ module Pass4_RewriteAssembly =
let envp = Zmap.force fc penv.envPackM ("TransApp - envp", string)
let fHat = Zmap.force f penv.fHatM ("TransApp - fHat", nameOfVal)
let tys = (List.map mkTyparTy envp.ep_etps) @ tys
- let aenvExprs = List.map (exprForVal m) envp.ep_aenvs
+ let aenvExprs = List.map (exprForVal vm) envp.ep_aenvs
let args = aenvExprs @ args
- mkApps penv.g ((exprForVal m fHat, fHat.Type), [tys], args, m) (* change, direct fHat call with closure (reqdTypars, aenvs) *)
+ mkApps penv.g ((exprForVal vm fHat, fHat.Type), [tys], args, m) (* change, direct fHat call with closure (reqdTypars, aenvs) *)
| _ ->
if isNil tys && isNil args then
fx
diff --git a/src/fsharp/LanguageFeatures.fs b/src/fsharp/LanguageFeatures.fs
index b8baecaefa..ee65da83ee 100644
--- a/src/fsharp/LanguageFeatures.fs
+++ b/src/fsharp/LanguageFeatures.fs
@@ -41,6 +41,7 @@ type LanguageFeature =
| PrintfBinaryFormat
| UseBindingValueDiscard
| NonVariablePatternsToRightOfAsPatterns
+ | AttributesToRightOfModuleKeyword
/// LanguageVersion management
type LanguageVersion (specifiedVersionAsString) =
@@ -87,6 +88,7 @@ type LanguageVersion (specifiedVersionAsString) =
LanguageFeature.PrintfBinaryFormat, previewVersion
LanguageFeature.UseBindingValueDiscard, previewVersion
LanguageFeature.NonVariablePatternsToRightOfAsPatterns, previewVersion
+ LanguageFeature.AttributesToRightOfModuleKeyword, previewVersion
]
let specified =
@@ -165,6 +167,7 @@ type LanguageVersion (specifiedVersionAsString) =
| LanguageFeature.PrintfBinaryFormat -> FSComp.SR.featurePrintfBinaryFormat()
| LanguageFeature.UseBindingValueDiscard -> FSComp.SR.featureDiscardUseValue()
| LanguageFeature.NonVariablePatternsToRightOfAsPatterns -> FSComp.SR.featureNonVariablePatternsToRightOfAsPatterns()
+ | LanguageFeature.AttributesToRightOfModuleKeyword -> FSComp.SR.featureAttributesToRightOfModuleKeyword()
/// Get a version string associated with the given feature.
member _.GetFeatureVersionString feature =
diff --git a/src/fsharp/LanguageFeatures.fsi b/src/fsharp/LanguageFeatures.fsi
index 24619dae14..ebc5e84650 100644
--- a/src/fsharp/LanguageFeatures.fsi
+++ b/src/fsharp/LanguageFeatures.fsi
@@ -29,6 +29,7 @@ type LanguageFeature =
| PrintfBinaryFormat
| UseBindingValueDiscard
| NonVariablePatternsToRightOfAsPatterns
+ | AttributesToRightOfModuleKeyword
/// LanguageVersion management
type LanguageVersion =
diff --git a/src/fsharp/LexFilter.fs b/src/fsharp/LexFilter.fs
index 152ff46a1a..2e84a4279f 100644
--- a/src/fsharp/LexFilter.fs
+++ b/src/fsharp/LexFilter.fs
@@ -47,7 +47,7 @@ type Context =
| CtxtTypeDefns of Position // 'type =', not removed when we find the "="
| CtxtNamespaceHead of Position * token
- | CtxtModuleHead of Position * token
+ | CtxtModuleHead of Position * token * LexingModuleAttributes
| CtxtMemberHead of Position
| CtxtMemberBody of Position
// If bool is true then this is "whole file"
@@ -65,7 +65,7 @@ type Context =
member c.StartPos =
match c with
- | CtxtNamespaceHead (p, _) | CtxtModuleHead (p, _) | CtxtException p | CtxtModuleBody (p, _) | CtxtNamespaceBody p
+ | CtxtNamespaceHead (p, _) | CtxtModuleHead (p, _, _) | CtxtException p | CtxtModuleBody (p, _) | CtxtNamespaceBody p
| CtxtLetDecl (_, p) | CtxtDo p | CtxtInterfaceHead p | CtxtTypeDefns p | CtxtParen (_, p) | CtxtMemberHead p | CtxtMemberBody p
| CtxtWithAsLet p
| CtxtWithAsAugment p
@@ -108,6 +108,7 @@ type Context =
and AddBlockEnd = AddBlockEnd | NoAddBlockEnd | AddOneSidedBlockEnd
and FirstInSequence = FirstInSeqBlock | NotFirstInSeqBlock
+and LexingModuleAttributes = LexingModuleAttributes | NotLexingModuleAttributes
let isInfix token =
@@ -1426,19 +1427,27 @@ type LexFilterImpl (lightStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbu
// Transition rule. CtxtModuleHead ~~~> push CtxtModuleBody; push CtxtSeqBlock
// Applied when a ':' or '=' token is seen
- // Otherwise it's a 'head' module declaration, so ignore it
- | _, (CtxtModuleHead (moduleTokenPos, prevToken) :: _) ->
- match prevToken, token with
- | MODULE, GLOBAL when moduleTokenPos.Column < tokenStartPos.Column ->
- replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, token))
+ // Otherwise it's a 'head' module declaration, so ignore it
+
+ // Here prevToken is either 'module', 'rec', 'global' (invalid), '.', or ident, because we skip attribute tokens and access modifier tokens
+ | _, (CtxtModuleHead (moduleTokenPos, prevToken, lexingModuleAttributes) :: _) ->
+ match prevToken, token with
+ | _, GREATER_RBRACK when lexingModuleAttributes = LexingModuleAttributes
+ && moduleTokenPos.Column < tokenStartPos.Column ->
+ replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, prevToken, NotLexingModuleAttributes))
returnToken tokenLexbufState token
- | MODULE, (PUBLIC | PRIVATE | INTERNAL) when moduleTokenPos.Column < tokenStartPos.Column ->
+ | _ when lexingModuleAttributes = LexingModuleAttributes
+ && moduleTokenPos.Column < tokenStartPos.Column ->
returnToken tokenLexbufState token
- | (MODULE | DOT | REC), (REC | IDENT _) when moduleTokenPos.Column < tokenStartPos.Column ->
- replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, token))
+ | MODULE, (PUBLIC | PRIVATE | INTERNAL) when moduleTokenPos.Column < tokenStartPos.Column ->
returnToken tokenLexbufState token
+ | MODULE, GLOBAL
+ | (MODULE | REC | DOT), (REC | IDENT _)
| IDENT _, DOT when moduleTokenPos.Column < tokenStartPos.Column ->
- replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, token))
+ replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, token, NotLexingModuleAttributes))
+ returnToken tokenLexbufState token
+ | MODULE, LBRACK_LESS when moduleTokenPos.Column < tokenStartPos.Column ->
+ replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, prevToken, LexingModuleAttributes))
returnToken tokenLexbufState token
| _, (EQUALS | COLON) ->
if debug then dprintf "CtxtModuleHead: COLON/EQUALS, pushing CtxtModuleBody and CtxtSeqBlock\n"
@@ -1453,12 +1462,12 @@ type LexFilterImpl (lightStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbu
match tokenTup.Token with
| Parser.EOF _ ->
returnToken tokenLexbufState token
- | _ ->
+ | _ ->
+ // We have reached other tokens without encountering '=' or ':', so this is a module declaration spanning the whole file
delayToken tokenTup
pushCtxt tokenTup (CtxtModuleBody (moduleTokenPos, true))
pushCtxtSeqBlockAt (tokenTup, true, AddBlockEnd)
hwTokenFetch false
-
// Offside rule for SeqBlock.
// f x
// g x
@@ -1769,7 +1778,7 @@ type LexFilterImpl (lightStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbu
| MODULE, (_ :: _) ->
insertComingSoonTokens("MODULE", MODULE_COMING_SOON, MODULE_IS_HERE)
if debug then dprintf "MODULE: entering CtxtModuleHead, awaiting EQUALS to go to CtxtSeqBlock (%a)\n" outputPos tokenStartPos
- pushCtxt tokenTup (CtxtModuleHead (tokenStartPos, token))
+ pushCtxt tokenTup (CtxtModuleHead (tokenStartPos, token, NotLexingModuleAttributes))
pool.Return tokenTup
hwTokenFetch useBlockRule
diff --git a/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec b/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec
index 8f9f4824dd..f4877b8258 100644
--- a/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec
+++ b/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec
@@ -22,8 +22,8 @@
-
-
+
+
diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs
index d579077b08..6c61ca7985 100644
--- a/src/fsharp/Optimizer.fs
+++ b/src/fsharp/Optimizer.fs
@@ -97,13 +97,13 @@ type ExprValueInfo =
| ConstValue of Const * TType
- /// CurriedLambdaValue(id, arity, size, lambdaExpression, ty)
+ /// CurriedLambdaValue(id, arity, size, lambdaExpression, isCrossAssembly, ty)
///
/// arities: The number of bunches of untupled args and type args, and
/// the number of args in each bunch. NOTE: This include type arguments.
/// expr: The value, a lambda term.
/// ty: The type of lambda term
- | CurriedLambdaValue of id: Unique * arity: int * size: int * value: Expr * TType
+ | CurriedLambdaValue of id: Unique * arity: int * size: int * lambdaExpr: Expr * isCrossAssembly: bool * lambdaExprTy: TType
/// ConstExprValue(size, value)
| ConstExprValue of size: int * value: Expr
@@ -202,7 +202,7 @@ let rec exprValueInfoL g exprVal =
| TupleValue vinfos -> bracketL (exprValueInfosL g vinfos)
| RecdValue (_, vinfos) -> braceL (exprValueInfosL g vinfos)
| UnionCaseValue (ucr, vinfos) -> unionCaseRefL ucr ^^ bracketL (exprValueInfosL g vinfos)
- | CurriedLambdaValue(_lambdaId, _arities, _bsize, expr, _ety) -> wordL (tagText "lam") ++ exprL expr (* (sprintf "lam(size=%d)" bsize) *)
+ | CurriedLambdaValue(_lambdaId, _arities, _bsize, expr, _isCrossAssembly, _ety) -> wordL (tagText "lam") ++ exprL expr (* (sprintf "lam(size=%d)" bsize) *)
| ConstExprValue (_size, x) -> exprL x
and exprValueInfosL g vinfos = commaListL (List.map (exprValueInfoL g) (Array.toList vinfos))
@@ -252,7 +252,7 @@ and SizeOfValueInfo x =
| TupleValue vinfos
| RecdValue (_, vinfos)
| UnionCaseValue (_, vinfos) -> 1 + SizeOfValueInfos vinfos
- | CurriedLambdaValue(_lambdaId, _arities, _bsize, _expr, _ety) -> 1
+ | CurriedLambdaValue _ -> 1
| ConstExprValue (_size, _) -> 1
let [] minDepthForASizeNode = 5 // for small vinfos do not record size info, save space
@@ -279,7 +279,7 @@ let BoundValueInfoBySize vinfo =
| UnionCaseValue (ucr, vinfos) -> UnionCaseValue (ucr, Array.map (bound (depth-1)) vinfos)
| ConstValue _ -> x
| UnknownValue -> x
- | CurriedLambdaValue(_lambdaId, _arities, _bsize, _expr, _ety) -> x
+ | CurriedLambdaValue _ -> x
| ConstExprValue (_size, _) -> x
let maxDepth = 6 (* beware huge constants! *)
let trimDepth = 3
@@ -661,7 +661,7 @@ let (|StripConstValue|_|) ev =
let (|StripLambdaValue|_|) ev =
match stripValue ev with
- | CurriedLambdaValue (id, arity, sz, expr, ty) -> Some (id, arity, sz, expr, ty)
+ | CurriedLambdaValue (id, arity, sz, expr, isCrossAssembly, ty) -> Some (id, arity, sz, expr, isCrossAssembly, ty)
| _ -> None
let destTupleValue ev =
@@ -1064,7 +1064,7 @@ let AbstractLazyModulInfoByHiding isAssemblyBoundary mhi =
else ValValue (vref2, detailR)
// Check for escape in lambda
- | CurriedLambdaValue (_, _, _, expr, _) | ConstExprValue(_, expr) when
+ | CurriedLambdaValue (_, _, _, expr, _, _) | ConstExprValue(_, expr) when
(let fvs = freeInExpr CollectAll expr
(isAssemblyBoundary && not (freeVarsAllPublic fvs)) ||
Zset.exists hiddenVal fvs.FreeLocals ||
@@ -1158,7 +1158,7 @@ let AbstractExprInfoByVars (boundVars: Val list, boundTyVars) ivalue =
ValValue (v2, detailR)
// Check for escape in lambda
- | CurriedLambdaValue (_, _, _, expr, _) | ConstExprValue(_, expr) when
+ | CurriedLambdaValue (_, _, _, expr, _, _) | ConstExprValue(_, expr) when
(let fvs = freeInExpr (if isNil boundTyVars then CollectLocals else CollectTyparsAndLocals) expr
(not (isNil boundVars) && List.exists (Zset.memberOf fvs.FreeLocals) boundVars) ||
(not (isNil boundTyVars) && List.exists (Zset.memberOf fvs.FreeTyvars.FreeTypars) boundTyVars) ||
@@ -1207,7 +1207,7 @@ let RemapOptimizationInfo g tmenv =
| UnionCaseValue(cspec, vinfos) -> UnionCaseValue (remapUnionCaseRef tmenv.tyconRefRemap cspec, Array.map remapExprInfo vinfos)
| SizeValue(_vdepth, vinfo) -> MakeSizedValueInfo (remapExprInfo vinfo)
| UnknownValue -> UnknownValue
- | CurriedLambdaValue (uniq, arity, sz, expr, ty) -> CurriedLambdaValue (uniq, arity, sz, remapExpr g CloneAll tmenv expr, remapPossibleForallTy g tmenv ty)
+ | CurriedLambdaValue (uniq, arity, sz, expr, isCrossAssembly, ty) -> CurriedLambdaValue (uniq, arity, sz, remapExpr g CloneAll tmenv expr, isCrossAssembly, remapPossibleForallTy g tmenv ty)
| ConstValue (c, ty) -> ConstValue (c, remapPossibleForallTy g tmenv ty)
| ConstExprValue (sz, expr) -> ConstExprValue (sz, remapExpr g CloneAll tmenv expr)
@@ -2557,6 +2557,17 @@ and OptimizeTraitCall cenv env (traitInfo, args, m) =
let argsR, arginfos = OptimizeExprsThenConsiderSplits cenv env args
OptimizeExprOpFallback cenv env (TOp.TraitCall traitInfo, [], argsR, m) arginfos UnknownValue
+and CopyExprForInlining cenv isCrossAssembly expr m =
+ if isCrossAssembly then
+ // Debug points are erased when doing cross-assembly inlining
+ // Locals are marked compiler generated when doing cross-assembly inlining
+ expr
+ |> copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated
+ |> remarkExpr m
+ else
+ expr
+ |> copyExpr cenv.g CloneAll
+
/// Make optimization decisions once we know the optimization information
/// for a value
and TryOptimizeVal cenv env (vOpt: ValRef option, mustInline, valInfoForVal, m) =
@@ -2579,9 +2590,10 @@ and TryOptimizeVal cenv env (vOpt: ValRef option, mustInline, valInfoForVal, m)
// If we have proven 'v = compilerGeneratedValue'
// and 'v' is being eliminated in favour of 'compilerGeneratedValue'
// then replace the name of 'compilerGeneratedValue'
- // by 'v' and mark it not compiler generated so we preserve good debugging and names
+ // by 'v' and mark it not compiler generated so we preserve good debugging and names.
+ // Don't do this for things represented statically as it may publish multiple values with the same name.
match vOpt with
- | Some v when not v.IsCompilerGenerated && vR.IsCompilerGenerated ->
+ | Some v when not v.IsCompilerGenerated && vR.IsCompilerGenerated && not vR.IsCompiledAsTopLevel && not v.IsCompiledAsTopLevel ->
vR.Deref.SetIsCompilerGenerated(false)
vR.Deref.SetLogicalName(v.LogicalName)
| _ -> ()
@@ -2590,8 +2602,9 @@ and TryOptimizeVal cenv env (vOpt: ValRef option, mustInline, valInfoForVal, m)
| ConstExprValue(_size, expr) ->
Some (remarkExpr m (copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated expr))
- | CurriedLambdaValue (_, _, _, expr, _) when mustInline ->
- Some (remarkExpr m (copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated expr))
+ | CurriedLambdaValue (_, _, _, expr, isCrossAssembly, _) when mustInline ->
+ let exprCopy = CopyExprForInlining cenv isCrossAssembly expr m
+ Some exprCopy
| TupleValue _ | UnionCaseValue _ | RecdValue _ when mustInline ->
failwith "tuple, union and record values cannot be marked 'inline'"
@@ -2887,7 +2900,7 @@ and TryDevirtualizeApplication cenv env (f, tyargs, args, m) =
and TryInlineApplication cenv env finfo (tyargs: TType list, args: Expr list, m) =
// Considering inlining app
match finfo.Info with
- | StripLambdaValue (lambdaId, arities, size, f2, f2ty) when
+ | StripLambdaValue (lambdaId, arities, size, f2, isCrossAssembly, f2ty) when
(// Considering inlining lambda
cenv.optimizing &&
cenv.settings.InlineLambdas () &&
@@ -2948,7 +2961,8 @@ and TryInlineApplication cenv env finfo (tyargs: TType list, args: Expr list, m)
// Inlining lambda
(* ---------- printf "Inlining lambda near %a = %s\n" outputRange m (showL (exprL f2)) (* JAMES: *) ----------*)
- let f2R = remarkExpr m (copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated f2)
+ let f2R = CopyExprForInlining cenv isCrossAssembly f2 m
+
// Optimizing arguments after inlining
// REVIEW: this is a cheapshot way of optimizing the arg expressions as well without the restriction of recursive
@@ -2962,6 +2976,16 @@ and TryInlineApplication cenv env finfo (tyargs: TType list, args: Expr list, m)
| _ -> None
+/// When optimizing a function in an application, use the whole range including arguments for the range
+/// to apply to 'inline' code
+and OptimizeFuncInApplication cenv env f0 mWithArgs =
+ let f0 = stripExpr f0
+ match f0 with
+ | Expr.Val (v, _vFlags, _) ->
+ OptimizeVal cenv env f0 (v, mWithArgs)
+ | _ ->
+ OptimizeExpr cenv env f0
+
/// Optimize/analyze an application of a function to type and term arguments
and OptimizeApplication cenv env (f0, f0ty, tyargs, args, m) =
// trying to devirtualize
@@ -2970,7 +2994,7 @@ and OptimizeApplication cenv env (f0, f0ty, tyargs, args, m) =
// devirtualized
res
| None ->
- let newf0, finfo = OptimizeExpr cenv env f0
+ let newf0, finfo = OptimizeFuncInApplication cenv env f0 m
match TryInlineApplication cenv env finfo (tyargs, args, m) with
| Some res ->
// inlined
@@ -3086,14 +3110,14 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety =
// can't inline any values with semi-recursive object references to self or base
let valu =
match baseValOpt with
- | None -> CurriedLambdaValue (lambdaId, arities, bsize, exprR, ety)
+ | None -> CurriedLambdaValue (lambdaId, arities, bsize, exprR, false, ety)
| Some baseVal ->
let fvs = freeInExpr CollectLocals bodyR
if fvs.UsesMethodLocalConstructs || fvs.FreeLocals.Contains baseVal then
UnknownValue
else
let expr2 = mkMemberLambdas m tps ctorThisValOpt None vsl (bodyR, bodyty)
- CurriedLambdaValue (lambdaId, arities, bsize, expr2, ety)
+ CurriedLambdaValue (lambdaId, arities, bsize, expr2, false, ety)
let estimatedSize =
match vspec with
@@ -3323,7 +3347,7 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) =
// Trim out optimization information for expressions that call protected members
let rec cut ivalue =
match ivalue with
- | CurriedLambdaValue (_, arities, size, body, _) ->
+ | CurriedLambdaValue (_, arities, size, body, _, _) ->
if size > (cenv.settings.lambdaInlineThreshold + arities + 2) then
// Discarding lambda for large binding
UnknownValue
@@ -3600,7 +3624,7 @@ let rec p_ExprValueInfo x st =
| UnionCaseValue (a, b) ->
p_byte 4 st
p_tup2 p_ucref (p_array p_ExprValueInfo) (a, b) st
- | CurriedLambdaValue (_, b, c, d, e) ->
+ | CurriedLambdaValue (_, b, c, d, _isCrossAssembly, e) ->
p_byte 5 st
p_tup4 p_int p_int p_expr p_ty (b, c, d, e) st
| ConstExprValue (a, b) ->
@@ -3635,11 +3659,12 @@ let rec u_ExprInfo st =
| 2 -> u_tup2 u_vref loop st |> (fun (a, b) -> ValValue (a, b))
| 3 -> u_array loop st |> (fun a -> TupleValue a)
| 4 -> u_tup2 u_ucref (u_array loop) st |> (fun (a, b) -> UnionCaseValue (a, b))
- | 5 -> u_tup4 u_int u_int u_expr u_ty st |> (fun (b, c, d, e) -> CurriedLambdaValue (newUnique(), b, c, d, e))
+ | 5 -> u_tup4 u_int u_int u_expr u_ty st |> (fun (b, c, d, e) -> CurriedLambdaValue (newUnique(), b, c, d, (* isCrossAssembly *) true, e))
| 6 -> u_tup2 u_int u_expr st |> (fun (a, b) -> ConstExprValue (a, b))
| 7 -> u_tup2 u_tcref (u_array loop) st |> (fun (a, b) -> RecdValue (a, b))
| _ -> failwith "loop"
- MakeSizedValueInfo (loop st) (* calc size of unpicked ExprValueInfo *)
+ // calc size of unpicked ExprValueInfo
+ MakeSizedValueInfo (loop st)
and u_ValInfo st =
let a, b = u_tup2 u_ExprInfo u_bool st
diff --git a/src/fsharp/ParseAndCheckInputs.fs b/src/fsharp/ParseAndCheckInputs.fs
index ffe1bfe4a9..d6c7991cf7 100644
--- a/src/fsharp/ParseAndCheckInputs.fs
+++ b/src/fsharp/ParseAndCheckInputs.fs
@@ -170,9 +170,12 @@ let GetScopedPragmasForHashDirective hd =
[ match hd with
| ParsedHashDirective("nowarn", numbers, m) ->
for s in numbers do
- match GetWarningNumber(m, s) with
- | None -> ()
- | Some n -> yield ScopedPragma.WarningOff(m, n)
+ match s with
+ | ParsedHashDirectiveArgument.SourceIdentifier _ -> ()
+ | ParsedHashDirectiveArgument.String (s, _, _) ->
+ match GetWarningNumber(m, s) with
+ | None -> ()
+ | Some n -> yield ScopedPragma.WarningOff(m, n)
| _ -> () ]
let PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, ParsedImplFile (hashDirectives, impls)) =
@@ -286,11 +289,13 @@ let ParseInput (lexer, errorLogger: ErrorLogger, lexbuf: UnicodeLexing.Lexbuf, d
let filteringErrorLogger = GetErrorLoggerFilteringByScopedPragmas(false, scopedPragmas, errorLogger)
delayLogger.CommitDelayedDiagnostics filteringErrorLogger
+type Tokenizer = unit -> Parser.token
+
// Show all tokens in the stream, for testing purposes
-let ShowAllTokensAndExit (shortFilename, tokenizer: LexFilter.LexFilter, lexbuf: LexBuffer) =
+let ShowAllTokensAndExit (shortFilename, tokenizer: Tokenizer, lexbuf: LexBuffer) =
while true do
printf "tokenize - getting one token from %s\n" shortFilename
- let t = tokenizer.GetToken()
+ let t = tokenizer ()
printf "tokenize - got %s @ %a\n" (Parser.token_to_string t) outputRange lexbuf.LexemeRange
match t with
| Parser.EOF _ -> exit 0
@@ -298,11 +303,11 @@ let ShowAllTokensAndExit (shortFilename, tokenizer: LexFilter.LexFilter, lexbuf:
if lexbuf.IsPastEndOfStream then printf "!!! at end of stream\n"
// Test one of the parser entry points, just for testing purposes
-let TestInteractionParserAndExit (tokenizer: LexFilter.LexFilter, lexbuf: LexBuffer) =
+let TestInteractionParserAndExit (tokenizer: Tokenizer, lexbuf: LexBuffer) =
while true do
- match (Parser.interaction (fun _ -> tokenizer.GetToken()) lexbuf) with
+ match (Parser.interaction (fun _ -> tokenizer ()) lexbuf) with
| ParsedScriptInteraction.Definitions(l, m) -> printfn "Parsed OK, got %d defs @ %a" l.Length outputRange m
- | ParsedScriptInteraction.HashDirective (_, m) -> printfn "Parsed OK, got hash @ %a" outputRange m
+ | ParsedScriptInteraction.HashDirective(_, m) -> printfn "Parsed OK, got hash @ %a" outputRange m
exit 0
// Report the statistics for testing purposes
@@ -366,10 +371,14 @@ let ParseOneInputLexbuf (tcConfig: TcConfig, lexResourceManager, conditionalComp
Lexhelp.usingLexbufForParsing (lexbuf, filename) (fun lexbuf ->
// Set up the LexFilter over the token stream
- let tokenizer = LexFilter.LexFilter(lightStatus, tcConfig.compilingFslib, Lexer.token lexargs skipWhitespaceTokens, lexbuf)
+ let tokenizer,tokenizeOnly =
+ match tcConfig.tokenize with
+ | Unfiltered -> (fun () -> Lexer.token lexargs skipWhitespaceTokens lexbuf), true
+ | Only -> LexFilter.LexFilter(lightStatus, tcConfig.compilingFslib, Lexer.token lexargs skipWhitespaceTokens, lexbuf).GetToken, true
+ | _ -> LexFilter.LexFilter(lightStatus, tcConfig.compilingFslib, Lexer.token lexargs skipWhitespaceTokens, lexbuf).GetToken, false
// If '--tokenize' then show the tokens now and exit
- if tcConfig.tokenizeOnly then
+ if tokenizeOnly then
ShowAllTokensAndExit(shortFilename, tokenizer, lexbuf)
// Test hook for one of the parser entry points
@@ -377,7 +386,7 @@ let ParseOneInputLexbuf (tcConfig: TcConfig, lexResourceManager, conditionalComp
TestInteractionParserAndExit (tokenizer, lexbuf)
// Parse the input
- let res = ParseInput((fun _ -> tokenizer.GetToken()), errorLogger, lexbuf, None, filename, isLastCompiland)
+ let res = ParseInput((fun _ -> tokenizer ()), errorLogger, lexbuf, None, filename, isLastCompiland)
// Report the statistics for testing purposes
if tcConfig.reportNumDecls then
@@ -408,7 +417,8 @@ let parseInputFileAux (tcConfig: TcConfig, lexResourceManager, conditionalCompil
use reader = fileStream.GetReader(tcConfig.inputCodePage, retryLocked)
// Set up the LexBuffer for the file
- let lexbuf = UnicodeLexing.StreamReaderAsLexbuf(not tcConfig.compilingFslib, tcConfig.langVersion.SupportsFeature, reader)
+ let checkLanguageFeatureErrorRecover = ErrorLogger.checkLanguageFeatureErrorRecover tcConfig.langVersion
+ let lexbuf = UnicodeLexing.StreamReaderAsLexbuf(not tcConfig.compilingFslib, tcConfig.langVersion.SupportsFeature, checkLanguageFeatureErrorRecover, reader)
// Parse the file drawing tokens from the lexbuf
ParseOneInputLexbuf(tcConfig, lexResourceManager, conditionalCompilationDefines, lexbuf, filename, isLastCompiland, errorLogger)
@@ -512,7 +522,7 @@ let ProcessMetaCommandsFromInput
let mutable matchedm = range0
try
match hash with
- | ParsedHashDirective("I", args, m) ->
+ | ParsedHashDirective("I", ParsedHashDirectiveArguments args, m) ->
if not canHaveScriptMetaCommands then
errorR(HashIncludeNotAllowedInNonScript m)
match args with
@@ -523,18 +533,18 @@ let ProcessMetaCommandsFromInput
| _ ->
errorR(Error(FSComp.SR.buildInvalidHashIDirective(), m))
state
- | ParsedHashDirective("nowarn",numbers,m) ->
+ | ParsedHashDirective("nowarn", ParsedHashDirectiveArguments numbers,m) ->
List.fold (fun state d -> nowarnF state (m,d)) state numbers
- | ParsedHashDirective(("reference" | "r"), args, m) ->
+ | ParsedHashDirective(("reference" | "r"), ParsedHashDirectiveArguments args, m) ->
matchedm<-m
ProcessDependencyManagerDirective Directive.Resolution args m state
- | ParsedHashDirective(("i"), args, m) ->
+ | ParsedHashDirective(("i"), ParsedHashDirectiveArguments args, m) ->
matchedm<-m
ProcessDependencyManagerDirective Directive.Include args m state
- | ParsedHashDirective("load", args, m) ->
+ | ParsedHashDirective("load", ParsedHashDirectiveArguments args, m) ->
if not canHaveScriptMetaCommands then
errorR(HashDirectiveNotAllowedInNonScript m)
match args with
@@ -544,7 +554,7 @@ let ProcessMetaCommandsFromInput
| _ ->
errorR(Error(FSComp.SR.buildInvalidHashloadDirective(), m))
state
- | ParsedHashDirective("time", args, m) ->
+ | ParsedHashDirective("time", ParsedHashDirectiveArguments args, m) ->
if not canHaveScriptMetaCommands then
errorR(HashDirectiveNotAllowedInNonScript m)
match args with
diff --git a/src/fsharp/ParseHelpers.fs b/src/fsharp/ParseHelpers.fs
index 35a10a0b1f..445d44a5a8 100644
--- a/src/fsharp/ParseHelpers.fs
+++ b/src/fsharp/ParseHelpers.fs
@@ -220,7 +220,7 @@ and LexCont = LexerContinuation
// Parse IL assembly code
//------------------------------------------------------------------------
-let ParseAssemblyCodeInstructions s reportLibraryOnlyFeatures (isFeatureSupported: LanguageFeature -> bool) m : IL.ILInstr[] =
+let ParseAssemblyCodeInstructions s reportLibraryOnlyFeatures (isFeatureSupported: LanguageFeature -> bool) checkLanguageFeatureErrorRecover m : IL.ILInstr[] =
#if NO_INLINE_IL_PARSER
ignore s
ignore isFeatureSupported
@@ -231,24 +231,26 @@ let ParseAssemblyCodeInstructions s reportLibraryOnlyFeatures (isFeatureSupporte
try
FSharp.Compiler.AbstractIL.AsciiParser.ilInstrs
FSharp.Compiler.AbstractIL.AsciiLexer.token
- (UnicodeLexing.StringAsLexbuf(reportLibraryOnlyFeatures, isFeatureSupported, s))
+ (UnicodeLexing.StringAsLexbuf(reportLibraryOnlyFeatures, isFeatureSupported, checkLanguageFeatureErrorRecover, s))
with _ ->
errorR(Error(FSComp.SR.astParseEmbeddedILError(), m)); [||]
#endif
-let ParseAssemblyCodeType s reportLibraryOnlyFeatures (isFeatureSupported: Features.LanguageFeature -> bool) m =
+let ParseAssemblyCodeType s reportLibraryOnlyFeatures (isFeatureSupported: Features.LanguageFeature -> bool) (checkLanguageFeatureErrorRecover: Features.LanguageFeature -> range -> unit) m =
ignore s
ignore isFeatureSupported
+ ignore checkLanguageFeatureErrorRecover
#if NO_INLINE_IL_PARSER
errorR(Error((193, "Inline IL not valid in a hosted environment"), m))
IL.PrimaryAssemblyILGlobals.typ_Object
#else
let isFeatureSupported (_featureId:LanguageFeature) = true
+ let checkLanguageFeatureErrorRecover (_featureId:LanguageFeature) _range = ()
try
FSharp.Compiler.AbstractIL.AsciiParser.ilType
FSharp.Compiler.AbstractIL.AsciiLexer.token
- (UnicodeLexing.StringAsLexbuf(reportLibraryOnlyFeatures, isFeatureSupported, s))
+ (UnicodeLexing.StringAsLexbuf(reportLibraryOnlyFeatures, isFeatureSupported, checkLanguageFeatureErrorRecover, s))
with RecoverableParseError ->
errorR(Error(FSComp.SR.astParseEmbeddedILTypeError(), m));
IL.PrimaryAssemblyILGlobals.typ_Object
diff --git a/src/fsharp/ParseHelpers.fsi b/src/fsharp/ParseHelpers.fsi
index 716246338a..3a2e5e511f 100644
--- a/src/fsharp/ParseHelpers.fsi
+++ b/src/fsharp/ParseHelpers.fsi
@@ -108,6 +108,6 @@ type LexerContinuation =
and LexCont = LexerContinuation
-val ParseAssemblyCodeInstructions: s:string -> reportLibraryOnlyFeatures: bool -> isFeatureSupported:(Features.LanguageFeature -> bool) -> m:range -> ILInstr[]
+val ParseAssemblyCodeInstructions: s:string -> reportLibraryOnlyFeatures: bool -> isFeatureSupported:(Features.LanguageFeature -> bool) -> checkLanguageFeatureErrorRecover:(Features.LanguageFeature -> range -> unit) -> m:range -> ILInstr[]
-val ParseAssemblyCodeType: s:string -> reportLibraryOnlyFeatures: bool -> isFeatureSupported:(Features.LanguageFeature -> bool) -> m:range -> ILType
+val ParseAssemblyCodeType: s:string -> reportLibraryOnlyFeatures: bool -> isFeatureSupported:(Features.LanguageFeature -> bool) -> checkLanguageFeatureErrorRecover:(Features.LanguageFeature -> range -> unit) -> m:range -> ILType
diff --git a/src/fsharp/ScriptClosure.fs b/src/fsharp/ScriptClosure.fs
index c7fa44a6b2..887e1dbe00 100644
--- a/src/fsharp/ScriptClosure.fs
+++ b/src/fsharp/ScriptClosure.fs
@@ -111,7 +111,8 @@ module ScriptPreprocessClosure =
| CodeContext.Editing -> "EDITING" :: (if IsScript filename then ["INTERACTIVE"] else ["COMPILED"])
let isFeatureSupported featureId = tcConfig.langVersion.SupportsFeature featureId
- let lexbuf = UnicodeLexing.SourceTextAsLexbuf(true, isFeatureSupported, sourceText)
+ let checkLanguageFeatureErrorRecover = ErrorLogger.checkLanguageFeatureErrorRecover tcConfig.langVersion
+ let lexbuf = UnicodeLexing.SourceTextAsLexbuf(true, isFeatureSupported, checkLanguageFeatureErrorRecover, sourceText)
let isLastCompiland = (IsScript filename), tcConfig.target.IsExe // The root compiland is last in the list of compilands.
ParseOneInputLexbuf (tcConfig, lexResourceManager, defines, lexbuf, filename, isLastCompiland, errorLogger)
diff --git a/src/fsharp/SyntaxTree.fs b/src/fsharp/SyntaxTree.fs
index 92e4dcd3db..efec365b65 100644
--- a/src/fsharp/SyntaxTree.fs
+++ b/src/fsharp/SyntaxTree.fs
@@ -1826,11 +1826,21 @@ type SynModuleOrNamespaceSig =
match this with
| SynModuleOrNamespaceSig (range=m) -> m
+[]
+type ParsedHashDirectiveArgument =
+ | String of value: string * stringKind: SynStringKind * range: Range
+ | SourceIdentifier of constant: string * value: string * range: Range
+
+ member this.Range =
+ match this with
+ | ParsedHashDirectiveArgument.String (range=m)
+ | ParsedHashDirectiveArgument.SourceIdentifier (range=m) -> m
+
[]
type ParsedHashDirective =
| ParsedHashDirective of
ident: string *
- args: string list *
+ args: ParsedHashDirectiveArgument list *
range: range
[]
diff --git a/src/fsharp/SyntaxTree.fsi b/src/fsharp/SyntaxTree.fsi
index 3c2f8b9965..a04fc70da3 100644
--- a/src/fsharp/SyntaxTree.fsi
+++ b/src/fsharp/SyntaxTree.fsi
@@ -2014,12 +2014,21 @@ type SynModuleOrNamespaceSig =
/// Gets the syntax range of this construct
member Range: range
+/// Represents a parsed hash directive argument
+[]
+type ParsedHashDirectiveArgument =
+ | String of value: string * stringKind: SynStringKind * range: Range
+ | SourceIdentifier of constant: string * value: string * range: Range
+
+ /// Gets the syntax range of this construct
+ member Range: range
+
/// Represents a parsed hash directive
[]
type ParsedHashDirective =
| ParsedHashDirective of
ident: string *
- args: string list *
+ args: ParsedHashDirectiveArgument list *
range: range
/// Represents the syntax tree for the contents of a parsed implementation file
diff --git a/src/fsharp/SyntaxTreeOps.fs b/src/fsharp/SyntaxTreeOps.fs
index f0f02e268f..0efa234487 100644
--- a/src/fsharp/SyntaxTreeOps.fs
+++ b/src/fsharp/SyntaxTreeOps.fs
@@ -748,3 +748,10 @@ let rec synExprContainsError inpExpr =
| SynInterpolatedStringPart.FillExpr (x, _) -> Some x))
walkExpr inpExpr
+
+let (|ParsedHashDirectiveArguments|) (input: ParsedHashDirectiveArgument list) =
+ List.map
+ (function
+ | ParsedHashDirectiveArgument.String (s, _, _) -> s
+ | ParsedHashDirectiveArgument.SourceIdentifier (_, v, _) -> v)
+ input
\ No newline at end of file
diff --git a/src/fsharp/SyntaxTreeOps.fsi b/src/fsharp/SyntaxTreeOps.fsi
index 48f7812d07..106b7a6154 100644
--- a/src/fsharp/SyntaxTreeOps.fsi
+++ b/src/fsharp/SyntaxTreeOps.fsi
@@ -266,3 +266,5 @@ val inferredTyparDecls: SynValTyparDecls
val noInferredTypars: SynValTyparDecls
val synExprContainsError: inpExpr:SynExpr -> bool
+
+val ( |ParsedHashDirectiveArguments| ) : ParsedHashDirectiveArgument list -> string list
\ No newline at end of file
diff --git a/src/fsharp/TypedTreeOps.fs b/src/fsharp/TypedTreeOps.fs
index 3cdda13adc..18b78371c1 100644
--- a/src/fsharp/TypedTreeOps.fs
+++ b/src/fsharp/TypedTreeOps.fs
@@ -7544,7 +7544,7 @@ let rec MakeApplicationAndBetaReduceAux g (f, fty, tyargsl: TType list list, arg
match f with
| Expr.TyLambda (_, tyvs, body, _, bodyty) when tyvs.Length = List.length tyargs ->
let tpenv = bindTypars tyvs tyargs emptyTyparInst
- let body = remarkExpr m (instExpr g tpenv body)
+ let body = instExpr g tpenv body
let bodyty' = instType tpenv bodyty
MakeApplicationAndBetaReduceAux g (body, bodyty', rest, argsl, m)
diff --git a/src/fsharp/UnicodeLexing.fs b/src/fsharp/UnicodeLexing.fs
index 99ee27ff72..946d791844 100644
--- a/src/fsharp/UnicodeLexing.fs
+++ b/src/fsharp/UnicodeLexing.fs
@@ -8,18 +8,18 @@ open Internal.Utilities.Text.Lexing
type Lexbuf = LexBuffer
-let StringAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, s: string) =
- LexBuffer.FromChars (reportLibraryOnlyFeatures, supportsFeature, s.ToCharArray())
+let StringAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, s: string) =
+ LexBuffer.FromChars (reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, s.ToCharArray())
-let FunctionAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, bufferFiller) =
- LexBuffer.FromFunction(reportLibraryOnlyFeatures, supportsFeature, bufferFiller)
+let FunctionAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, bufferFiller) =
+ LexBuffer.FromFunction(reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, bufferFiller)
-let SourceTextAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, sourceText) =
- LexBuffer.FromSourceText(reportLibraryOnlyFeatures, supportsFeature, sourceText)
+let SourceTextAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, sourceText) =
+ LexBuffer.FromSourceText(reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, sourceText)
-let StreamReaderAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, reader: StreamReader) =
+let StreamReaderAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, reader: StreamReader) =
let mutable isFinished = false
- FunctionAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, fun (chars, start, length) ->
+ FunctionAsLexbuf (reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, fun (chars, start, length) ->
if isFinished then 0
else
let nBytesRead = reader.Read(chars, start, length)
diff --git a/src/fsharp/UnicodeLexing.fsi b/src/fsharp/UnicodeLexing.fsi
index 838b96a6a1..7d2c56ff6f 100644
--- a/src/fsharp/UnicodeLexing.fsi
+++ b/src/fsharp/UnicodeLexing.fsi
@@ -9,11 +9,11 @@ open Internal.Utilities.Text.Lexing
type Lexbuf = LexBuffer
-val internal StringAsLexbuf: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * string -> Lexbuf
+val internal StringAsLexbuf: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * (LanguageFeature -> range -> unit) * string -> Lexbuf
-val public FunctionAsLexbuf: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * (char [] * int * int -> int) -> Lexbuf
+val public FunctionAsLexbuf: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * (LanguageFeature -> range -> unit) * (char [] * int * int -> int) -> Lexbuf
-val public SourceTextAsLexbuf: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * ISourceText -> Lexbuf
+val public SourceTextAsLexbuf: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * (LanguageFeature -> range -> unit) * ISourceText -> Lexbuf
/// Will not dispose of the stream reader.
-val public StreamReaderAsLexbuf: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * StreamReader -> Lexbuf
+val public StreamReaderAsLexbuf: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * (LanguageFeature -> range -> unit) * StreamReader -> Lexbuf
diff --git a/src/fsharp/block.fs b/src/fsharp/block.fs
new file mode 100644
index 0000000000..ca74049032
--- /dev/null
+++ b/src/fsharp/block.fs
@@ -0,0 +1,187 @@
+module Internal.Utilities.Library.Block
+
+open System.Collections.Immutable
+
+type block<'T> = ImmutableArray<'T>
+type blockbuilder<'T> = ImmutableArray<'T>.Builder
+
+[]
+module BlockBuilder =
+
+ let create size : blockbuilder<'T> =
+ ImmutableArray.CreateBuilder(size)
+
+[]
+module Block =
+
+ []
+ let empty<'T> = ImmutableArray<'T>.Empty
+
+ let init n (f: int -> 'T) : block<_> =
+ match n with
+ | 0 -> ImmutableArray.Empty
+ | 1 -> ImmutableArray.Create(f 0)
+ | n ->
+ if n < 0 then
+ invalidArg "n" "Below zero."
+
+ let builder = ImmutableArray.CreateBuilder(n)
+ for i = 0 to n - 1 do
+ builder.Add(f i)
+ builder.MoveToImmutable()
+
+ let iter f (arr: block<'T>) =
+ for i = 0 to arr.Length - 1 do
+ f arr.[i]
+
+ let iteri f (arr: block<'T>) =
+ for i = 0 to arr.Length - 1 do
+ f i arr.[i]
+
+ let iter2 f (arr1: block<'T1>) (arr2: block<'T2>) =
+ if arr1.Length <> arr2.Length then
+ invalidOp "Block lengths do not match."
+
+ for i = 0 to arr1.Length - 1 do
+ f arr1.[i] arr2.[i]
+
+ let iteri2 f (arr1: block<'T1>) (arr2: block<'T2>) =
+ if arr1.Length <> arr2.Length then
+ invalidOp "Block lengths do not match."
+
+ for i = 0 to arr1.Length - 1 do
+ f i arr1.[i] arr2.[i]
+
+ let map (mapper: 'T -> 'U) (arr: block<'T>) : block<_> =
+ match arr.Length with
+ | 0 -> ImmutableArray.Empty
+ | 1 -> ImmutableArray.Create(mapper arr.[0])
+ | _ ->
+ let builder = ImmutableArray.CreateBuilder(arr.Length)
+ for i = 0 to arr.Length - 1 do
+ builder.Add(mapper arr.[i])
+ builder.MoveToImmutable()
+
+ let mapi (mapper: int -> 'T -> 'U) (arr: block<'T>) : block<_> =
+ match arr.Length with
+ | 0 -> ImmutableArray.Empty
+ | 1 -> ImmutableArray.Create(mapper 0 arr.[0])
+ | _ ->
+ let builder = ImmutableArray.CreateBuilder(arr.Length)
+ for i = 0 to arr.Length - 1 do
+ builder.Add(mapper i arr.[i])
+ builder.MoveToImmutable()
+
+ let map2 (mapper: 'T1 -> 'T2 -> 'T) (arr1: block<'T1>) (arr2: block<'T2>) : block<_> =
+ if arr1.Length <> arr2.Length then
+ invalidOp "Block lengths do not match."
+
+ match arr1.Length with
+ | 0 -> ImmutableArray.Empty
+ | 1 -> ImmutableArray.Create(mapper arr1.[0] arr2.[0])
+ | n ->
+ let builder = ImmutableArray.CreateBuilder(n)
+ for i = 0 to n - 1 do
+ builder.Add(mapper arr1.[i] arr2.[i])
+ builder.MoveToImmutable()
+
+ let mapi2 (mapper: int -> 'T1 -> 'T2 -> 'T) (arr1: block<'T1>) (arr2: block<'T2>) : block<_> =
+ if arr1.Length <> arr2.Length then
+ invalidOp "Block lengths do not match."
+
+ match arr1.Length with
+ | 0 -> ImmutableArray.Empty
+ | 1 -> ImmutableArray.Create(mapper 0 arr1.[0] arr2.[0])
+ | n ->
+ let builder = ImmutableArray.CreateBuilder(n)
+ for i = 0 to n - 1 do
+ builder.Add(mapper i arr1.[i] arr2.[i])
+ builder.MoveToImmutable()
+
+ let concat (arrs: block>) : block<'T> =
+ match arrs.Length with
+ | 0 -> ImmutableArray.Empty
+ | 1 -> arrs.[0]
+ | 2 -> arrs.[0].AddRange(arrs.[1])
+ | _ ->
+ let mutable acc = 0
+ for h in arrs do
+ acc <- acc + h.Length
+
+ let builder = ImmutableArray.CreateBuilder(acc)
+ for i = 0 to arrs.Length - 1 do
+ builder.AddRange(arrs.[i])
+ builder.MoveToImmutable()
+
+ let forall predicate (arr: block<'T>) =
+ let len = arr.Length
+ let rec loop i = i >= len || (predicate arr.[i] && loop (i+1))
+ loop 0
+
+ let forall2 predicate (arr1: block<'T1>) (arr2: block<'T2>) =
+ if arr1.Length <> arr2.Length then
+ invalidOp "Block lengths do not match."
+
+ let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(predicate)
+ let len1 = arr1.Length
+ let rec loop i = i >= len1 || (f.Invoke(arr1.[i], arr2.[i]) && loop (i+1))
+ loop 0
+
+ let tryFind predicate (arr: block<'T>) =
+ let rec loop i =
+ if i >= arr.Length then None else
+ if predicate arr.[i] then Some arr.[i] else loop (i+1)
+ loop 0
+
+ let tryFindIndex predicate (arr: block<'T>) =
+ let len = arr.Length
+ let rec go n = if n >= len then None elif predicate arr.[n] then Some n else go (n+1)
+ go 0
+
+ let tryPick chooser (arr: block<'T>) =
+ let rec loop i =
+ if i >= arr.Length then None else
+ match chooser arr.[i] with
+ | None -> loop(i+1)
+ | res -> res
+ loop 0
+
+ let ofSeq (xs: 'T seq) =
+ ImmutableArray.CreateRange(xs)
+
+ let append (arr1: block<'T1>) (arr2: block<'T1>) : block<_> =
+ arr1.AddRange(arr2)
+
+ let createOne (item: 'T) : block<_> =
+ ImmutableArray.Create(item)
+
+ let filter predicate (arr: block<'T>) : block<'T> =
+ let builder = ImmutableArray.CreateBuilder(arr.Length)
+ for i = 0 to arr.Length - 1 do
+ if predicate arr.[i] then
+ builder.Add(arr.[i])
+ builder.Capacity <- builder.Count
+ builder.MoveToImmutable()
+
+ let exists predicate (arr: block<'T>) =
+ let len = arr.Length
+ let rec loop i = i < len && (predicate arr.[i] || loop (i+1))
+ len > 0 && loop 0
+
+ let choose (chooser: 'T -> 'U option) (arr: block<'T>) : block<'U> =
+ let builder = ImmutableArray.CreateBuilder(arr.Length)
+ for i = 0 to arr.Length - 1 do
+ let result = chooser arr.[i]
+ if result.IsSome then
+ builder.Add(result.Value)
+ builder.Capacity <- builder.Count
+ builder.MoveToImmutable()
+
+ let isEmpty (arr: block<_>) = arr.IsEmpty
+
+ let fold folder state (arr: block<_>) =
+ let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(folder)
+ let mutable state = state
+ for i = 0 to arr.Length - 1 do
+ state <- f.Invoke(state, arr.[i])
+ state
diff --git a/src/fsharp/block.fsi b/src/fsharp/block.fsi
new file mode 100644
index 0000000000..ec7ef7fa5a
--- /dev/null
+++ b/src/fsharp/block.fsi
@@ -0,0 +1,63 @@
+[]
+module internal Internal.Utilities.Library.Block
+
+open System.Collections.Immutable
+
+/// Type alias for System.Collections.Immutable.ImmutableArray<'T>
+type block<'T> = ImmutableArray<'T>
+
+/// Type alias for System.Collections.Immutable.ImmutableArray<'T>.Builder
+type blockbuilder<'T> = ImmutableArray<'T>.Builder
+
+[]
+module BlockBuilder =
+
+ val create : size: int -> blockbuilder<'T>
+
+[]
+module Block =
+
+ []
+ val empty<'T> : block<'T>
+
+ val init : n: int -> f: (int -> 'T) -> block<'T>
+
+ val iter : f: ('T -> unit) -> block<'T> -> unit
+
+ val iteri : f: (int -> 'T -> unit) -> block<'T> -> unit
+
+ val iter2 : f: ('T1 -> 'T2 -> unit) -> block<'T1> -> block<'T2> -> unit
+
+ val iteri2 : f: (int -> 'T1 -> 'T2 -> unit) -> block<'T1> -> block<'T2> -> unit
+
+ val map : mapper: ('T1 -> 'T2) -> block<'T1> -> block<'T2>
+
+ val mapi : mapper: (int -> 'T1 -> 'T2) -> block<'T1> -> block<'T2>
+
+ val concat : block> -> block<'T>
+
+ val forall : predicate: ('T -> bool) -> block<'T> -> bool
+
+ val forall2 : predicate: ('T1 -> 'T2 -> bool) -> block<'T1> -> block<'T2> -> bool
+
+ val tryFind : predicate: ('T -> bool) -> block<'T> -> 'T option
+
+ val tryFindIndex : predicate: ('T -> bool) -> block<'T> -> int option
+
+ val tryPick : chooser: ('T1 -> 'T2 option) -> block<'T1> -> 'T2 option
+
+ val ofSeq : seq<'T> -> block<'T>
+
+ val append : block<'T> -> block<'T> -> block<'T>
+
+ val createOne : 'T -> block<'T>
+
+ val filter : predicate: ('T -> bool) -> block<'T> -> block<'T>
+
+ val exists : predicate: ('T -> bool) -> block<'T> -> bool
+
+ val choose : chooser: ('T -> 'U option) -> block<'T> -> block<'U>
+
+ val isEmpty : block<'T> -> bool
+
+ val fold : folder: ('State -> 'T -> 'State) -> 'State -> block<'T> -> 'State
\ No newline at end of file
diff --git a/src/fsharp/fsc/fsc.fsproj b/src/fsharp/fsc/fsc.fsproj
index 211415f64e..7fa31fc215 100644
--- a/src/fsharp/fsc/fsc.fsproj
+++ b/src/fsharp/fsc/fsc.fsproj
@@ -41,6 +41,7 @@
+
diff --git a/src/fsharp/fsi/fsi.fs b/src/fsharp/fsi/fsi.fs
index 61a80b2d1a..7329224d5a 100644
--- a/src/fsharp/fsi/fsi.fs
+++ b/src/fsharp/fsi/fsi.fs
@@ -2003,10 +2003,11 @@ type internal FsiStdinLexerProvider
LightSyntaxStatus (initialLightSyntaxStatus, false (* no warnings *))
let isFeatureSupported featureId = tcConfigB.langVersion.SupportsFeature featureId
+ let checkLanguageFeatureErrorRecover = ErrorLogger.checkLanguageFeatureErrorRecover tcConfigB.langVersion
let LexbufFromLineReader (fsiStdinSyphon: FsiStdinSyphon) readF =
UnicodeLexing.FunctionAsLexbuf
- (true, isFeatureSupported, (fun (buf: char[], start, len) ->
+ (true, isFeatureSupported, checkLanguageFeatureErrorRecover, (fun (buf: char[], start, len) ->
//fprintf fsiConsoleOutput.Out "Calling ReadLine\n"
let inputOption = try Some(readF()) with :? EndOfStreamException -> None
inputOption |> Option.iter (fun t -> fsiStdinSyphon.Add (t + "\n"))
@@ -2044,6 +2045,7 @@ type internal FsiStdinLexerProvider
tokenizer
let isFeatureSupported featureId = tcConfigB.langVersion.SupportsFeature featureId
+ let checkLanguageFeatureErrorRecover = ErrorLogger.checkLanguageFeatureErrorRecover tcConfigB.langVersion
// Create a new lexer to read stdin
member _.CreateStdinLexer (errorLogger) =
@@ -2062,12 +2064,12 @@ type internal FsiStdinLexerProvider
// Create a new lexer to read an "included" script file
member _.CreateIncludedScriptLexer (sourceFileName, reader, errorLogger) =
- let lexbuf = UnicodeLexing.StreamReaderAsLexbuf(true, isFeatureSupported, reader)
+ let lexbuf = UnicodeLexing.StreamReaderAsLexbuf(true, isFeatureSupported, checkLanguageFeatureErrorRecover, reader)
CreateLexerForLexBuffer (sourceFileName, lexbuf, errorLogger)
// Create a new lexer to read a string
member this.CreateStringLexer (sourceFileName, source, errorLogger) =
- let lexbuf = UnicodeLexing.StringAsLexbuf(true, isFeatureSupported, source)
+ let lexbuf = UnicodeLexing.StringAsLexbuf(true, isFeatureSupported, checkLanguageFeatureErrorRecover, source)
CreateLexerForLexBuffer (sourceFileName, lexbuf, errorLogger)
member _.ConsoleInput = fsiConsoleInput
@@ -2126,6 +2128,7 @@ type internal FsiInteractionProcessor
istate, CompletedWithReportedError e
let isFeatureSupported featureId = tcConfigB.langVersion.SupportsFeature featureId
+ let checkLanguageFeatureErrorRecover = ErrorLogger.checkLanguageFeatureErrorRecover tcConfigB.langVersion
let rangeStdin = rangeN Lexhelp.stdinMockFilename 0
@@ -2223,26 +2226,26 @@ type internal FsiInteractionProcessor
let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger)
fsiDynamicCompiler.EvalParsedDefinitions (ctok, errorLogger, istate, true, false, defs)
- | ParsedScriptInteraction.HashDirective (ParsedHashDirective("load", sourceFiles, m), _) ->
+ | ParsedScriptInteraction.HashDirective (ParsedHashDirective("load", ParsedHashDirectiveArguments sourceFiles, m), _) ->
let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger)
fsiDynamicCompiler.EvalSourceFiles (ctok, istate, m, sourceFiles, lexResourceManager, errorLogger),Completed None
- | ParsedScriptInteraction.HashDirective (ParsedHashDirective(("reference" | "r"), [path], m), _) ->
+ | ParsedScriptInteraction.HashDirective (ParsedHashDirective(("reference" | "r"), ParsedHashDirectiveArguments [path], m), _) ->
packageManagerDirective Directive.Resolution path m
- | ParsedScriptInteraction.HashDirective (ParsedHashDirective("i", [path], m), _) ->
+ | ParsedScriptInteraction.HashDirective (ParsedHashDirective("i", ParsedHashDirectiveArguments [path], m), _) ->
packageManagerDirective Directive.Include path m
- | ParsedScriptInteraction.HashDirective (ParsedHashDirective("I", [path], m), _) ->
+ | ParsedScriptInteraction.HashDirective (ParsedHashDirective("I", ParsedHashDirectiveArguments [path], m), _) ->
tcConfigB.AddIncludePath (m, path, tcConfig.implicitIncludeDir)
fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiDidAHashI(tcConfig.MakePathAbsolute path))
istate, Completed None
- | ParsedScriptInteraction.HashDirective (ParsedHashDirective("cd", [path], m), _) ->
+ | ParsedScriptInteraction.HashDirective (ParsedHashDirective("cd", ParsedHashDirectiveArguments [path], m), _) ->
ChangeDirectory path m
istate, Completed None
- | ParsedScriptInteraction.HashDirective (ParsedHashDirective("silentCd", [path], m), _) ->
+ | ParsedScriptInteraction.HashDirective (ParsedHashDirective("silentCd", ParsedHashDirectiveArguments [path], m), _) ->
ChangeDirectory path m
fsiConsolePrompt.SkipNext() (* "silent" directive *)
istate, Completed None
@@ -2257,14 +2260,14 @@ type internal FsiInteractionProcessor
fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOn())
{istate with timing = not istate.timing}, Completed None
- | ParsedScriptInteraction.HashDirective (ParsedHashDirective("time", [("on" | "off") as v], _), _) ->
+ | ParsedScriptInteraction.HashDirective (ParsedHashDirective("time", ParsedHashDirectiveArguments [("on" | "off") as v], _), _) ->
if v <> "on" then
fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOff())
else
fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOn())
{istate with timing = (v = "on")}, Completed None
- | ParsedScriptInteraction.HashDirective (ParsedHashDirective("nowarn", numbers, m), _) ->
+ | ParsedScriptInteraction.HashDirective (ParsedHashDirective("nowarn", ParsedHashDirectiveArguments numbers, m), _) ->
List.iter (fun (d:string) -> tcConfigB.TurnWarningOff(m, d)) numbers
istate, Completed None
@@ -2293,7 +2296,7 @@ type internal FsiInteractionProcessor
fsiOptions.ShowHelp(m)
istate, Completed None
- | ParsedScriptInteraction.HashDirective (ParsedHashDirective(c, arg, m), _) ->
+ | ParsedScriptInteraction.HashDirective (ParsedHashDirective(c, ParsedHashDirectiveArguments arg, m), _) ->
warning(Error((FSComp.SR.fsiInvalidDirective(c, String.concat " " arg)), m))
istate, Completed None
)
@@ -2537,7 +2540,7 @@ type internal FsiInteractionProcessor
use _unwind1 = ErrorLogger.PushThreadBuildPhaseUntilUnwind(ErrorLogger.BuildPhase.Interactive)
use _unwind2 = ErrorLogger.PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger)
use _scope = SetCurrentUICultureForThread fsiOptions.FsiLCID
- let lexbuf = UnicodeLexing.StringAsLexbuf(true, isFeatureSupported, sourceText)
+ let lexbuf = UnicodeLexing.StringAsLexbuf(true, isFeatureSupported, checkLanguageFeatureErrorRecover, sourceText)
let tokenizer = fsiStdinLexerProvider.CreateBufferLexer(scriptFileName, lexbuf, errorLogger)
currState
|> InteractiveCatch errorLogger (fun istate ->
@@ -2554,7 +2557,7 @@ type internal FsiInteractionProcessor
use _unwind1 = ErrorLogger.PushThreadBuildPhaseUntilUnwind(ErrorLogger.BuildPhase.Interactive)
use _unwind2 = ErrorLogger.PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger)
use _scope = SetCurrentUICultureForThread fsiOptions.FsiLCID
- let lexbuf = UnicodeLexing.StringAsLexbuf(true, isFeatureSupported, sourceText)
+ let lexbuf = UnicodeLexing.StringAsLexbuf(true, isFeatureSupported, checkLanguageFeatureErrorRecover, sourceText)
let tokenizer = fsiStdinLexerProvider.CreateBufferLexer(scriptFileName, lexbuf, errorLogger)
currState
|> InteractiveCatch errorLogger (fun istate ->
diff --git a/src/fsharp/lex.fsl b/src/fsharp/lex.fsl
index 40da392835..409e766fd1 100644
--- a/src/fsharp/lex.fsl
+++ b/src/fsharp/lex.fsl
@@ -212,8 +212,8 @@ let shouldStartFile args lexbuf (m:range) err tok =
if (m.StartColumn <> 0 || m.StartLine <> 1) then fail args lexbuf err tok
else tok
-let evalIfDefExpression startPos reportLibraryOnlyFeatures isFeatureSupported args (lookup:string->bool) (lexed:string) =
- let lexbuf = LexBuffer.FromChars (reportLibraryOnlyFeatures, isFeatureSupported, lexed.ToCharArray ())
+let evalIfDefExpression startPos reportLibraryOnlyFeatures isFeatureSupported errorIfFeatureUnsupported args (lookup:string->bool) (lexed:string) =
+ let lexbuf = LexBuffer.FromChars (reportLibraryOnlyFeatures, isFeatureSupported, errorIfFeatureUnsupported, lexed.ToCharArray ())
lexbuf.StartPos <- startPos
lexbuf.EndPos <- startPos
let tokenStream = FSharp.Compiler.PPLexer.tokenstream args
@@ -938,7 +938,7 @@ rule token args skip = parse
{ let m = lexbuf.LexemeRange
let lookup id = List.contains id args.defines
let lexed = lexeme lexbuf
- let isTrue = evalIfDefExpression lexbuf.StartPos lexbuf.ReportLibraryOnlyFeatures lexbuf.SupportsFeature args lookup lexed
+ let isTrue = evalIfDefExpression lexbuf.StartPos lexbuf.ReportLibraryOnlyFeatures lexbuf.SupportsFeature lexbuf.CheckLanguageFeatureErrorRecover args lookup lexed
args.ifdefStack <- (IfDefIf,m) :: args.ifdefStack
// Get the token; make sure it starts at zero position & return
diff --git a/src/fsharp/lib.fs b/src/fsharp/lib.fs
index 07ba0f0f91..ef4785546b 100755
--- a/src/fsharp/lib.fs
+++ b/src/fsharp/lib.fs
@@ -604,3 +604,4 @@ module ArrayParallel =
let inline map f (arr: 'T []) =
arr |> mapi (fun _ item -> f item)
+
\ No newline at end of file
diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy
index 66289f3cf5..334e6d7409 100644
--- a/src/fsharp/pars.fsy
+++ b/src/fsharp/pars.fsy
@@ -649,11 +649,14 @@ hashDirectiveArgs:
/* One argument to a #directive */
-hashDirectiveArg:
+hashDirectiveArg:
| string
- { let s, _ = $1
- s }
-
+ { let s, kind = $1
+ ParsedHashDirectiveArgument.String (s, kind, lhs parseState) }
+ | sourceIdentifier
+ { let c,v = $1
+ ParsedHashDirectiveArgument.SourceIdentifier (c, v, lhs parseState) }
+
/*--------------------------------------------------------------------------*/
/* F# Language Proper - signature files */
@@ -677,8 +680,10 @@ signatureFile:
/* The start of a module declaration */
moduleIntro:
- | moduleKeyword opt_access opt_rec path
- { $3, $4.Lid, grabXmlDoc(parseState, 1), $2 }
+ | moduleKeyword opt_attributes opt_access opt_rec path
+ { if not (isNil $2) then
+ parseState.LexBuffer.CheckLanguageFeatureErrorRecover LanguageFeature.AttributesToRightOfModuleKeyword <| rhs parseState 4
+ $4, $5.Lid, grabXmlDoc(parseState, 1), $3, $2 }
/* The start of a namespace declaration */
@@ -723,16 +728,16 @@ fileNamespaceSpec:
/* The single module declaration that can make up a signature file */
fileModuleSpec:
- | opt_attributes opt_declVisibility moduleIntro moduleSpfnsPossiblyEmptyBlock
+ | opt_attributes opt_declVisibility moduleIntro moduleSpfnsPossiblyEmptyBlock
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2))
let m2 = rhs parseState 3
let mDeclsAndAttrs = (List.map (fun (a: SynAttributeList) -> a.Range) $1) @ (List.map (fun (d: SynModuleSigDecl) -> d.Range) $4)
let m = (m2, mDeclsAndAttrs) ||> unionRangeWithListBy id
- let isRec, path2, xml, vis = $3
+ let isRec, path2, xml, vis, attribs2 = $3
(fun (isRec2, path, _) ->
if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(), m2))
let lid = path@path2
- ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xml, $1, vis, m))) }
+ ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xml, $1 @ attribs2, vis, m))) }
| moduleSpfnsPossiblyEmptyBlock
{ let m = (rhs parseState 1)
@@ -793,19 +798,20 @@ moduleSpfn:
| opt_attributes opt_declVisibility moduleIntro colonOrEquals namedModuleAbbrevBlock
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2))
- let isRec, path, xml, vis = $3
+ let isRec, path, xml, vis, attribs2 = $3
if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec())
if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName())
if not (isNil $1) then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation())
+ if not (isNil attribs2) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation())
match vis with
| Some vis -> raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreVisibilityOnModuleAbbreviationAlwaysPrivate(vis.ToString()))
| _ -> SynModuleSigDecl.ModuleAbbrev(List.head path, $5, rhs2 parseState 1 5) }
- | opt_attributes opt_declVisibility moduleIntro colonOrEquals moduleSpecBlock
- { let isRec, path, xml, vis = $3
+ | opt_attributes opt_declVisibility moduleIntro colonOrEquals moduleSpecBlock
+ { let isRec, path, xml, vis, attribs2 = $3
if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleDefnMustBeSimpleName())
if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec())
- let info = SynComponentInfo($1, None, [], path, xml, false, vis, rhs parseState 3)
+ let info = SynComponentInfo($1 @ attribs2, None, [], path, xml, false, vis, rhs parseState 3)
if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2))
let m = (rhs2 parseState 1 4, $5) ||> unionRangeWithListBy (fun (d: SynModuleSigDecl) -> d.Range)
SynModuleSigDecl.NestedModule(info, isRec, $5, m) }
@@ -1164,11 +1170,11 @@ fileModuleImpl:
let m2 = rhs parseState 3
let mDeclsAndAttrs = (List.map (fun (a: SynAttributeList) -> a.Range) $1) @ (List.map (fun (d: SynModuleDecl) -> d.Range) $4)
let m = (m2, mDeclsAndAttrs) ||> unionRangeWithListBy id
- let isRec2, path2, xml, vis = $3
+ let isRec2, path2, xml, vis, attribs2 = $3
(fun (isRec, path, _) ->
if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(), m2))
let lid = path@path2
- ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xml, $1, vis, m))) }
+ ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xml, $1@attribs2, vis, m))) }
| moduleDefnsOrExprPossiblyEmptyOrBlock
{ let m = (rhs parseState 1)
@@ -1308,22 +1314,23 @@ moduleDefn:
[ SynModuleDecl.Exception(ec, f) ] }
/* 'module' definitions */
- | opt_attributes opt_declVisibility moduleIntro EQUALS namedModuleDefnBlock
+ | opt_attributes opt_declVisibility moduleIntro EQUALS namedModuleDefnBlock
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2))
- let attribs, (isRec, path, xml, vis) = $1, $3
- match $5 with
+ let attribs, (isRec, path, xml, vis, attribs2) = $1, $3
+ match $5 with
| Choice1Of2 eqn ->
if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2))
if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec())
if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName())
- if not (isNil $1) then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation())
+ if not (isNil attribs) then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation())
+ if not (isNil attribs2) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation())
match vis with
| Some vis -> raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviationAlwaysPrivate(vis.ToString()))
- | _ -> ()
+ | None -> ()
[ SynModuleDecl.ModuleAbbrev(List.head path, eqn, (rhs parseState 3, eqn) ||> unionRangeWithListBy (fun id -> id.idRange) ) ]
| Choice2Of2 def ->
if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName())
- let info = SynComponentInfo(attribs, None, [], path, xml, false, vis, rhs parseState 3)
+ let info = SynComponentInfo(attribs @ attribs2, None, [], path, xml, false, vis, rhs parseState 3)
[ SynModuleDecl.NestedModule(info, isRec, def, false, (rhs2 parseState 1 4, def) ||> unionRangeWithListBy (fun d -> d.Range) ) ] }
/* unattached custom attributes */
@@ -2230,7 +2237,7 @@ tyconDefnOrSpfnSimpleRepr:
if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyError lhsm
if Option.isSome $2 then errorR(Error(FSComp.SR.parsInlineAssemblyCannotHaveVisibilityDeclarations(), rhs parseState 2))
let s, _ = $5
- let ilType = ParseAssemblyCodeType s parseState.LexBuffer.ReportLibraryOnlyFeatures parseState.LexBuffer.SupportsFeature (rhs parseState 5)
+ let ilType = ParseAssemblyCodeType s parseState.LexBuffer.ReportLibraryOnlyFeatures parseState.LexBuffer.SupportsFeature parseState.LexBuffer.CheckLanguageFeatureErrorRecover (rhs parseState 5)
SynTypeDefnSimpleRepr.LibraryOnlyILAssembly (box ilType, lhsm) }
@@ -2699,9 +2706,10 @@ cPrototype:
mRhs)
(fun attrs _ ->
let bindingId = SynPat.LongIdent (LongIdentWithDots([nm], []), None, Some noInferredTypars, SynArgPats.Pats [SynPat.Tuple(false, args, argsm)], vis, nmm)
+ let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
let binding = mkSynBinding
(xmlDoc, bindingId)
- (vis, false, false, mBindLhs, DebugPointAtBinding.NoneAtInvisible, Some rty, rhsExpr, mRhs, [], attrs, None)
+ (vis, false, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, Some rty, rhsExpr, mRhs, [], attrs, None)
[], [binding]) }
/* A list of arguments in an 'extern' DllImport function definition */
@@ -4543,7 +4551,7 @@ inlineAssemblyExpr:
{ if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning (lhs parseState)
let (s, _), sm = $2, rhs parseState 2
(fun m ->
- let ilInstrs = ParseAssemblyCodeInstructions s parseState.LexBuffer.ReportLibraryOnlyFeatures parseState.LexBuffer.SupportsFeature sm
+ let ilInstrs = ParseAssemblyCodeInstructions s parseState.LexBuffer.ReportLibraryOnlyFeatures parseState.LexBuffer.SupportsFeature parseState.LexBuffer.CheckLanguageFeatureErrorRecover sm
SynExpr.LibraryOnlyILAssembly (box ilInstrs, $3, List.rev $4, $5, m)) }
optCurriedArgExprs:
diff --git a/src/fsharp/service/FSharpCheckerResults.fs b/src/fsharp/service/FSharpCheckerResults.fs
index ecfbcedfb3..d7509fee97 100644
--- a/src/fsharp/service/FSharpCheckerResults.fs
+++ b/src/fsharp/service/FSharpCheckerResults.fs
@@ -1639,9 +1639,10 @@ module internal ParseAndCheckFile =
// Public callers are unable to answer LanguageVersion feature support questions.
// External Tools including the VS IDE will enable the default LanguageVersion
let isFeatureSupported (_featureId:LanguageFeature) = true
+ let checkLanguageFeatureErrorRecover _featureId _range = ()
let createLexbuf sourceText =
- UnicodeLexing.SourceTextAsLexbuf(true, isFeatureSupported, sourceText)
+ UnicodeLexing.SourceTextAsLexbuf(true, isFeatureSupported, checkLanguageFeatureErrorRecover, sourceText)
let matchBraces(sourceText: ISourceText, fileName, options: FSharpParsingOptions, userOpName: string, suggestNamesForErrors: bool) =
let delayedLogger = CapturingErrorLogger("matchBraces")
diff --git a/src/fsharp/service/IncrementalBuild.fs b/src/fsharp/service/IncrementalBuild.fs
index ddcfefd2a5..f4267b9d5e 100644
--- a/src/fsharp/service/IncrementalBuild.fs
+++ b/src/fsharp/service/IncrementalBuild.fs
@@ -701,49 +701,8 @@ type RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, generate
member _.HasAnyFSharpSignatureDataAttribute = true
member _.HasMatchingFSharpSignatureDataAttribute = true
-type IncrementalBuilderState =
- {
- // stampedFileNames represent the real stamps of the files.
- // logicalStampedFileNames represent the stamps of the files that are used to calculate the project's logical timestamp.
- stampedFileNames: ImmutableArray
- logicalStampedFileNames: ImmutableArray
- stampedReferencedAssemblies: ImmutableArray
- initialBoundModel: GraphNode
- boundModels: ImmutableArray>
- finalizedBoundModel: GraphNode<((ILAssemblyRef * IRawFSharpAssemblyData option * TypedImplFile list option * BoundModel) * DateTime)>
- }
-
-/// Manages an incremental build graph for the build of a single F# project
-type IncrementalBuilder(
- initialBoundModel: BoundModel,
- tcGlobals,
- nonFrameworkAssemblyInputs,
- tcConfig: TcConfig,
- outfile,
- assemblyName,
- lexResourceManager,
- sourceFiles,
- enablePartialTypeChecking,
- beforeFileChecked: Event,
- fileChecked: Event,
-#if !NO_EXTENSIONTYPING
- importsInvalidatedByTypeProvider: Event,
-#endif
- allDependencies) =
-
- let fileParsed = new Event()
- let projectChecked = new Event()
-
- let defaultTimeStamp = DateTime.UtcNow
-
- let mutable isImportsInvalidated = false
-
-#if !NO_EXTENSIONTYPING
- do importsInvalidatedByTypeProvider.Publish.Add(fun () -> isImportsInvalidated <- true)
-#endif
-
- //----------------------------------------------------
- // START OF BUILD TASK FUNCTIONS
+[]
+module IncrementalBuilderHelpers =
/// Get the timestamp of the given file name.
let StampFileNameTask (cache: TimeStampCache) (_m: range, filename: string, _isLastCompiland) =
@@ -754,7 +713,7 @@ type IncrementalBuilder(
timeStamper cache
// Link all the assemblies together and produce the input typecheck accumulator
- static let CombineImportedAssembliesTask (
+ let CombineImportedAssembliesTask (
assemblyName,
tcConfig: TcConfig,
tcConfigP,
@@ -866,14 +825,14 @@ type IncrementalBuilder(
}
/// Finish up the typechecking to produce outputs for the rest of the compilation process
- let FinalizeTypeCheckTask (boundModels: ImmutableArray) =
+ let FinalizeTypeCheckTask (tcConfig: TcConfig) tcGlobals enablePartialTypeChecking assemblyName outfile (boundModels: block) =
node {
let errorLogger = CompilationErrorLogger("FinalizeTypeCheckTask", tcConfig.errorSeverityOptions)
use _ = new CompilationGlobalsScope(errorLogger, BuildPhase.TypeCheck)
let! results =
boundModels
- |> Seq.map (fun boundModel -> node {
+ |> Block.map (fun boundModel -> node {
if enablePartialTypeChecking then
let! tcInfo = boundModel.GetOrComputeTcInfo()
return tcInfo, None
@@ -881,7 +840,7 @@ type IncrementalBuilder(
let! tcInfo, tcInfoExtras = boundModel.GetOrComputeTcInfoWithExtras()
return tcInfo, tcInfoExtras.latestImplFile
})
- |> Seq.map (fun work ->
+ |> Block.map (fun work ->
node {
let! tcInfo, latestImplFile = work
return (tcInfo.tcEnvAtEndOfFile, defaultArg tcInfo.topAttribs EmptyTopAttrs, latestImplFile, tcInfo.latestCcuSigForFile)
@@ -954,53 +913,134 @@ type IncrementalBuilder(
return ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt, finalBoundModelWithErrors
}
- // END OF BUILD TASK FUNCTIONS
- // ---------------------------------------------------------------------------------------------
+ let GetSyntaxTree tcConfig fileParsed lexResourceManager (sourceRange: range, filename: string, isLastCompiland) =
+ SyntaxTree(tcConfig, fileParsed, lexResourceManager, sourceRange, filename, isLastCompiland)
+
+[]
+type IncrementalBuilderInitialState =
+ {
+ initialBoundModel: BoundModel
+ tcGlobals: TcGlobals
+ referencedAssemblies: block<(Choice * (TimeStampCache -> DateTime))>
+ tcConfig: TcConfig
+ outfile: string
+ assemblyName: string
+ lexResourceManager: Lexhelp.LexResourceManager
+ fileNames: block<(range * string * (bool * bool))>
+ enablePartialTypeChecking: bool
+ beforeFileChecked: Event
+ fileChecked: Event
+ fileParsed: Event
+ projectChecked: Event
+#if !NO_EXTENSIONTYPING
+ importsInvalidatedByTypeProvider: Event
+#endif
+ allDependencies: string []
+ defaultTimeStamp: DateTime
+ mutable isImportsInvalidated: bool
+ }
+
+ static member Create(
+ initialBoundModel: BoundModel,
+ tcGlobals,
+ nonFrameworkAssemblyInputs,
+ tcConfig: TcConfig,
+ outfile,
+ assemblyName,
+ lexResourceManager,
+ sourceFiles,
+ enablePartialTypeChecking,
+ beforeFileChecked: Event,
+ fileChecked: Event,
+#if !NO_EXTENSIONTYPING
+ importsInvalidatedByTypeProvider: Event,
+#endif
+ allDependencies,
+ defaultTimeStamp: DateTime) =
- // ---------------------------------------------------------------------------------------------
- // START OF BUILD DESCRIPTION
+ let initialState =
+ {
+ initialBoundModel = initialBoundModel
+ tcGlobals = tcGlobals
+ referencedAssemblies = nonFrameworkAssemblyInputs |> Block.ofSeq
+ tcConfig = tcConfig
+ outfile = outfile
+ assemblyName = assemblyName
+ lexResourceManager = lexResourceManager
+ fileNames = sourceFiles |> Block.ofSeq
+ enablePartialTypeChecking = enablePartialTypeChecking
+ beforeFileChecked = beforeFileChecked
+ fileChecked = fileChecked
+ fileParsed = Event()
+ projectChecked = Event()
+#if !NO_EXTENSIONTYPING
+ importsInvalidatedByTypeProvider = importsInvalidatedByTypeProvider
+#endif
+ allDependencies = allDependencies
+ defaultTimeStamp = defaultTimeStamp
+ isImportsInvalidated = false
+ }
+#if !NO_EXTENSIONTYPING
+ importsInvalidatedByTypeProvider.Publish.Add(fun () -> initialState.isImportsInvalidated <- true)
+#endif
+ initialState
- let GetSyntaxTree (sourceRange: range, filename: string, isLastCompiland) =
- SyntaxTree(tcConfig, fileParsed, lexResourceManager, sourceRange, filename, isLastCompiland)
+[]
+type IncrementalBuilderState =
+ {
+ // stampedFileNames represent the real stamps of the files.
+ // logicalStampedFileNames represent the stamps of the files that are used to calculate the project's logical timestamp.
+ stampedFileNames: block
+ logicalStampedFileNames: block
+ stampedReferencedAssemblies: block
+ initialBoundModel: GraphNode
+ boundModels: block>
+ finalizedBoundModel: GraphNode<((ILAssemblyRef * IRawFSharpAssemblyData option * TypedImplFile list option * BoundModel) * DateTime)>
+ }
- // Inputs
- let fileNames = sourceFiles |> Array.ofList // TODO: This should be an immutable array.
- let referencedAssemblies = nonFrameworkAssemblyInputs |> Array.ofList // TODO: This should be an immutable array.
+[]
+module IncrementalBuilderStateHelpers =
- let createBoundModelGraphNode initialBoundModel (boundModels: ImmutableArray>.Builder) i =
- let fileInfo = fileNames.[i]
+ let createBoundModelGraphNode (initialState: IncrementalBuilderInitialState) initialBoundModel (boundModels: blockbuilder>) i =
+ let fileInfo = initialState.fileNames.[i]
let prevBoundModelGraphNode =
match i with
| 0 (* first file *) -> initialBoundModel
| _ -> boundModels.[i - 1]
- let syntaxTree = GetSyntaxTree fileInfo
+ let syntaxTree = GetSyntaxTree initialState.tcConfig initialState.fileParsed initialState.lexResourceManager fileInfo
GraphNode(node {
let! prevBoundModel = prevBoundModelGraphNode.GetOrComputeValue()
- return! TypeCheckTask enablePartialTypeChecking prevBoundModel syntaxTree
+ return! TypeCheckTask initialState.enablePartialTypeChecking prevBoundModel syntaxTree
})
- let rec createFinalizeBoundModelGraphNode (boundModels: ImmutableArray>.Builder) =
+ let rec createFinalizeBoundModelGraphNode (initialState: IncrementalBuilderInitialState) (boundModels: blockbuilder>) =
GraphNode(node {
// Compute last bound model then get all the evaluated models.
let! _ = boundModels.[boundModels.Count - 1].GetOrComputeValue()
let boundModels =
- boundModels
- |> Seq.map (fun x -> x.TryPeekValue().Value)
- |> ImmutableArray.CreateRange
-
- let! result = FinalizeTypeCheckTask boundModels
+ boundModels.ToImmutable()
+ |> Block.map (fun x -> x.TryPeekValue().Value)
+
+ let! result =
+ FinalizeTypeCheckTask
+ initialState.tcConfig
+ initialState.tcGlobals
+ initialState.enablePartialTypeChecking
+ initialState.assemblyName
+ initialState.outfile
+ boundModels
let result = (result, DateTime.UtcNow)
return result
})
- and computeStampedFileName (state: IncrementalBuilderState) (cache: TimeStampCache) slot fileInfo =
+ and computeStampedFileName (initialState: IncrementalBuilderInitialState) (state: IncrementalBuilderState) (cache: TimeStampCache) slot fileInfo =
let currentStamp = state.stampedFileNames.[slot]
let stamp = StampFileNameTask cache fileInfo
if currentStamp <> stamp then
match state.boundModels.[slot].TryPeekValue() with
// This prevents an implementation file that has a backing signature file from invalidating the rest of the build.
- | ValueSome(boundModel) when enablePartialTypeChecking && boundModel.BackingSignature.IsSome ->
+ | ValueSome(boundModel) when initialState.enablePartialTypeChecking && boundModel.BackingSignature.IsSome ->
let newBoundModel = boundModel.ClearTcInfoExtras()
{ state with
boundModels = state.boundModels.RemoveAt(slot).Insert(slot, GraphNode(node { return newBoundModel }))
@@ -1014,14 +1054,14 @@ type IncrementalBuilder(
// Invalidate the file and all files below it.
for j = 0 to stampedFileNames.Count - slot - 1 do
- let stamp = StampFileNameTask cache fileNames.[slot + j]
+ let stamp = StampFileNameTask cache initialState.fileNames.[slot + j]
stampedFileNames.[slot + j] <- stamp
logicalStampedFileNames.[slot + j] <- stamp
- boundModels.[slot + j] <- createBoundModelGraphNode state.initialBoundModel boundModels (slot + j)
+ boundModels.[slot + j] <- createBoundModelGraphNode initialState state.initialBoundModel boundModels (slot + j)
{ state with
// Something changed, the finalized view of the project must be invalidated.
- finalizedBoundModel = createFinalizeBoundModelGraphNode boundModels
+ finalizedBoundModel = createFinalizeBoundModelGraphNode initialState boundModels
stampedFileNames = stampedFileNames.ToImmutable()
logicalStampedFileNames = logicalStampedFileNames.ToImmutable()
@@ -1030,21 +1070,21 @@ type IncrementalBuilder(
else
state
- and computeStampedFileNames state (cache: TimeStampCache) =
+ and computeStampedFileNames (initialState: IncrementalBuilderInitialState) state (cache: TimeStampCache) =
let mutable i = 0
- (state, fileNames)
- ||> Array.fold (fun state fileInfo ->
- let newState = computeStampedFileName state cache i fileInfo
+ (state, initialState.fileNames)
+ ||> Block.fold (fun state fileInfo ->
+ let newState = computeStampedFileName initialState state cache i fileInfo
i <- i + 1
newState
)
- and computeStampedReferencedAssemblies state canTriggerInvalidation (cache: TimeStampCache) =
+ and computeStampedReferencedAssemblies (initialState: IncrementalBuilderInitialState) state canTriggerInvalidation (cache: TimeStampCache) =
let stampedReferencedAssemblies = state.stampedReferencedAssemblies.ToBuilder()
let mutable referencesUpdated = false
- referencedAssemblies
- |> Array.iteri (fun i asmInfo ->
+ initialState.referencedAssemblies
+ |> Block.iteri (fun i asmInfo ->
let currentStamp = state.stampedReferencedAssemblies.[i]
let stamp = StampReferencedAssemblyTask cache asmInfo
@@ -1056,14 +1096,63 @@ type IncrementalBuilder(
if referencesUpdated then
// Build is invalidated. The build must be rebuilt with the newly updated references.
- if not isImportsInvalidated && canTriggerInvalidation then
- isImportsInvalidated <- true
+ if not initialState.isImportsInvalidated && canTriggerInvalidation then
+ initialState.isImportsInvalidated <- true
{ state with
stampedReferencedAssemblies = stampedReferencedAssemblies.ToImmutable()
}
else
state
+type IncrementalBuilderState with
+
+ (*
+ The data below represents a dependency graph.
+
+ ReferencedAssembliesStamps => FileStamps => BoundModels => FinalizedBoundModel
+ *)
+ static member Create(initialState: IncrementalBuilderInitialState) =
+ let defaultTimeStamp = initialState.defaultTimeStamp
+ let initialBoundModel = initialState.initialBoundModel
+ let fileNames = initialState.fileNames
+ let referencedAssemblies = initialState.referencedAssemblies
+
+ let cache = TimeStampCache(defaultTimeStamp)
+ let initialBoundModel = GraphNode(node { return initialBoundModel })
+ let boundModels = BlockBuilder.create fileNames.Length
+
+ for slot = 0 to fileNames.Length - 1 do
+ boundModels.Add(createBoundModelGraphNode initialState initialBoundModel boundModels slot)
+
+ let state =
+ {
+ stampedFileNames = Block.init fileNames.Length (fun _ -> DateTime.MinValue)
+ logicalStampedFileNames = Block.init fileNames.Length (fun _ -> DateTime.MinValue)
+ stampedReferencedAssemblies = Block.init referencedAssemblies.Length (fun _ -> DateTime.MinValue)
+ initialBoundModel = initialBoundModel
+ boundModels = boundModels.ToImmutable()
+ finalizedBoundModel = createFinalizeBoundModelGraphNode initialState boundModels
+ }
+ let state = computeStampedReferencedAssemblies initialState state false cache
+ let state = computeStampedFileNames initialState state cache
+ state
+
+/// Manages an incremental build graph for the build of a single F# project
+type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: IncrementalBuilderState) =
+
+ let initialBoundModel = initialState.initialBoundModel
+ let tcConfig = initialState.tcConfig
+ let fileNames = initialState.fileNames
+ let beforeFileChecked = initialState.beforeFileChecked
+ let fileChecked = initialState.fileChecked
+#if !NO_EXTENSIONTYPING
+ let importsInvalidatedByTypeProvider = initialState.importsInvalidatedByTypeProvider
+#endif
+ let allDependencies = initialState.allDependencies
+ let defaultTimeStamp = initialState.defaultTimeStamp
+ let fileParsed = initialState.fileParsed
+ let projectChecked = initialState.projectChecked
+
let tryGetSlot (state: IncrementalBuilderState) slot =
match state.boundModels.[slot].TryPeekValue() with
| ValueSome boundModel ->
@@ -1075,7 +1164,7 @@ type IncrementalBuilder(
let tryGetBeforeSlot (state: IncrementalBuilderState) slot =
match slot with
| 0 (* first file *) ->
- (initialBoundModel, DateTime.MinValue)
+ (initialBoundModel, defaultTimeStamp)
|> Some
| _ ->
tryGetSlot state (slot - 1)
@@ -1083,7 +1172,7 @@ type IncrementalBuilder(
let evalUpToTargetSlot (state: IncrementalBuilderState) targetSlot =
node {
if targetSlot < 0 then
- return Some(initialBoundModel, DateTime.MinValue)
+ return Some(initialBoundModel, defaultTimeStamp)
else
let! boundModel = state.boundModels.[targetSlot].GetOrComputeValue()
return Some(boundModel, state.stampedFileNames.[targetSlot])
@@ -1091,51 +1180,23 @@ type IncrementalBuilder(
let MaxTimeStampInDependencies stamps =
if Seq.isEmpty stamps then
- DateTime.MinValue
+ defaultTimeStamp
else
stamps
|> Seq.max
- // END OF BUILD DESCRIPTION
- // ---------------------------------------------------------------------------------------------
-
- (*
- The data below represents a dependency graph.
-
- ReferencedAssembliesStamps => FileStamps => BoundModels => FinalizedBoundModel
- *)
-
- let gate = obj ()
- let mutable currentState =
- let cache = TimeStampCache(defaultTimeStamp)
- let initialBoundModel = GraphNode(node { return initialBoundModel })
- let boundModels = ImmutableArray.CreateBuilder(fileNames.Length)
-
- for slot = 0 to fileNames.Length - 1 do
- boundModels.Add(createBoundModelGraphNode initialBoundModel boundModels slot)
-
- let state =
- {
- stampedFileNames = Array.init fileNames.Length (fun _ -> DateTime.MinValue) |> ImmutableArray.CreateRange
- logicalStampedFileNames = Array.init fileNames.Length (fun _ -> DateTime.MinValue) |> ImmutableArray.CreateRange
- stampedReferencedAssemblies = Array.init referencedAssemblies.Length (fun _ -> DateTime.MinValue) |> ImmutableArray.CreateRange
- initialBoundModel = initialBoundModel
- boundModels = boundModels.ToImmutable()
- finalizedBoundModel = createFinalizeBoundModelGraphNode boundModels
- }
- let state = computeStampedReferencedAssemblies state false cache
- let state = computeStampedFileNames state cache
- state
-
let computeProjectTimeStamp (state: IncrementalBuilderState) =
let t1 = MaxTimeStampInDependencies state.stampedReferencedAssemblies
let t2 = MaxTimeStampInDependencies state.logicalStampedFileNames
max t1 t2
+ let gate = obj()
+ let mutable currentState = state
+
let setCurrentState state cache (ct: CancellationToken) =
lock gate (fun () ->
ct.ThrowIfCancellationRequested()
- currentState <- computeStampedFileNames state cache
+ currentState <- computeStampedFileNames initialState state cache
)
let checkFileTimeStamps (cache: TimeStampCache) =
@@ -1162,10 +1223,10 @@ type IncrementalBuilder(
member _.IsReferencesInvalidated =
// fast path
- if isImportsInvalidated then true
+ if initialState.isImportsInvalidated then true
else
- computeStampedReferencedAssemblies currentState true (TimeStampCache(defaultTimeStamp)) |> ignore
- isImportsInvalidated
+ computeStampedReferencedAssemblies initialState currentState true (TimeStampCache(defaultTimeStamp)) |> ignore
+ initialState.isImportsInvalidated
member _.AllDependenciesDeprecated = allDependencies
@@ -1195,7 +1256,7 @@ type IncrementalBuilder(
member builder.TryGetCheckResultsBeforeFileInProject (filename) =
let cache = TimeStampCache defaultTimeStamp
- let tmpState = computeStampedFileNames currentState cache
+ let tmpState = computeStampedFileNames initialState currentState cache
let slotOfFile = builder.GetSlotOfFileName filename
match tryGetBeforeSlot tmpState slotOfFile with
@@ -1268,7 +1329,7 @@ type IncrementalBuilder(
}
member _.GetLogicalTimeStampForProject(cache) =
- let tmpState = computeStampedFileNames currentState cache
+ let tmpState = computeStampedFileNames initialState currentState cache
computeProjectTimeStamp tmpState
member _.TryGetSlotOfFileName(filename: string) =
@@ -1278,7 +1339,7 @@ type IncrementalBuilder(
String.Compare(filename, f2, StringComparison.CurrentCultureIgnoreCase)=0
|| String.Compare(FileSystem.GetFullPathShim filename, FileSystem.GetFullPathShim f2, StringComparison.CurrentCultureIgnoreCase)=0
result
- match fileNames |> Array.tryFindIndex CompareFileNames with
+ match fileNames |> Block.tryFindIndex CompareFileNames with
| Some slot -> Some slot
| None -> None
@@ -1296,10 +1357,10 @@ type IncrementalBuilder(
let slotOfFile = builder.GetSlotOfFileName filename
let fileInfo = fileNames.[slotOfFile]
// re-parse on demand instead of retaining
- let syntaxTree = GetSyntaxTree fileInfo
+ let syntaxTree = GetSyntaxTree initialState.tcConfig initialState.fileParsed initialState.lexResourceManager fileInfo
syntaxTree.Parse None
- member _.SourceFiles = sourceFiles |> List.map (fun (_, f, _) -> f)
+ member _.SourceFiles = fileNames |> Seq.map (fun (_, f, _) -> f) |> List.ofSeq
/// CreateIncrementalBuilder (for background type checking). Note that fsc.fs also
/// creates an incremental builder used by the command line compiler.
@@ -1338,7 +1399,7 @@ type IncrementalBuilder(
let tcConfigB, sourceFiles =
let getSwitchValue switchString =
- match commandLineArgs |> Seq.tryFindIndex(fun s -> s.StartsWithOrdinal switchString) with
+ match commandLineArgs |> List.tryFindIndex(fun s -> s.StartsWithOrdinal switchString) with
| Some idx -> Some(commandLineArgs.[idx].Substring(switchString.Length))
| _ -> None
@@ -1500,6 +1561,8 @@ type IncrementalBuilder(
| None -> new DependencyProvider()
| Some dependencyProvider -> dependencyProvider
+ let defaultTimeStamp = DateTime.UtcNow
+
let! initialBoundModel =
CombineImportedAssembliesTask(
assemblyName,
@@ -1523,8 +1586,8 @@ type IncrementalBuilder(
importsInvalidatedByTypeProvider
)
- let builder =
- new IncrementalBuilder(
+ let initialState =
+ IncrementalBuilderInitialState.Create(
initialBoundModel,
tcGlobals,
nonFrameworkAssemblyInputs,
@@ -1539,7 +1602,10 @@ type IncrementalBuilder(
#if !NO_EXTENSIONTYPING
importsInvalidatedByTypeProvider,
#endif
- allDependencies)
+ allDependencies,
+ defaultTimeStamp)
+
+ let builder = IncrementalBuilder(initialState, IncrementalBuilderState.Create(initialState))
return Some builder
with e ->
errorRecoveryNoRange e
diff --git a/src/fsharp/service/ServiceLexing.fs b/src/fsharp/service/ServiceLexing.fs
index b0b66a6f35..fb6e237024 100644
--- a/src/fsharp/service/ServiceLexing.fs
+++ b/src/fsharp/service/ServiceLexing.fs
@@ -924,6 +924,7 @@ type FSharpSourceTokenizer(conditionalDefines: string list, filename: string opt
// Public callers are unable to answer LanguageVersion feature support questions.
// External Tools including the VS IDE will enable the default LanguageVersion
let isFeatureSupported (_featureId:LanguageFeature) = true
+ let checkLanguageFeatureErrorRecover (_featureId:LanguageFeature) _range = ()
let reportLibraryOnlyFeatures = true
let lexResourceManager = new Lexhelp.LexResourceManager()
@@ -931,11 +932,11 @@ type FSharpSourceTokenizer(conditionalDefines: string list, filename: string opt
let lexargs = mkLexargs(conditionalDefines, LightSyntaxStatus(true, false), lexResourceManager, [], DiscardErrorsLogger, PathMap.empty)
member _.CreateLineTokenizer(lineText: string) =
- let lexbuf = UnicodeLexing.StringAsLexbuf(reportLibraryOnlyFeatures, isFeatureSupported, lineText)
+ let lexbuf = UnicodeLexing.StringAsLexbuf(reportLibraryOnlyFeatures, isFeatureSupported, checkLanguageFeatureErrorRecover, lineText)
FSharpLineTokenizer(lexbuf, Some lineText.Length, filename, lexargs)
member _.CreateBufferTokenizer bufferFiller =
- let lexbuf = UnicodeLexing.FunctionAsLexbuf(reportLibraryOnlyFeatures, isFeatureSupported, bufferFiller)
+ let lexbuf = UnicodeLexing.FunctionAsLexbuf(reportLibraryOnlyFeatures, isFeatureSupported, checkLanguageFeatureErrorRecover, bufferFiller)
FSharpLineTokenizer(lexbuf, None, filename, lexargs)
module FSharpKeywords =
@@ -1514,14 +1515,14 @@ type FSharpToken =
[]
module FSharpLexerImpl =
- let lexWithErrorLogger (text: ISourceText) conditionalCompilationDefines (flags: FSharpLexerFlags) reportLibraryOnlyFeatures supportsFeature errorLogger onToken pathMap (ct: CancellationToken) =
+ let lexWithErrorLogger (text: ISourceText) conditionalCompilationDefines (flags: FSharpLexerFlags) reportLibraryOnlyFeatures supportsFeature checkLanguageFeatureErrorRecover errorLogger onToken pathMap (ct: CancellationToken) =
let canSkipTrivia = (flags &&& FSharpLexerFlags.SkipTrivia) = FSharpLexerFlags.SkipTrivia
let isLightSyntaxOn = (flags &&& FSharpLexerFlags.LightSyntaxOn) = FSharpLexerFlags.LightSyntaxOn
let isCompiling = (flags &&& FSharpLexerFlags.Compiling) = FSharpLexerFlags.Compiling
let isCompilingFSharpCore = (flags &&& FSharpLexerFlags.CompilingFSharpCore) = FSharpLexerFlags.CompilingFSharpCore
let canUseLexFilter = (flags &&& FSharpLexerFlags.UseLexFilter) = FSharpLexerFlags.UseLexFilter
- let lexbuf = UnicodeLexing.SourceTextAsLexbuf(reportLibraryOnlyFeatures, supportsFeature, text)
+ let lexbuf = UnicodeLexing.SourceTextAsLexbuf(reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, text)
let lightStatus = LightSyntaxStatus(isLightSyntaxOn, true)
let lexargs = mkLexargs (conditionalCompilationDefines, lightStatus, Lexhelp.LexResourceManager(0), [], errorLogger, pathMap)
let lexargs = { lexargs with applyLineDirectives = isCompiling }
@@ -1543,22 +1544,23 @@ module FSharpLexerImpl =
ct.ThrowIfCancellationRequested ()
onToken (getNextToken lexbuf) lexbuf.LexemeRange
- let lex text conditionalCompilationDefines flags reportLibraryOnlyFeatures supportsFeature lexCallback pathMap ct =
+ let lex text conditionalCompilationDefines flags reportLibraryOnlyFeatures supportsFeature checkLanguageFeatureErrorRecover lexCallback pathMap ct =
let errorLogger = CompilationErrorLogger("Lexer", FSharpDiagnosticOptions.Default)
- lexWithErrorLogger text conditionalCompilationDefines flags reportLibraryOnlyFeatures supportsFeature errorLogger lexCallback pathMap ct
+ lexWithErrorLogger text conditionalCompilationDefines flags reportLibraryOnlyFeatures supportsFeature checkLanguageFeatureErrorRecover errorLogger lexCallback pathMap ct
[]
type FSharpLexer =
static member Tokenize(text: ISourceText, tokenCallback, ?langVersion, ?filePath: string, ?conditionalCompilationDefines, ?flags, ?pathMap, ?ct) =
- let langVersion = defaultArg langVersion "latestmajor"
+ let langVersion = defaultArg langVersion "latestmajor" |> LanguageVersion
let flags = defaultArg flags FSharpLexerFlags.Default
ignore filePath // can be removed at later point
let conditionalCompilationDefines = defaultArg conditionalCompilationDefines []
let pathMap = defaultArg pathMap Map.Empty
let ct = defaultArg ct CancellationToken.None
- let supportsFeature = (LanguageVersion langVersion).SupportsFeature
+ let supportsFeature = langVersion.SupportsFeature
+ let checkLanguageFeatureErrorRecover = ErrorLogger.checkLanguageFeatureErrorRecover langVersion
let pathMap =
(PathMap.empty, pathMap)
@@ -1571,4 +1573,4 @@ type FSharpLexer =
| _ -> tokenCallback fsTok
let reportLibraryOnlyFeatures = true
- lex text conditionalCompilationDefines flags reportLibraryOnlyFeatures supportsFeature onToken pathMap ct
+ lex text conditionalCompilationDefines flags reportLibraryOnlyFeatures supportsFeature checkLanguageFeatureErrorRecover onToken pathMap ct
diff --git a/src/fsharp/service/ServiceLexing.fsi b/src/fsharp/service/ServiceLexing.fsi
index 86848ea599..625ce113db 100755
--- a/src/fsharp/service/ServiceLexing.fsi
+++ b/src/fsharp/service/ServiceLexing.fsi
@@ -340,6 +340,7 @@ module FSharpKeywords =
val DoesIdentifierNeedQuotation : string -> bool
/// Add backticks if the identifier is a keyword.
+ /// A utility to help determine if an identifier needs to be quoted, this doesn't quote F# keywords.
val QuoteIdentifierIfNeeded : string -> string
/// Remove backticks if present.
@@ -348,9 +349,6 @@ module FSharpKeywords =
/// Keywords paired with their descriptions. Used in completion and quick info.
val KeywordsWithDescription : (string * string) list
- /// A utility to help determine if an identifier needs to be quoted, this doesn't quote F# keywords.
- val QuoteIdentifierIfNeeded: string -> string
-
/// All the keywords in the F# language
val KeywordNames: string list
@@ -581,4 +579,3 @@ type public FSharpLexer =
[]
static member Tokenize: text: ISourceText * tokenCallback: (FSharpToken -> unit) * ?langVersion: string * ?filePath: string * ?conditionalCompilationDefines: string list * ?flags: FSharpLexerFlags * ?pathMap: Map * ?ct: CancellationToken -> unit
-
diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs
index 1ed29a7665..501ad1c4b0 100644
--- a/src/fsharp/service/service.fs
+++ b/src/fsharp/service/service.fs
@@ -334,6 +334,25 @@ type BackgroundCompiler(
return (builderOpt, diagnostics)
}
+ let parseCacheLock = Lock()
+
+ // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.parseFileInProjectCache. Most recently used cache for parsing files.
+ let parseFileCache = MruCache(parseFileCacheSize, areSimilar = AreSimilarForParsing, areSame = AreSameForParsing)
+
+ // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.checkFileInProjectCache
+ //
+ /// Cache which holds recently seen type-checks.
+ /// This cache may hold out-of-date entries, in two senses
+ /// - there may be a more recent antecedent state available because the background build has made it available
+ /// - the source for the file may have changed
+
+ // Also keyed on source. This can only be out of date if the antecedent is out of date
+ let checkFileInProjectCache =
+ MruCache>
+ (keepStrongly=checkFileInProjectCacheSize,
+ areSame=AreSameForChecking3,
+ areSimilar=AreSubsumable3)
+
// STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.backgroundCompiler.incrementalBuildersCache. This root typically holds more
// live information than anything else in the F# Language Service, since it holds up to 3 (projectCacheStrongSize) background project builds
// strongly.
@@ -388,6 +407,17 @@ type BackgroundCompiler(
Logger.Log LogCompilerFunctionId.Service_IncrementalBuildersCache_GettingCache
return builderOpt,creationDiags
| _ ->
+ // The builder could be re-created,
+ // clear the check file caches that are associated with it.
+ // We must do this in order to not return stale results when references
+ // in the project get changed/added/removed.
+ parseCacheLock.AcquireLock(fun ltok ->
+ options.SourceFiles
+ |> Array.iter (fun sourceFile ->
+ let key = (sourceFile, 0L, options)
+ checkFileInProjectCache.RemoveAnySimilar(ltok, key)
+ )
+ )
return! createAndGetBuilder (options, userOpName)
}
| _ ->
@@ -413,25 +443,6 @@ type BackgroundCompiler(
| _ ->
getOrCreateBuilder (options, userOpName)
- let parseCacheLock = Lock()
-
- // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.parseFileInProjectCache. Most recently used cache for parsing files.
- let parseFileCache = MruCache(parseFileCacheSize, areSimilar = AreSimilarForParsing, areSame = AreSameForParsing)
-
- // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.checkFileInProjectCache
- //
- /// Cache which holds recently seen type-checks.
- /// This cache may hold out-of-date entries, in two senses
- /// - there may be a more recent antecedent state available because the background build has made it available
- /// - the source for the file may have changed
-
- // Also keyed on source. This can only be out of date if the antecedent is out of date
- let checkFileInProjectCache =
- MruCache>
- (keepStrongly=checkFileInProjectCacheSize,
- areSame=AreSameForChecking3,
- areSimilar=AreSubsumable3)
-
/// Should be a fast operation. Ensures that we have only one async lazy object per file and its hash.
let getCheckFileNode (parseResults,
sourceText,
diff --git a/src/fsharp/utils/prim-lexing.fs b/src/fsharp/utils/prim-lexing.fs
index f5d4edee58..fdb0cf56ff 100644
--- a/src/fsharp/utils/prim-lexing.fs
+++ b/src/fsharp/utils/prim-lexing.fs
@@ -177,7 +177,7 @@ namespace Internal.Utilities.Text.Lexing
type internal LexBufferFiller<'Char> = (LexBuffer<'Char> -> unit)
and []
- internal LexBuffer<'Char>(filler: LexBufferFiller<'Char>, reportLibraryOnlyFeatures: bool, supportsFeature:LanguageFeature -> bool) =
+ internal LexBuffer<'Char>(filler: LexBufferFiller<'Char>, reportLibraryOnlyFeatures: bool, supportsFeature:LanguageFeature -> bool, checkLanguageFeatureErrorRecover:LanguageFeature -> range -> unit) =
let context = new Dictionary(1)
let mutable buffer = [||]
/// number of valid characters beyond bufferScanStart.
@@ -249,34 +249,36 @@ namespace Internal.Utilities.Text.Lexing
member _.ReportLibraryOnlyFeatures = reportLibraryOnlyFeatures
member _.SupportsFeature featureId = supportsFeature featureId
+ member _.CheckLanguageFeatureErrorRecover featureId range = checkLanguageFeatureErrorRecover featureId range
- static member FromFunction (reportLibraryOnlyFeatures, supportsFeature:LanguageFeature -> bool, f : 'Char[] * int * int -> int) : LexBuffer<'Char> =
+ static member FromFunction (reportLibraryOnlyFeatures, supportsFeature:LanguageFeature -> bool, checkLanguageFeatureErrorRecover, f : 'Char[] * int * int -> int) : LexBuffer<'Char> =
let extension= Array.zeroCreate 4096
let filler (lexBuffer: LexBuffer<'Char>) =
let n = f (extension,0,extension.Length)
lexBuffer.EnsureBufferSize n
Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n
lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n
- new LexBuffer<'Char>(filler, reportLibraryOnlyFeatures, supportsFeature)
+ new LexBuffer<'Char>(filler, reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover)
// Important: This method takes ownership of the array
- static member FromArrayNoCopy (reportLibraryOnlyFeatures, supportsFeature:LanguageFeature -> bool, buffer: 'Char[]) : LexBuffer<'Char> =
- let lexBuffer = new LexBuffer<'Char>((fun _ -> ()), reportLibraryOnlyFeatures, supportsFeature)
+ static member FromArrayNoCopy (reportLibraryOnlyFeatures, supportsFeature:LanguageFeature -> bool, checkLanguageFeatureErrorRecover, buffer: 'Char[]) : LexBuffer<'Char> =
+ let lexBuffer = new LexBuffer<'Char>((fun _ -> ()), reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover)
lexBuffer.Buffer <- buffer
lexBuffer.BufferMaxScanLength <- buffer.Length
lexBuffer
// Important: this method does copy the array
- static member FromArray (reportLibraryOnlyFeatures, supportsFeature: LanguageFeature -> bool, s: 'Char[]) : LexBuffer<'Char> =
+ static member FromArray (reportLibraryOnlyFeatures, supportsFeature: LanguageFeature -> bool, checkLanguageFeatureErrorRecover, s: 'Char[]) : LexBuffer<'Char> =
let buffer = Array.copy s
- LexBuffer<'Char>.FromArrayNoCopy(reportLibraryOnlyFeatures, supportsFeature, buffer)
+ LexBuffer<'Char>.FromArrayNoCopy(reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, buffer)
// Important: This method takes ownership of the array
- static member FromChars (reportLibraryOnlyFeatures, supportsFeature:LanguageFeature -> bool, arr:char[]) = LexBuffer.FromArrayNoCopy (reportLibraryOnlyFeatures, supportsFeature, arr)
+ static member FromChars (reportLibraryOnlyFeatures, supportsFeature:LanguageFeature -> bool, checkLanguageFeatureErrorRecover, arr:char[]) =
+ LexBuffer.FromArrayNoCopy (reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, arr)
- static member FromSourceText (reportLibraryOnlyFeatures, supportsFeature: LanguageFeature -> bool, sourceText: ISourceText) =
+ static member FromSourceText (reportLibraryOnlyFeatures, supportsFeature: LanguageFeature -> bool, checkLanguageFeatureErrorRecover, sourceText: ISourceText) =
let mutable currentSourceIndex = 0
- LexBuffer.FromFunction(reportLibraryOnlyFeatures, supportsFeature, fun (chars, start, length) ->
+ LexBuffer.FromFunction(reportLibraryOnlyFeatures, supportsFeature, checkLanguageFeatureErrorRecover, fun (chars, start, length) ->
let lengthToCopy =
if currentSourceIndex + length <= sourceText.Length then
length
diff --git a/src/fsharp/utils/prim-lexing.fsi b/src/fsharp/utils/prim-lexing.fsi
index d8023a76f6..d3088aa4cc 100644
--- a/src/fsharp/utils/prim-lexing.fsi
+++ b/src/fsharp/utils/prim-lexing.fsi
@@ -127,18 +127,21 @@ type internal LexBuffer<'Char> =
/// Determines if the parser can report FSharpCore library-only features.
member ReportLibraryOnlyFeatures: bool
- /// True if the refill of the buffer ever failed , or if explicitly set to True.
- member SupportsFeature:LanguageFeature -> bool
+ /// True if the specified language feature is supported.
+ member SupportsFeature: LanguageFeature -> bool
+
+ /// Logs a recoverable error if a language feature is unsupported, at the specified range.
+ member CheckLanguageFeatureErrorRecover: LanguageFeature -> range -> unit
/// Create a lex buffer suitable for Unicode lexing that reads characters from the given array.
/// Important: does take ownership of the array.
- static member FromChars: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * char[] -> LexBuffer
+ static member FromChars: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * (LanguageFeature -> range -> unit) * char[] -> LexBuffer
/// Create a lex buffer that reads character or byte inputs by using the given function.
- static member FromFunction: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * ('Char[] * int * int -> int) -> LexBuffer<'Char>
+ static member FromFunction: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * (LanguageFeature -> range -> unit) * ('Char[] * int * int -> int) -> LexBuffer<'Char>
/// Create a lex buffer backed by source text.
- static member FromSourceText: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * ISourceText -> LexBuffer
+ static member FromSourceText: reportLibraryOnlyFeatures: bool * (LanguageFeature -> bool) * (LanguageFeature -> range -> unit) * ISourceText -> LexBuffer
/// The type of tables for an unicode lexer generated by fslex.exe.
[]
diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf
index a0a44a6089..d0a4a98716 100644
--- a/src/fsharp/xlf/FSComp.txt.cs.xlf
+++ b/src/fsharp/xlf/FSComp.txt.cs.xlf
@@ -97,6 +97,11 @@
aplikativní výpočetní výrazy
+
+ attributes to the right of the 'module' keyword
+ atributy napravo od klíčového slova Module
+
+
default interface member consumption
využití člena výchozího rozhraní
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ neproměnné vzory napravo od vzorů typu „jako“
@@ -364,7 +369,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ Sada .NET SDK pro tento skript nedá určit. dotnet.exe se nepovedlo najít, ujistěte se, že je sada .NET SDK nainstalovaná.
@@ -7489,7 +7494,7 @@
A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'.
- K ukazateli byref vrácenému funkcí nebo metodou se od F# 4.5 implicitně přistupuje přes ukazatel. Pokud chcete návratovou hodnotu získat jako ukazatel, použijte operátor adresy, například &f(x) nebo &obj.Metoda(arg1, arg2).
+ K ukazateli byref vrácenému funkcí nebo metodou se od F# 4.5 implicitně přistupuje přes ukazatel. Pokud chcete návratovou hodnotu získat jako ukazatel, použijte operátor adresy, například &f(x) nebo &obj.Method(arg1, arg2).
diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf
index c01340dd19..bd129dcab3 100644
--- a/src/fsharp/xlf/FSComp.txt.de.xlf
+++ b/src/fsharp/xlf/FSComp.txt.de.xlf
@@ -97,6 +97,11 @@
applikative Berechnungsausdrücke
+
+ attributes to the right of the 'module' keyword
+ Attribute rechts vom "Module"-Schlüsselwort
+
+
default interface member consumption
standardmäßige Schnittstellenmembernutzung
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ Nicht-Variablenmuster rechts neben as-Mustern
@@ -364,7 +369,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ Das .NET SDK für dieses Skript konnte nicht bestimmt werden. "dotnet.exe" konnte nicht gefunden werden, um sicherzustellen, dass ein .NET SDK installiert ist.
@@ -7489,7 +7494,7 @@
A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'.
- Ein byref-Zeiger, der von einer Funktion oder Methode zurückgegeben wird, wird explizit als von F# 4.5 stammend dereferenziert. Verwenden Sie den &-Operator (z.B. "&f(x)" oder "&obj.Method(arg1, arg2)"), um den Rückgabewert als Zeiger abzurufen.
+ Ein byref-Zeiger, der von einer Funktion oder Methode zurückgegeben wird, wird explizit als von F# 4.5 stammend dereferenziert. Verwenden Sie den Operator (z.B. "&f(x)" oder "&obj.Method(arg1, arg2)"), um den Rückgabewert als Zeiger abzurufen.
diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf
index fd90daa377..94172c4982 100644
--- a/src/fsharp/xlf/FSComp.txt.es.xlf
+++ b/src/fsharp/xlf/FSComp.txt.es.xlf
@@ -97,6 +97,11 @@
expresiones de cálculo aplicativas
+
+ attributes to the right of the 'module' keyword
+ atributos a la derecha de la palabra clave “módulo”
+
+
default interface member consumption
consumo de miembros de interfaz predeterminados
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ patrones no variables a la derecha de los patrones "as"
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ No se pudo determinar el SDK de .NET para este script. No se encontró dotnet.exe. Asegúrese de tener instalado un SDK de .NET.
diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf
index d3d196afd6..9029b98de5 100644
--- a/src/fsharp/xlf/FSComp.txt.fr.xlf
+++ b/src/fsharp/xlf/FSComp.txt.fr.xlf
@@ -97,6 +97,11 @@
expressions de calcul applicatives
+
+ attributes to the right of the 'module' keyword
+ attributs à droite du mot clé 'module'
+
+
default interface member consumption
consommation par défaut des membres d'interface
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ modèles non variables à droite de modèles « as »
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ Impossible de déterminer le Kit de développement logiciel (SDK) .NET pour ce script. dotnet.exe est introuvable pour garantir l’installation d’un kit SDK .NET.
diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf
index 75b8d5f67a..0c4cd6fea0 100644
--- a/src/fsharp/xlf/FSComp.txt.it.xlf
+++ b/src/fsharp/xlf/FSComp.txt.it.xlf
@@ -97,6 +97,11 @@
espressioni di calcolo applicativo
+
+ attributes to the right of the 'module' keyword
+ attributi a destra della parola chiave 'module'
+
+
default interface member consumption
utilizzo predefinito dei membri di interfaccia
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ modelli non variabili a destra dei modelli 'as'
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ Non e stato possibile determinare il Software Development Kit .NET per questo script. Non è stato possibile trovare dotnet.exe; assicurarsi che sia installato un Software Development Kit .NET.
diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf
index e4fce23a9e..653250970d 100644
--- a/src/fsharp/xlf/FSComp.txt.ja.xlf
+++ b/src/fsharp/xlf/FSComp.txt.ja.xlf
@@ -97,6 +97,11 @@
適用できる計算式
+
+ attributes to the right of the 'module' keyword
+ 'module' キーワードの右側の属性
+
+
default interface member consumption
既定のインターフェイス メンバーの消費
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ 'as' パターンの右側の非変数パターン
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ このスクリプトの .NET SDK を特定できませんでした。dotnet.exe が見つかりませんでした。 .NET SDK がインストールされていることをご確認ください。
diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf
index 407b6b9c71..0fbdbb2a9a 100644
--- a/src/fsharp/xlf/FSComp.txt.ko.xlf
+++ b/src/fsharp/xlf/FSComp.txt.ko.xlf
@@ -97,6 +97,11 @@
적용 가능한 계산 식
+
+ attributes to the right of the 'module' keyword
+ 'module' 키워드 오른쪽에 있는 특성
+
+
default interface member consumption
기본 인터페이스 멤버 사용
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ 'as' 패턴의 오른쪽에 있는 변수가 아닌 패턴
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ 이 스크립트의 .NET SDK를 확인할 수 없습니다. dotnet.exe를 찾을 수 없습니다. .NET SDK가 설치되어 있는지 확인하세요.
diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf
index 476e97005c..ab5274e1e9 100644
--- a/src/fsharp/xlf/FSComp.txt.pl.xlf
+++ b/src/fsharp/xlf/FSComp.txt.pl.xlf
@@ -97,6 +97,11 @@
praktyczne wyrażenia obliczeniowe
+
+ attributes to the right of the 'module' keyword
+ atrybuty po prawej stronie słowa kluczowego "module"
+
+
default interface member consumption
domyślne użycie składowej interfejsu
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ stałe wzorce po prawej stronie wzorców typu „as”
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ Nie można określić zestawu .NET SDK dla tego skryptu. Nie można odnaleźć pliku dotnet.exe. Upewnij się, że zestaw .NET SDK jest zainstalowany.
@@ -7489,7 +7494,7 @@
A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'.
- Wskaźnik byref zwracany przez funkcję lub metodę jest niejawnie wyłuskiwany w języku F# 4.5 i nowszych. Aby uzyskać wartość zwracaną jako wskaźnik, użyj operatora address-of, np. „&f(x)” lub „&obj.Method(argument1, argument2)”.
+ Wskaźnik byref zwracany przez funkcję lub metodę jest niejawnie wyłuskiwany w języku F# 4.5 i nowszych. Aby uzyskać wartość zwracaną jako wskaźnik, użyj operatora address-of, np. „&f(x)” lub „&obj.Method(arg1, arg2)”.
diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf
index 1baa0678a5..a3e8c17c14 100644
--- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf
@@ -97,6 +97,11 @@
expressões de computação aplicáveis
+
+ attributes to the right of the 'module' keyword
+ atributos à direita da palavra-chave 'módulo'
+
+
default interface member consumption
consumo de membro da interface padrão
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ padrões não-variáveis à direita dos padrões 'as'.
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ Não foi possível determinar o .NET SDK para este script. Não foi possível encontrar dotnet.exe e certifique-se de que o SDK do .NET esteja instalado.
diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf
index 4bbd80001b..74829d26b0 100644
--- a/src/fsharp/xlf/FSComp.txt.ru.xlf
+++ b/src/fsharp/xlf/FSComp.txt.ru.xlf
@@ -97,6 +97,11 @@
применимые вычислительные выражения
+
+ attributes to the right of the 'module' keyword
+ атрибуты справа от ключевого слова "module"
+
+
default interface member consumption
использование элемента интерфейса по умолчанию
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ шаблоны без переменных справа от шаблонов "as"
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ Не удалось определить пакет SDK .NET для этого сценария. Не удалось найти dotnet.exe. Убедитесь, что пакет SDK .NET установлен.
@@ -7454,12 +7459,12 @@
This expression returns a value of type '{0}' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield'.
- Это выражение возвращает значение типа "{0}", но оно неявно отбрасывается. Чтобы привязать результат к какому-то имени, используйте "let", например: "let <результат> = <выражение>". Если вы собирались использовать выражение как значение в последовательности, используйте в явном виде "yield".
+ Это выражение возвращает значение типа "{0}", но оно неявно отбрасывается. Чтобы привязать результат к какому-то имени, используйте "let", например: "let <результат>= <выражение>". Если вы собирались использовать выражение как значение в последовательности, используйте в явном виде "yield".
This expression returns a value of type '{0}' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield!'.
- Это выражение возвращает значение типа "{0}", но оно неявно отбрасывается. Чтобы привязать результат к какому-то имени, используйте "let", например: "let <результат> = <выражение>". Если вы собирались использовать выражение как значение в последовательности, используйте в явном виде "yield!".
+ Это выражение возвращает значение типа "{0}", но оно неявно отбрасывается. Чтобы привязать результат к какому-то имени, используйте "let", например: "let <результат>= <выражение>". Если вы собирались использовать выражение как значение в последовательности, используйте в явном виде "yield!".
diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf
index 6e480a70cc..e6d11c8a09 100644
--- a/src/fsharp/xlf/FSComp.txt.tr.xlf
+++ b/src/fsharp/xlf/FSComp.txt.tr.xlf
@@ -97,6 +97,11 @@
uygulama hesaplama ifadeleri
+
+ attributes to the right of the 'module' keyword
+ 'modül' anahtar sözcüğünün sağındaki öznitelikler
+
+
default interface member consumption
varsayılan arabirim üyesi tüketimi
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ 'as' desenlerinin sağındaki değişken olmayan desenler
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ Bu betik için .NET SDK belirlenemedi. dotnet.exe bulunamadı, bir .NET SDK'nın yüklü olduğundan emin olun.
diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
index 62cc9cc4d8..dd1f942cbe 100644
--- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
@@ -97,6 +97,11 @@
适用的计算表达式
+
+ attributes to the right of the 'module' keyword
+ "module" 关键字右侧的属性
+
+
default interface member consumption
默认接口成员消耗
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ "as" 模式右侧的非变量模式
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ 无法确定此脚本的 .NET SDK。找不到 dotnet.exe,请确保安装了 .NET SDK。
diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
index ae756b033f..98e1a87ca9 100644
--- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
@@ -97,6 +97,11 @@
適用的計算運算式
+
+ attributes to the right of the 'module' keyword
+ 'module' 關鍵字右邊的屬性
+
+
default interface member consumption
預設介面成員使用
@@ -144,7 +149,7 @@
non-variable patterns to the right of 'as' patterns
- non-variable patterns to the right of 'as' patterns
+ 'as' 模式右邊的非變數模式
@@ -369,7 +374,7 @@
The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
- The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+ 無法判斷此指令碼的 .NET SDK。找不到 dotnet.exe,請確保已安裝 .NET SDK。
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/StringFormatAndInterpolation.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StringFormatAndInterpolation.fs
new file mode 100644
index 0000000000..716568cf83
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StringFormatAndInterpolation.fs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace FSharp.Compiler.ComponentTests.EmittedIL
+
+open Xunit
+open FSharp.Test.Utilities.Compiler
+
+module ``StringFormatAndInterpolation`` =
+ []
+ let ``Interpolated string with no holes is reduced to a string or simple format when used in printf``() =
+ FSharp """
+module StringFormatAndInterpolation
+
+let stringOnly () = $"no hole"
+
+let printed () = printf $"printed no hole"
+ """
+ |> compile
+ |> shouldSucceed
+ |> verifyIL ["""
+IL_0000: ldstr "no hole"
+IL_0005: ret"""
+ """
+IL_0000: ldstr "printed no hole"
+IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string)
+IL_000a: stloc.0
+IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out()
+IL_0010: ldloc.0
+IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatToTextWriter(class [runtime]System.IO.TextWriter,
+ class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+IL_0016: pop
+IL_0017: ret"""]
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleAbbreviationTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleAbbreviationTests.fs
deleted file mode 100644
index 932fde27aa..0000000000
--- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleAbbreviationTests.fs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
-
-namespace FSharp.Compiler.ComponentTests.ErrorMessages
-
-open Xunit
-open FSharp.Test.Utilities.Compiler
-
-
-module ``Module Abbreviations`` =
-
- []
- let ``Public Module Abbreviation``() =
- FSharp "module public L1 = List"
- |> typecheck
- |> shouldFail
- |> withSingleDiagnostic (Error 536, Line 1, Col 1, Line 1, Col 7,
- "The 'Public' accessibility attribute is not allowed on module abbreviation. Module abbreviations are always private.")
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleTests.fs
new file mode 100644
index 0000000000..f96f59a9ce
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleTests.fs
@@ -0,0 +1,204 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace FSharp.Compiler.ComponentTests.ErrorMessages
+
+open Xunit
+open FSharp.Test.Utilities.Compiler
+
+
+module Modules =
+
+ []
+ let ``Public Module Abbreviation``() =
+ FSharp "module public L1 = List"
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 536, Line 1, Col 1, Line 1, Col 7,
+ "The 'Public' accessibility attribute is not allowed on module abbreviation. Module abbreviations are always private.")
+
+ []
+ let ``Private Module Abbreviation``() =
+ FSharp "module private L1 = List"
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 536, Line 1, Col 1, Line 1, Col 7,
+ "The 'Private' accessibility attribute is not allowed on module abbreviation. Module abbreviations are always private.")
+
+ []
+ let ``Internal Module Abbreviation``() =
+ FSharp "module internal L1 = List"
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 536, Line 1, Col 1, Line 1, Col 7,
+ "The 'Internal' accessibility attribute is not allowed on module abbreviation. Module abbreviations are always private.")
+ []
+ let ``Rec Module Abbreviation``() =
+ FSharp "module rec L1 = List"
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 3203, Line 1, Col 1, Line 1, Col 14,
+ "Invalid use of 'rec' keyword")
+
+ []
+ let ``Left Attribute Module Abbreviation``() =
+ FSharp """[] module L1 = List"""
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 535, Line 1, Col 1, Line 1, Col 32,
+ "Ignoring attributes on module abbreviation")
+
+ []
+ let ``Right Attribute Module Abbreviation``() =
+ FSharp """module [] L1 = List"""
+ |> withLangVersionPreview
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 535, Line 1, Col 1, Line 1, Col 35,
+ "Ignoring attributes on module abbreviation")
+
+ []
+ let ``Right Attribute Module Abbreviation without preview (typecheck)``() =
+ FSharp """module [] L1 = List"""
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 535, Line 1, Col 1, Line 1, Col 35,
+ "Ignoring attributes on module abbreviation")
+ []
+ let ``Right Attribute Module Abbreviation without preview (compile)``() =
+ FSharp """module [] L1 = List"""
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ Error 3350, Line 1, Col 33, Line 1, Col 35, "Feature 'attributes to the right of the 'module' keyword' is not available in F# 5.0. Please use language version 'preview' or greater."
+ Error 535, Line 1, Col 1, Line 1, Col 35, "Ignoring attributes on module abbreviation"
+ Error 222, Line 1, Col 1, Line 1, Col 42, "Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration."
+ ]
+
+ []
+ let ``Attribute Module Abbreviation``() =
+ FSharp """[] module [] internal L1 = List"""
+ |> withLangVersionPreview
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 535, Line 1, Col 1, Line 1, Col 32,
+ "Ignoring attributes on module abbreviation")
+
+ []
+ let ``Attributes applied successfully``() =
+ Fsx """
+[] module [] rec L1 = type L2() = do ()
+match typeof.DeclaringType.GetCustomAttributes false with
+| [|:? AutoOpenAttribute; :? ExperimentalAttribute as experimental; :? CompilationMappingAttribute as compilationMapping|] ->
+ if compilationMapping.SourceConstructFlags <> SourceConstructFlags.Module then failwithf "CompilationMapping attribute did not contain the correct SourceConstructFlags: %A" compilationMapping.SourceConstructFlags
+ if experimental.Message <> "Hello" then failwithf "Experimental attribute did not contain the correct message: %s" experimental.Message
+| t -> failwithf "Attribute array is not of length 3 and correct types: %A" t
+ """
+ |> withLangVersionPreview
+ |> compileExeAndRun
+ |> shouldSucceed
+ []
+ let ``Attributes applied successfully 2``() =
+ Fsx """
+open System
+open System.ComponentModel
+[] [] module [][] private rec L1 = type L2() = do ()
+match typeof.DeclaringType.GetCustomAttributes false with
+| [|:? ObsoleteAttribute as obsolete
+ :? BrowsableAttribute as browsable
+ :? BindableAttribute as bindable
+ :? AmbientValueAttribute as ambientValue
+ :? ExperimentalAttribute as experimental
+ :? CategoryAttribute as category
+ :? DefaultValueAttribute as defaultValue
+ :? AutoOpenAttribute
+ :? CompilationMappingAttribute as compilationMapping|] ->
+ if obsolete.Message <> "Hi" then failwithf "Obsolete attribute did not contain the correct message: %s" obsolete.Message
+ if browsable.Browsable <> false then failwithf "Browsable attribute did not contain the correct flag: %b" browsable.Browsable
+ if bindable.Bindable <> true then failwithf "Bindable attribute did not contain the correct flag: %b" bindable.Bindable
+ if ambientValue.Value <> box false then failwithf "AmbientValue attribute did not contain the correct value: %O" ambientValue.Value
+ if experimental.Message <> "Hello" then failwithf "Experimental attribute did not contain the correct message: %s" experimental.Message
+ if category.Category <> "Oi" then failwithf "Category attribute did not contain the correct category: %s" category.Category
+ if defaultValue.Value <> box "Howdy" then failwithf "DefaultValue attribute did not contain the correct value: %O" defaultValue.Value
+ if compilationMapping.SourceConstructFlags <> SourceConstructFlags.Module then failwithf "CompilationMapping attribute did not contain the correct SourceConstructFlags: %O" compilationMapping.SourceConstructFlags
+| t -> failwithf "Attribute array is not of length 9 and correct types: %A" t
+ """
+ |> withLangVersionPreview
+ |> compileExeAndRun
+ |> shouldSucceed
+ []
+ let ``Fun attribute indentation``() =
+ Fsx """
+open System
+open System.ComponentModel
+[][] module
+ []
+ []
+ private
+ rec
+ L1
+ =
+ type
+ []
+ []
+ L2
+ ()
+ =
+ let
+ []
+ []
+ a
+ =
+ 1
+ member _.A = a
+match typeof.DeclaringType.GetCustomAttributes false with
+| [|:? ObsoleteAttribute as obsolete
+ :? BrowsableAttribute as browsable
+ :? BindableAttribute as bindable
+ :? AmbientValueAttribute as ambientValue
+ :? ExperimentalAttribute as experimental
+ :? CategoryAttribute as category
+ :? DefaultValueAttribute as defaultValue
+ :? AutoOpenAttribute
+ :? CompilationMappingAttribute as compilationMapping|] ->
+ if obsolete.Message <> "Hi" then failwithf "Obsolete attribute did not contain the correct message: %s" obsolete.Message
+ if browsable.Browsable <> false then failwithf "Browsable attribute did not contain the correct flag: %b" browsable.Browsable
+ if bindable.Bindable <> true then failwithf "Bindable attribute did not contain the correct flag: %b" bindable.Bindable
+ if ambientValue.Value <> box false then failwithf "AmbientValue attribute did not contain the correct value: %O" ambientValue.Value
+ if experimental.Message <> "Hello" then failwithf "Experimental attribute did not contain the correct message: %s" experimental.Message
+ if category.Category <> "Oi" then failwithf "Category attribute did not contain the correct category: %s" category.Category
+ if defaultValue.Value <> box "Howdy" then failwithf "DefaultValue attribute did not contain the correct value: %O" defaultValue.Value
+ if compilationMapping.SourceConstructFlags <> SourceConstructFlags.Module then failwithf "CompilationMapping attribute did not contain the correct SourceConstructFlags: %O" compilationMapping.SourceConstructFlags
+| t -> failwithf "Attribute array is not of length 9 and correct types: %A" t
+ """
+ |> withLangVersionPreview
+ |> compileExeAndRun
+ |> shouldSucceed
+
+ []
+ let ``Offside rule works for attributes inside module declarations``() =
+ Fsx """
+module [<
+AutoOpen>] L1 = do ()
+ """
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 10, Line 3, Col 1, Line 3, Col 9,
+ "Unexpected start of structured construct in attribute list")
+ []
+ let ``Offside rule works for attributes inside module declarations without preview``() =
+ Fsx """
+module [<
+AutoOpen>] L1 = do ()
+ """
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ Error 10, Line 3, Col 1, Line 3, Col 9, "Unexpected start of structured construct in attribute list"
+ Error 3350, Line 3, Col 1, Line 3, Col 9, "Feature 'attributes to the right of the 'module' keyword' is not available in F# 5.0. Please use language version 'preview' or greater."
+ ]
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index b4b0d58df6..e4ec28b52a 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -23,6 +23,7 @@
+
@@ -36,7 +37,7 @@
-
+
diff --git a/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs
index af765bcc81..b8b5c504c0 100644
--- a/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs
+++ b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs
@@ -5353,16 +5353,45 @@ FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpLis
FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] get_dotRanges()
FSharp.Compiler.Syntax.LongIdentWithDots: System.String ToString()
FSharp.Compiler.Syntax.ParsedHashDirective
-FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Syntax.ParsedHashDirective NewParsedHashDirective(System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], FSharp.Compiler.Text.Range)
+FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Syntax.ParsedHashDirective NewParsedHashDirective(System.String, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirectiveArgument], FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Text.Range range
FSharp.Compiler.Syntax.ParsedHashDirective: Int32 Tag
FSharp.Compiler.Syntax.ParsedHashDirective: Int32 get_Tag()
-FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[System.String] args
-FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_args()
+FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirectiveArgument] args
+FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirectiveArgument] get_args()
FSharp.Compiler.Syntax.ParsedHashDirective: System.String ToString()
FSharp.Compiler.Syntax.ParsedHashDirective: System.String get_ident()
FSharp.Compiler.Syntax.ParsedHashDirective: System.String ident
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: FSharp.Compiler.Text.Range get_range()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: FSharp.Compiler.Text.Range range
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String constant
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String get_constant()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String get_value()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String value
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Syntax.SynStringKind get_stringKind()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Syntax.SynStringKind stringKind
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Text.Range get_range()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Text.Range range
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: System.String get_value()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: System.String value
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 SourceIdentifier
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 String
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsSourceIdentifier
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsString
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsSourceIdentifier()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsString()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewSourceIdentifier(System.String, System.String, FSharp.Compiler.Text.Range)
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewString(System.String, FSharp.Compiler.Syntax.SynStringKind, FSharp.Compiler.Text.Range)
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Text.Range Range
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Text.Range get_Range()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Int32 Tag
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Int32 get_Tag()
+FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: System.String ToString()
FSharp.Compiler.Syntax.ParsedImplFile
FSharp.Compiler.Syntax.ParsedImplFile: FSharp.Compiler.Syntax.ParsedImplFile NewParsedImplFile(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedImplFileFragment])
FSharp.Compiler.Syntax.ParsedImplFile: Int32 Tag
diff --git a/tests/FSharp.Compiler.UnitTests/BlockTests.fs b/tests/FSharp.Compiler.UnitTests/BlockTests.fs
new file mode 100644
index 0000000000..e4f4bdd29f
--- /dev/null
+++ b/tests/FSharp.Compiler.UnitTests/BlockTests.fs
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+namespace FSharp.Compiler.UnitTests
+
+open Xunit
+open FSharp.Test.Utilities
+open Internal.Utilities.Library
+
+module BlockTests =
+
+ []
+ let ``Iter should work correctly``() =
+ let b = Block.init 5 id
+
+ let results = ResizeArray()
+ b
+ |> Block.iter (fun x ->
+ results.Add(x)
+ )
+
+ Assert.Equal(
+ [
+ 0
+ 1
+ 2
+ 3
+ 4
+ ],
+ results
+ )
+
+ []
+ let ``Map should work correctly``() =
+ let b = Block.init 5 id
+
+ let b2 = b |> Block.map (fun x -> x + 1)
+
+ Assert.Equal(
+ [
+ 1
+ 2
+ 3
+ 4
+ 5
+ ],
+ b2
+ )
+
+ []
+ let ``Fold should work correctly``() =
+ let b = Block.init 5 id
+
+ let result =
+ (0, b)
+ ||> Block.fold (fun state n ->
+ state + n
+ )
+
+ Assert.Equal(10, result)
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj
index c3d3ca35ae..dda54a28a4 100644
--- a/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj
+++ b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj
@@ -24,6 +24,7 @@
+
diff --git a/tests/FSharp.Compiler.UnitTests/HashIfExpression.fs b/tests/FSharp.Compiler.UnitTests/HashIfExpression.fs
index 201c329190..039b1c5335 100644
--- a/tests/FSharp.Compiler.UnitTests/HashIfExpression.fs
+++ b/tests/FSharp.Compiler.UnitTests/HashIfExpression.fs
@@ -70,7 +70,8 @@ type public HashIfExpression() =
let parser (s : string) =
let isFeatureSupported (_featureId:LanguageFeature) = true
- let lexbuf = LexBuffer.FromChars (true, isFeatureSupported, s.ToCharArray ())
+ let checkLanguageFeatureErrorRecover _featureId _range = ()
+ let lexbuf = LexBuffer.FromChars (true, isFeatureSupported, checkLanguageFeatureErrorRecover, s.ToCharArray ())
lexbuf.StartPos <- startPos
lexbuf.EndPos <- startPos
let tokenStream = PPLexer.tokenstream args
diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs
index 153904e163..f5f9152312 100644
--- a/tests/FSharp.Test.Utilities/Compiler.fs
+++ b/tests/FSharp.Test.Utilities/Compiler.fs
@@ -442,10 +442,10 @@ module rec Compiler =
let run (result: TestResult) : TestResult =
match result with
- | Failure f -> failwith (sprintf "Compilation should be successfull in order to run.\n Errors: %A" (f.Diagnostics))
+ | Failure f -> failwith (sprintf "Compilation should be successful in order to run.\n Errors: %A" (f.Diagnostics))
| Success s ->
match s.OutputPath with
- | None -> failwith "Compilation didn't produce any output. Unable to run. (did you forget to set output type to Exe?)"
+ | None -> failwith "Compilation didn't produce any output. Unable to run. (Did you forget to set output type to Exe?)"
| Some p ->
let (exitCode, output, errors) = CompilerAssert.ExecuteAndReturnResult (p, s.Dependencies, false)
let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors }) }
diff --git a/tests/fsharp/Compiler/Service/MultiProjectTests.fs b/tests/fsharp/Compiler/Service/MultiProjectTests.fs
index 6b4bedc74f..9f0bc33178 100644
--- a/tests/fsharp/Compiler/Service/MultiProjectTests.fs
+++ b/tests/fsharp/Compiler/Service/MultiProjectTests.fs
@@ -72,6 +72,54 @@ let test() =
Assert.shouldBeEmpty(checkResults.Diagnostics)
WeakReference(ms)
+ let compileFileAsDll (checker: FSharpChecker) filePath outputFilePath =
+ try
+ let result, _ =
+ checker.Compile([|"fsc.dll";filePath;$"-o:{ outputFilePath }";"--deterministic+";"--optimize+";"--target:library"|])
+ |> Async.RunSynchronously
+
+ if result.Length > 0 then
+ failwith "Compilation has errors."
+ with
+ | _ ->
+ try File.Delete(outputFilePath) with | _ -> ()
+ reraise()
+
+ let createOnDisk src =
+ let tmpFilePath = Path.GetTempFileName()
+ let tmpRealFilePath = Path.ChangeExtension(tmpFilePath, ".fs")
+ try File.Delete(tmpFilePath) with | _ -> ()
+ File.WriteAllText(tmpRealFilePath, src)
+ tmpRealFilePath
+
+ let createOnDiskCompiledAsDll checker src =
+ let tmpFilePath = Path.GetTempFileName()
+ let tmpRealFilePath = Path.ChangeExtension(tmpFilePath, ".fs")
+ try File.Delete(tmpFilePath) with | _ -> ()
+ File.WriteAllText(tmpRealFilePath, src)
+
+ let outputFilePath = Path.ChangeExtension(tmpRealFilePath, ".dll")
+
+ try
+ compileFileAsDll checker tmpRealFilePath outputFilePath
+ outputFilePath
+ finally
+ try File.Delete(tmpRealFilePath) with | _ -> ()
+
+ let updateFileOnDisk filePath src =
+ File.WriteAllText(filePath, src)
+
+ let updateCompiledDllOnDisk checker (dllPath: string) src =
+ if not (File.Exists dllPath) then
+ failwith $"File {dllPath} does not exist."
+
+ let filePath = createOnDisk src
+
+ try
+ compileFileAsDll checker filePath dllPath
+ finally
+ try File.Delete(filePath) with | _ -> ()
+
[]
let ``Using a CSharp reference project in-memory``() =
AssertInMemoryCSharpReferenceIsValid() |> ignore
@@ -83,5 +131,73 @@ let test() =
GC.Collect(2, GCCollectionMode.Forced, true)
Assert.shouldBeFalse(weakRef.IsAlive)
+ []
+ let ``Using compiler service, file referencing a DLL will correctly update when the referenced DLL file changes``() =
+ let checker = CompilerAssert.Checker
+
+ let dllPath1 =
+ createOnDiskCompiledAsDll checker
+ """
+module Script1
+
+let x = 1
+ """
+
+ let filePath1 =
+ createOnDisk
+ """
+module Script2
+
+let x = Script1.x
+ """
+
+ try
+ let fsOptions1 = CompilerAssert.DefaultProjectOptions
+ let fsOptions1 =
+ { fsOptions1 with
+ ProjectId = Some(Guid.NewGuid().ToString())
+ OtherOptions = [|"-r:" + dllPath1|]
+ ReferencedProjects = [||]
+ SourceFiles = [|filePath1|] }
+
+ let checkProjectResults =
+ checker.ParseAndCheckProject(fsOptions1)
+ |> Async.RunSynchronously
+
+ Assert.IsEmpty(checkProjectResults.Diagnostics)
+
+ updateFileOnDisk filePath1
+ """
+module Script2
+
+let x = Script1.x
+let y = Script1.y
+ """
+
+ let checkProjectResults =
+ checker.ParseAndCheckProject(fsOptions1)
+ |> Async.RunSynchronously
+
+ Assert.IsNotEmpty(checkProjectResults.Diagnostics)
+
+ updateCompiledDllOnDisk checker dllPath1
+ """
+module Script1
+
+let x = 1
+let y = 1
+ """
+
+ let checkProjectResults =
+ checker.ParseAndCheckProject(fsOptions1)
+ |> Async.RunSynchronously
+
+ Assert.IsEmpty(checkProjectResults.Diagnostics)
+
+ finally
+ try File.Delete(dllPath1) with | _ -> ()
+ try File.Delete(filePath1) with | _ -> ()
+
+
diff --git a/tests/fsharp/core/innerpoly/test.fsx b/tests/fsharp/core/innerpoly/test.fsx
index 752ba98a3d..76c88c8fd7 100644
--- a/tests/fsharp/core/innerpoly/test.fsx
+++ b/tests/fsharp/core/innerpoly/test.fsx
@@ -439,6 +439,45 @@ module Bug10408 =
| [| |] -> x
| _ -> x
+module Bug11620A =
+
+ let createService (metadata: 'T) : 'Data when 'Data :> System.IComparable = Unchecked.defaultof<'Data>
+
+ let getCreateServiceCallback<'T> (thing: 'T) =
+ let getService () : 'Data = createService thing
+ (fun () -> getService)
+
+// The generated signature for this bug repro has mistakes, we are not enabling it yet
+#if !GENERATED_SIGNATURE
+module Bug11620B =
+
+ type Data = interface end
+ and Service<'Data when 'Data :> Data>() = class end
+
+ type IThing = interface end
+ and Thing<'T> = { Metadata: 'T } with interface IThing
+
+ let createService metadata = (Service<'Data>())
+
+ let getCreateServiceCallback<'T> (thing: IThing) =
+ let upcastThing =
+ thing
+ :?> Thing<'T>
+ let getService () = createService upcastThing.Metadata
+ (fun () -> getService)
+
+ let main _ =
+ let dummyThing : Thing = { Thing.Metadata = 42 }
+ // crash occured on the following line
+ let callback = getCreateServiceCallback dummyThing
+ let resolvedService = callback ()
+ printfn "Resolved service: %A" resolvedService
+ 0
+
+ main ()
+#endif
+
+
#if TESTS_AS_APP
let RUN() = !failures
#else
diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx
index 6415c466a6..39d2e4218e 100644
--- a/tests/fsharp/core/quotes/test.fsx
+++ b/tests/fsharp/core/quotes/test.fsx
@@ -2912,7 +2912,7 @@ module ReflectionOverTypeInstantiations =
let notRequired opname item =
let msg = sprintf "The operation '%s' on item '%s' should not be called on provided type, member or parameter" opname item
- System.Diagnostics.Debug.Assert (false, msg)
+ //System.Diagnostics.Debug.Assert (false, msg)
raise (System.NotSupportedException msg)
/// DO NOT ADJUST THIS TYPE - it is the implementation of symbol types from the F# type provider starer pack.
@@ -4119,6 +4119,19 @@ module CheckEliminatedConstructs =
"""IfThenElse (Call (None, op_Equality, [ValueWithName ([||], ts), Value ()]),
Value (true), Value (false))"""
+module Interpolation =
+ let interpolatedNoHoleQuoted = <@ $"abc" @>
+ let actual1 = interpolatedNoHoleQuoted.ToString()
+ checkStrings "brewbreebrwhat1" actual1 """Value ("abc")"""
+
+ let interpolatedWithLiteralQuoted = <@ $"abc {1} def" @>
+ let actual2 = interpolatedWithLiteralQuoted.ToString()
+ checkStrings "brewbreebrwhat2" actual2
+ """Call (None, PrintFormatToString,
+ [NewObject (PrintfFormat`5, Value ("abc %P() def"),
+ NewArray (Object, Call (None, Box, [Value (1)])),
+ Value ())])"""
+
module TestAssemblyAttributes =
let attributes = System.Reflection.Assembly.GetExecutingAssembly().GetCustomAttributes(false)
diff --git a/tests/fsharp/single-test.fs b/tests/fsharp/single-test.fs
index 31b26fa76c..b2c6f77242 100644
--- a/tests/fsharp/single-test.fs
+++ b/tests/fsharp/single-test.fs
@@ -9,6 +9,7 @@ open FSharp.Compiler.IO
type Permutation =
| FSC_CORECLR
+ | FSC_CORECLR_OPT_MINUS
| FSC_CORECLR_BUILDONLY
| FSI_CORECLR
#if !NETCOREAPP
@@ -304,6 +305,7 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion =
match p with
| FSC_CORECLR -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "net5.0" true false
+ | FSC_CORECLR_OPT_MINUS -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "net5.0" false false
| FSC_CORECLR_BUILDONLY -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "net5.0" true true
| FSI_CORECLR -> executeSingleTestBuildAndRun OutputType.Script "coreclr" "net5.0" true false
@@ -333,7 +335,7 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion =
source1 |> Option.iter (fun from -> copy_y cfg from "tmptest.fs")
log "Generated signature file..."
- fsc cfg "%s --sig:tmptest.fsi" cfg.fsc_flags ["tmptest.fs"]
+ fsc cfg "%s --sig:tmptest.fsi --define:GENERATED_SIGNATURE" cfg.fsc_flags ["tmptest.fs"]
(if FileSystem.FileExistsShim("FSharp.Core.dll") then log "found fsharp.core.dll after build" else log "found fsharp.core.dll after build") |> ignore
log "Compiling against generated signature file..."
diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs
index 53183028f1..93957279eb 100644
--- a/tests/fsharp/tests.fs
+++ b/tests/fsharp/tests.fs
@@ -21,10 +21,12 @@ open HandleExpects
#if NETCOREAPP
// Use these lines if you want to test CoreCLR
let FSC_BASIC = FSC_CORECLR
+let FSC_BASIC_OPT_MINUS = FSC_CORECLR_OPT_MINUS
let FSC_BUILDONLY = FSC_CORECLR_BUILDONLY
let FSI_BASIC = FSI_CORECLR
#else
let FSC_BASIC = FSC_OPT_PLUS_DEBUG
+let FSC_BASIC_OPT_MINUS = FSC_OPT_MINUS_DEBUG
let FSI_BASIC = FSI_FILE
#endif
// ^^^^^^^^^^^^ To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test ^^^^^^^^^^^^
@@ -37,18 +39,27 @@ let testConfig = getTestsDirectory >> testConfig
[]
module CoreTests =
// These tests are enabled for .NET Framework and .NET Core
+ []
+ let ``access-FSC_BASIC_OPT_MINUS``() = singleTestBuildAndRun "core/access" FSC_BASIC_OPT_MINUS
+
[]
let ``access-FSC_BASIC``() = singleTestBuildAndRun "core/access" FSC_BASIC
[]
let ``access-FSI_BASIC``() = singleTestBuildAndRun "core/access" FSI_BASIC
+ []
+ let ``apporder-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/apporder" FSC_BASIC_OPT_MINUS
+
[]
let ``apporder-FSC_BASIC`` () = singleTestBuildAndRun "core/apporder" FSC_BASIC
[]
let ``apporder-FSI_BASIC`` () = singleTestBuildAndRun "core/apporder" FSI_BASIC
+ []
+ let ``array-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/array" FSC_BASIC_OPT_MINUS
+
[]
let ``array-FSC_BASIC`` () = singleTestBuildAndRun "core/array" FSC_BASIC
@@ -61,7 +72,11 @@ module CoreTests =
singleVersionedNegTest cfg "5.0" "test"
[]
- let ``auto-widen-version-preview``() =
+ let ``auto-widen-version-FSC_BASIC_OPT_MINUS-preview``() =
+ singleTestBuildAndRunVersion "core/auto-widen/preview" FSC_BASIC_OPT_MINUS "preview"
+
+ []
+ let ``auto-widen-version-FSC_BASIC-preview``() =
singleTestBuildAndRunVersion "core/auto-widen/preview" FSC_BASIC "preview"
[]
@@ -70,81 +85,123 @@ module CoreTests =
let cfg = { cfg with fsc_flags = cfg.fsc_flags + " --warnon:3386 --warnaserror+ --define:NEGATIVE" }
singleVersionedNegTest cfg "preview" "test"
+ []
+ let ``comprehensions-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/comprehensions" FSC_BASIC_OPT_MINUS
+
[]
let ``comprehensions-FSC_BASIC`` () = singleTestBuildAndRun "core/comprehensions" FSC_BASIC
[]
let ``comprehensions-FSI_BASIC`` () = singleTestBuildAndRun "core/comprehensions" FSI_BASIC
+ []
+ let ``comprehensionshw-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/comprehensions-hw" FSC_BASIC_OPT_MINUS
+
[]
let ``comprehensionshw-FSC_BASIC`` () = singleTestBuildAndRun "core/comprehensions-hw" FSC_BASIC
[]
let ``comprehensionshw-FSI_BASIC`` () = singleTestBuildAndRun "core/comprehensions-hw" FSI_BASIC
+ []
+ let ``genericmeasures-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/genericmeasures" FSC_BASIC_OPT_MINUS
+
[]
let ``genericmeasures-FSC_BASIC`` () = singleTestBuildAndRun "core/genericmeasures" FSC_BASIC
[]
let ``genericmeasures-FSI_BASIC`` () = singleTestBuildAndRun "core/genericmeasures" FSI_BASIC
+ []
+ let ``innerpoly-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/innerpoly" FSC_BASIC_OPT_MINUS
+
[]
let ``innerpoly-FSC_BASIC`` () = singleTestBuildAndRun "core/innerpoly" FSC_BASIC
[]
let ``innerpoly-FSI_BASIC`` () = singleTestBuildAndRun "core/innerpoly" FSI_BASIC
+ []
+ let ``namespaceAttributes-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/namespaces" FSC_BASIC_OPT_MINUS
+
[]
let ``namespaceAttributes-FSC_BASIC`` () = singleTestBuildAndRun "core/namespaces" FSC_BASIC
+ []
+ let ``unicode2-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/unicode" FSC_BASIC_OPT_MINUS // TODO: fails on coreclr
+
[]
let ``unicode2-FSC_BASIC`` () = singleTestBuildAndRun "core/unicode" FSC_BASIC // TODO: fails on coreclr
[]
let ``unicode2-FSI_BASIC`` () = singleTestBuildAndRun "core/unicode" FSI_BASIC
+ []
+ let ``lazy test-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/lazy" FSC_BASIC_OPT_MINUS
+
[]
let ``lazy test-FSC_BASIC`` () = singleTestBuildAndRun "core/lazy" FSC_BASIC
[]
let ``lazy test-FSI_BASIC`` () = singleTestBuildAndRun "core/lazy" FSI_BASIC
+ []
+ let ``letrec-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/letrec" FSC_BASIC_OPT_MINUS
+
[]
let ``letrec-FSC_BASIC`` () = singleTestBuildAndRun "core/letrec" FSC_BASIC
[]
let ``letrec-FSI_BASIC`` () = singleTestBuildAndRun "core/letrec" FSI_BASIC
+ []
+ let ``letrec (mutrec variations part one) FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/letrec-mutrec" FSC_BASIC_OPT_MINUS
+
[]
let ``letrec (mutrec variations part one) FSC_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec" FSC_BASIC
[]
let ``letrec (mutrec variations part one) FSI_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec" FSI_BASIC
+ []
+ let ``libtest-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/libtest" FSC_BASIC_OPT_MINUS
+
[]
let ``libtest-FSC_BASIC`` () = singleTestBuildAndRun "core/libtest" FSC_BASIC
[]
let ``libtest-FSI_BASIC`` () = singleTestBuildAndRun "core/libtest" FSI_BASIC
+ []
+ let ``lift-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/lift" FSC_BASIC_OPT_MINUS
+
[]
let ``lift-FSC_BASIC`` () = singleTestBuildAndRun "core/lift" FSC_BASIC
[]
let ``lift-FSI_BASIC`` () = singleTestBuildAndRun "core/lift" FSI_BASIC
+ []
+ let ``map-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/map" FSC_BASIC_OPT_MINUS
+
[]
let ``map-FSC_BASIC`` () = singleTestBuildAndRun "core/map" FSC_BASIC
[]
let ``map-FSI_BASIC`` () = singleTestBuildAndRun "core/map" FSI_BASIC
+ []
+ let ``measures-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/measures" FSC_BASIC_OPT_MINUS
+
[]
let ``measures-FSC_BASIC`` () = singleTestBuildAndRun "core/measures" FSC_BASIC
[]
let ``measures-FSI_BASIC`` () = singleTestBuildAndRun "core/measures" FSI_BASIC
+ []
+ let ``nested-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/nested" FSC_BASIC_OPT_MINUS
+
[]
let ``nested-FSC_BASIC`` () = singleTestBuildAndRun "core/nested" FSC_BASIC
@@ -154,15 +211,24 @@ module CoreTests =
[]
let ``members-ops-FSC_BASIC`` () = singleTestBuildAndRun "core/members/ops" FSC_BASIC
+ []
+ let ``members-ops-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/ops" FSC_BASIC_OPT_MINUS
+
[]
let ``members-ops-FSI_BASIC`` () = singleTestBuildAndRun "core/members/ops" FSI_BASIC
+ []
+ let ``members-ops-mutrec-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/ops-mutrec" FSC_BASIC_OPT_MINUS
+
[]
let ``members-ops-mutrec-FSC_BASIC`` () = singleTestBuildAndRun "core/members/ops-mutrec" FSC_BASIC
[]
let ``members-ops-mutrec-FSI_BASIC`` () = singleTestBuildAndRun "core/members/ops-mutrec" FSI_BASIC
+ []
+ let ``seq-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/seq" FSC_BASIC_OPT_MINUS
+
[]
let ``seq-FSC_BASIC`` () = singleTestBuildAndRun "core/seq" FSC_BASIC
@@ -175,36 +241,54 @@ module CoreTests =
[]
let ``math-numbers-FSI_BASIC`` () = singleTestBuildAndRun "core/math/numbers" FSI_BASIC
+ []
+ let ``members-ctree-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/ctree" FSC_BASIC_OPT_MINUS
+
[]
let ``members-ctree-FSC_BASIC`` () = singleTestBuildAndRun "core/members/ctree" FSC_BASIC
[]
let ``members-ctree-FSI_BASIC`` () = singleTestBuildAndRun "core/members/ctree" FSI_BASIC
+ []
+ let ``members-factors-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/factors" FSC_BASIC_OPT_MINUS
+
[]
let ``members-factors-FSC_BASIC`` () = singleTestBuildAndRun "core/members/factors" FSC_BASIC
[]
let ``members-factors-FSI_BASIC`` () = singleTestBuildAndRun "core/members/factors" FSI_BASIC
+ []
+ let ``members-factors-mutrec-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/factors-mutrec" FSC_BASIC_OPT_MINUS
+
[]
let ``members-factors-mutrec-FSC_BASIC`` () = singleTestBuildAndRun "core/members/factors-mutrec" FSC_BASIC
[]
let ``members-factors-mutrec-FSI_BASIC`` () = singleTestBuildAndRun "core/members/factors-mutrec" FSI_BASIC
+ []
+ let ``graph-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "perf/graph" FSC_BASIC_OPT_MINUS
+
[]
let ``graph-FSC_BASIC`` () = singleTestBuildAndRun "perf/graph" FSC_BASIC
[]
let ``graph-FSI_BASIC`` () = singleTestBuildAndRun "perf/graph" FSI_BASIC
+ []
+ let ``nbody-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "perf/nbody" FSC_BASIC_OPT_MINUS
+
[]
let ``nbody-FSC_BASIC`` () = singleTestBuildAndRun "perf/nbody" FSC_BASIC
[]
let ``nbody-FSI_BASIC`` () = singleTestBuildAndRun "perf/nbody" FSI_BASIC
+ []
+ let ``letrec (mutrec variations part two) FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/letrec-mutrec2" FSC_BASIC_OPT_MINUS
+
[]
let ``letrec (mutrec variations part two) FSC_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec2" FSC_BASIC
@@ -217,36 +301,54 @@ module CoreTests =
[]
let ``printf-interpolated`` () = singleTestBuildAndRunVersion "core/printf-interpolated" FSC_BASIC "preview"
+ []
+ let ``tlr-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/tlr" FSC_BASIC_OPT_MINUS
+
[]
let ``tlr-FSC_BASIC`` () = singleTestBuildAndRun "core/tlr" FSC_BASIC
[]
let ``tlr-FSI_BASIC`` () = singleTestBuildAndRun "core/tlr" FSI_BASIC
+ []
+ let ``subtype-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/subtype" FSC_BASIC_OPT_MINUS
+
[]
let ``subtype-FSC_BASIC`` () = singleTestBuildAndRun "core/subtype" FSC_BASIC
[]
let ``subtype-FSI_BASIC`` () = singleTestBuildAndRun "core/subtype" FSI_BASIC
+ []
+ let ``syntax-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/syntax" FSC_BASIC_OPT_MINUS
+
[]
let ``syntax-FSC_BASIC`` () = singleTestBuildAndRun "core/syntax" FSC_BASIC
[]
let ``syntax-FSI_BASIC`` () = singleTestBuildAndRun "core/syntax" FSI_BASIC
+ []
+ let ``test int32-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/int32" FSC_BASIC_OPT_MINUS
+
[]
let ``test int32-FSC_BASIC`` () = singleTestBuildAndRun "core/int32" FSC_BASIC
[]
let ``test int32-FSI_BASIC`` () = singleTestBuildAndRun "core/int32" FSI_BASIC
+ []
+ let ``quotes-FSC-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/quotes" FSC_BASIC_OPT_MINUS
+
[]
let ``quotes-FSC-BASIC`` () = singleTestBuildAndRun "core/quotes" FSC_BASIC
[]
let ``quotes-FSI-BASIC`` () = singleTestBuildAndRun "core/quotes" FSI_BASIC
+ []
+ let ``recordResolution-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/recordResolution" FSC_BASIC_OPT_MINUS
+
[]
let ``recordResolution-FSC_BASIC`` () = singleTestBuildAndRun "core/recordResolution" FSC_BASIC
diff --git a/tests/fsharp/typecheck/sigs/neg117.bsl b/tests/fsharp/typecheck/sigs/neg117.bsl
index 9ad81d0003..2c8fbee14c 100644
--- a/tests/fsharp/typecheck/sigs/neg117.bsl
+++ b/tests/fsharp/typecheck/sigs/neg117.bsl
@@ -1,5 +1,5 @@
-neg117.fs(79,18,79,59): ilxgen error FS0041: No overloads match for method 'Transform'.
+neg117.fs(74,51,74,121): ilxgen error FS0041: No overloads match for method 'Transform'.
Known return type: ('a -> Neg117.TargetA.M1 Microsoft.FSharp.Core.[])
diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompareIL.cmd b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompareIL.cmd
index 0e3c4acf21..ea97cebadc 100644
--- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompareIL.cmd
+++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompareIL.cmd
@@ -1,15 +1,17 @@
REM == %1 --> assembly
ildasm /TEXT /LINENUM /NOBAR "%~nx1" >"%~n1.il"
-IF NOT ERRORLEVEL 0 exit 1
+IF %ERRORLEVEL% NEQ 0 exit /b 1
echo %~dp0..\..\..\testenv\bin\ILComparer.exe "%~n1.il.bsl" "%~n1.il"
%~dp0..\..\..\testenv\bin\ILComparer.exe "%~n1.il.bsl" "%~n1.il"
+IF %ERRORLEVEL% EQU 0 exit /b 0
+
if /i "%TEST_UPDATE_BSL%" == "1" (
echo copy /y "%~n1.il" "%~n1.il.bsl"
copy /y "%~n1.il" "%~n1.il.bsl"
)
-exit /b %ERRORLEVEL%
+exit /b 1
diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Grouping01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Grouping01.il.bsl
index e5bad87d72..38346254e8 100644
--- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Grouping01.il.bsl
+++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Grouping01.il.bsl
@@ -50,13 +50,13 @@
// Offset: 0x00000408 Length: 0x00000129
}
.module Linq101Grouping01.exe
-// MVID: {60B78A59-FB79-E5BF-A745-0383598AB760}
+// MVID: {60D46F1F-FB79-E5BF-A745-03831F6FD460}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
-// Image base: 0x06730000
+// Image base: 0x05800000
// =============== CLASS MEMBERS DECLARATION ===================
@@ -371,7 +371,7 @@
{
// Code size 8 (0x8)
.maxstack 8
- .line 25,25 : 24,25 ''
+ .line 25,25 : 23,28 ''
IL_0000: ldarg.1
IL_0001: ldc.i4.0
IL_0002: callvirt instance char [netstandard]System.String::get_Chars(int32)
diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101SetOperators01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101SetOperators01.il.bsl
index 02331dbae8..baba5ea96e 100644
--- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101SetOperators01.il.bsl
+++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101SetOperators01.il.bsl
@@ -45,13 +45,13 @@
// Offset: 0x00000390 Length: 0x0000011E
}
.module Linq101SetOperators01.exe
-// MVID: {60B78A59-4EE5-349F-A745-0383598AB760}
+// MVID: {60D46F1F-4EE5-349F-A745-03831F6FD460}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
-// Image base: 0x06940000
+// Image base: 0x04FA0000
// =============== CLASS MEMBERS DECLARATION ===================
@@ -846,7 +846,7 @@
IL_0057: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum'
IL_005c: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current()
IL_0061: stloc.0
- .line 33,33 : 29,30 ''
+ .line 33,33 : 16,33 ''
IL_0062: ldarg.0
IL_0063: ldc.i4.2
IL_0064: stfld int32 Linq101SetOperators01/productFirstChars@33::pc
@@ -1196,7 +1196,7 @@
IL_0057: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum'
IL_005c: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current()
IL_0061: stloc.0
- .line 39,39 : 29,30 ''
+ .line 39,39 : 16,33 ''
IL_0062: ldarg.0
IL_0063: ldc.i4.2
IL_0064: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc
diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModule.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModule.il.bsl
index bf83c61d10..e4ab112f17 100644
--- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModule.il.bsl
+++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModule.il.bsl
@@ -1,4 +1,1673 @@
-// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
+// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0
// Copyright (c) Microsoft Corporation. All rights reserved.
+
+
+// Metadata version: v4.0.30319
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 4:0:0:0
+}
+.assembly extern FSharp.Core
+{
+ .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
+ .ver 5:0:0:0
+}
+.assembly TopLevelModule
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32,
+ int32,
+ int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 )
+
+ // --- The following custom attribute is added automatically, do not uncomment -------
+ // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 01 01 00 00 00 00 )
+
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.mresource public FSharpSignatureData.TopLevelModule
+{
+ // Offset: 0x00000000 Length: 0x0000113D
+}
+.mresource public FSharpOptimizationData.TopLevelModule
+{
+ // Offset: 0x00001148 Length: 0x000003FD
+}
+.module TopLevelModule.dll
+// MVID: {60D4892F-37F5-C118-A745-03832F89D460}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x06F60000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public abstract auto ansi sealed ABC
+ extends [mscorlib]System.Object
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
+ .class auto autochar serializable sealed nested public beforefieldinit Expr
+ extends [mscorlib]System.Object
+ implements class [mscorlib]System.IEquatable`1,
+ [mscorlib]System.Collections.IStructuralEquatable,
+ class [mscorlib]System.IComparable`1,
+ [mscorlib]System.IComparable,
+ [mscorlib]System.Collections.IStructuralComparable
+ {
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl
+ 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}..
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 )
+ .field assembly initonly int32 item
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method public static class ABC/Expr
+ NewNum(int32 item) cil managed
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags,
+ int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 )
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: newobj instance void ABC/Expr::.ctor(int32)
+ IL_0006: ret
+ } // end of method Expr::NewNum
+
+ .method assembly specialname rtspecialname
+ instance void .ctor(int32 item) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 14 (0xe)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: ldarg.1
+ IL_0008: stfld int32 ABC/Expr::item
+ IL_000d: ret
+ } // end of method Expr::.ctor
+
+ .method public hidebysig instance int32
+ get_Item() cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld int32 ABC/Expr::item
+ IL_0006: ret
+ } // end of method Expr::get_Item
+
+ .method public hidebysig instance int32
+ get_Tag() cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 4 (0x4)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: pop
+ IL_0002: ldc.i4.0
+ IL_0003: ret
+ } // end of method Expr::get_Tag
+
+ .method assembly hidebysig specialname
+ instance object __DebugDisplay() cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 22 (0x16)
+ .maxstack 8
+ IL_0000: ldstr "%+0.8A"
+ IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string)
+ IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_000f: ldarg.0
+ IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0)
+ IL_0015: ret
+ } // end of method Expr::__DebugDisplay
+
+ .method public strict virtual instance string
+ ToString() cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 22 (0x16)
+ .maxstack 8
+ IL_0000: ldstr "%+A"
+ IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class ABC/Expr>::.ctor(string)
+ IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_000f: ldarg.0
+ IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0)
+ IL_0015: ret
+ } // end of method Expr::ToString
+
+ .method public hidebysig virtual final
+ instance int32 CompareTo(class ABC/Expr obj) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 64 (0x40)
+ .maxstack 4
+ .locals init ([0] class ABC/Expr V_0,
+ [1] class ABC/Expr V_1,
+ [2] class [mscorlib]System.Collections.IComparer V_2,
+ [3] int32 V_3,
+ [4] int32 V_4)
+ .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
+ .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SerializableAttribute\\ToplevelModule.fs'
+ IL_0000: ldarg.0
+ IL_0001: ldnull
+ IL_0002: cgt.un
+ IL_0004: brfalse.s IL_0036
+
+ .line 100001,100001 : 0,0 ''
+ IL_0006: ldarg.1
+ IL_0007: ldnull
+ IL_0008: cgt.un
+ IL_000a: brfalse.s IL_0034
+
+ .line 100001,100001 : 0,0 ''
+ IL_000c: ldarg.0
+ IL_000d: pop
+ .line 100001,100001 : 0,0 ''
+ IL_000e: ldarg.0
+ IL_000f: stloc.0
+ IL_0010: ldarg.1
+ IL_0011: stloc.1
+ IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer()
+ IL_0017: stloc.2
+ IL_0018: ldloc.0
+ IL_0019: ldfld int32 ABC/Expr::item
+ IL_001e: stloc.3
+ IL_001f: ldloc.1
+ IL_0020: ldfld int32 ABC/Expr::item
+ IL_0025: stloc.s V_4
+ IL_0027: ldloc.3
+ IL_0028: ldloc.s V_4
+ IL_002a: bge.s IL_002e
+
+ .line 100001,100001 : 0,0 ''
+ IL_002c: ldc.i4.m1
+ IL_002d: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_002e: ldloc.3
+ IL_002f: ldloc.s V_4
+ IL_0031: cgt
+ IL_0033: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0034: ldc.i4.1
+ IL_0035: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0036: ldarg.1
+ IL_0037: ldnull
+ IL_0038: cgt.un
+ IL_003a: brfalse.s IL_003e
+
+ .line 100001,100001 : 0,0 ''
+ IL_003c: ldc.i4.m1
+ IL_003d: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_003e: ldc.i4.0
+ IL_003f: ret
+ } // end of method Expr::CompareTo
+
+ .method public hidebysig virtual final
+ instance int32 CompareTo(object obj) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 13 (0xd)
+ .maxstack 8
+ .line 6,6 : 14,18 ''
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: unbox.any ABC/Expr
+ IL_0007: callvirt instance int32 ABC/Expr::CompareTo(class ABC/Expr)
+ IL_000c: ret
+ } // end of method Expr::CompareTo
+
+ .method public hidebysig virtual final
+ instance int32 CompareTo(object obj,
+ class [mscorlib]System.Collections.IComparer comp) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 80 (0x50)
+ .maxstack 4
+ .locals init ([0] class ABC/Expr V_0,
+ [1] class ABC/Expr V_1,
+ [2] class ABC/Expr V_2,
+ [3] class [mscorlib]System.Collections.IComparer V_3,
+ [4] int32 V_4,
+ [5] int32 V_5)
+ .line 6,6 : 14,18 ''
+ IL_0000: ldarg.1
+ IL_0001: unbox.any ABC/Expr
+ IL_0006: stloc.0
+ IL_0007: ldarg.0
+ IL_0008: ldnull
+ IL_0009: cgt.un
+ IL_000b: brfalse.s IL_0041
+
+ .line 100001,100001 : 0,0 ''
+ IL_000d: ldarg.1
+ IL_000e: unbox.any ABC/Expr
+ IL_0013: ldnull
+ IL_0014: cgt.un
+ IL_0016: brfalse.s IL_003f
+
+ .line 100001,100001 : 0,0 ''
+ IL_0018: ldarg.0
+ IL_0019: pop
+ .line 100001,100001 : 0,0 ''
+ IL_001a: ldarg.0
+ IL_001b: stloc.1
+ IL_001c: ldloc.0
+ IL_001d: stloc.2
+ IL_001e: ldarg.2
+ IL_001f: stloc.3
+ IL_0020: ldloc.1
+ IL_0021: ldfld int32 ABC/Expr::item
+ IL_0026: stloc.s V_4
+ IL_0028: ldloc.2
+ IL_0029: ldfld int32 ABC/Expr::item
+ IL_002e: stloc.s V_5
+ IL_0030: ldloc.s V_4
+ IL_0032: ldloc.s V_5
+ IL_0034: bge.s IL_0038
+
+ .line 100001,100001 : 0,0 ''
+ IL_0036: ldc.i4.m1
+ IL_0037: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0038: ldloc.s V_4
+ IL_003a: ldloc.s V_5
+ IL_003c: cgt
+ IL_003e: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_003f: ldc.i4.1
+ IL_0040: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0041: ldarg.1
+ IL_0042: unbox.any ABC/Expr
+ IL_0047: ldnull
+ IL_0048: cgt.un
+ IL_004a: brfalse.s IL_004e
+
+ .line 100001,100001 : 0,0 ''
+ IL_004c: ldc.i4.m1
+ IL_004d: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_004e: ldc.i4.0
+ IL_004f: ret
+ } // end of method Expr::CompareTo
+
+ .method public hidebysig virtual final
+ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 41 (0x29)
+ .maxstack 7
+ .locals init ([0] int32 V_0,
+ [1] class ABC/Expr V_1,
+ [2] class [mscorlib]System.Collections.IEqualityComparer V_2)
+ .line 100001,100001 : 0,0 ''
+ IL_0000: ldarg.0
+ IL_0001: ldnull
+ IL_0002: cgt.un
+ IL_0004: brfalse.s IL_0027
+
+ .line 100001,100001 : 0,0 ''
+ IL_0006: ldc.i4.0
+ IL_0007: stloc.0
+ IL_0008: ldarg.0
+ IL_0009: pop
+ .line 100001,100001 : 0,0 ''
+ IL_000a: ldarg.0
+ IL_000b: stloc.1
+ IL_000c: ldc.i4.0
+ IL_000d: stloc.0
+ IL_000e: ldc.i4 0x9e3779b9
+ IL_0013: ldarg.1
+ IL_0014: stloc.2
+ IL_0015: ldloc.1
+ IL_0016: ldfld int32 ABC/Expr::item
+ IL_001b: ldloc.0
+ IL_001c: ldc.i4.6
+ IL_001d: shl
+ IL_001e: ldloc.0
+ IL_001f: ldc.i4.2
+ IL_0020: shr
+ IL_0021: add
+ IL_0022: add
+ IL_0023: add
+ IL_0024: stloc.0
+ IL_0025: ldloc.0
+ IL_0026: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0027: ldc.i4.0
+ IL_0028: ret
+ } // end of method Expr::GetHashCode
+
+ .method public hidebysig virtual final
+ instance int32 GetHashCode() cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 12 (0xc)
+ .maxstack 8
+ .line 6,6 : 14,18 ''
+ IL_0000: ldarg.0
+ IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer()
+ IL_0006: callvirt instance int32 ABC/Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer)
+ IL_000b: ret
+ } // end of method Expr::GetHashCode
+
+ .method public hidebysig virtual final
+ instance bool Equals(object obj,
+ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 52 (0x34)
+ .maxstack 4
+ .locals init ([0] class ABC/Expr V_0,
+ [1] class ABC/Expr V_1,
+ [2] class ABC/Expr V_2,
+ [3] class ABC/Expr V_3,
+ [4] class [mscorlib]System.Collections.IEqualityComparer V_4)
+ .line 100001,100001 : 0,0 ''
+ IL_0000: ldarg.0
+ IL_0001: ldnull
+ IL_0002: cgt.un
+ IL_0004: brfalse.s IL_002c
+
+ .line 100001,100001 : 0,0 ''
+ IL_0006: ldarg.1
+ IL_0007: isinst ABC/Expr
+ IL_000c: stloc.0
+ IL_000d: ldloc.0
+ IL_000e: brfalse.s IL_002a
+
+ .line 100001,100001 : 0,0 ''
+ IL_0010: ldloc.0
+ IL_0011: stloc.1
+ IL_0012: ldarg.0
+ IL_0013: pop
+ .line 100001,100001 : 0,0 ''
+ IL_0014: ldarg.0
+ IL_0015: stloc.2
+ IL_0016: ldloc.1
+ IL_0017: stloc.3
+ IL_0018: ldarg.2
+ IL_0019: stloc.s V_4
+ IL_001b: ldloc.2
+ IL_001c: ldfld int32 ABC/Expr::item
+ IL_0021: ldloc.3
+ IL_0022: ldfld int32 ABC/Expr::item
+ IL_0027: ceq
+ IL_0029: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_002a: ldc.i4.0
+ IL_002b: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_002c: ldarg.1
+ IL_002d: ldnull
+ IL_002e: cgt.un
+ IL_0030: ldc.i4.0
+ IL_0031: ceq
+ IL_0033: ret
+ } // end of method Expr::Equals
+
+ .method public hidebysig virtual final
+ instance bool Equals(class ABC/Expr obj) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 43 (0x2b)
+ .maxstack 4
+ .locals init ([0] class ABC/Expr V_0,
+ [1] class ABC/Expr V_1)
+ .line 100001,100001 : 0,0 ''
+ IL_0000: ldarg.0
+ IL_0001: ldnull
+ IL_0002: cgt.un
+ IL_0004: brfalse.s IL_0023
+
+ .line 100001,100001 : 0,0 ''
+ IL_0006: ldarg.1
+ IL_0007: ldnull
+ IL_0008: cgt.un
+ IL_000a: brfalse.s IL_0021
+
+ .line 100001,100001 : 0,0 ''
+ IL_000c: ldarg.0
+ IL_000d: pop
+ .line 100001,100001 : 0,0 ''
+ IL_000e: ldarg.0
+ IL_000f: stloc.0
+ IL_0010: ldarg.1
+ IL_0011: stloc.1
+ IL_0012: ldloc.0
+ IL_0013: ldfld int32 ABC/Expr::item
+ IL_0018: ldloc.1
+ IL_0019: ldfld int32 ABC/Expr::item
+ IL_001e: ceq
+ IL_0020: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0021: ldc.i4.0
+ IL_0022: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0023: ldarg.1
+ IL_0024: ldnull
+ IL_0025: cgt.un
+ IL_0027: ldc.i4.0
+ IL_0028: ceq
+ IL_002a: ret
+ } // end of method Expr::Equals
+
+ .method public hidebysig virtual final
+ instance bool Equals(object obj) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 20 (0x14)
+ .maxstack 4
+ .locals init ([0] class ABC/Expr V_0)
+ .line 6,6 : 14,18 ''
+ IL_0000: ldarg.1
+ IL_0001: isinst ABC/Expr
+ IL_0006: stloc.0
+ IL_0007: ldloc.0
+ IL_0008: brfalse.s IL_0012
+
+ .line 100001,100001 : 0,0 ''
+ IL_000a: ldarg.0
+ IL_000b: ldloc.0
+ IL_000c: callvirt instance bool ABC/Expr::Equals(class ABC/Expr)
+ IL_0011: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0012: ldc.i4.0
+ IL_0013: ret
+ } // end of method Expr::Equals
+
+ .property instance int32 Tag()
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .get instance int32 ABC/Expr::get_Tag()
+ } // end of property Expr::Tag
+ .property instance int32 Item()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags,
+ int32,
+ int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 )
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .get instance int32 ABC/Expr::get_Item()
+ } // end of property Expr::Item
+ } // end of class Expr
+
+ .class auto ansi serializable nested public beforefieldinit MyExn
+ extends [mscorlib]System.Exception
+ implements [mscorlib]System.Collections.IStructuralEquatable
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 )
+ .field assembly int32 Data0@
+ .method public specialname rtspecialname
+ instance void .ctor(int32 data0) cil managed
+ {
+ // Code size 14 (0xe)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Exception::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: ldarg.1
+ IL_0008: stfld int32 ABC/MyExn::Data0@
+ IL_000d: ret
+ } // end of method MyExn::.ctor
+
+ .method public specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Exception::.ctor()
+ IL_0006: ret
+ } // end of method MyExn::.ctor
+
+ .method family specialname rtspecialname
+ instance void .ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo info,
+ valuetype [mscorlib]System.Runtime.Serialization.StreamingContext context) cil managed
+ {
+ // Code size 9 (0x9)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: ldarg.2
+ IL_0003: call instance void [mscorlib]System.Exception::.ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo,
+ valuetype [mscorlib]System.Runtime.Serialization.StreamingContext)
+ IL_0008: ret
+ } // end of method MyExn::.ctor
+
+ .method public hidebysig specialname
+ instance int32 get_Data0() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld int32 ABC/MyExn::Data0@
+ IL_0006: ret
+ } // end of method MyExn::get_Data0
+
+ .method public hidebysig virtual instance int32
+ GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 40 (0x28)
+ .maxstack 7
+ .locals init ([0] int32 V_0,
+ [1] class [mscorlib]System.Collections.IEqualityComparer V_1)
+ .line 100001,100001 : 0,0 ''
+ IL_0000: ldarg.0
+ IL_0001: ldnull
+ IL_0002: cgt.un
+ IL_0004: brfalse.s IL_0026
+
+ .line 100001,100001 : 0,0 ''
+ IL_0006: ldc.i4.0
+ IL_0007: stloc.0
+ IL_0008: ldc.i4 0x9e3779b9
+ IL_000d: ldarg.1
+ IL_000e: stloc.1
+ IL_000f: ldarg.0
+ IL_0010: castclass ABC/MyExn
+ IL_0015: call instance int32 ABC/MyExn::get_Data0()
+ IL_001a: ldloc.0
+ IL_001b: ldc.i4.6
+ IL_001c: shl
+ IL_001d: ldloc.0
+ IL_001e: ldc.i4.2
+ IL_001f: shr
+ IL_0020: add
+ IL_0021: add
+ IL_0022: add
+ IL_0023: stloc.0
+ IL_0024: ldloc.0
+ IL_0025: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0026: ldc.i4.0
+ IL_0027: ret
+ } // end of method MyExn::GetHashCode
+
+ .method public hidebysig virtual instance int32
+ GetHashCode() cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 12 (0xc)
+ .maxstack 8
+ .line 7,7 : 19,24 ''
+ IL_0000: ldarg.0
+ IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer()
+ IL_0006: callvirt instance int32 ABC/MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer)
+ IL_000b: ret
+ } // end of method MyExn::GetHashCode
+
+ .method public hidebysig virtual instance bool
+ Equals(object obj,
+ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 67 (0x43)
+ .maxstack 4
+ .locals init ([0] class [mscorlib]System.Exception V_0,
+ [1] class [mscorlib]System.Exception V_1,
+ [2] class [mscorlib]System.Collections.IEqualityComparer V_2)
+ .line 100001,100001 : 0,0 ''
+ IL_0000: ldarg.0
+ IL_0001: ldnull
+ IL_0002: cgt.un
+ IL_0004: brfalse.s IL_003b
+
+ .line 100001,100001 : 0,0 ''
+ IL_0006: ldarg.1
+ IL_0007: isinst [mscorlib]System.Exception
+ IL_000c: stloc.0
+ IL_000d: ldloc.0
+ IL_000e: brfalse.s IL_0039
+
+ .line 100001,100001 : 0,0 ''
+ IL_0010: ldloc.0
+ IL_0011: stloc.1
+ IL_0012: ldloc.0
+ IL_0013: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object)
+ IL_0018: brtrue.s IL_001c
+
+ IL_001a: br.s IL_0037
+
+ .line 100001,100001 : 0,0 ''
+ IL_001c: ldarg.2
+ IL_001d: stloc.2
+ IL_001e: ldarg.0
+ IL_001f: castclass ABC/MyExn
+ IL_0024: call instance int32 ABC/MyExn::get_Data0()
+ IL_0029: ldloc.1
+ IL_002a: castclass ABC/MyExn
+ IL_002f: call instance int32 ABC/MyExn::get_Data0()
+ IL_0034: ceq
+ IL_0036: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0037: ldc.i4.0
+ IL_0038: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0039: ldc.i4.0
+ IL_003a: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_003b: ldarg.1
+ IL_003c: ldnull
+ IL_003d: cgt.un
+ IL_003f: ldc.i4.0
+ IL_0040: ceq
+ IL_0042: ret
+ } // end of method MyExn::Equals
+
+ .method public hidebysig instance bool
+ Equals(class [mscorlib]System.Exception obj) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 59 (0x3b)
+ .maxstack 8
+ .line 100001,100001 : 0,0 ''
+ IL_0000: ldarg.0
+ IL_0001: ldnull
+ IL_0002: cgt.un
+ IL_0004: brfalse.s IL_0033
+
+ .line 100001,100001 : 0,0 ''
+ IL_0006: ldarg.1
+ IL_0007: ldnull
+ IL_0008: cgt.un
+ IL_000a: brfalse.s IL_0031
+
+ .line 100001,100001 : 0,0 ''
+ IL_000c: ldarg.1
+ IL_000d: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object)
+ IL_0012: brtrue.s IL_0016
+
+ IL_0014: br.s IL_002f
+
+ .line 100001,100001 : 0,0 ''
+ IL_0016: ldarg.0
+ IL_0017: castclass ABC/MyExn
+ IL_001c: call instance int32 ABC/MyExn::get_Data0()
+ IL_0021: ldarg.1
+ IL_0022: castclass ABC/MyExn
+ IL_0027: call instance int32 ABC/MyExn::get_Data0()
+ IL_002c: ceq
+ IL_002e: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_002f: ldc.i4.0
+ IL_0030: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0031: ldc.i4.0
+ IL_0032: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0033: ldarg.1
+ IL_0034: ldnull
+ IL_0035: cgt.un
+ IL_0037: ldc.i4.0
+ IL_0038: ceq
+ IL_003a: ret
+ } // end of method MyExn::Equals
+
+ .method public hidebysig virtual instance bool
+ Equals(object obj) cil managed
+ {
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ // Code size 20 (0x14)
+ .maxstack 4
+ .locals init ([0] class [mscorlib]System.Exception V_0)
+ .line 7,7 : 19,24 ''
+ IL_0000: ldarg.1
+ IL_0001: isinst [mscorlib]System.Exception
+ IL_0006: stloc.0
+ IL_0007: ldloc.0
+ IL_0008: brfalse.s IL_0012
+
+ .line 100001,100001 : 0,0 ''
+ IL_000a: ldarg.0
+ IL_000b: ldloc.0
+ IL_000c: callvirt instance bool ABC/MyExn::Equals(class [mscorlib]System.Exception)
+ IL_0011: ret
+
+ .line 100001,100001 : 0,0 ''
+ IL_0012: ldc.i4.0
+ IL_0013: ret
+ } // end of method MyExn::Equals
+
+ .property instance int32 Data0()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags,
+ int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 )
+ .get instance int32 ABC/MyExn::get_Data0()
+ } // end of property MyExn::Data0
+ } // end of class MyExn
+
+ .class auto ansi serializable nested public A
+ extends [mscorlib]System.Object
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field assembly string x
+ .method public specialname rtspecialname
+ instance void .ctor(string x) cil managed
+ {
+ // Code size 16 (0x10)
+ .maxstack 8
+ .line 100001,100001 : 0,0 ''
+ IL_0000: ldarg.0
+ IL_0001: callvirt instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: pop
+ .line 8,8 : 16,17 ''
+ IL_0008: ldarg.0
+ IL_0009: ldarg.1
+ IL_000a: stfld string ABC/A::x
+ .line 8,8 : 14,15 ''
+ IL_000f: ret
+ } // end of method A::.ctor
+
+ .method public hidebysig specialname
+ instance string get_X() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ .line 8,8 : 42,43 ''
+ IL_0000: ldarg.0
+ IL_0001: ldfld string ABC/A::x
+ IL_0006: ret
+ } // end of method A::get_X
+
+ .property instance string X()
+ {
+ .get instance string ABC/A::get_X()
+ } // end of property A::X
+ } // end of class A
+
+ .class abstract auto ansi sealed nested public ABC
+ extends [mscorlib]System.Object
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
+ .class auto autochar serializable sealed nested public beforefieldinit Expr
+ extends [mscorlib]System.Object
+ implements class [mscorlib]System.IEquatable`1