diff --git a/.fantomasignore b/.fantomasignore
index a4802164d9b..20249273f54 100644
--- a/.fantomasignore
+++ b/.fantomasignore
@@ -117,6 +117,9 @@ src/Compiler/Facilities/AsyncMemoize.fsi
src/Compiler/Facilities/AsyncMemoize.fs
src/Compiler/AbstractIL/il.fs
+src/Compiler/Driver/GraphChecking/Graph.fsi
+src/Compiler/Driver/GraphChecking/Graph.fs
+
# Fantomas limitations on implementation files (to investigate)
src/Compiler/AbstractIL/ilwrite.fs
diff --git a/FSharpTests.Directory.Build.targets b/FSharpTests.Directory.Build.targets
index 075321e3fb5..2e0b335b411 100644
--- a/FSharpTests.Directory.Build.targets
+++ b/FSharpTests.Directory.Build.targets
@@ -7,33 +7,35 @@
Returns=""
DependsOnTargets="$(CoreCompileDependsOn)"
>
-
-
-
+
+
+
+
<_CoreCompileResourceInputs Remove="@(_CoreCompileResourceInputs)" />
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index b49d6e126b6..1e5aaebbdf9 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -29,7 +29,7 @@ variables:
# Should be 'current' release branch name, i.e. 'release/dev17.10' in dotnet/fsharp/refs/heads/main, 'release/dev17.10' in dotnet/fsharp/refs/heads/release/dev17.10 and 'release/dev17.9' in dotnet/fsharp/refs/heads/release/dev17.9
# Should **never** be 'main' in dotnet/fsharp/refs/heads/main, since it will start inserting to VS twice.
- name: FSharpReleaseBranchName
- value: release/dev17.12
+ value: release/dev17.13
# VS Insertion branch name (NOT the same as F# branch)
# Should be previous release branch or 'main' in 'main' and 'main' in release branch
# (since for all *new* release branches we insert into VS main and for all *previous* releases we insert into corresponding VS release),
@@ -73,6 +73,9 @@ extends:
sbom:
enabled: false # VS SBOM is generated with other steps
justificationForDisabling: 'SBOM for F# is generated via build process. Will be migrated at later date.'
+ tsa:
+ enabled: true
+ configFile: '$(Build.SourcesDirectory)/eng/TSAConfig.gdntsa'
sourceAnalysisPool:
name: NetCore1ESPool-Svc-Internal
image: 1es-windows-2022
@@ -85,7 +88,7 @@ extends:
# Signed build #
#-------------------------------------------------------------------------------------------------------------------#
# Localization: we only run it for specific release branches
- - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/dev17.12') }}:
+ - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/dev17.13') }}:
- template: /eng/common/templates-official/job/onelocbuild.yml@self
parameters:
MirrorRepo: fsharp
diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
index b98195c81d7..d350b30edbe 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
@@ -35,10 +35,11 @@
* Enable FSharp 9.0 Language Version ([Issue #17497](https://github.com/dotnet/fsharp/issues/17438)), [PR](https://github.com/dotnet/fsharp/pull/17500)))
* Enable LanguageFeature.EnforceAttributeTargets in F# 9.0. ([Issue #17514](https://github.com/dotnet/fsharp/issues/17558), [PR #17516](https://github.com/dotnet/fsharp/pull/17558))
* Parser: better recovery for unfinished patterns ([PR #17231](https://github.com/dotnet/fsharp/pull/17231), [PR #17232](https://github.com/dotnet/fsharp/pull/17232)))
-* Enable consuming generic arguments defined as `allows ref struct` in C# ([Issue #17597](https://github.com/dotnet/fsharp/issues/17597)
+* Enable consuming generic arguments defined as `allows ref struct` in C# ([Issue #17597](https://github.com/dotnet/fsharp/issues/17597), display them in tooltips [PR #17706](https://github.com/dotnet/fsharp/pull/17706))
* Trivia for SynTypeConstraint.WhereTyparNotSupportsNull. ([Issue #17721](https://github.com/dotnet/fsharp/issues/17721), [PR #17745](https://github.com/dotnet/fsharp/pull/17745))
* Trivia for SynType.WithNull. ([Issue #17720](https://github.com/dotnet/fsharp/issues/17720), [PR #17745](https://github.com/dotnet/fsharp/pull/17745))
+
### Changed
* Change compiler default setting realsig+ when building assemblies ([Issue #17384](https://github.com/dotnet/fsharp/issues/17384), [PR #17378](https://github.com/dotnet/fsharp/pull/17385))
diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
index f282c6ae800..fe3cde0444a 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
@@ -1,12 +1,14 @@
### Fixed
+* Fix false negatives for passing null to "obj" arguments. Only "obj | null" can now subsume any type ([PR #17757](https://github.com/dotnet/fsharp/pull/17757))
* Fix internal error when calling 'AddSingleton' and other overloads only differing in generic arity ([PR #17804](https://github.com/dotnet/fsharp/pull/17804))
* Fix extension methods support for non-reference system assemblies ([PR #17799](https://github.com/dotnet/fsharp/pull/17799))
-* Ensure `frameworkTcImportsCache` mutations are threadsafe. ([PR #17795](https://github.com/dotnet/fsharp/pull/17795))
-
+* Ensure `frameworkTcImportsCache` mutations are thread-safe. ([PR #17795](https://github.com/dotnet/fsharp/pull/17795))
+* Fix concurrency issue in `ILPreTypeDefImpl` ([PR #17812](https://github.com/dotnet/fsharp/pull/17812))
### Added
+* Support literal attribute on decimals ([PR #17769](https://github.com/dotnet/fsharp/pull/17769))
### Changed
@@ -14,6 +16,8 @@
* Remove non-functional useSyntaxTreeCache option. ([PR #17768](https://github.com/dotnet/fsharp/pull/17768))
* Better ranges for CE `let!` and `use!` error reporting. ([PR #17712](https://github.com/dotnet/fsharp/pull/17712))
* Better ranges for CE `do!` error reporting. ([PR #17779](https://github.com/dotnet/fsharp/pull/17779))
+* Better ranges for CE `return, yield, return! and yield!` error reporting. ([PR #17792](https://github.com/dotnet/fsharp/pull/17792))
* Better ranges for CE `match!`. ([PR #17789](https://github.com/dotnet/fsharp/pull/17789))
+* Better ranges for CE `use` error reporting. ([PR #17811](https://github.com/dotnet/fsharp/pull/17811))
### Breaking Changes
diff --git a/docs/release-notes/.VisualStudio/17.12.md b/docs/release-notes/.VisualStudio/17.12.md
index 83df7173b2e..690ec481a20 100644
--- a/docs/release-notes/.VisualStudio/17.12.md
+++ b/docs/release-notes/.VisualStudio/17.12.md
@@ -5,9 +5,10 @@
### Added
### Changed
+* Fix unwanted navigation on hover [PR #17592](https://github.com/dotnet/fsharp/pull/17592)
+* Update `RemoveReturnOrYield` code fix range calculation [PR #17792](https://github.com/dotnet/fsharp/pull/17792)
* Fix unwanted navigation on hover [PR #17592](https://github.com/dotnet/fsharp/pull/17592))
* Remove non-functional useSyntaxTreeCache option. ([PR #17768](https://github.com/dotnet/fsharp/pull/17768))
-
### Breaking Changes
* Enable FSharp 9.0 Language Version ([Issue #17497](https://github.com/dotnet/fsharp/issues/17438)), [PR](https://github.com/dotnet/fsharp/pull/17500)))
diff --git a/eng/TSAConfig.gdntsa b/eng/TSAConfig.gdntsa
new file mode 100644
index 00000000000..f4621b68272
--- /dev/null
+++ b/eng/TSAConfig.gdntsa
@@ -0,0 +1,16 @@
+{
+ "codebaseName": "FSharp-GitHub",
+ "notificationAliases": [
+ "fsharp@microsoft.com"
+ ],
+ "codebaseAdmins": [
+ "EUROPE\\vlza",
+ "REDMOND\\kevinransom",
+ "EUROPE\\tomasgrosup"
+ ],
+ "instanceUrl": "https://devdiv.visualstudio.com",
+ "projectName": "DevDiv",
+ "areaPath": "DevDiv\\FSharp",
+ "iterationPath": "DevDiv",
+ "allTools": true
+}
diff --git a/eng/Versions.props b/eng/Versions.props
index 614ced1604c..d89aec3f3cd 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -43,7 +43,7 @@
$(FSCorePackageVersionValue)-$(PreReleaseVersionLabel).*
- 12
+ 13
9
$(FSBuildVersion)
$(FSRevisionVersion)
@@ -53,7 +53,7 @@
17
- 12
+ 13
$(VSMajorVersion).0
$(VSMajorVersion).$(VSMinorVersion).0
$(VSAssemblyVersionPrefix).0
diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs
index 3c70f5eb93f..82faea51c5e 100644
--- a/src/Compiler/AbstractIL/il.fs
+++ b/src/Compiler/AbstractIL/il.fs
@@ -2913,35 +2913,17 @@ and [] ILPreTypeDef =
/// This is a memory-critical class. Very many of these objects get allocated and held to represent the contents of .NET assemblies.
and [] ILPreTypeDefImpl(nameSpace: string list, name: string, metadataIndex: int32, storage: ILTypeDefStored) =
- let mutable store: ILTypeDef = Unchecked.defaultof<_>
- let mutable storage = storage
+ let stored =
+ lazy
+ match storage with
+ | ILTypeDefStored.Given td -> td
+ | ILTypeDefStored.Computed f -> f ()
+ | ILTypeDefStored.Reader f -> f metadataIndex
interface ILPreTypeDef with
member _.Namespace = nameSpace
member _.Name = name
-
- member x.GetTypeDef() =
- match box store with
- | null ->
- let syncObj = storage
- Monitor.Enter(syncObj)
-
- try
- match box store with
- | null ->
- let value =
- match storage with
- | ILTypeDefStored.Given td -> td
- | ILTypeDefStored.Computed f -> f ()
- | ILTypeDefStored.Reader f -> f metadataIndex
-
- store <- value
- storage <- Unchecked.defaultof<_>
- value
- | _ -> store
- finally
- Monitor.Exit(syncObj)
- | _ -> store
+ member x.GetTypeDef() = stored.Value
and ILTypeDefStored =
| Given of ILTypeDef
diff --git a/src/Compiler/AbstractIL/ilreflect.fs b/src/Compiler/AbstractIL/ilreflect.fs
index 2a65eb8679b..5a52ddc017a 100644
--- a/src/Compiler/AbstractIL/ilreflect.fs
+++ b/src/Compiler/AbstractIL/ilreflect.fs
@@ -277,7 +277,7 @@ type TypeBuilder with
match m with
| null -> raise (MissingMethodException nm)
- | m -> m.Invoke(null, args)
+ | m -> m.Invoke(null, (args: obj array))
member typB.SetCustomAttributeAndLog(cinfo, bytes) =
if logRefEmitCalls then
diff --git a/src/Compiler/Checking/AttributeChecking.fs b/src/Compiler/Checking/AttributeChecking.fs
index a91ace98d4a..8ef659ac20e 100644
--- a/src/Compiler/Checking/AttributeChecking.fs
+++ b/src/Compiler/Checking/AttributeChecking.fs
@@ -466,9 +466,9 @@ let MethInfoIsUnseen g (m: range) (ty: TType) minfo =
let isUnseenByHidingAttribute () =
#if !NO_TYPEPROVIDERS
- not (isObjTy g ty) &&
+ not (isObjTyAnyNullness g ty) &&
isAppTy g ty &&
- isObjTy g minfo.ApparentEnclosingType &&
+ isObjTyAnyNullness g minfo.ApparentEnclosingType &&
let tcref = tcrefOfAppTy g ty
match tcref.TypeReprInfo with
| TProvidedTypeRepr info ->
diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs
index 196a62c3fec..6c79c33be97 100644
--- a/src/Compiler/Checking/ConstraintSolver.fs
+++ b/src/Compiler/Checking/ConstraintSolver.fs
@@ -1024,6 +1024,7 @@ and SolveTypMeetsTyparConstraints (csenv: ConstraintSolverEnv) ndeep m2 trace ty
| TyparConstraint.IsDelegate(aty, bty, m2) -> SolveTypeIsDelegate csenv ndeep m2 trace ty aty bty
| TyparConstraint.IsNonNullableStruct m2 -> SolveTypeIsNonNullableValueType csenv ndeep m2 trace ty
| TyparConstraint.IsUnmanaged m2 -> SolveTypeIsUnmanaged csenv ndeep m2 trace ty
+ | TyparConstraint.AllowsRefStruct _ -> CompleteD
| TyparConstraint.IsReferenceType m2 -> SolveTypeIsReferenceType csenv ndeep m2 trace ty
| TyparConstraint.RequiresDefaultConstructor m2 -> SolveTypeRequiresDefaultConstructor csenv ndeep m2 trace ty
| TyparConstraint.SimpleChoice(tys, m2) -> SolveTypeChoice csenv ndeep m2 trace ty tys
@@ -1224,164 +1225,165 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr
TransactMemberConstraintSolution traitInfo trace traitSln
| _ -> ()
- if ty1 === ty2 then CompleteD else
+ if ty1 === ty2 then
+ CompleteD
+ else
+ let canShortcut = not trace.HasTrace
+ let sty1 = stripTyEqnsA csenv.g canShortcut ty1
+ let sty2 = stripTyEqnsA csenv.g canShortcut ty2
+
+ let csenv =
+ match ty1 with
+ | TType.TType_var(r,_) when r.typar_flags.IsSupportsNullFlex ->
+ { csenv with IsSupportsNullFlex = true}
+ | _ -> csenv
+
+ match sty1, sty2 with
+ // type vars inside forall-types may be alpha-equivalent
+ | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when typarEq tp1 tp2 || (match aenv.EquivTypars.TryFind tp1 with | Some tpTy1 when typeEquiv g tpTy1 ty2 -> true | _ -> false) ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
+
+ | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when PreferUnifyTypar tp1 tp2 ->
+ match nullness1.TryEvaluate(), nullness2.TryEvaluate() with
+ // Unifying 'T1? and 'T2?
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty1 (TType_var (tp2, g.knownWithoutNull))
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithoutNull ->
+ let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false)
+ trackErrors {
+ do! SolveTypeEqualsType csenv ndeep m2 trace cxsln sty2 (TType_var(tpNew, g.knownWithNull))
+ do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty1
+ }
+ //// Unifying 'T1 % and 'T2 %
+ //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
+ // SolveTyparEqualsType csenv ndeep m2 trace sty1 (TType_var (tp2, g.knownWithoutNull))
+ | _ ->
+ trackErrors {
+ do! SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2
+ let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1
+ do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 nullness2
+ }
- let canShortcut = not trace.HasTrace
- let sty1 = stripTyEqnsA csenv.g canShortcut ty1
- let sty2 = stripTyEqnsA csenv.g canShortcut ty2
- let csenv =
- match ty1 with
- | TType.TType_var(r,_) when r.typar_flags.IsSupportsNullFlex ->
- { csenv with IsSupportsNullFlex = true}
- | _ -> csenv
-
- match sty1, sty2 with
- // type vars inside forall-types may be alpha-equivalent
- | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when typarEq tp1 tp2 || (match aenv.EquivTypars.TryFind tp1 with | Some tpTy1 when typeEquiv g tpTy1 ty2 -> true | _ -> false) ->
- SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
-
- | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when PreferUnifyTypar tp1 tp2 ->
- match nullness1.TryEvaluate(), nullness2.TryEvaluate() with
- // Unifying 'T1? and 'T2?
- | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
- SolveTyparEqualsType csenv ndeep m2 trace sty1 (TType_var (tp2, g.knownWithoutNull))
- | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithoutNull ->
- let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false)
- trackErrors {
- do! SolveTypeEqualsType csenv ndeep m2 trace cxsln sty2 (TType_var(tpNew, g.knownWithNull))
- do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty1
- }
- //// Unifying 'T1 % and 'T2 %
- //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
- // SolveTyparEqualsType csenv ndeep m2 trace sty1 (TType_var (tp2, g.knownWithoutNull))
- | _ ->
- trackErrors {
- do! SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2
- let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1
- do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 nullness2
- }
+ | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when not csenv.MatchingOnly && PreferUnifyTypar tp2 tp1 ->
+ match nullness1.TryEvaluate(), nullness2.TryEvaluate() with
+ // Unifying 'T1? and 'T2?
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty2 (TType_var (tp1, g.knownWithoutNull))
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithoutNull ->
+ let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false)
+ trackErrors {
+ do! SolveTypeEqualsType csenv ndeep m2 trace cxsln sty2 (TType_var(tpNew, g.knownWithNull))
+ do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty1
+ }
+ //// Unifying 'T1 % and 'T2 %
+ //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
+ // SolveTyparEqualsType csenv ndeep m2 trace sty2 (TType_var (tp1, g.knownWithoutNull))
+ | _ ->
+ // Unifying 'T1 ? and 'T2 %
+ // Unifying 'T1 % and 'T2 ?
+ trackErrors {
+ do! SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1
+ let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
+ do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2
+ }
+ | TType_var (tp1, nullness1), _ when not (IsRigid csenv tp1) ->
+ match nullness1.TryEvaluate(), (nullnessOfTy g sty2).TryEvaluate() with
+ // Unifying 'T1? and 'T2?
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2)
+ | ValueSome NullnessInfo.WithoutNull, ValueSome NullnessInfo.WithoutNull when
+ csenv.IsSupportsNullFlex &&
+ isAppTy g sty2 &&
+ tp1.Constraints |> List.exists (function TyparConstraint.SupportsNull _ -> true | _ -> false) ->
+ let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false)
+ trackErrors {
+ do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty2
+ do! SolveTypeEqualsType csenv ndeep m2 trace cxsln ty1 (TType_var(tpNew, g.knownWithNull))
+ }
+ // Unifying 'T1 % and 'T2 %
+ //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
+ // SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2)
+ | _ ->
+ trackErrors {
+ do! SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2
+ let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1
+ do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 (nullnessOfTy g sty2)
+ }
- | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when not csenv.MatchingOnly && PreferUnifyTypar tp2 tp1 ->
- match nullness1.TryEvaluate(), nullness2.TryEvaluate() with
- // Unifying 'T1? and 'T2?
- | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
- SolveTyparEqualsType csenv ndeep m2 trace sty2 (TType_var (tp1, g.knownWithoutNull))
- | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithoutNull ->
- let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false)
- trackErrors {
- do! SolveTypeEqualsType csenv ndeep m2 trace cxsln sty2 (TType_var(tpNew, g.knownWithNull))
- do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty1
- }
- //// Unifying 'T1 % and 'T2 %
- //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
- // SolveTyparEqualsType csenv ndeep m2 trace sty2 (TType_var (tp1, g.knownWithoutNull))
- | _ ->
- // Unifying 'T1 ? and 'T2 %
- // Unifying 'T1 % and 'T2 ?
+ | _, TType_var (tp2, nullness2) when not csenv.MatchingOnly && not (IsRigid csenv tp2) ->
+ match (nullnessOfTy g sty1).TryEvaluate(), nullness2.TryEvaluate() with
+ // Unifying 'T1? and 'T2?
+ | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
+ SolveTyparEqualsType csenv ndeep m2 trace sty2 (replaceNullnessOfTy g.knownWithoutNull sty1)
+ // Unifying 'T1 % and 'T2 %
+ //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
+ // SolveTyparEqualsType csenv ndeep m2 trace sty2 (replaceNullnessOfTy g.knownWithoutNull sty1)
+ | _ ->
+ trackErrors {
+ do! SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1
+ let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
+ do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2
+ }
+
+ // Catch float<_>=float<1>, float32<_>=float32<1> and decimal<_>=decimal<1>
+ | (_, TType_app (tc2, [ms2], _)) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2])) ->
trackErrors {
- do! SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1
- let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
- do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2
+ do! SolveTypeEqualsType csenv ndeep m2 trace None (TType_measure Measure.One) ms2
+ do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
}
- | TType_var (tp1, nullness1), _ when not (IsRigid csenv tp1) ->
- match nullness1.TryEvaluate(), (nullnessOfTy g sty2).TryEvaluate() with
- // Unifying 'T1? and 'T2?
- | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
- SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2)
- | ValueSome NullnessInfo.WithoutNull, ValueSome NullnessInfo.WithoutNull when
- csenv.IsSupportsNullFlex &&
- isAppTy g sty2 &&
- tp1.Constraints |> List.exists (function TyparConstraint.SupportsNull _ -> true | _ -> false) ->
- let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false)
- trackErrors {
- do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty2
- do! SolveTypeEqualsType csenv ndeep m2 trace cxsln ty1 (TType_var(tpNew, g.knownWithNull))
- }
- // Unifying 'T1 % and 'T2 %
- //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
- // SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2)
- | _ ->
+ | (TType_app (tc1, [ms1], _), _) when (tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1])) ->
trackErrors {
- do! SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2
- let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1
- do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 (nullnessOfTy g sty2)
+ do! SolveTypeEqualsType csenv ndeep m2 trace None ms1 (TType_measure Measure.One)
+ do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
}
- | _, TType_var (tp2, nullness2) when not csenv.MatchingOnly && not (IsRigid csenv tp2) ->
- match (nullnessOfTy g sty1).TryEvaluate(), nullness2.TryEvaluate() with
- // Unifying 'T1? and 'T2?
- | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull ->
- SolveTyparEqualsType csenv ndeep m2 trace sty2 (replaceNullnessOfTy g.knownWithoutNull sty1)
- // Unifying 'T1 % and 'T2 %
- //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull ->
- // SolveTyparEqualsType csenv ndeep m2 trace sty2 (replaceNullnessOfTy g.knownWithoutNull sty1)
- | _ ->
+ | TType_app (tc1, l1, _), TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 ->
trackErrors {
- do! SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1
- let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
- do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2
+ do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
+ do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
}
+ | TType_app _, TType_app _ ->
+ localAbortD
- // Catch float<_>=float<1>, float32<_>=float32<1> and decimal<_>=decimal<1>
- | (_, TType_app (tc2, [ms2], _)) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2])) ->
- trackErrors {
- do! SolveTypeEqualsType csenv ndeep m2 trace None (TType_measure Measure.One) ms2
- do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
- }
-
- | (TType_app (tc1, [ms1], _), _) when (tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1])) ->
- trackErrors {
- do! SolveTypeEqualsType csenv ndeep m2 trace None ms1 (TType_measure Measure.One)
- do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
- }
-
- | TType_app (tc1, l1, _), TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 ->
- trackErrors {
- do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
- do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
- }
- | TType_app _, TType_app _ ->
- localAbortD
-
- | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) ->
- if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then
- ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2))
- else
- SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
+ | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) ->
+ if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then
+ ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2))
+ else
+ SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
- | TType_anon (anonInfo1, l1),TType_anon (anonInfo2, l2) ->
- trackErrors {
- do! SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2
- do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
- }
+ | TType_anon (anonInfo1, l1),TType_anon (anonInfo2, l2) ->
+ trackErrors {
+ do! SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2
+ do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
+ }
- | TType_fun (domainTy1, rangeTy1, nullness1), TType_fun (domainTy2, rangeTy2, nullness2) ->
- trackErrors {
- do! SolveFunTypeEqn csenv ndeep m2 trace None domainTy1 domainTy2 rangeTy1 rangeTy2
- do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
- }
+ | TType_fun (domainTy1, rangeTy1, nullness1), TType_fun (domainTy2, rangeTy2, nullness2) ->
+ trackErrors {
+ do! SolveFunTypeEqn csenv ndeep m2 trace None domainTy1 domainTy2 rangeTy1 rangeTy2
+ do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
+ }
- | TType_measure ms1, TType_measure ms2 ->
- UnifyMeasures csenv trace ms1 ms2
+ | TType_measure ms1, TType_measure ms2 ->
+ UnifyMeasures csenv trace ms1 ms2
- | TType_forall(tps1, bodyTy1), TType_forall(tps2, bodyTy2) ->
- if tps1.Length <> tps2.Length then
- localAbortD
- else
- let aenv = aenv.BindEquivTypars tps1 tps2
- let csenv = {csenv with EquivEnv = aenv }
- if not (typarsAEquiv g aenv tps1 tps2) then
+ | TType_forall(tps1, bodyTy1), TType_forall(tps2, bodyTy2) ->
+ if tps1.Length <> tps2.Length then
localAbortD
else
- SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace bodyTy1 bodyTy2
+ let aenv = aenv.BindEquivTypars tps1 tps2
+ let csenv = {csenv with EquivEnv = aenv }
+ if not (typarsAEquiv g aenv tps1 tps2) then
+ localAbortD
+ else
+ SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace bodyTy1 bodyTy2
- | TType_ucase (uc1, l1), TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 ->
- SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
+ | TType_ucase (uc1, l1), TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 ->
+ SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2
- | _ -> localAbortD
+ | _ -> localAbortD
and SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1 ty2 =
SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace None ty1 ty2
@@ -1454,132 +1456,136 @@ and SolveFunTypeEqn csenv ndeep m2 trace cxsln domainTy1 domainTy2 rangeTy1 rang
//
// "ty2 casts to ty1"
// "a value of type ty2 can be used where a value of type ty1 is expected"
-and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) cxsln ty1 ty2 =
- // 'a :> obj --->
+and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) cxsln ty1 ty2 =
let ndeep = ndeep + 1
let g = csenv.g
- if isObjTy g ty1 then CompleteD else
let canShortcut = not trace.HasTrace
- let sty1 = stripTyEqnsA csenv.g canShortcut ty1
- let sty2 = stripTyEqnsA csenv.g canShortcut ty2
- let amap = csenv.amap
- let aenv = csenv.EquivEnv
- let denv = csenv.DisplayEnv
+ // 'a :> objnull --->
+ if isObjNullTy g ty1 then
+ CompleteD
+ elif isObjTyAnyNullness g ty1 && not csenv.MatchingOnly && not(isTyparTy g ty2) then
+ let nullness t = t |> stripTyEqnsA g canShortcut |> nullnessOfTy g
+ SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullness ty1) (nullness ty2)
+ else
+ let sty1 = stripTyEqnsA csenv.g canShortcut ty1
+ let sty2 = stripTyEqnsA csenv.g canShortcut ty2
+ let amap = csenv.amap
+ let aenv = csenv.EquivEnv
+ let denv = csenv.DisplayEnv
- match sty1, sty2 with
- | TType_var (tp1, nullness1) , _ ->
- match aenv.EquivTypars.TryFind tp1 with
- | Some tpTy1 -> SolveTypeSubsumesType csenv ndeep m2 trace cxsln tpTy1 ty2
- | _ ->
- match sty2 with
- | TType_var (r2, nullness2) when typarEq tp1 r2 ->
- SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
- | TType_var (r2, nullness2) when not csenv.MatchingOnly ->
+ match sty1, sty2 with
+ | TType_var (tp1, nullness1) , _ ->
+ match aenv.EquivTypars.TryFind tp1 with
+ | Some tpTy1 -> SolveTypeSubsumesType csenv ndeep m2 trace cxsln tpTy1 ty2
+ | _ ->
+ match sty2 with
+ | TType_var (r2, nullness2) when typarEq tp1 r2 ->
+ SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2
+ | TType_var (r2, nullness2) when not csenv.MatchingOnly ->
+ trackErrors {
+ do! SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1
+ let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
+ do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2
+ }
+ | _ -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1 ty2
+
+ | _, TType_var (r2, nullness2) when not csenv.MatchingOnly ->
trackErrors {
do! SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1
let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
- do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2
+ do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2
}
- | _ -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1 ty2
-
- | _, TType_var (r2, nullness2) when not csenv.MatchingOnly ->
- trackErrors {
- do! SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1
- let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2
- do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2
- }
-
- | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) ->
- if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then
- ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2))
- else
- SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *)
- | TType_fun (domainTy1, rangeTy1, nullness1), TType_fun (domainTy2, rangeTy2, nullness2) ->
- // nb. can unify since no variance
- trackErrors {
- do! SolveFunTypeEqn csenv ndeep m2 trace cxsln domainTy1 domainTy2 rangeTy1 rangeTy2
- do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullness2
- }
- | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) ->
- trackErrors {
- do! SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2
- do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2
- }
- | TType_measure ms1, TType_measure ms2 ->
- UnifyMeasures csenv trace ms1 ms2
- // Enforce the identities float=float<1>, float32=float32<1> and decimal=decimal<1>
- | _, TType_app (tc2, [ms2], _) when tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2]) ->
- trackErrors {
- do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms2 (TType_measure Measure.One)
- do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
- }
-
- | TType_app (tc1, [ms1], _), _ when tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1]) ->
- trackErrors {
- do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms1 (TType_measure Measure.One)
- do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
- }
+ | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) ->
+ if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then
+ ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2))
+ else
+ SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *)
+ | TType_fun (domainTy1, rangeTy1, nullness1), TType_fun (domainTy2, rangeTy2, nullness2) ->
+ // nb. can unify since no variance
+ trackErrors {
+ do! SolveFunTypeEqn csenv ndeep m2 trace cxsln domainTy1 domainTy2 rangeTy1 rangeTy2
+ do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullness2
+ }
+ | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) ->
+ trackErrors {
+ do! SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2
+ do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2
+ }
+ | TType_measure ms1, TType_measure ms2 ->
+ UnifyMeasures csenv trace ms1 ms2
- // Special subsumption rule for byref tags
- | TType_app (tc1, l1, _) , TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 && g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tc1 ->
- match l1, l2 with
- | [ h1; tag1 ], [ h2; tag2 ] -> trackErrors {
- do! SolveTypeEqualsType csenv ndeep m2 trace None h1 h2
- match stripTyEqnsA csenv.g canShortcut tag1, stripTyEqnsA csenv.g canShortcut tag2 with
- | TType_app(tagc1, [], _), TType_app(tagc2, [], _)
- when (tyconRefEq g tagc2 g.byrefkind_InOut_tcr &&
- (tyconRefEq g tagc1 g.byrefkind_In_tcr || tyconRefEq g tagc1 g.byrefkind_Out_tcr) ) -> ()
- | _ -> return! SolveTypeEqualsType csenv ndeep m2 trace cxsln tag1 tag2
- }
- | _ -> SolveTypeEqualsTypeWithContravarianceEqns csenv ndeep m2 trace cxsln l1 l2 tc1.TyparsNoRange
-
- | TType_app (tc1, l1, _) , TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 ->
- trackErrors {
- do! SolveTypeEqualsTypeWithContravarianceEqns csenv ndeep m2 trace cxsln l1 l2 tc1.TyparsNoRange
- do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
- }
+ // Enforce the identities float=float<1>, float32=float32<1> and decimal=decimal<1>
+ | _, TType_app (tc2, [ms2], _) when tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2]) ->
+ trackErrors {
+ do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms2 (TType_measure Measure.One)
+ do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
+ }
- | TType_ucase (uc1, l1), TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 ->
- SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2
+ | TType_app (tc1, [ms1], _), _ when tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1]) ->
+ trackErrors {
+ do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms1 (TType_measure Measure.One)
+ do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
+ }
- | _ ->
- // By now we know the type is not a variable type
+ // Special subsumption rule for byref tags
+ | TType_app (tc1, l1, _) , TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 && g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tc1 ->
+ match l1, l2 with
+ | [ h1; tag1 ], [ h2; tag2 ] -> trackErrors {
+ do! SolveTypeEqualsType csenv ndeep m2 trace None h1 h2
+ match stripTyEqnsA csenv.g canShortcut tag1, stripTyEqnsA csenv.g canShortcut tag2 with
+ | TType_app(tagc1, [], _), TType_app(tagc2, [], _)
+ when (tyconRefEq g tagc2 g.byrefkind_InOut_tcr &&
+ (tyconRefEq g tagc1 g.byrefkind_In_tcr || tyconRefEq g tagc1 g.byrefkind_Out_tcr) ) -> ()
+ | _ -> return! SolveTypeEqualsType csenv ndeep m2 trace cxsln tag1 tag2
+ }
+ | _ -> SolveTypeEqualsTypeWithContravarianceEqns csenv ndeep m2 trace cxsln l1 l2 tc1.TyparsNoRange
- // C :> obj --->
- if isObjTy g ty1 then CompleteD else
-
- let m = csenv.m
+ | TType_app (tc1, l1, _) , TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 ->
+ trackErrors {
+ do! SolveTypeEqualsTypeWithContravarianceEqns csenv ndeep m2 trace cxsln l1 l2 tc1.TyparsNoRange
+ do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
+ }
- // 'a[] :> IList<'b> ---> 'a = 'b
- // 'a[] :> ICollection<'b> ---> 'a = 'b
- // 'a[] :> IEnumerable<'b> ---> 'a = 'b
- // 'a[] :> IReadOnlyList<'b> ---> 'a = 'b
- // 'a[] :> IReadOnlyCollection<'b> ---> 'a = 'b
- // Note we don't support co-variance on array types nor
- // the special .NET conversions for these types
- match ty1 with
- | AppTy g (tcref1, tinst1) when
- isArray1DTy g ty2 &&
- (tyconRefEq g tcref1 g.tcref_System_Collections_Generic_IList ||
- tyconRefEq g tcref1 g.tcref_System_Collections_Generic_ICollection ||
- tyconRefEq g tcref1 g.tcref_System_Collections_Generic_IReadOnlyList ||
- tyconRefEq g tcref1 g.tcref_System_Collections_Generic_IReadOnlyCollection ||
- tyconRefEq g tcref1 g.tcref_System_Collections_Generic_IEnumerable) ->
- match tinst1 with
- | [elemTy1] ->
- let elemTy2 = destArrayTy g ty2
- SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln elemTy1 elemTy2
- | _ -> error(InternalError("destArrayTy", m))
+ | TType_ucase (uc1, l1), TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 ->
+ SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2
| _ ->
- // D :> Head<_> --> C :> Head<_> for the
- // first interface or super-class C supported by D which
- // may feasibly convert to Head.
- match FindUniqueFeasibleSupertype g amap m ty1 ty2 with
- | None -> ErrorD(ConstraintSolverTypesNotInSubsumptionRelation(denv, ty1, ty2, m, m2))
- | Some t -> SolveTypeSubsumesType csenv ndeep m2 trace cxsln ty1 t
+ // By now we know the type is not a variable type
+ // C :> obj --->
+ if isObjNullTy g ty1 then
+ CompleteD
+ else
+ let m = csenv.m
+ // 'a[] :> IList<'b> ---> 'a = 'b
+ // 'a[] :> ICollection<'b> ---> 'a = 'b
+ // 'a[] :> IEnumerable<'b> ---> 'a = 'b
+ // 'a[] :> IReadOnlyList<'b> ---> 'a = 'b
+ // 'a[] :> IReadOnlyCollection<'b> ---> 'a = 'b
+ // Note we don't support co-variance on array types nor
+ // the special .NET conversions for these types
+ match ty1 with
+ | AppTy g (tcref1, tinst1) when
+ isArray1DTy g ty2 &&
+ (tyconRefEq g tcref1 g.tcref_System_Collections_Generic_IList ||
+ tyconRefEq g tcref1 g.tcref_System_Collections_Generic_ICollection ||
+ tyconRefEq g tcref1 g.tcref_System_Collections_Generic_IReadOnlyList ||
+ tyconRefEq g tcref1 g.tcref_System_Collections_Generic_IReadOnlyCollection ||
+ tyconRefEq g tcref1 g.tcref_System_Collections_Generic_IEnumerable) ->
+ match tinst1 with
+ | [elemTy1] ->
+ let elemTy2 = destArrayTy g ty2
+ SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln elemTy1 elemTy2
+ | _ -> error(InternalError("destArrayTy", m))
+
+ | _ ->
+ // D :> Head<_> --> C :> Head<_> for the
+ // first interface or super-class C supported by D which
+ // may feasibly convert to Head.
+ match FindUniqueFeasibleSupertype g amap m ty1 ty2 with
+ | None -> ErrorD(ConstraintSolverTypesNotInSubsumptionRelation(denv, ty1, ty2, m, m2))
+ | Some t -> SolveTypeSubsumesType csenv ndeep m2 trace cxsln ty1 t
and SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m2 trace cxsln ty1 ty2 =
let denv = csenv.DisplayEnv
@@ -1594,15 +1600,22 @@ and SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m2 trace cxsln ty1 ty2 =
and SolveTyparSubtypeOfType (csenv: ConstraintSolverEnv) ndeep m2 trace tp ty1 =
let g = csenv.g
- if isObjTy g ty1 then CompleteD
- elif typeEquiv g ty1 (mkTyparTy tp) then CompleteD
+ if isObjNullTy g ty1 then
+ CompleteD
+ elif isObjTyAnyNullness g ty1 then
+ AddConstraint csenv ndeep m2 trace tp (TyparConstraint.NotSupportsNull csenv.m)
+ elif typeEquiv g ty1 (mkTyparTy tp) then
+ CompleteD
elif isSealedTy g ty1 then
SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace (mkTyparTy tp) ty1
else
AddConstraint csenv ndeep m2 trace tp (TyparConstraint.CoercesTo(ty1, csenv.m))
and DepthCheck ndeep m =
- if ndeep > 300 then error(Error(FSComp.SR.csTypeInferenceMaxDepth(), m)) else CompleteD
+ if ndeep > 300 then
+ error(Error(FSComp.SR.csTypeInferenceMaxDepth(), m))
+ else
+ CompleteD
// If this is a type that's parameterized on a unit-of-measure (expected to be numeric), unify its measure with 1
and SolveDimensionlessNumericType (csenv: ConstraintSolverEnv) ndeep m2 trace ty =
@@ -1624,434 +1637,435 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
trackErrors {
let (TTrait(supportTys, nm, memFlags, traitObjAndArgTys, retTy, source, sln)) = traitInfo
// Do not re-solve if already solved
- if sln.Value.IsSome then return true else
-
- let g = csenv.g
- let m = csenv.m
- let amap = csenv.amap
- let aenv = csenv.EquivEnv
- let denv = csenv.DisplayEnv
+ if sln.Value.IsSome then
+ return true
+ else
+ let g = csenv.g
+ let m = csenv.m
+ let amap = csenv.amap
+ let aenv = csenv.EquivEnv
+ let denv = csenv.DisplayEnv
- let ndeep = ndeep + 1
- do! DepthCheck ndeep m
+ let ndeep = ndeep + 1
+ do! DepthCheck ndeep m
- // Remove duplicates from the set of types in the support
- let supportTys = ListSet.setify (typeAEquiv g aenv) supportTys
+ // Remove duplicates from the set of types in the support
+ let supportTys = ListSet.setify (typeAEquiv g aenv) supportTys
- // Rebuild the trait info after removing duplicates
- let traitInfo = traitInfo.WithSupportTypes supportTys
- let retTy = GetFSharpViewOfReturnType g retTy
+ // Rebuild the trait info after removing duplicates
+ let traitInfo = traitInfo.WithSupportTypes supportTys
+ let retTy = GetFSharpViewOfReturnType g retTy
- // Assert the object type if the constraint is for an instance member
- if memFlags.IsInstance then
- match supportTys, traitObjAndArgTys with
- | [ty], h :: _ -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace h ty
- | _ -> do! ErrorD (ConstraintSolverError(FSComp.SR.csExpectedArguments(), m, m2))
+ // Assert the object type if the constraint is for an instance member
+ if memFlags.IsInstance then
+ match supportTys, traitObjAndArgTys with
+ | [ty], h :: _ -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace h ty
+ | _ -> do! ErrorD (ConstraintSolverError(FSComp.SR.csExpectedArguments(), m, m2))
+
+ // Trait calls are only supported on pseudo type (variables)
+ if not (g.langVersion.SupportsFeature LanguageFeature.InterfacesWithAbstractStaticMembers) then
+ for e in supportTys do
+ do! SolveTypStaticReq csenv trace TyparStaticReq.HeadType e
+
+ // SRTP constraints on rigid type parameters do not need to be solved
+ let isRigid =
+ supportTys |> List.forall (fun ty ->
+ match tryDestTyparTy g ty with
+ | ValueSome tp ->
+ match tp.Rigidity with
+ | TyparRigidity.Rigid
+ | TyparRigidity.WillBeRigid -> true
+ | _ -> false
+ | ValueNone -> false)
+
+ let argTys = if memFlags.IsInstance then List.tail traitObjAndArgTys else traitObjAndArgTys
+
+ let minfos = GetRelevantMethodsForTrait csenv permitWeakResolution nm traitInfo
+
+ let! res =
+ trackErrors {
+ match minfos, supportTys, memFlags.IsInstance, nm, argTys with
+ | _, _, false, ("op_Division" | "op_Multiply"), [argTy1;argTy2]
+ when
+ // This simulates the existence of
+ // float * float -> float
+ // float32 * float32 -> float32
+ // float<'u> * float<'v> -> float<'u 'v>
+ // float32<'u> * float32<'v> -> float32<'u 'v>
+ // decimal<'u> * decimal<'v> -> decimal<'u 'v>
+ // decimal<'u> * decimal -> decimal<'u>
+ // float32<'u> * float32<'v> -> float32<'u 'v>
+ // int * int -> int
+ // int64 * int64 -> int64
+ //
+ // The rule is triggered by these sorts of inputs when permitWeakResolution=false
+ // float * float
+ // float * float32 // will give error
+ // decimal * decimal
+ // decimal * decimal <-- Note this one triggers even though "decimal" has some possibly-relevant methods
+ // float * Matrix // the rule doesn't trigger for this one since Matrix has overloads we can use and we prefer those instead
+ // float * Matrix // the rule doesn't trigger for this one since Matrix has overloads we can use and we prefer those instead
+ //
+ // The rule is triggered by these sorts of inputs when permitWeakResolution=true
+ // float * 'a
+ // 'a * float
+ // decimal<'u> * 'a
+ (let checkRuleAppliesInPreferenceToMethods argTy1 argTy2 =
+ // Check that at least one of the argument types is numeric
+ IsNumericOrIntegralEnumType g argTy1 &&
+ // Check the other type is nominal, unless using weak resolution
+ IsBinaryOpOtherArgType g permitWeakResolution argTy2 &&
+ // This next condition checks that either
+ // - Neither type contributes any methods OR
+ // - We have the special case "decimal<_> * decimal". In this case we have some
+ // possibly-relevant methods from "decimal" but we ignore them in this case.
+ (isNil minfos || (Option.isSome (getMeasureOfType g argTy1) && isDecimalTy g argTy2)) in
+
+ checkRuleAppliesInPreferenceToMethods argTy1 argTy2 ||
+ checkRuleAppliesInPreferenceToMethods argTy2 argTy1) ->
+
+ match getMeasureOfType g argTy1 with
+ | Some (tcref, ms1) ->
+ let ms2 = freshMeasure ()
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 (mkWoNullAppTy tcref [TType_measure ms2])
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))])
+ return TTraitBuiltIn
- // Trait calls are only supported on pseudo type (variables)
- if not (g.langVersion.SupportsFeature LanguageFeature.InterfacesWithAbstractStaticMembers) then
- for e in supportTys do
- do! SolveTypStaticReq csenv trace TyparStaticReq.HeadType e
+ | _ ->
- // SRTP constraints on rigid type parameters do not need to be solved
- let isRigid =
- supportTys |> List.forall (fun ty ->
- match tryDestTyparTy g ty with
- | ValueSome tp ->
- match tp.Rigidity with
- | TyparRigidity.Rigid
- | TyparRigidity.WillBeRigid -> true
- | _ -> false
- | ValueNone -> false)
+ match getMeasureOfType g argTy2 with
+ | Some (tcref, ms2) ->
+ let ms1 = freshMeasure ()
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkWoNullAppTy tcref [TType_measure ms1])
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))])
+ return TTraitBuiltIn
+
+ | _ ->
+
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
+ return TTraitBuiltIn
+
+ | _, _, false, ("op_Addition" | "op_Subtraction" | "op_Modulus"), [argTy1;argTy2]
+ when // Ignore any explicit +/- overloads from any basic integral types
+ (minfos |> List.forall (fun (_, minfo) -> isIntegerTy g minfo.ApparentEnclosingType ) &&
+ ( IsAddSubModType nm g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2
+ || IsAddSubModType nm g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1)) ->
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
+ return TTraitBuiltIn
- let argTys = if memFlags.IsInstance then List.tail traitObjAndArgTys else traitObjAndArgTys
+ | _, _, false, ("op_LessThan" | "op_LessThanOrEqual" | "op_GreaterThan" | "op_GreaterThanOrEqual" | "op_Equality" | "op_Inequality" ), [argTy1;argTy2]
+ when // Ignore any explicit overloads from any basic integral types
+ (minfos |> List.forall (fun (_, minfo) -> isIntegerTy g minfo.ApparentEnclosingType ) &&
+ ( IsRelationalType g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2
+ || IsRelationalType g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1)) ->
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.bool_ty
+ return TTraitBuiltIn
- let minfos = GetRelevantMethodsForTrait csenv permitWeakResolution nm traitInfo
+ // We pretend for uniformity that the numeric types have a static property called Zero and One
+ // As with constants, only zero is polymorphic in its units
+ | [], [ty], false, "get_Zero", []
+ when isNumericType g ty || isCharTy g ty ->
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty
+ return TTraitBuiltIn
- let! res =
- trackErrors {
- match minfos, supportTys, memFlags.IsInstance, nm, argTys with
- | _, _, false, ("op_Division" | "op_Multiply"), [argTy1;argTy2]
- when
- // This simulates the existence of
- // float * float -> float
- // float32 * float32 -> float32
- // float<'u> * float<'v> -> float<'u 'v>
- // float32<'u> * float32<'v> -> float32<'u 'v>
- // decimal<'u> * decimal<'v> -> decimal<'u 'v>
- // decimal<'u> * decimal -> decimal<'u>
- // float32<'u> * float32<'v> -> float32<'u 'v>
- // int * int -> int
- // int64 * int64 -> int64
- //
- // The rule is triggered by these sorts of inputs when permitWeakResolution=false
- // float * float
- // float * float32 // will give error
- // decimal * decimal
- // decimal * decimal <-- Note this one triggers even though "decimal" has some possibly-relevant methods
- // float * Matrix // the rule doesn't trigger for this one since Matrix has overloads we can use and we prefer those instead
- // float * Matrix // the rule doesn't trigger for this one since Matrix has overloads we can use and we prefer those instead
- //
- // The rule is triggered by these sorts of inputs when permitWeakResolution=true
- // float * 'a
- // 'a * float
- // decimal<'u> * 'a
- (let checkRuleAppliesInPreferenceToMethods argTy1 argTy2 =
- // Check that at least one of the argument types is numeric
- IsNumericOrIntegralEnumType g argTy1 &&
- // Check the other type is nominal, unless using weak resolution
- IsBinaryOpOtherArgType g permitWeakResolution argTy2 &&
- // This next condition checks that either
- // - Neither type contributes any methods OR
- // - We have the special case "decimal<_> * decimal". In this case we have some
- // possibly-relevant methods from "decimal" but we ignore them in this case.
- (isNil minfos || (Option.isSome (getMeasureOfType g argTy1) && isDecimalTy g argTy2)) in
-
- checkRuleAppliesInPreferenceToMethods argTy1 argTy2 ||
- checkRuleAppliesInPreferenceToMethods argTy2 argTy1) ->
-
- match getMeasureOfType g argTy1 with
- | Some (tcref, ms1) ->
- let ms2 = freshMeasure ()
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 (mkWoNullAppTy tcref [TType_measure ms2])
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))])
+ | [], [ty], false, "get_One", []
+ when isNumericType g ty || isCharTy g ty ->
+ do! SolveDimensionlessNumericType csenv ndeep m2 trace ty
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty
return TTraitBuiltIn
- | _ ->
+ | [], _, false, "DivideByInt", [argTy1;argTy2]
+ when isFpTy g argTy1 || isDecimalTy g argTy1 ->
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 g.int_ty
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
+ return TTraitBuiltIn
- match getMeasureOfType g argTy2 with
- | Some (tcref, ms2) ->
- let ms1 = freshMeasure ()
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkWoNullAppTy tcref [TType_measure ms1])
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))])
- return TTraitBuiltIn
+ // We pretend for uniformity that the 'string' and 'array' types have an indexer property called 'Item'
+ | [], [ty], true, "get_Item", [argTy1]
+ when isStringTy g ty ->
- | _ ->
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 g.int_ty
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.char_ty
+ return TTraitBuiltIn
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
- return TTraitBuiltIn
+ | [], [ty], true, "get_Item", argTys
+ when isArrayTy g ty ->
+
+ if rankOfArrayTy g ty <> argTys.Length then
+ do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), argTys.Length), m, m2))
+
+ for argTy in argTys do
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy g.int_ty
- | _, _, false, ("op_Addition" | "op_Subtraction" | "op_Modulus"), [argTy1;argTy2]
- when // Ignore any explicit +/- overloads from any basic integral types
- (minfos |> List.forall (fun (_, minfo) -> isIntegerTy g minfo.ApparentEnclosingType ) &&
- ( IsAddSubModType nm g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2
- || IsAddSubModType nm g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1)) ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
- return TTraitBuiltIn
-
- | _, _, false, ("op_LessThan" | "op_LessThanOrEqual" | "op_GreaterThan" | "op_GreaterThanOrEqual" | "op_Equality" | "op_Inequality" ), [argTy1;argTy2]
- when // Ignore any explicit overloads from any basic integral types
- (minfos |> List.forall (fun (_, minfo) -> isIntegerTy g minfo.ApparentEnclosingType ) &&
- ( IsRelationalType g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2
- || IsRelationalType g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1)) ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.bool_ty
- return TTraitBuiltIn
-
- // We pretend for uniformity that the numeric types have a static property called Zero and One
- // As with constants, only zero is polymorphic in its units
- | [], [ty], false, "get_Zero", []
- when isNumericType g ty || isCharTy g ty ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty
- return TTraitBuiltIn
-
- | [], [ty], false, "get_One", []
- when isNumericType g ty || isCharTy g ty ->
- do! SolveDimensionlessNumericType csenv ndeep m2 trace ty
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty
- return TTraitBuiltIn
-
- | [], _, false, "DivideByInt", [argTy1;argTy2]
- when isFpTy g argTy1 || isDecimalTy g argTy1 ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 g.int_ty
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
- return TTraitBuiltIn
-
- // We pretend for uniformity that the 'string' and 'array' types have an indexer property called 'Item'
- | [], [ty], true, "get_Item", [argTy1]
- when isStringTy g ty ->
-
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 g.int_ty
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.char_ty
- return TTraitBuiltIn
-
- | [], [ty], true, "get_Item", argTys
- when isArrayTy g ty ->
-
- if rankOfArrayTy g ty <> argTys.Length then
- do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), argTys.Length), m, m2))
-
- for argTy in argTys do
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy g.int_ty
-
- let ety = destArrayTy g ty
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ety
- return TTraitBuiltIn
-
- | [], [ty], true, "set_Item", argTys
- when isArrayTy g ty ->
+ let ety = destArrayTy g ty
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ety
+ return TTraitBuiltIn
+
+ | [], [ty], true, "set_Item", argTys
+ when isArrayTy g ty ->
- if rankOfArrayTy g ty <> argTys.Length - 1 then
- do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), (argTys.Length - 1)), m, m2))
- let argTys, lastTy = List.frontAndBack argTys
+ if rankOfArrayTy g ty <> argTys.Length - 1 then
+ do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), (argTys.Length - 1)), m, m2))
+ let argTys, lastTy = List.frontAndBack argTys
+
+ for argTy in argTys do
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy g.int_ty
+
+ let elemTy = destArrayTy g ty
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace lastTy elemTy
+ return TTraitBuiltIn
- for argTy in argTys do
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy g.int_ty
+ | [], _, false, ("op_BitwiseAnd" | "op_BitwiseOr" | "op_ExclusiveOr"), [argTy1;argTy2]
+ when IsBitwiseOpType g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2
+ || IsBitwiseOpType g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1 ->
- let elemTy = destArrayTy g ty
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace lastTy elemTy
- return TTraitBuiltIn
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
+ do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1
+ return TTraitBuiltIn
- | [], _, false, ("op_BitwiseAnd" | "op_BitwiseOr" | "op_ExclusiveOr"), [argTy1;argTy2]
- when IsBitwiseOpType g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2
- || IsBitwiseOpType g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1 ->
+ | [], _, false, ("op_LeftShift" | "op_RightShift"), [argTy1;argTy2]
+ when IsIntegerOrIntegerEnumTy g argTy1 ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
- do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1
- return TTraitBuiltIn
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 g.int_ty
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
+ do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1
+ return TTraitBuiltIn
- | [], _, false, ("op_LeftShift" | "op_RightShift"), [argTy1;argTy2]
- when IsIntegerOrIntegerEnumTy g argTy1 ->
+ | _, _, false, "op_UnaryPlus", [argTy]
+ when IsNumericOrIntegralEnumType g argTy ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 g.int_ty
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
- do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1
- return TTraitBuiltIn
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
+ return TTraitBuiltIn
- | _, _, false, "op_UnaryPlus", [argTy]
- when IsNumericOrIntegralEnumType g argTy ->
+ | _, _, false, "op_UnaryNegation", [argTy]
+ when isSignedIntegerTy g argTy || isFpTy g argTy || isDecimalTy g argTy ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
- return TTraitBuiltIn
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
+ return TTraitBuiltIn
- | _, _, false, "op_UnaryNegation", [argTy]
- when isSignedIntegerTy g argTy || isFpTy g argTy || isDecimalTy g argTy ->
+ | _, _, true, "get_Sign", []
+ when IsSignType g supportTys.Head ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
- return TTraitBuiltIn
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.int32_ty
+ return TTraitBuiltIn
- | _, _, true, "get_Sign", []
- when IsSignType g supportTys.Head ->
+ | _, _, false, ("op_LogicalNot" | "op_OnesComplement"), [argTy]
+ when IsIntegerOrIntegerEnumTy g argTy ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.int32_ty
- return TTraitBuiltIn
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
+ do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy
+ return TTraitBuiltIn
- | _, _, false, ("op_LogicalNot" | "op_OnesComplement"), [argTy]
- when IsIntegerOrIntegerEnumTy g argTy ->
+ | _, _, false, "Abs", [argTy]
+ when isSignedIntegerTy g argTy || isFpTy g argTy || isDecimalTy g argTy ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
- do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy
- return TTraitBuiltIn
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
+ return TTraitBuiltIn
- | _, _, false, "Abs", [argTy]
- when isSignedIntegerTy g argTy || isFpTy g argTy || isDecimalTy g argTy ->
+ | _, _, false, "Sqrt", [argTy1]
+ when isFpTy g argTy1 ->
+ match getMeasureOfType g argTy1 with
+ | Some (tcref, _) ->
+ let ms1 = freshMeasure ()
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkWoNullAppTy tcref [TType_measure (Measure.Prod (ms1, ms1))])
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure ms1])
+ return TTraitBuiltIn
+ | None ->
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
+ return TTraitBuiltIn
+
+ | _, _, false, ("Sin" | "Cos" | "Tan" | "Sinh" | "Cosh" | "Tanh" | "Atan" | "Acos" | "Asin" | "Exp" | "Ceiling" | "Floor" | "Round" | "Truncate" | "Log10" | "Log" | "Sqrt"), [argTy]
+ when isFpTy g argTy ->
+
+ do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
+ return TTraitBuiltIn
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
- return TTraitBuiltIn
+ // Conversions from non-decimal numbers / strings / chars to non-decimal numbers / chars are built-in
+ | _, _, false, "op_Explicit", [argTy]
+ when (// The input type.
+ (IsNonDecimalNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) &&
+ // The output type
+ (IsNonDecimalNumericOrIntegralEnumType g retTy || isCharTy g retTy)) ->
- | _, _, false, "Sqrt", [argTy1]
- when isFpTy g argTy1 ->
- match getMeasureOfType g argTy1 with
- | Some (tcref, _) ->
- let ms1 = freshMeasure ()
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkWoNullAppTy tcref [TType_measure (Measure.Prod (ms1, ms1))])
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure ms1])
- return TTraitBuiltIn
- | None ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
- return TTraitBuiltIn
+ return TTraitBuiltIn
+
+ // Conversions from (including decimal) numbers / strings / chars to decimals are built-in
+ | _, _, false, "op_Explicit", [argTy]
+ when (// The input type.
+ (IsNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) &&
+ // The output type
+ (isDecimalTy g retTy)) ->
+ return TTraitBuiltIn
+
+ // Conversions from decimal numbers to native integers are built-in
+ // The rest of decimal conversions are handled via op_Explicit lookup on System.Decimal (which also looks for op_Implicit)
+ | _, _, false, "op_Explicit", [argTy]
+ when (// The input type.
+ (isDecimalTy g argTy) &&
+ // The output type
+ (isNativeIntegerTy g retTy)) ->
+ return TTraitBuiltIn
- | _, _, false, ("Sin" | "Cos" | "Tan" | "Sinh" | "Cosh" | "Tanh" | "Atan" | "Acos" | "Asin" | "Exp" | "Ceiling" | "Floor" | "Round" | "Truncate" | "Log10" | "Log" | "Sqrt"), [argTy]
- when isFpTy g argTy ->
-
- do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
- return TTraitBuiltIn
-
- // Conversions from non-decimal numbers / strings / chars to non-decimal numbers / chars are built-in
- | _, _, false, "op_Explicit", [argTy]
- when (// The input type.
- (IsNonDecimalNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) &&
- // The output type
- (IsNonDecimalNumericOrIntegralEnumType g retTy || isCharTy g retTy)) ->
-
- return TTraitBuiltIn
-
- // Conversions from (including decimal) numbers / strings / chars to decimals are built-in
- | _, _, false, "op_Explicit", [argTy]
- when (// The input type.
- (IsNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) &&
- // The output type
- (isDecimalTy g retTy)) ->
- return TTraitBuiltIn
-
- // Conversions from decimal numbers to native integers are built-in
- // The rest of decimal conversions are handled via op_Explicit lookup on System.Decimal (which also looks for op_Implicit)
- | _, _, false, "op_Explicit", [argTy]
- when (// The input type.
- (isDecimalTy g argTy) &&
- // The output type
- (isNativeIntegerTy g retTy)) ->
- return TTraitBuiltIn
-
- | [], _, false, "Pow", [argTy1; argTy2]
- when isFpTy g argTy1 ->
+ | [], _, false, "Pow", [argTy1; argTy2]
+ when isFpTy g argTy1 ->
- do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
- return TTraitBuiltIn
-
- | _, _, false, "Atan2", [argTy1; argTy2]
- when isFpTy g argTy1 ->
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
- match getMeasureOfType g argTy1 with
- | None -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
- | Some (tcref, _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure Measure.One])
- return TTraitBuiltIn
+ do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
+ return TTraitBuiltIn
- | _ ->
- // OK, this is not solved by a built-in constraint.
- // Now look for real solutions
-
- // First look for a solution by a record property
- let recdPropSearch =
- let isGetProp = nm.StartsWithOrdinal("get_")
- let isSetProp = nm.StartsWithOrdinal("set_")
- if not isRigid && ((argTys.IsEmpty && isGetProp) || isSetProp) then
- let propName = nm[4..]
- let props =
- supportTys |> List.choose (fun ty ->
- match TryFindIntrinsicNamedItemOfType csenv.InfoReader (propName, AccessibleFromEverywhere, false) FindMemberFlag.IgnoreOverrides m ty with
- | Some (RecdFieldItem rfinfo)
- when (isGetProp || rfinfo.RecdField.IsMutable) &&
- (rfinfo.IsStatic = not memFlags.IsInstance) &&
- IsRecdFieldAccessible amap m AccessibleFromEverywhere rfinfo.RecdFieldRef &&
- not rfinfo.LiteralValue.IsSome &&
- not rfinfo.RecdField.IsCompilerGenerated ->
- Some (rfinfo, isSetProp)
- | _ -> None)
- match props with
- | [ prop ] -> Some prop
- | _ -> None
- else
- None
-
- let anonRecdPropSearch =
- let isGetProp = nm.StartsWithOrdinal("get_")
- if not isRigid && isGetProp && memFlags.IsInstance then
- let propName = nm[4..]
- let props =
- supportTys |> List.choose (fun ty ->
- match TryFindAnonRecdFieldOfType g ty propName with
- | Some (Item.AnonRecdField(anonInfo, tinst, i, _)) -> Some (anonInfo, tinst, i)
- | _ -> None)
- match props with
- | [ prop ] -> Some prop
- | _ -> None
- else
- None
-
- // Now check if there are no feasible solutions at all
- match minfos, recdPropSearch, anonRecdPropSearch with
- | [], None, None when MemberConstraintIsReadyForStrongResolution csenv traitInfo ->
- if supportTys |> List.exists (isFunTy g) then
- return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenFunction(ConvertValLogicalNameToDisplayNameCore nm), m, m2))
- elif supportTys |> List.exists (isAnyTupleTy g) then
- return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenTuple(ConvertValLogicalNameToDisplayNameCore nm), m, m2))
- else
- match nm, argTys with
- | "op_Explicit", [argTy] ->
- let argTyString = NicePrint.prettyStringOfTy denv argTy
- let rtyString = NicePrint.prettyStringOfTy denv retTy
- return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportConversion(argTyString, rtyString), m, m2))
- | _ ->
- let tyString =
- match supportTys with
- | [ty] -> NicePrint.minimalStringOfType denv ty
- | _ -> supportTys |> List.map (NicePrint.minimalStringOfType denv) |> String.concat ", "
- let opName = ConvertValLogicalNameToDisplayNameCore nm
- let err =
- match opName with
- | "?>=" | "?>" | "?<=" | "?<" | "?=" | "?<>"
- | ">=?" | ">?" | "<=?" | "" | "=?" | "<>?"
- | "?>=?" | "?>?" | "?<=?" | "?" | "?=?" | "?<>?" ->
- if List.isSingleton supportTys then FSComp.SR.csTypeDoesNotSupportOperatorNullable(tyString, opName)
- else FSComp.SR.csTypesDoNotSupportOperatorNullable(tyString, opName)
- | _ ->
- match supportTys, source.Value with
- | [_], Some s when s.StartsWith("Operators.") ->
- let opSource = s[10..]
- if opSource = nm then FSComp.SR.csTypeDoesNotSupportOperator(tyString, opName)
- else FSComp.SR.csTypeDoesNotSupportOperator(tyString, opSource)
- | [_], Some s ->
- FSComp.SR.csFunctionDoesNotSupportType(s, tyString, nm)
- | [_], _
- -> FSComp.SR.csTypeDoesNotSupportOperator(tyString, opName)
- | _, _
- -> FSComp.SR.csTypesDoNotSupportOperator(tyString, opName)
- return! ErrorD(ConstraintSolverError(err, m, m2))
+ | _, _, false, "Atan2", [argTy1; argTy2]
+ when isFpTy g argTy1 ->
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
+ match getMeasureOfType g argTy1 with
+ | None -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
+ | Some (tcref, _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure Measure.One])
+ return TTraitBuiltIn
| _ ->
- let dummyExpr = mkUnit g m
- let calledMethGroup =
- minfos
- // curried members may not be used to satisfy constraints
- |> List.choose (fun (staticTy, minfo) ->
- if minfo.IsCurried then
- None
- else
- let callerArgs =
- {
- Unnamed = [ (argTys |> List.map (fun argTy -> CallerArg(argTy, m, false, dummyExpr))) ]
- Named = [ [ ] ]
- }
- let minst = FreshenMethInfo m minfo
- let objtys = minfo.GetObjArgTypes(amap, m, minst)
- Some(CalledMeth(csenv.InfoReader, None, false, FreshenMethInfo, m, AccessibleFromEverywhere, minfo, minst, minst, None, objtys, callerArgs, false, false, None, Some staticTy)))
-
- let methOverloadResult, errors =
- trace.CollectThenUndoOrCommit
- (fun (a, _) -> Option.isSome a)
- (fun trace -> ResolveOverloading csenv (WithTrace trace) nm ndeep (Some traitInfo) CallerArgs.Empty AccessibleFromEverywhere calledMethGroup false (Some (MustEqual retTy)))
-
- match anonRecdPropSearch, recdPropSearch, methOverloadResult with
- | Some (anonInfo, tinst, i), None, None ->
- // OK, the constraint is solved by a record property. Assert that the return types match.
- let rty2 = List.item i tinst
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy rty2
- return TTraitSolvedAnonRecdProp(anonInfo, tinst, i)
-
- | None, Some (rfinfo, isSetProp), None ->
- // OK, the constraint is solved by a record property. Assert that the return types match.
- let rty2 = if isSetProp then g.unit_ty else rfinfo.FieldType
- do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy rty2
- return TTraitSolvedRecdProp(rfinfo, isSetProp)
-
- | None, None, Some (calledMeth: CalledMeth<_>) ->
- // OK, the constraint is solved.
- let minfo = calledMeth.Method
-
- do! errors
- let isInstance = minfo.IsInstance
- if isInstance <> memFlags.IsInstance then
- return!
- if isInstance then
- ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsNotStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 ))
- else
- ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 ))
- else
- do! CheckMethInfoAttributes g m None minfo
- return TTraitSolved (minfo, calledMeth.CalledTyArgs, calledMeth.OptionalStaticType)
+ // OK, this is not solved by a built-in constraint.
+ // Now look for real solutions
+
+ // First look for a solution by a record property
+ let recdPropSearch =
+ let isGetProp = nm.StartsWithOrdinal("get_")
+ let isSetProp = nm.StartsWithOrdinal("set_")
+ if not isRigid && ((argTys.IsEmpty && isGetProp) || isSetProp) then
+ let propName = nm[4..]
+ let props =
+ supportTys |> List.choose (fun ty ->
+ match TryFindIntrinsicNamedItemOfType csenv.InfoReader (propName, AccessibleFromEverywhere, false) FindMemberFlag.IgnoreOverrides m ty with
+ | Some (RecdFieldItem rfinfo)
+ when (isGetProp || rfinfo.RecdField.IsMutable) &&
+ (rfinfo.IsStatic = not memFlags.IsInstance) &&
+ IsRecdFieldAccessible amap m AccessibleFromEverywhere rfinfo.RecdFieldRef &&
+ not rfinfo.LiteralValue.IsSome &&
+ not rfinfo.RecdField.IsCompilerGenerated ->
+ Some (rfinfo, isSetProp)
+ | _ -> None)
+ match props with
+ | [ prop ] -> Some prop
+ | _ -> None
+ else
+ None
+
+ let anonRecdPropSearch =
+ let isGetProp = nm.StartsWithOrdinal("get_")
+ if not isRigid && isGetProp && memFlags.IsInstance then
+ let propName = nm[4..]
+ let props =
+ supportTys |> List.choose (fun ty ->
+ match TryFindAnonRecdFieldOfType g ty propName with
+ | Some (Item.AnonRecdField(anonInfo, tinst, i, _)) -> Some (anonInfo, tinst, i)
+ | _ -> None)
+ match props with
+ | [ prop ] -> Some prop
+ | _ -> None
+ else
+ None
+
+ // Now check if there are no feasible solutions at all
+ match minfos, recdPropSearch, anonRecdPropSearch with
+ | [], None, None when MemberConstraintIsReadyForStrongResolution csenv traitInfo ->
+ if supportTys |> List.exists (isFunTy g) then
+ return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenFunction(ConvertValLogicalNameToDisplayNameCore nm), m, m2))
+ elif supportTys |> List.exists (isAnyTupleTy g) then
+ return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenTuple(ConvertValLogicalNameToDisplayNameCore nm), m, m2))
+ else
+ match nm, argTys with
+ | "op_Explicit", [argTy] ->
+ let argTyString = NicePrint.prettyStringOfTy denv argTy
+ let rtyString = NicePrint.prettyStringOfTy denv retTy
+ return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportConversion(argTyString, rtyString), m, m2))
+ | _ ->
+ let tyString =
+ match supportTys with
+ | [ty] -> NicePrint.minimalStringOfType denv ty
+ | _ -> supportTys |> List.map (NicePrint.minimalStringOfType denv) |> String.concat ", "
+ let opName = ConvertValLogicalNameToDisplayNameCore nm
+ let err =
+ match opName with
+ | "?>=" | "?>" | "?<=" | "?<" | "?=" | "?<>"
+ | ">=?" | ">?" | "<=?" | "" | "=?" | "<>?"
+ | "?>=?" | "?>?" | "?<=?" | "?" | "?=?" | "?<>?" ->
+ if List.isSingleton supportTys then FSComp.SR.csTypeDoesNotSupportOperatorNullable(tyString, opName)
+ else FSComp.SR.csTypesDoNotSupportOperatorNullable(tyString, opName)
+ | _ ->
+ match supportTys, source.Value with
+ | [_], Some s when s.StartsWith("Operators.") ->
+ let opSource = s[10..]
+ if opSource = nm then FSComp.SR.csTypeDoesNotSupportOperator(tyString, opName)
+ else FSComp.SR.csTypeDoesNotSupportOperator(tyString, opSource)
+ | [_], Some s ->
+ FSComp.SR.csFunctionDoesNotSupportType(s, tyString, nm)
+ | [_], _
+ -> FSComp.SR.csTypeDoesNotSupportOperator(tyString, opName)
+ | _, _
+ -> FSComp.SR.csTypesDoNotSupportOperator(tyString, opName)
+ return! ErrorD(ConstraintSolverError(err, m, m2))
| _ ->
- do! AddUnsolvedMemberConstraint csenv ndeep m2 trace permitWeakResolution ignoreUnresolvedOverload traitInfo errors
- return TTraitUnsolved
- }
- return! RecordMemberConstraintSolution csenv.SolverState m trace traitInfo res
+ let dummyExpr = mkUnit g m
+ let calledMethGroup =
+ minfos
+ // curried members may not be used to satisfy constraints
+ |> List.choose (fun (staticTy, minfo) ->
+ if minfo.IsCurried then
+ None
+ else
+ let callerArgs =
+ {
+ Unnamed = [ (argTys |> List.map (fun argTy -> CallerArg(argTy, m, false, dummyExpr))) ]
+ Named = [ [ ] ]
+ }
+ let minst = FreshenMethInfo m minfo
+ let objtys = minfo.GetObjArgTypes(amap, m, minst)
+ Some(CalledMeth(csenv.InfoReader, None, false, FreshenMethInfo, m, AccessibleFromEverywhere, minfo, minst, minst, None, objtys, callerArgs, false, false, None, Some staticTy)))
+
+ let methOverloadResult, errors =
+ trace.CollectThenUndoOrCommit
+ (fun (a, _) -> Option.isSome a)
+ (fun trace -> ResolveOverloading csenv (WithTrace trace) nm ndeep (Some traitInfo) CallerArgs.Empty AccessibleFromEverywhere calledMethGroup false (Some (MustEqual retTy)))
+
+ match anonRecdPropSearch, recdPropSearch, methOverloadResult with
+ | Some (anonInfo, tinst, i), None, None ->
+ // OK, the constraint is solved by a record property. Assert that the return types match.
+ let rty2 = List.item i tinst
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy rty2
+ return TTraitSolvedAnonRecdProp(anonInfo, tinst, i)
+
+ | None, Some (rfinfo, isSetProp), None ->
+ // OK, the constraint is solved by a record property. Assert that the return types match.
+ let rty2 = if isSetProp then g.unit_ty else rfinfo.FieldType
+ do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy rty2
+ return TTraitSolvedRecdProp(rfinfo, isSetProp)
+
+ | None, None, Some (calledMeth: CalledMeth<_>) ->
+ // OK, the constraint is solved.
+ let minfo = calledMeth.Method
+
+ do! errors
+ let isInstance = minfo.IsInstance
+ if isInstance <> memFlags.IsInstance then
+ return!
+ if isInstance then
+ ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsNotStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 ))
+ else
+ ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 ))
+ else
+ do! CheckMethInfoAttributes g m None minfo
+ return TTraitSolved (minfo, calledMeth.CalledTyArgs, calledMeth.OptionalStaticType)
+
+ | _ ->
+ do! AddUnsolvedMemberConstraint csenv ndeep m2 trace permitWeakResolution ignoreUnresolvedOverload traitInfo errors
+ return TTraitUnsolved
+ }
+ return! RecordMemberConstraintSolution csenv.SolverState m trace traitInfo res
}
and AddUnsolvedMemberConstraint csenv ndeep m2 trace permitWeakResolution ignoreUnresolvedOverload traitInfo errors =
@@ -2465,6 +2479,7 @@ and CheckConstraintImplication (csenv: ConstraintSolverEnv) tpc1 tpc2 =
| TyparConstraint.NotSupportsNull _, TyparConstraint.NotSupportsNull _
| TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _
| TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _
+ | TyparConstraint.AllowsRefStruct _, TyparConstraint.AllowsRefStruct _
| TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _
| TyparConstraint.RequiresDefaultConstructor _, TyparConstraint.RequiresDefaultConstructor _ -> true
| TyparConstraint.SimpleChoice (tys1, _), TyparConstraint.SimpleChoice (tys2, _) -> ListSet.isSubsetOf (typeEquiv g) tys1 tys2
diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs
index d328f6a310a..645897a6793 100644
--- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs
+++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs
@@ -1545,7 +1545,9 @@ let rec TryTranslateComputationExpression
let dataCompPrior =
translatedCtxt (
- TranslateComputationExpressionNoQueryOps ceenv (SynExpr.YieldOrReturn((true, false), varSpaceExpr, mClause))
+ TranslateComputationExpressionNoQueryOps
+ ceenv
+ (SynExpr.YieldOrReturn((true, false), varSpaceExpr, mClause, SynExprYieldOrReturnTrivia.Zero))
)
// Rebind using for ...
@@ -1576,7 +1578,9 @@ let rec TryTranslateComputationExpression
let isYield = not (customOperationMaintainsVarSpaceUsingBind ceenv nm)
translatedCtxt (
- TranslateComputationExpressionNoQueryOps ceenv (SynExpr.YieldOrReturn((isYield, false), varSpaceExpr, mClause))
+ TranslateComputationExpressionNoQueryOps
+ ceenv
+ (SynExpr.YieldOrReturn((isYield, false), varSpaceExpr, mClause, SynExprYieldOrReturnTrivia.Zero))
)
// Now run the consumeCustomOpClauses
@@ -1801,11 +1805,8 @@ let rec TryTranslateComputationExpression
| SynExpr.LetOrUse(
isUse = true
bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr; debugPoint = spBind) ]
- body = innerComp) ->
- let mBind =
- match spBind with
- | DebugPointAtBinding.Yes m -> m
- | _ -> rhsExpr.Range
+ body = innerComp
+ trivia = { LetOrUseKeyword = mBind }) ->
if ceenv.isQuery then
error (Error(FSComp.SR.tcUseMayNotBeUsedInQueries (), mBind))
@@ -2374,7 +2375,7 @@ let rec TryTranslateComputationExpression
Some(translatedCtxt callExpr)
- | SynExpr.YieldOrReturnFrom((true, _), synYieldExpr, m) ->
+ | SynExpr.YieldOrReturnFrom((true, _), synYieldExpr, _, { YieldOrReturnFromKeyword = m }) ->
let yieldFromExpr =
mkSourceExpr synYieldExpr ceenv.sourceMethInfo ceenv.builderValName
@@ -2392,7 +2393,8 @@ let rec TryTranslateComputationExpression
then
error (Error(FSComp.SR.tcRequireBuilderMethod ("YieldFrom"), m))
- let yieldFromCall = mkSynCall "YieldFrom" m [ yieldFromExpr ] ceenv.builderValName
+ let yieldFromCall =
+ mkSynCall "YieldFrom" synYieldExpr.Range [ yieldFromExpr ] ceenv.builderValName
let yieldFromCall =
if IsControlFlowExpression synYieldExpr then
@@ -2402,7 +2404,7 @@ let rec TryTranslateComputationExpression
Some(translatedCtxt yieldFromCall)
- | SynExpr.YieldOrReturnFrom((false, _), synReturnExpr, m) ->
+ | SynExpr.YieldOrReturnFrom((false, _), synReturnExpr, _, { YieldOrReturnFromKeyword = m }) ->
let returnFromExpr =
mkSourceExpr synReturnExpr ceenv.sourceMethInfo ceenv.builderValName
@@ -2424,7 +2426,7 @@ let rec TryTranslateComputationExpression
error (Error(FSComp.SR.tcRequireBuilderMethod ("ReturnFrom"), m))
let returnFromCall =
- mkSynCall "ReturnFrom" m [ returnFromExpr ] ceenv.builderValName
+ mkSynCall "ReturnFrom" synReturnExpr.Range [ returnFromExpr ] ceenv.builderValName
let returnFromCall =
if IsControlFlowExpression synReturnExpr then
@@ -2434,7 +2436,7 @@ let rec TryTranslateComputationExpression
Some(translatedCtxt returnFromCall)
- | SynExpr.YieldOrReturn((isYield, _), synYieldOrReturnExpr, m) ->
+ | SynExpr.YieldOrReturn((isYield, _), synYieldOrReturnExpr, _, { YieldOrReturnKeyword = m }) ->
let methName = (if isYield then "Yield" else "Return")
if ceenv.isQuery && not isYield then
@@ -2452,10 +2454,10 @@ let rec TryTranslateComputationExpression
ceenv.builderTy
)
then
- error (Error(FSComp.SR.tcRequireBuilderMethod (methName), m))
+ error (Error(FSComp.SR.tcRequireBuilderMethod methName, m))
let yieldOrReturnCall =
- mkSynCall methName m [ synYieldOrReturnExpr ] ceenv.builderValName
+ mkSynCall methName synYieldOrReturnExpr.Range [ synYieldOrReturnExpr ] ceenv.builderValName
let yieldOrReturnCall =
if IsControlFlowExpression synYieldOrReturnExpr then
@@ -2759,7 +2761,7 @@ and TranslateComputationExpressionBind
/// The inner option indicates if a custom operation is involved inside
and convertSimpleReturnToExpr (ceenv: ComputationExpressionContext<'a>) comp varSpace innerComp =
match innerComp with
- | SynExpr.YieldOrReturn((false, _), returnExpr, m) ->
+ | SynExpr.YieldOrReturn((false, _), returnExpr, m, _) ->
let returnExpr = SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, returnExpr)
Some(returnExpr, None)
@@ -2901,7 +2903,7 @@ and TranslateComputationExpression (ceenv: ComputationExpressionContext<'a>) fir
with
| minfo :: _ when MethInfoHasAttribute ceenv.cenv.g m ceenv.cenv.g.attrib_DefaultValueAttribute minfo ->
SynExpr.ImplicitZero m
- | _ -> SynExpr.YieldOrReturn((false, true), SynExpr.Const(SynConst.Unit, m), m)
+ | _ -> SynExpr.YieldOrReturn((false, true), SynExpr.Const(SynConst.Unit, m), m, SynExprYieldOrReturnTrivia.Zero)
let letBangBind =
SynExpr.LetOrUseBang(
diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs
index d2df1aff642..4325d503206 100644
--- a/src/Compiler/Checking/Expressions/CheckExpressions.fs
+++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs
@@ -3283,7 +3283,7 @@ let AnalyzeArbitraryExprAsEnumerable (cenv: cenv) (env: TcEnv) localAlloc m expr
let enumElemTy =
- if isObjTy g enumElemTy then
+ if isObjTyAnyNullness g enumElemTy then
// Look for an 'Item' property, or a set of these with consistent return types
let allEquivReturnTypes (minfo: MethInfo) (others: MethInfo list) =
let returnTy = minfo.GetFSharpReturnType(cenv.amap, m, [])
@@ -5163,6 +5163,7 @@ and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags
| TyparConstraint.SupportsComparison _
| TyparConstraint.SupportsEquality _
| TyparConstraint.DefaultsTo (ty = Unit)
+ | TyparConstraint.AllowsRefStruct _
| TyparConstraint.MayResolveMember _ -> true
// Any other kind of constraint is incompatible with unit.
@@ -5990,16 +5991,16 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE
CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights)
TcQuotationExpr cenv overallTy env tpenv (oper, raw, ast, isFromQueryExpression, m)
- | SynExpr.YieldOrReturn ((isTrueYield, _), _, m)
- | SynExpr.YieldOrReturnFrom ((isTrueYield, _), _, m) when isTrueYield ->
+ | SynExpr.YieldOrReturn ((isTrueYield, _), _, _m, { YieldOrReturnKeyword = m })
+ | SynExpr.YieldOrReturnFrom ((isTrueYield, _), _, _m, { YieldOrReturnFromKeyword = m }) when isTrueYield ->
error(Error(FSComp.SR.tcConstructRequiresListArrayOrSequence(), m))
- | SynExpr.YieldOrReturn ((_, isTrueReturn), _, m)
- | SynExpr.YieldOrReturnFrom ((_, isTrueReturn), _, m) when isTrueReturn ->
+ | SynExpr.YieldOrReturn ((_, isTrueReturn), _, _m, { YieldOrReturnKeyword = m })
+ | SynExpr.YieldOrReturnFrom ((_, isTrueReturn), _, _m, { YieldOrReturnFromKeyword = m }) when isTrueReturn ->
error(Error(FSComp.SR.tcConstructRequiresComputationExpressions(), m))
- | SynExpr.YieldOrReturn (_, _, m)
- | SynExpr.YieldOrReturnFrom (_, _, m)
+ | SynExpr.YieldOrReturn (trivia = { YieldOrReturnKeyword = m })
+ | SynExpr.YieldOrReturnFrom (trivia = { YieldOrReturnFromKeyword = m })
| SynExpr.ImplicitZero m ->
error(Error(FSComp.SR.tcConstructRequiresSequenceOrComputations(), m))
@@ -6194,7 +6195,7 @@ and TcExprObjectExpr (cenv: cenv) overallTy env tpenv (synObjTy, argopt, binds,
errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(), m))
(m, intfTy, overrides), tpenv)
- let realObjTy = if isObjTy g objTy && not (isNil extraImpls) then (p23 (List.head extraImpls)) else objTy
+ let realObjTy = if isObjTyAnyNullness g objTy && not (isNil extraImpls) then (p23 (List.head extraImpls)) else objTy
TcPropagatingExprLeafThenConvert cenv overallTy realObjTy env (* canAdhoc *) m (fun () ->
TcObjectExpr cenv env tpenv (objTy, realObjTy, argopt, binds, extraImpls, mObjTy, mNewExpr, m)
@@ -7319,7 +7320,7 @@ and TcFormatStringExpr cenv (overallTy: OverallTy) env m tpenv (fmtString: strin
let formatTy = mkPrintfFormatTy g aty bty cty dty ety
// This might qualify as a format string - check via a type directed rule
- let ok = not (isObjTy g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy
+ let ok = not (isObjTyAnyNullness g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy
if ok then
// Parse the format string to work out the phantom types
@@ -7398,7 +7399,7 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn
Choice1Of2 (true, newFormatMethod)
// ... or if that fails then may be a FormattableString by a type-directed rule....
- elif (not (isObjTy g overallTy.Commit) &&
+ elif (not (isObjTyAnyNullness g overallTy.Commit) &&
((g.system_FormattableString_tcref.CanDeref && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit g.system_FormattableString_ty)
|| (g.system_IFormattable_tcref.CanDeref && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit g.system_IFormattable_ty))) then
@@ -7419,7 +7420,7 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn
| None -> languageFeatureNotSupportedInLibraryError LanguageFeature.StringInterpolation m
// ... or if that fails then may be a PrintfFormat by a type-directed rule....
- elif not (isObjTy g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy then
+ elif not (isObjTyAnyNullness g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy then
// And if that succeeds, the printerTy and printerResultTy must be the same (there are no curried arguments)
UnifyTypes cenv env m printerTy printerResultTy
diff --git a/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs b/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs
index b627eef2922..3154d3e1e74 100644
--- a/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs
+++ b/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs
@@ -232,9 +232,10 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
// 'use x = expr in expr'
| SynExpr.LetOrUse(
isUse = true
- bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr; debugPoint = spBind) ]
+ bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr) ]
body = innerComp
- range = wholeExprMark) ->
+ range = wholeExprMark
+ trivia = { LetOrUseKeyword = mBind }) ->
let bindPatTy = NewInferenceType g
let inputExprTy = NewInferenceType g
@@ -252,11 +253,6 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
let envinner = { envinner with eIsControlFlow = true }
tcSequenceExprBody envinner genOuterTy tpenv innerComp
- let mBind =
- match spBind with
- | DebugPointAtBinding.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.Binding)
- | _ -> inputExpr.Range
-
let inputExprMark = inputExpr.Range
let matchv, matchExpr =
@@ -353,43 +349,44 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
Some(combinatorExpr, tpenv)
- | SynExpr.YieldOrReturnFrom((isYield, _), synYieldExpr, m) ->
+ | SynExpr.YieldOrReturnFrom(flags = (isYield, _); expr = synYieldExpr; trivia = { YieldOrReturnFromKeyword = m }) ->
let env = { env with eIsControlFlow = false }
let resultExpr, genExprTy, tpenv = TcExprOfUnknownType cenv env tpenv synYieldExpr
if not isYield then
errorR (Error(FSComp.SR.tcUseYieldBangForMultipleResults (), m))
- AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace genOuterTy genExprTy
+ AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css synYieldExpr.Range NoTrace genOuterTy genExprTy
- let resultExpr = mkCoerceExpr (resultExpr, genOuterTy, m, genExprTy)
+ let resultExpr =
+ mkCoerceExpr (resultExpr, genOuterTy, synYieldExpr.Range, genExprTy)
let resultExpr =
if IsControlFlowExpression synYieldExpr then
resultExpr
else
- mkDebugPoint m resultExpr
+ mkDebugPoint resultExpr.Range resultExpr
Some(resultExpr, tpenv)
- | SynExpr.YieldOrReturn((isYield, _), synYieldExpr, m) ->
+ | SynExpr.YieldOrReturn(flags = (isYield, _); expr = synYieldExpr; trivia = { YieldOrReturnKeyword = m }) ->
let env = { env with eIsControlFlow = false }
let genResultTy = NewInferenceType g
if not isYield then
errorR (Error(FSComp.SR.tcSeqResultsUseYield (), m))
- UnifyTypes cenv env m genOuterTy (mkSeqTy cenv.g genResultTy)
+ UnifyTypes cenv env synYieldExpr.Range genOuterTy (mkSeqTy cenv.g genResultTy)
let resultExpr, tpenv = TcExprFlex cenv flex true genResultTy env tpenv synYieldExpr
- let resultExpr = mkCallSeqSingleton cenv.g m genResultTy resultExpr
+ let resultExpr = mkCallSeqSingleton cenv.g synYieldExpr.Range genResultTy resultExpr
let resultExpr =
if IsControlFlowExpression synYieldExpr then
resultExpr
else
- mkDebugPoint m resultExpr
+ mkDebugPoint synYieldExpr.Range resultExpr
Some(resultExpr, tpenv)
diff --git a/src/Compiler/Checking/InfoReader.fs b/src/Compiler/Checking/InfoReader.fs
index f4a9f033c64..24a2d5bbf6e 100644
--- a/src/Compiler/Checking/InfoReader.fs
+++ b/src/Compiler/Checking/InfoReader.fs
@@ -1082,7 +1082,7 @@ let TryDestStandardDelegateType (infoReader: InfoReader) m ad delTy =
let g = infoReader.g
let (SigOfFunctionForDelegate(_, delArgTys, delRetTy, _)) = GetSigOfFunctionForDelegate infoReader delTy m ad
match delArgTys with
- | senderTy :: argTys when (isObjTy g senderTy) && not (List.exists (isByrefTy g) argTys) -> Some(mkRefTupledTy g argTys, delRetTy)
+ | senderTy :: argTys when (isObjTyAnyNullness g senderTy) && not (List.exists (isByrefTy g) argTys) -> Some(mkRefTupledTy g argTys, delRetTy)
| _ -> None
diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs
index 72363943549..ac4d92141d8 100644
--- a/src/Compiler/Checking/MethodCalls.fs
+++ b/src/Compiler/Checking/MethodCalls.fs
@@ -1319,7 +1319,7 @@ let BuildNewDelegateExpr (eventInfoOpt: EventInfo option, g, amap, delegateTy, d
| Some einfo ->
match delArgVals with
| [] -> error(nonStandardEventError einfo.EventName m)
- | h :: _ when not (isObjTy g h.Type) -> error(nonStandardEventError einfo.EventName m)
+ | h :: _ when not (isObjTyAnyNullness g h.Type) -> error(nonStandardEventError einfo.EventName m)
| h :: t -> [exprForVal m h; mkRefTupledVars g m t]
| None ->
if isNil delArgTys then [mkUnit g m] else List.map (exprForVal m) delArgVals
diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs
index 2eb5b14fa02..010e9e0cd8d 100644
--- a/src/Compiler/Checking/NameResolution.fs
+++ b/src/Compiler/Checking/NameResolution.fs
@@ -4422,14 +4422,14 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso
//
// Don't show GetHashCode or Equals for F# types that admit equality as an abnormal operation
let isUnseenDueToBasicObjRules =
- not (isObjTy g ty) &&
+ not (isObjTyAnyNullness g ty) &&
not minfo.IsExtensionMember &&
match minfo.LogicalName with
| "GetType" -> false
- | "GetHashCode" -> isObjTy g minfo.ApparentEnclosingType && not (AugmentTypeDefinitions.TypeDefinitelyHasEquality g ty)
+ | "GetHashCode" -> isObjTyAnyNullness g minfo.ApparentEnclosingType && not (AugmentTypeDefinitions.TypeDefinitelyHasEquality g ty)
| "ToString" -> false
| "Equals" ->
- if not (isObjTy g minfo.ApparentEnclosingType) then
+ if not (isObjTyAnyNullness g minfo.ApparentEnclosingType) then
// declaring type is not System.Object - show it
false
elif minfo.IsInstance then
@@ -4440,7 +4440,7 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso
true
| _ ->
// filter out self methods of obj type
- isObjTy g minfo.ApparentEnclosingType
+ isObjTyAnyNullness g minfo.ApparentEnclosingType
let result =
not isUnseenDueToBasicObjRules &&
@@ -5121,14 +5121,14 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty (
//
// Don't show GetHashCode or Equals for F# types that admit equality as an abnormal operation
let isUnseenDueToBasicObjRules =
- not (isObjTy g ty) &&
+ not (isObjTyAnyNullness g ty) &&
not minfo.IsExtensionMember &&
match minfo.LogicalName with
| "GetType" -> false
- | "GetHashCode" -> isObjTy g minfo.ApparentEnclosingType && not (AugmentTypeDefinitions.TypeDefinitelyHasEquality g ty)
+ | "GetHashCode" -> isObjTyAnyNullness g minfo.ApparentEnclosingType && not (AugmentTypeDefinitions.TypeDefinitelyHasEquality g ty)
| "ToString" -> false
| "Equals" ->
- if not (isObjTy g minfo.ApparentEnclosingType) then
+ if not (isObjTyAnyNullness g minfo.ApparentEnclosingType) then
// declaring type is not System.Object - show it
false
elif minfo.IsInstance then
@@ -5139,7 +5139,7 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty (
true
| _ ->
// filter out self methods of obj type
- isObjTy g minfo.ApparentEnclosingType
+ isObjTyAnyNullness g minfo.ApparentEnclosingType
let result =
not isUnseenDueToBasicObjRules &&
not minfo.IsInstance = statics &&
diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs
index ccb99f12139..09e8708b894 100644
--- a/src/Compiler/Checking/NicePrint.fs
+++ b/src/Compiler/Checking/NicePrint.fs
@@ -773,8 +773,13 @@ module PrintTypes =
| _ ->
if denv.abbreviateAdditionalConstraints then
wordL (tagKeyword "when") ^^ wordL(tagText "")
- elif denv.shortConstraints then
- LeftL.leftParen ^^ wordL (tagKeyword "requires") ^^ sepListL (wordL (tagKeyword "and")) cxsL ^^ RightL.rightParen
+ elif denv.shortConstraints then
+ match cxs with
+ | (_,TyparConstraint.AllowsRefStruct _) :: _ ->
+ // If the first constraint is 'allows ref struct', we do not want to prefix it with 'requires', because that just reads wrong.
+ LeftL.leftParen ^^ sepListL (wordL (tagKeyword "and")) cxsL ^^ RightL.rightParen
+ | _ ->
+ LeftL.leftParen ^^ wordL (tagKeyword "requires") ^^ sepListL (wordL (tagKeyword "and")) cxsL ^^ RightL.rightParen
else
wordL (tagKeyword "when") ^^ sepListL (wordL (tagKeyword "and")) cxsL
@@ -834,6 +839,12 @@ module PrintTypes =
[wordL (tagKeyword "unmanaged")]
else
[wordL (tagKeyword "unmanaged") |> longConstraintPrefix]
+
+ | TyparConstraint.AllowsRefStruct _ ->
+ if denv.shortConstraints then
+ [wordL (tagKeyword "allows ref struct")]
+ else
+ [wordL (tagKeyword "allows ref struct") |> longConstraintPrefix]
| TyparConstraint.IsReferenceType _ ->
if denv.shortConstraints then
@@ -2180,7 +2191,7 @@ module TastDefinitionPrinting =
let inherits =
[ if not (suppressInheritanceAndInterfacesForTyInSimplifiedDisplays g amap m ty) then
match GetSuperTypeOfType g amap m ty with
- | Some superTy when not (isObjTy g superTy) && not (isValueTypeTy g superTy) ->
+ | Some superTy when not (isObjTyAnyNullness g superTy) && not (isValueTypeTy g superTy) ->
superTy
| _ -> ()
]
diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index 06ef1b9766a..645f43fe3cb 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -448,6 +448,7 @@ and CheckTypeConstraintDeep cenv f g env x =
| TyparConstraint.NotSupportsNull _
| TyparConstraint.IsNonNullableStruct _
| TyparConstraint.IsUnmanaged _
+ | TyparConstraint.AllowsRefStruct _
| TyparConstraint.IsReferenceType _
| TyparConstraint.RequiresDefaultConstructor _ -> ()
@@ -1957,7 +1958,8 @@ and CheckAttribArgExpr cenv env expr =
| Const.Single _
| Const.Char _
| Const.Zero
- | Const.String _ -> ()
+ | Const.String _
+ | Const.Decimal _ -> ()
| _ ->
if cenv.reportErrors then
errorR (Error (FSComp.SR.tastNotAConstantExpression(), m))
diff --git a/src/Compiler/Checking/SignatureHash.fs b/src/Compiler/Checking/SignatureHash.fs
index f3f81b2fee3..66aeb0912c7 100644
--- a/src/Compiler/Checking/SignatureHash.fs
+++ b/src/Compiler/Checking/SignatureHash.fs
@@ -165,6 +165,7 @@ module rec HashTypes =
| TyparConstraint.SimpleChoice(tys, _) -> tpHash @@ 12 @@ (tys |> hashListOrderIndependent (hashTType g))
| TyparConstraint.RequiresDefaultConstructor _ -> tpHash @@ 13
| TyparConstraint.NotSupportsNull(_) -> tpHash @@ 14
+ | TyparConstraint.AllowsRefStruct _ -> tpHash @@ 15
/// Hash type parameter constraints
let private hashConstraints (g: TcGlobals) cxs =
diff --git a/src/Compiler/Checking/TypeHierarchy.fs b/src/Compiler/Checking/TypeHierarchy.fs
index 0805fcaf09b..9bf7c2ec892 100644
--- a/src/Compiler/Checking/TypeHierarchy.fs
+++ b/src/Compiler/Checking/TypeHierarchy.fs
@@ -67,7 +67,7 @@ let GetSuperTypeOfType g amap m ty =
Some (instType (mkInstForAppTy g ty) (superOfTycon g tcref.Deref))
elif isArrayTy g ty then
Some g.system_Array_ty
- elif isRefTy g ty && not (isObjTy g ty) then
+ elif isRefTy g ty && not (isObjTyAnyNullness g ty) then
Some g.obj_ty_noNulls
elif isStructTupleTy g ty then
Some g.system_Value_ty
@@ -284,6 +284,7 @@ let FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst skipUnref visitor
| TyparConstraint.NotSupportsNull _
| TyparConstraint.IsNonNullableStruct _
| TyparConstraint.IsUnmanaged _
+ | TyparConstraint.AllowsRefStruct _
| TyparConstraint.IsReferenceType _
| TyparConstraint.SimpleChoice _
| TyparConstraint.RequiresDefaultConstructor _ -> vacc
@@ -411,7 +412,9 @@ let ImportReturnTypeFromMetadata amap m nullnessSource ilTy scoref tinst minst =
let CopyTyparConstraints m tprefInst (tporig: Typar) =
tporig.Constraints
- |> List.map (fun tpc ->
+ // F# does not have escape analysis for authoring 'allows ref struct' generic code. Therefore, typar is not copied, can only come from C# authored code
+ |> List.filter (fun tp -> match tp with | TyparConstraint.AllowsRefStruct _ -> false | _ -> true)
+ |> List.map (fun tpc ->
match tpc with
| TyparConstraint.CoercesTo(ty, _) ->
TyparConstraint.CoercesTo (instType tprefInst ty, m)
@@ -433,6 +436,7 @@ let CopyTyparConstraints m tprefInst (tporig: Typar) =
TyparConstraint.IsNonNullableStruct m
| TyparConstraint.IsUnmanaged _ ->
TyparConstraint.IsUnmanaged m
+ | TyparConstraint.AllowsRefStruct _ -> failwith "impossible, filtered above"
| TyparConstraint.IsReferenceType _ ->
TyparConstraint.IsReferenceType m
| TyparConstraint.SimpleChoice (tys, _) ->
diff --git a/src/Compiler/Checking/TypeRelations.fs b/src/Compiler/Checking/TypeRelations.fs
index 16ed5e9f9d3..498fd3e3bb8 100644
--- a/src/Compiler/Checking/TypeRelations.fs
+++ b/src/Compiler/Checking/TypeRelations.fs
@@ -117,7 +117,7 @@ let rec TypeFeasiblySubsumesType ndeep g amap m ty1 canCoerce ty2 =
| _ ->
// F# reference types are subtypes of type 'obj'
- (isObjTy g ty1 && (canCoerce = CanCoerce || isRefTy g ty2))
+ (isObjTyAnyNullness g ty1 && (canCoerce = CanCoerce || isRefTy g ty2))
||
(isAppTy g ty2 &&
(canCoerce = CanCoerce || isRefTy g ty2) &&
@@ -151,19 +151,13 @@ let ChooseTyparSolutionAndRange (g: TcGlobals) amap (tp:Typar) =
match tpc with
| TyparConstraint.CoercesTo(x, m) ->
join m x, m
- | TyparConstraint.MayResolveMember(_traitInfo, m) ->
- (maxTy, isRefined), m
| TyparConstraint.SimpleChoice(_, m) ->
errorR(Error(FSComp.SR.typrelCannotResolveAmbiguityInPrintf(), m))
(maxTy, isRefined), m
| TyparConstraint.SupportsNull m ->
((addNullnessToTy KnownWithNull maxTy), isRefined), m
- | TyparConstraint.NotSupportsNull m ->
- (maxTy, isRefined), m // NOTE: this doesn't "force" non-nullness, since it is the default choice in 'obj' or 'int'
| TyparConstraint.SupportsComparison m ->
join m g.mk_IComparable_ty, m
- | TyparConstraint.SupportsEquality m ->
- (maxTy, isRefined), m
| TyparConstraint.IsEnum(_, m) ->
errorR(Error(FSComp.SR.typrelCannotResolveAmbiguityInEnum(), m))
(maxTy, isRefined), m
@@ -175,12 +169,15 @@ let ChooseTyparSolutionAndRange (g: TcGlobals) amap (tp:Typar) =
| TyparConstraint.IsUnmanaged m ->
errorR(Error(FSComp.SR.typrelCannotResolveAmbiguityInUnmanaged(), m))
(maxTy, isRefined), m
- | TyparConstraint.RequiresDefaultConstructor m ->
- (maxTy, isRefined), m
- | TyparConstraint.IsReferenceType m ->
+ | TyparConstraint.NotSupportsNull m // NOTE: this doesn't "force" non-nullness, since it is the default choice in 'obj' or 'int'
+ | TyparConstraint.SupportsEquality m
+ | TyparConstraint.AllowsRefStruct m
+ | TyparConstraint.RequiresDefaultConstructor m
+ | TyparConstraint.IsReferenceType m
+ | TyparConstraint.MayResolveMember(_, m)
+ | TyparConstraint.DefaultsTo(_,_, m) ->
(maxTy, isRefined), m
- | TyparConstraint.DefaultsTo(_priority, _ty, m) ->
- (maxTy, isRefined), m)
+ )
if g.langVersion.SupportsFeature LanguageFeature.DiagnosticForObjInference then
match tp.Kind with
diff --git a/src/Compiler/Checking/import.fs b/src/Compiler/Checking/import.fs
index 68e3512864b..1c1b0ed9ea1 100644
--- a/src/Compiler/Checking/import.fs
+++ b/src/Compiler/Checking/import.fs
@@ -653,6 +653,8 @@ let ImportILGenericParameters amap m scoref tinst (nullableFallback:Nullness.Nul
TyparConstraint.IsNonNullableStruct(m)
if gp.HasReferenceTypeConstraint then
TyparConstraint.IsReferenceType(m)
+ if gp.HasAllowsRefStruct then
+ TyparConstraint.AllowsRefStruct(m)
for ilTy in gp.Constraints do
TyparConstraint.CoercesTo(ImportILType amap m importInst (rescopeILType scoref ilTy), m) ]
diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs
index 23afa7bece5..18add6588d0 100644
--- a/src/Compiler/Checking/infos.fs
+++ b/src/Compiler/Checking/infos.fs
@@ -207,7 +207,7 @@ type OptionalArgInfo =
if isByrefTy g ty then
let ty = destByrefTy g ty
PassByRef (ty, analyze ty)
- elif isObjTy g ty then
+ elif isObjTyAnyNullness g ty then
match ilParam.Marshal with
| Some(ILNativeType.IUnknown | ILNativeType.IDispatch | ILNativeType.Interface) -> Constant ILFieldInit.Null
| _ ->
@@ -296,7 +296,7 @@ let CrackParamAttribsInfo g (ty: TType, argInfo: ArgReprInfo) =
| None ->
// Do a type-directed analysis of the type to determine the default value to pass.
// Similar rules as OptionalArgInfo.FromILParameter are applied here, except for the COM and byref-related stuff.
- CallerSide (if isObjTy g ty then MissingValue else DefaultValue)
+ CallerSide (if isObjTyAnyNullness g ty then MissingValue else DefaultValue)
| Some attr ->
let defaultValue = OptionalArgInfo.ValueOfDefaultParameterValueAttrib attr
match defaultValue with
@@ -364,7 +364,9 @@ type ILFieldInit with
| :? uint32 as i -> ILFieldInit.UInt32 i
| :? int64 as i -> ILFieldInit.Int64 i
| :? uint64 as i -> ILFieldInit.UInt64 i
- | _ -> error(Error(FSComp.SR.infosInvalidProvidedLiteralValue(try !!v.ToString() with _ -> "?"), m))
+ | _ ->
+ let txt = match v with | null -> "?" | v -> try !!v.ToString() with _ -> "?"
+ error(Error(FSComp.SR.infosInvalidProvidedLiteralValue(txt), m))
/// Compute the OptionalArgInfo for a provided parameter.
@@ -382,7 +384,7 @@ let OptionalArgInfoOfProvidedParameter (amap: ImportMap) m (provParam : Tainted<
if isByrefTy g ty then
let ty = destByrefTy g ty
PassByRef (ty, analyze ty)
- elif isObjTy g ty then MissingValue
+ elif isObjTyAnyNullness g ty then MissingValue
else DefaultValue
let paramTy = ImportProvidedType amap m (provParam.PApply((fun p -> p.ParameterType), m))
diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs
index 82572ea888a..2a1c876b8f5 100644
--- a/src/Compiler/CodeGen/IlxGen.fs
+++ b/src/Compiler/CodeGen/IlxGen.fs
@@ -3782,11 +3782,11 @@ and GenCoerce cenv cgbuf eenv (e, tgtTy, m, srcTy) sequel =
else
GenExpr cenv cgbuf eenv e Continue
- if not (isObjTy g srcTy) then
+ if not (isObjTyAnyNullness g srcTy) then
let ilFromTy = GenType cenv m eenv.tyenv srcTy
CG.EmitInstr cgbuf (pop 1) (Push [ g.ilg.typ_Object ]) (I_box ilFromTy)
- if not (isObjTy g tgtTy) then
+ if not (isObjTyAnyNullness g tgtTy) then
let ilToTy = GenType cenv m eenv.tyenv tgtTy
CG.EmitInstr cgbuf (pop 1) (Push [ ilToTy ]) (I_unbox_any ilToTy)
@@ -8563,10 +8563,15 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
let ilFieldDef = mkILStaticField (fspec.Name, fty, None, None, access)
+ let isDecimalConstant =
+ match vref.LiteralValue with
+ | Some(Const.Decimal _) -> true
+ | _ -> false
+
let ilFieldDef =
match vref.LiteralValue with
- | Some konst -> ilFieldDef.WithLiteralDefaultValue(Some(GenFieldInit m konst))
- | None -> ilFieldDef
+ | Some konst when not isDecimalConstant -> ilFieldDef.WithLiteralDefaultValue(Some(GenFieldInit m konst))
+ | _ -> ilFieldDef
let ilFieldDef =
let isClassInitializer = (cgbuf.MethodName = ".cctor")
@@ -8578,6 +8583,7 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
|| not isClassInitializer
|| hasLiteralAttr
)
+ || isDecimalConstant
)
let ilAttribs =
@@ -8590,6 +8596,64 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
let ilAttribs = GenAdditionalAttributesForTy g vspec.Type @ ilAttribs
+ let ilAttribs =
+ if isDecimalConstant then
+ match vref.LiteralValue with
+ | Some(Const.Decimal d) ->
+ match System.Decimal.GetBits d with
+ | [| lo; med; hi; signExp |] ->
+ let scale = (min (((signExp &&& 0xFF0000) >>> 16) &&& 0xFF) 28) |> byte
+ let sign = if (signExp &&& 0x80000000) <> 0 then 1uy else 0uy
+
+ let attrib =
+ mkILCustomAttribute (
+ g.attrib_DecimalConstantAttribute.TypeRef,
+ [
+ g.ilg.typ_Byte
+ g.ilg.typ_Byte
+ g.ilg.typ_Int32
+ g.ilg.typ_Int32
+ g.ilg.typ_Int32
+ ],
+ [
+ ILAttribElem.Byte scale
+ ILAttribElem.Byte sign
+ ILAttribElem.UInt32(uint32 hi)
+ ILAttribElem.UInt32(uint32 med)
+ ILAttribElem.UInt32(uint32 lo)
+ ],
+ []
+ )
+
+ let ilInstrs =
+ [
+ mkLdcInt32 lo
+ mkLdcInt32 med
+ mkLdcInt32 hi
+ mkLdcInt32 (int32 sign)
+ mkLdcInt32 (int32 scale)
+ mkNormalNewobj (
+ mkILCtorMethSpecForTy (
+ fspec.ActualType,
+ [
+ g.ilg.typ_Int32
+ g.ilg.typ_Int32
+ g.ilg.typ_Int32
+ g.ilg.typ_Bool
+ g.ilg.typ_Byte
+ ]
+ )
+ )
+ mkNormalStsfld fspec
+ ]
+
+ CG.EmitInstrs cgbuf (pop 0) (Push0) ilInstrs
+ [ attrib ]
+ | _ -> failwith "unreachable"
+ | _ -> failwith "unreachable"
+ else
+ ilAttribs
+
let ilFieldDef =
ilFieldDef.With(customAttrs = mkILCustomAttrs (ilAttribs @ [ g.DebuggerBrowsableNeverAttribute ]))
@@ -12118,7 +12182,7 @@ let LookupGeneratedValue (cenv: cenv) (ctxt: ExecutionContext) eenv (v: Val) =
None
// Invoke the set_Foo method for a declaration with a value. Used to create variables with values programmatically in fsi.exe.
-let SetGeneratedValue (ctxt: ExecutionContext) eenv isForced (v: Val) (value: obj) =
+let SetGeneratedValue (ctxt: ExecutionContext) eenv isForced (v: Val) (value: objnull) =
try
match StorageForVal v.Range v eenv with
| StaticPropertyWithField(fspec, _, hasLiteralAttr, _, _, _, _f, ilSetterMethRef, _) ->
diff --git a/src/Compiler/DependencyManager/DependencyProvider.fs b/src/Compiler/DependencyManager/DependencyProvider.fs
index 709899e9a05..a241880e620 100644
--- a/src/Compiler/DependencyManager/DependencyProvider.fs
+++ b/src/Compiler/DependencyManager/DependencyProvider.fs
@@ -160,19 +160,19 @@ type ReflectionDependencyManagerProvider
let instance =
if not (isNull (theType.GetConstructor([| typeof; typeof |]))) then
- Activator.CreateInstance(theType, [| outputDir :> obj; useResultsCache :> obj |])
+ Activator.CreateInstance(theType, [| outputDir :> objnull; useResultsCache :> objnull |])
else
- Activator.CreateInstance(theType, [| outputDir :> obj |])
+ Activator.CreateInstance(theType, [| outputDir :> objnull |])
- let nameProperty = nameProperty.GetValue >> string
- let keyProperty = keyProperty.GetValue >> string
+ let nameProperty (x: objnull) = x |> nameProperty.GetValue |> string
+ let keyProperty (x: objnull) = x |> keyProperty.GetValue |> string
- let helpMessagesProperty =
- let toStringArray (o: obj) = o :?> string[]
+ let helpMessagesProperty (x: objnull) =
+ let toStringArray (o: objnull) = o :?> string[]
match helpMessagesProperty with
- | Some helpMessagesProperty -> helpMessagesProperty.GetValue >> toStringArray
- | None -> fun _ -> [||]
+ | Some helpMessagesProperty -> x |> helpMessagesProperty.GetValue |> toStringArray
+ | None -> [||]
static member InstanceMaker(theType: Type, outputDir: string option, useResultsCache: bool) =
match
@@ -453,14 +453,18 @@ type ReflectionDependencyManagerProvider
None, [||]
match method with
+ | None -> ReflectionDependencyManagerProvider.MakeResultFromFields(false, [||], [||], Seq.empty, Seq.empty, Seq.empty)
| Some m ->
- let result = m.Invoke(instance, arguments)
+ match m.Invoke(instance, arguments) with
+ | null -> ReflectionDependencyManagerProvider.MakeResultFromFields(false, [||], [||], Seq.empty, Seq.empty, Seq.empty)
// Verify the number of arguments returned in the tuple returned by resolvedependencies, it can be:
// 1 - object with properties
// 3 - (bool * string list * string list)
// Support legacy api return shape (bool, seq, seq) --- original paket packagemanager
- if FSharpType.IsTuple(result.GetType()) then
+ | result when FSharpType.IsTuple(result.GetType()) |> not ->
+ ReflectionDependencyManagerProvider.MakeResultFromObject(result)
+ | result ->
// Verify the number of arguments returned in the tuple returned by resolvedependencies, it can be:
// 3 - (bool * string list * string list)
let success, sourceFiles, packageRoots =
@@ -474,10 +478,6 @@ type ReflectionDependencyManagerProvider
| _ -> false, seqEmpty, seqEmpty
ReflectionDependencyManagerProvider.MakeResultFromFields(success, [||], [||], Seq.empty, sourceFiles, packageRoots)
- else
- ReflectionDependencyManagerProvider.MakeResultFromObject(result)
-
- | None -> ReflectionDependencyManagerProvider.MakeResultFromFields(false, [||], [||], Seq.empty, Seq.empty, Seq.empty)
/// Provides DependencyManagement functions.
/// Class is IDisposable
diff --git a/src/Compiler/Driver/GraphChecking/Graph.fs b/src/Compiler/Driver/GraphChecking/Graph.fs
index 210ca927c7f..6bfb1199181 100644
--- a/src/Compiler/Driver/GraphChecking/Graph.fs
+++ b/src/Compiler/Driver/GraphChecking/Graph.fs
@@ -83,7 +83,7 @@ module internal Graph =
graph
|> Seq.iter (fun (KeyValue(file, deps)) -> printfn $"{file} -> {deps |> Array.map nodePrinter |> join}")
- let print (graph: Graph<'Node>) : unit =
+ let print (graph: Graph<'Node> when 'Node: not null) : unit =
printCustom graph (fun node -> node.ToString() |> string)
let serialiseToMermaid (graph: Graph) =
diff --git a/src/Compiler/Driver/GraphChecking/Graph.fsi b/src/Compiler/Driver/GraphChecking/Graph.fsi
index a93e429d2fe..2caf421dc54 100644
--- a/src/Compiler/Driver/GraphChecking/Graph.fsi
+++ b/src/Compiler/Driver/GraphChecking/Graph.fsi
@@ -20,7 +20,7 @@ module internal Graph =
/// Create a reverse of the graph.
val reverse<'Node when 'Node: equality> : originalGraph: Graph<'Node> -> Graph<'Node>
/// Print the contents of the graph to the standard output.
- val print: graph: Graph<'Node> -> unit
+ val print: graph: Graph<'Node> -> unit when 'Node: not null
/// Create a simple Mermaid graph
val serialiseToMermaid: graph: Graph -> string
/// Create a simple Mermaid graph and save it under the path specified.
diff --git a/src/Compiler/Facilities/prim-parsing.fs b/src/Compiler/Facilities/prim-parsing.fs
index 3088a5579ed..7fb0d7fca41 100644
--- a/src/Compiler/Facilities/prim-parsing.fs
+++ b/src/Compiler/Facilities/prim-parsing.fs
@@ -14,7 +14,7 @@ exception Accept of obj
[]
type internal IParseState
- (ruleStartPoss: Position[], ruleEndPoss: Position[], lhsPos: Position[], ruleValues: obj[], lexbuf: LexBuffer) =
+ (ruleStartPoss: Position[], ruleEndPoss: Position[], lhsPos: Position[], ruleValues: objnull[], lexbuf: LexBuffer) =
member _.LexBuffer = lexbuf
member _.InputRange index =
@@ -125,7 +125,7 @@ type Stack<'a>(n) =
member buf.PrintStack() =
for i = 0 to (count - 1) do
- Console.Write("{0}{1}", contents[i], (if i = count - 1 then ":" else "-"))
+ Console.Write("{0}{1}", contents[i] :> objnull, (if i = count - 1 then ":" else "-"))
module Flags =
#if DEBUG
@@ -151,7 +151,10 @@ module internal Implementation =
//-------------------------------------------------------------------------
// Read the tables written by FSYACC.
- type AssocTable(elemTab: uint16[], offsetTab: uint16[], cache: int[], cacheSize: int) =
+ type AssocTable(elemTab: uint16[], offsetTab: uint16[], cache: int[]) =
+
+ do Array.fill cache 0 cache.Length -1
+ let cacheSize = cache.Length / 2
member t.ReadAssoc(minElemNum, maxElemNum, defaultValueOfAssoc, keyToFind) =
// do a binary chop on the table
@@ -231,7 +234,7 @@ module internal Implementation =
[]
[]
type ValueInfo =
- val value: obj
+ val value: objnull
val startPos: Position
val endPos: Position
@@ -269,17 +272,12 @@ module internal Implementation =
// The 100 here means a maximum of 100 elements for each rule
let ruleStartPoss = (Array.zeroCreate 100: Position[])
let ruleEndPoss = (Array.zeroCreate 100: Position[])
- let ruleValues = (Array.zeroCreate 100: obj[])
+ let ruleValues = (Array.zeroCreate 100: objnull[])
let lhsPos = (Array.zeroCreate 2: Position[])
let reductions = tables.reductions
let cacheSize = 7919 // the 1000'th prime
- // Use a simpler hash table with faster lookup, but only one
- // hash bucket per key.
let actionTableCache = ArrayPool.Shared.Rent(cacheSize * 2)
let gotoTableCache = ArrayPool.Shared.Rent(cacheSize * 2)
- // Clear the arrays since ArrayPool does not
- Array.Clear(actionTableCache, 0, actionTableCache.Length)
- Array.Clear(gotoTableCache, 0, gotoTableCache.Length)
use _cacheDisposal =
{ new IDisposable with
@@ -289,10 +287,10 @@ module internal Implementation =
}
let actionTable =
- AssocTable(tables.actionTableElements, tables.actionTableRowOffsets, actionTableCache, cacheSize)
+ AssocTable(tables.actionTableElements, tables.actionTableRowOffsets, actionTableCache)
let gotoTable =
- AssocTable(tables.gotos, tables.sparseGotoTableRowOffsets, gotoTableCache, cacheSize)
+ AssocTable(tables.gotos, tables.sparseGotoTableRowOffsets, gotoTableCache)
let stateToProdIdxsTable =
IdxToIdxListTable(tables.stateToProdIdxsTableElements, tables.stateToProdIdxsTableRowOffsets)
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 10991bb59f7..74fcc37340c 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -4693,7 +4693,7 @@ type FsiEvaluationSession
let lexResourceManager = LexResourceManager()
/// The lock stops the type checker running at the same time as the server intellisense implementation.
- let tcLockObject = box 7 // any new object will do
+ let tcLockObject = box 7 |> Unchecked.nonNull // any new object will do
let resolveAssemblyRef (aref: ILAssemblyRef) =
// Explanation: This callback is invoked during compilation to resolve assembly references
diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs
index d00b5fe7934..2623cbde347 100644
--- a/src/Compiler/Service/FSharpParseFileResults.fs
+++ b/src/Compiler/Service/FSharpParseFileResults.fs
@@ -573,11 +573,11 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
yield! checkRange m
yield! walkExpr isControlFlow innerExpr
- | SynExpr.YieldOrReturn(_, e, m) ->
+ | SynExpr.YieldOrReturn(_, e, m, _) ->
yield! checkRange m
yield! walkExpr false e
- | SynExpr.YieldOrReturnFrom(_, e, _)
+ | SynExpr.YieldOrReturnFrom(_, e, _, _)
| SynExpr.DoBang(expr = e) ->
yield! checkRange e.Range
yield! walkExpr false e
diff --git a/src/Compiler/Service/ServiceStructure.fs b/src/Compiler/Service/ServiceStructure.fs
index 6ca45aa6961..5fab5ef9eb5 100644
--- a/src/Compiler/Service/ServiceStructure.fs
+++ b/src/Compiler/Service/ServiceStructure.fs
@@ -246,11 +246,11 @@ module Structure =
rcheck Scope.New Collapse.Below r e.Range
parseExpr e
- | SynExpr.YieldOrReturn(_, e, r) ->
+ | SynExpr.YieldOrReturn(_, e, r, _) ->
rcheck Scope.YieldOrReturn Collapse.Below r r
parseExpr e
- | SynExpr.YieldOrReturnFrom(_, e, r) ->
+ | SynExpr.YieldOrReturnFrom(_, e, r, _) ->
rcheck Scope.YieldOrReturnBang Collapse.Below r r
parseExpr e
diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs
index 525faf3be3d..5f6588bd770 100644
--- a/src/Compiler/Service/service.fs
+++ b/src/Compiler/Service/service.fs
@@ -72,10 +72,10 @@ module CompileHelpers =
try
f exiter
- 0
+ None
with e ->
stopProcessingRecovery e range0
- 1
+ Some e
/// Compile using the given flags. Source files names are resolved via the FileSystem API. The output file must be given by a -o flag.
let compileFromArgs (ctok, argv: string[], legacyReferenceResolver, tcImportsCapture, dynamicAssemblyCreator) =
diff --git a/src/Compiler/Service/service.fsi b/src/Compiler/Service/service.fsi
index 0e48a0d6360..3e4fde2229c 100644
--- a/src/Compiler/Service/service.fsi
+++ b/src/Compiler/Service/service.fsi
@@ -400,11 +400,12 @@ type public FSharpChecker =
/// Compile using the given flags. Source files names are resolved via the FileSystem API.
/// The output file must be given by a -o flag.
/// The first argument is ignored and can just be "fsc.exe".
+ /// The method returns the collected diagnostics, and (possibly) a terminating exception.
///
///
/// The command line arguments for the project build.
/// An optional string used for tracing compiler operations associated with this request.
- member Compile: argv: string[] * ?userOpName: string -> Async
+ member Compile: argv: string[] * ?userOpName: string -> Async
///
/// Try to get type check results for a file. This looks up the results of recent type checks of the
diff --git a/src/Compiler/Symbols/Exprs.fs b/src/Compiler/Symbols/Exprs.fs
index 15b1bb2a3f6..91480597cc2 100644
--- a/src/Compiler/Symbols/Exprs.fs
+++ b/src/Compiler/Symbols/Exprs.fs
@@ -121,7 +121,7 @@ type E =
| ValueSet of FSharpMemberOrFunctionOrValue * FSharpExpr
| Unused
| DefaultValue of FSharpType
- | Const of obj * FSharpType
+ | Const of objnull * FSharpType
| AddressOf of FSharpExpr
| Sequential of FSharpExpr * FSharpExpr
| IntegerForLoop of FSharpExpr * FSharpExpr * FSharpExpr * bool * DebugPointAtFor * DebugPointAtInOrTo
diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs
index a40d2a36de1..c11647ab0a5 100644
--- a/src/Compiler/SyntaxTree/ParseHelpers.fs
+++ b/src/Compiler/SyntaxTree/ParseHelpers.fs
@@ -108,7 +108,7 @@ module LexbufLocalXmlDocStore =
|> unbox
let ClearXmlDoc (lexbuf: Lexbuf) =
- lexbuf.BufferLocalStore[xmlDocKey] <- box (XmlDocCollector())
+ lexbuf.BufferLocalStore[xmlDocKey] <- box (XmlDocCollector()) |> Unchecked.nonNull
/// Called from the lexer to save a single line of XML doc comment.
let SaveXmlDocLine (lexbuf: Lexbuf, lineText, range: range) =
@@ -1050,7 +1050,22 @@ let mkLocalBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs,
else
Some mIn)
- SynExpr.LetOrUse(isRec, isUse, decls, body, mWhole, { InKeyword = mIn })
+ let mLetOrUse =
+ match decls with
+ | SynBinding(trivia = trivia) :: _ -> trivia.LeadingKeyword.Range
+ | _ -> Range.Zero
+
+ SynExpr.LetOrUse(
+ isRec,
+ isUse,
+ decls,
+ body,
+ mWhole,
+ {
+ LetOrUseKeyword = mLetOrUse
+ InKeyword = mIn
+ }
+ )
let mkDefnBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, _bindingSetRange), attrs, vis, attrsm) =
if isUse then
diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs
index f97fe05234d..fc0c811e55d 100644
--- a/src/Compiler/SyntaxTree/SyntaxTree.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTree.fs
@@ -704,9 +704,9 @@ type SynExpr =
| SequentialOrImplicitYield of debugPoint: DebugPointAtSequential * expr1: SynExpr * expr2: SynExpr * ifNotStmt: SynExpr * range: range
- | YieldOrReturn of flags: (bool * bool) * expr: SynExpr * range: range
+ | YieldOrReturn of flags: (bool * bool) * expr: SynExpr * range: range * trivia: SynExprYieldOrReturnTrivia
- | YieldOrReturnFrom of flags: (bool * bool) * expr: SynExpr * range: range
+ | YieldOrReturnFrom of flags: (bool * bool) * expr: SynExpr * range: range * trivia: SynExprYieldOrReturnFromTrivia
| LetOrUseBang of
bindDebugPoint: DebugPointAtBinding *
diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi
index 99138631957..45b03ad3b75 100644
--- a/src/Compiler/SyntaxTree/SyntaxTree.fsi
+++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi
@@ -877,12 +877,12 @@ type SynExpr =
/// F# syntax: yield expr
/// F# syntax: return expr
/// Computation expressions only
- | YieldOrReturn of flags: (bool * bool) * expr: SynExpr * range: range
+ | YieldOrReturn of flags: (bool * bool) * expr: SynExpr * range: range * trivia: SynExprYieldOrReturnTrivia
/// F# syntax: yield! expr
/// F# syntax: return! expr
/// Computation expressions only
- | YieldOrReturnFrom of flags: (bool * bool) * expr: SynExpr * range: range
+ | YieldOrReturnFrom of flags: (bool * bool) * expr: SynExpr * range: range * trivia: SynExprYieldOrReturnFromTrivia
/// F# syntax: let! pat = expr in expr
/// F# syntax: use! pat = expr in expr
diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs
index 680986ea503..8dc46313341 100644
--- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs
@@ -883,8 +883,8 @@ let rec synExprContainsError inpExpr =
| SynExpr.InferredDowncast(e, _)
| SynExpr.Lazy(e, _)
| SynExpr.TraitCall(_, _, e, _)
- | SynExpr.YieldOrReturn(_, e, _)
- | SynExpr.YieldOrReturnFrom(_, e, _)
+ | SynExpr.YieldOrReturn(_, e, _, _)
+ | SynExpr.YieldOrReturnFrom(_, e, _, _)
| SynExpr.DoBang(e, _, _)
| SynExpr.Fixed(e, _)
| SynExpr.DebugPoint(_, _, e)
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
index 7e03572719e..6a550c3b1a8 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
@@ -85,10 +85,15 @@ type SynExprDotLambdaTrivia =
[]
type SynExprLetOrUseTrivia =
{
+ LetOrUseKeyword: range
InKeyword: range option
}
- static member Zero: SynExprLetOrUseTrivia = { InKeyword = None }
+ static member Zero: SynExprLetOrUseTrivia =
+ {
+ InKeyword = None
+ LetOrUseKeyword = Range.Zero
+ }
[]
type SynExprLetOrUseBangTrivia =
@@ -117,6 +122,25 @@ type SynExprMatchBangTrivia =
WithKeyword: range
}
+[]
+type SynExprYieldOrReturnTrivia =
+ {
+ YieldOrReturnKeyword: range
+ }
+
+ static member Zero: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = Range.Zero }
+
+[]
+type SynExprYieldOrReturnFromTrivia =
+ {
+ YieldOrReturnFromKeyword: range
+ }
+
+ static member Zero: SynExprYieldOrReturnFromTrivia =
+ {
+ YieldOrReturnFromKeyword = Range.Zero
+ }
+
[]
type SynExprDoBangTrivia = { DoBangKeyword: range }
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
index 3c678a72679..f16294b0a1d 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
@@ -129,6 +129,8 @@ type SynExprDotLambdaTrivia =
[]
type SynExprLetOrUseTrivia =
{
+ /// The syntax range of the `let` or `use` keyword.
+ LetOrUseKeyword: range
/// The syntax range of the `in` keyword.
InKeyword: range option
}
@@ -177,6 +179,24 @@ type SynExprDoBangTrivia =
DoBangKeyword: range
}
+/// Represents additional information for SynExpr.YieldOrReturn
+[]
+type SynExprYieldOrReturnTrivia =
+ {
+ /// The syntax range of the `yield` or `return` keyword.
+ YieldOrReturnKeyword: range
+ }
+
+ static member Zero: SynExprYieldOrReturnTrivia
+
+/// Represents additional information for SynExpr.YieldOrReturnFrom
+[]
+type SynExprYieldOrReturnFromTrivia =
+ {
+ /// The syntax range of the `yield!` or `return!` keyword.
+ YieldOrReturnFromKeyword: range
+ }
+
/// Represents additional information for SynExpr.AnonRecd
[]
type SynExprAnonRecdTrivia =
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index 2c065437f2b..531ef79d264 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -1490,6 +1490,7 @@ type TcGlobals(
member val attrib_CallerFilePathAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerFilePathAttribute"
member val attrib_CallerMemberNameAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerMemberNameAttribute"
member val attrib_SkipLocalsInitAttribute = findSysAttrib "System.Runtime.CompilerServices.SkipLocalsInitAttribute"
+ member val attrib_DecimalConstantAttribute = findSysAttrib "System.Runtime.CompilerServices.DecimalConstantAttribute"
member val attribs_Unsupported = v_attribs_Unsupported
member val attrib_ProjectionParameterAttribute = mk_MFCore_attrib "ProjectionParameterAttribute"
diff --git a/src/Compiler/TypedTree/TcGlobals.fsi b/src/Compiler/TypedTree/TcGlobals.fsi
index 950d5217500..b7d5a892d06 100644
--- a/src/Compiler/TypedTree/TcGlobals.fsi
+++ b/src/Compiler/TypedTree/TcGlobals.fsi
@@ -474,6 +474,8 @@ type internal TcGlobals =
member attrib_SkipLocalsInitAttribute: BuiltinAttribInfo
+ member attrib_DecimalConstantAttribute: BuiltinAttribInfo
+
member attrib_StructAttribute: BuiltinAttribInfo
member attrib_StructLayoutAttribute: BuiltinAttribInfo
diff --git a/src/Compiler/TypedTree/TypeProviders.fs b/src/Compiler/TypedTree/TypeProviders.fs
index 78baba4ee9d..5c81312e135 100644
--- a/src/Compiler/TypedTree/TypeProviders.fs
+++ b/src/Compiler/TypedTree/TypeProviders.fs
@@ -979,7 +979,7 @@ type ProvidedExprType =
| ProvidedTryFinallyExpr of ProvidedExpr * ProvidedExpr
| ProvidedLambdaExpr of ProvidedVar * ProvidedExpr
| ProvidedCallExpr of ProvidedExpr option * ProvidedMethodInfo * ProvidedExpr[]
- | ProvidedConstantExpr of obj * ProvidedType
+ | ProvidedConstantExpr of objnull * ProvidedType
| ProvidedDefaultExpr of ProvidedType
| ProvidedNewTupleExpr of ProvidedExpr[]
| ProvidedTupleGetExpr of ProvidedExpr * int
diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs
index daf31357df3..b948e91fb65 100644
--- a/src/Compiler/TypedTree/TypedTree.fs
+++ b/src/Compiler/TypedTree/TypedTree.fs
@@ -2531,6 +2531,9 @@ type TyparConstraint =
/// A constraint that a type is .NET unmanaged type
| IsUnmanaged of range: range
+
+ /// An anti-constraint indicating that ref structs (e.g. Span<>) are allowed here
+ | AllowsRefStruct of range:range
// %+A formatting is used, so this is not needed
//[]
diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi
index 3ba4f5c12ba..d357895728d 100644
--- a/src/Compiler/TypedTree/TypedTree.fsi
+++ b/src/Compiler/TypedTree/TypedTree.fsi
@@ -1694,6 +1694,9 @@ type TyparConstraint =
/// A constraint that a type is .NET unmanaged type
| IsUnmanaged of range: range
+ /// An anti-constraint indicating that ref structs (e.g. Span<>) are allowed here
+ | AllowsRefStruct of range: range
+
override ToString: unit -> string
[]
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs
index 333b29cd78f..71f26dbf95b 100644
--- a/src/Compiler/TypedTree/TypedTreeOps.fs
+++ b/src/Compiler/TypedTree/TypedTreeOps.fs
@@ -272,7 +272,8 @@ and remapTyparConstraintsAux tyenv cs =
| TyparConstraint.SupportsEquality _
| TyparConstraint.SupportsNull _
| TyparConstraint.NotSupportsNull _
- | TyparConstraint.IsUnmanaged _
+ | TyparConstraint.IsUnmanaged _
+ | TyparConstraint.AllowsRefStruct _
| TyparConstraint.IsNonNullableStruct _
| TyparConstraint.IsReferenceType _
| TyparConstraint.RequiresDefaultConstructor _ -> Some x)
@@ -1039,6 +1040,7 @@ and typarConstraintsAEquivAux erasureFlag g aenv tpc1 tpc2 =
| TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _
| TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _
| TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _
+ | TyparConstraint.AllowsRefStruct _, TyparConstraint.AllowsRefStruct _
| TyparConstraint.RequiresDefaultConstructor _, TyparConstraint.RequiresDefaultConstructor _ -> true
| _ -> false
@@ -1851,7 +1853,20 @@ let isArray1DTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _, _) -
let isUnitTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _, _) -> tyconRefEq g g.unit_tcr_canon tcref | _ -> false)
-let isObjTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _, _) -> tyconRefEq g g.system_Object_tcref tcref | _ -> false)
+let isObjTyAnyNullness g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _, _) -> tyconRefEq g g.system_Object_tcref tcref | _ -> false)
+
+let isObjNullTy g ty =
+ ty
+ |> stripTyEqns g
+ |> (function TType_app(tcref, _, n) when (not g.checkNullness) || (n.TryEvaluate() <> ValueSome(NullnessInfo.WithoutNull))
+ -> tyconRefEq g g.system_Object_tcref tcref | _ -> false)
+
+let isObjTyWithoutNull (g:TcGlobals) ty =
+ g.checkNullness &&
+ ty
+ |> stripTyEqns g
+ |> (function TType_app(tcref, _, n) when (n.TryEvaluate() = ValueSome(NullnessInfo.WithoutNull))
+ -> tyconRefEq g g.system_Object_tcref tcref | _ -> false)
let isValueTypeTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _, _) -> tyconRefEq g g.system_Value_tcref tcref | _ -> false)
@@ -2345,6 +2360,7 @@ and accFreeInTyparConstraint opts tpc acc =
| TyparConstraint.IsNonNullableStruct _
| TyparConstraint.IsReferenceType _
| TyparConstraint.IsUnmanaged _
+ | TyparConstraint.AllowsRefStruct _
| TyparConstraint.RequiresDefaultConstructor _ -> acc
and accFreeInTrait opts (TTrait(tys, _, _, argTys, retTy, _, sln)) acc =
@@ -2480,6 +2496,7 @@ and accFreeInTyparConstraintLeftToRight g cxFlag thruFlag acc tpc =
| TyparConstraint.NotSupportsNull _
| TyparConstraint.IsNonNullableStruct _
| TyparConstraint.IsUnmanaged _
+ | TyparConstraint.AllowsRefStruct _
| TyparConstraint.IsReferenceType _
| TyparConstraint.RequiresDefaultConstructor _ -> acc
@@ -4223,6 +4240,8 @@ module DebugPrint =
wordL (tagText "not null") |> constraintPrefix
| TyparConstraint.IsUnmanaged _ ->
wordL (tagText "unmanaged") |> constraintPrefix
+ | TyparConstraint.AllowsRefStruct _ ->
+ wordL (tagText "allows ref struct") |> constraintPrefix
| TyparConstraint.SimpleChoice(tys, _) ->
bracketL (sepListL (sepL (tagText "|")) (List.map (auxTypeL env) tys)) |> constraintPrefix
| TyparConstraint.RequiresDefaultConstructor _ ->
@@ -10014,7 +10033,7 @@ let EvalArithUnOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt3
| _ -> error (Error ( FSComp.SR.tastNotAConstantExpression(), m))
with :? System.OverflowException -> error (Error ( FSComp.SR.tastConstantExpressionOverflow(), m))
-let EvalArithBinOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt32, opUInt64, opSingle, opDouble) (arg1: Expr) (arg2: Expr) =
+let EvalArithBinOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt32, opUInt64, opSingle, opDouble, opDecimal) (arg1: Expr) (arg2: Expr) =
// At compile-time we check arithmetic
let m = unionRanges arg1.Range arg2.Range
try
@@ -10029,6 +10048,7 @@ let EvalArithBinOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt
| Expr.Const (Const.UInt64 x1, _, ty), Expr.Const (Const.UInt64 x2, _, _) -> Expr.Const (Const.UInt64 (opUInt64 x1 x2), m, ty)
| Expr.Const (Const.Single x1, _, ty), Expr.Const (Const.Single x2, _, _) -> Expr.Const (Const.Single (opSingle x1 x2), m, ty)
| Expr.Const (Const.Double x1, _, ty), Expr.Const (Const.Double x2, _, _) -> Expr.Const (Const.Double (opDouble x1 x2), m, ty)
+ | Expr.Const (Const.Decimal x1, _, ty), Expr.Const (Const.Decimal x2, _, _) -> Expr.Const (Const.Decimal (opDecimal x1 x2), m, ty)
| _ -> error (Error ( FSComp.SR.tastNotAConstantExpression(), m))
with :? System.OverflowException -> error (Error ( FSComp.SR.tastConstantExpressionOverflow(), m))
@@ -10060,9 +10080,10 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
| Const.Single _
| Const.Char _
| Const.Zero
- | Const.String _ ->
+ | Const.String _
+ | Const.Decimal _ ->
x
- | Const.Decimal _ | Const.IntPtr _ | Const.UIntPtr _ | Const.Unit ->
+ | Const.IntPtr _ | Const.UIntPtr _ | Const.Unit ->
errorR (Error ( FSComp.SR.tastNotAConstantExpression(), m))
x
@@ -10078,7 +10099,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
match v1 with
| IntegerConstExpr ->
- EvalArithBinOp ((|||), (|||), (|||), (|||), (|||), (|||), (|||), (|||), ignore2, ignore2) v1 (EvalAttribArgExpr suppressLangFeatureCheck g arg2)
+ EvalArithBinOp ((|||), (|||), (|||), (|||), (|||), (|||), (|||), (|||), ignore2, ignore2, ignore2) v1 (EvalAttribArgExpr suppressLangFeatureCheck g arg2)
| _ ->
errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range))
x
@@ -10093,7 +10114,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
Expr.Const (Const.Char (x1 + x2), m, ty)
| _ ->
checkFeature()
- EvalArithBinOp (Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+)) v1 v2
+ EvalArithBinOp (Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+)) v1 v2
| SpecificBinopExpr g g.unchecked_subtraction_vref (arg1, arg2) ->
checkFeature()
let v1, v2 = EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1, EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2
@@ -10102,16 +10123,16 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
| Expr.Const (Const.Char x1, m, ty), Expr.Const (Const.Char x2, _, _) ->
Expr.Const (Const.Char (x1 - x2), m, ty)
| _ ->
- EvalArithBinOp (Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-)) v1 v2
+ EvalArithBinOp (Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-)) v1 v2
| SpecificBinopExpr g g.unchecked_multiply_vref (arg1, arg2) ->
checkFeature()
- EvalArithBinOp (Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
+ EvalArithBinOp (Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
| SpecificBinopExpr g g.unchecked_division_vref (arg1, arg2) ->
checkFeature()
- EvalArithBinOp ((/), (/), (/), (/), (/), (/), (/), (/), (/), (/)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
+ EvalArithBinOp ((/), (/), (/), (/), (/), (/), (/), (/), (/), (/), (/)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
| SpecificBinopExpr g g.unchecked_modulus_vref (arg1, arg2) ->
checkFeature()
- EvalArithBinOp ((%), (%), (%), (%), (%), (%), (%), (%), (%), (%)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
+ EvalArithBinOp ((%), (%), (%), (%), (%), (%), (%), (%), (%), (%), (%)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
| SpecificBinopExpr g g.bitwise_shift_left_vref (arg1, arg2) ->
checkFeature()
EvalArithShiftOp ((<<<), (<<<), (<<<), (<<<), (<<<), (<<<), (<<<), (<<<)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
@@ -10124,7 +10145,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
match v1 with
| IntegerConstExpr ->
- EvalArithBinOp ((&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), ignore2, ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
+ EvalArithBinOp ((&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), ignore2, ignore2, ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
| _ ->
errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range))
x
@@ -10134,7 +10155,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
match v1 with
| IntegerConstExpr ->
- EvalArithBinOp ((^^^), (^^^), (^^^), (^^^), (^^^), (^^^), (^^^), (^^^), ignore2, ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
+ EvalArithBinOp ((^^^), (^^^), (^^^), (^^^), (^^^), (^^^), (^^^), (^^^), ignore2, ignore2, ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
| _ ->
errorR (Error (FSComp.SR.tastNotAConstantExpression(), x.Range))
x
@@ -10144,7 +10165,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
match v1 with
| FloatConstExpr ->
- EvalArithBinOp (ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ( ** ), ( ** )) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
+ EvalArithBinOp (ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ( ** ), ( ** ), ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
| _ ->
errorR (Error (FSComp.SR.tastNotAConstantExpression(), x.Range))
x
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi
index 8c17d530762..85c2adaab91 100755
--- a/src/Compiler/TypedTree/TypedTreeOps.fsi
+++ b/src/Compiler/TypedTree/TypedTreeOps.fsi
@@ -1666,8 +1666,14 @@ val rankOfArrayTyconRef: TcGlobals -> TyconRef -> int
/// Determine if a type is the F# unit type
val isUnitTy: TcGlobals -> TType -> bool
-/// Determine if a type is the System.Object type
-val isObjTy: TcGlobals -> TType -> bool
+/// Determine if a type is the System.Object type with any nullness qualifier
+val isObjTyAnyNullness: TcGlobals -> TType -> bool
+
+/// Determine if a type is the (System.Object | null) type. Allows either nullness if null checking is disabled.
+val isObjNullTy: TcGlobals -> TType -> bool
+
+/// Determine if a type is a strictly non-nullable System.Object type. If nullness checking is disabled, this returns false.
+val isObjTyWithoutNull: TcGlobals -> TType -> bool
/// Determine if a type is the System.ValueType type
val isValueTypeTy: TcGlobals -> TType -> bool
diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs
index 9ade306d77c..9515d49b80d 100644
--- a/src/Compiler/TypedTree/TypedTreePickle.fs
+++ b/src/Compiler/TypedTree/TypedTreePickle.fs
@@ -1612,19 +1612,22 @@ let p_tyar_constraint x st =
| TyparConstraint.SupportsComparison _ -> p_byte 10 st
| TyparConstraint.SupportsEquality _ -> p_byte 11 st
| TyparConstraint.IsUnmanaged _ -> p_byte 12 st
- | TyparConstraint.NotSupportsNull _ ->
- failwith "NotSupportsNull constraints should only be emitted to streamB"
+
+ | TyparConstraint.NotSupportsNull _
+ | TyparConstraint.AllowsRefStruct _ ->
+ failwith $"%A{x} constraints should only be emitted to streamB"
-// Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers
+// Some extra F#9+ constraints are stored in stream B, these will be ignored by earlier F# compilers
let p_tyar_constraintB x st =
match x with
| TyparConstraint.NotSupportsNull _ -> p_byteB 1 st
- | _ -> failwith "only NotSupportsNull constraints should be emitted to streamB"
+ | TyparConstraint.AllowsRefStruct _ -> p_byteB 2 st
+ | _ -> failwith "only NotSupportsNull and AllowsRefStruct constraints should be emitted to streamB"
let p_tyar_constraints cxs st =
- let cxs1, cxs2 = cxs |> List.partition (function TyparConstraint.NotSupportsNull _ -> false | _ -> true)
+ let cxs1, cxs2 = cxs |> List.partition (function TyparConstraint.NotSupportsNull _ | TyparConstraint.AllowsRefStruct _ -> false | _ -> true)
p_list p_tyar_constraint cxs1 st
- // Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers
+ // Some extra F#9+ constraints are stored in stream B, these will be ignored by earlier F# compilers
p_listB p_tyar_constraintB cxs2 st
let u_tyar_constraint st =
@@ -1645,16 +1648,17 @@ let u_tyar_constraint st =
| 12 -> (fun _ -> TyparConstraint.IsUnmanaged range0)
| _ -> ufailwith st "u_tyar_constraint"
-// Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers
+// Some extra F#9+ constraints are stored in stream B, these will be ignored by earlier F# compilers
let u_tyar_constraintB st =
let tag = u_byteB st
match tag with
- | 1 -> TyparConstraint.NotSupportsNull range0
+ | 1 -> TyparConstraint.NotSupportsNull range0
+ | 2 -> TyparConstraint.AllowsRefStruct range0
| _ -> ufailwith st "u_tyar_constraintB - unexpected constraint in streamB"
let u_tyar_constraints st =
let cxs1 = u_list_revi u_tyar_constraint st
- // Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers
+ // Some extra F#9+ constraints are stored in stream B, these will be ignored by earlier F# compilers
//
// If the B stream is not present (e.g. reading F# 4.5 components) then this list will be empty
// via the implementation of u_listB.
diff --git a/src/Compiler/Utilities/FileSystem.fs b/src/Compiler/Utilities/FileSystem.fs
index cb8c1cdbea8..a541234199e 100644
--- a/src/Compiler/Utilities/FileSystem.fs
+++ b/src/Compiler/Utilities/FileSystem.fs
@@ -157,7 +157,7 @@ type ByteArrayMemory(bytes: byte[], offset, length) =
type SafeUnmanagedMemoryStream =
inherit UnmanagedMemoryStream
- val mutable private holder: obj
+ val mutable private holder: objnull
val mutable private isDisposed: bool
new(addr, length, holder) =
diff --git a/src/Compiler/Utilities/illib.fs b/src/Compiler/Utilities/illib.fs
index 6c5a52a2fd8..e09c650e39b 100644
--- a/src/Compiler/Utilities/illib.fs
+++ b/src/Compiler/Utilities/illib.fs
@@ -1139,7 +1139,7 @@ module IPartialEqualityComparer =
member _.GetHashCode(Wrap x) = per.GetHashCode x
}
// Wrap a Wrap _ around all keys in case the key type is itself a type using null as a representation
- let dict = Dictionary, obj>(wper)
+ let dict = Dictionary, _>(wper)
seq
|> List.filter (fun v ->
diff --git a/src/Compiler/Utilities/sformat.fs b/src/Compiler/Utilities/sformat.fs
index 9279bf093d0..f6fc27b1e51 100644
--- a/src/Compiler/Utilities/sformat.fs
+++ b/src/Compiler/Utilities/sformat.fs
@@ -1012,7 +1012,7 @@ module Display =
// Recursive descent
let rec nestedObjL depthLim prec (x: obj, ty: Type) = objL ShowAll depthLim prec (x, ty)
- and objL showMode depthLim prec (x: obj, ty: Type) =
+ and objL showMode depthLim prec (x: objnull, ty: Type) =
let info = Value.GetValueInfo bindingFlags (x, ty)
try
if depthLim <= 0 || exceededPrintSize () then
@@ -1337,9 +1337,6 @@ module Display =
if
word = "map"
- && (match v with
- | null -> false
- | _ -> true)
&& tyv.IsGenericType
&& tyv.GetGenericTypeDefinition() = typedefof>
then
diff --git a/src/Compiler/Utilities/sr.fs b/src/Compiler/Utilities/sr.fs
index 9473cc8d78e..10a615846e3 100644
--- a/src/Compiler/Utilities/sr.fs
+++ b/src/Compiler/Utilities/sr.fs
@@ -27,7 +27,7 @@ module internal DiagnosticMessage =
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
- let mkFunctionValue (tys: System.Type[]) (impl: obj -> obj) =
+ let mkFunctionValue (tys: System.Type[]) (impl: objnull -> objnull) =
FSharpValue.MakeFunction(FSharpType.MakeFunctionType(tys[0], tys[1]), impl)
let funTyC = typeof obj>.GetGenericTypeDefinition()
diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy
index 656b75c39ff..185bd1ed842 100644
--- a/src/Compiler/pars.fsy
+++ b/src/Compiler/pars.fsy
@@ -4402,18 +4402,22 @@ declExpr:
exprFromParseError (SynExpr.ForEach(spFor, spIn, SeqExprOnly false, true, $2, arbExpr ("forLoopCollection", mFor), arbExpr ("forLoopBody3", mForLoopBodyArb), mForLoopAll)) }
| YIELD declExpr
- { SynExpr.YieldOrReturn(($1, not $1), $2, unionRanges (rhs parseState 1) $2.Range) }
+ { let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 }
+ SynExpr.YieldOrReturn(($1, not $1), $2, (unionRanges (rhs parseState 1) $2.Range), trivia) }
| YIELD_BANG declExpr
- { SynExpr.YieldOrReturnFrom(($1, not $1), $2, unionRanges (rhs parseState 1) $2.Range) }
+ { let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 }
+ SynExpr.YieldOrReturnFrom(($1, not $1), $2, (unionRanges (rhs parseState 1) $2.Range), trivia) }
| YIELD recover
{ let mYieldAll = rhs parseState 1
- SynExpr.YieldOrReturn(($1, not $1), arbExpr ("yield", mYieldAll), mYieldAll) }
+ let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 }
+ SynExpr.YieldOrReturn(($1, not $1), arbExpr ("yield", mYieldAll), mYieldAll, trivia) }
| YIELD_BANG recover
{ let mYieldAll = rhs parseState 1
- SynExpr.YieldOrReturnFrom(($1, not $1), arbExpr ("yield!", mYieldAll), mYieldAll) }
+ let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 }
+ SynExpr.YieldOrReturnFrom(($1, not $1), arbExpr ("yield!", mYieldAll), mYieldAll, trivia) }
| BINDER headBindingPattern EQUALS typedSequentialExprBlock IN opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let
{ let spBind = DebugPointAtBinding.Yes(rhs2 parseState 1 5)
@@ -4458,7 +4462,8 @@ declExpr:
{ errorR(Error(FSComp.SR.parsArrowUseIsLimited(), lhs parseState))
let mArrow = rhs parseState 1
let expr = $2 mArrow
- SynExpr.YieldOrReturn((true, true), expr, (unionRanges mArrow expr.Range)) }
+ let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 }
+ SynExpr.YieldOrReturn((true, true), expr, (unionRanges mArrow expr.Range), trivia) }
| declExpr COLON_QMARK typ
{ SynExpr.TypeTest($1, $3, unionRanges $1.Range $3.Range) }
@@ -5456,7 +5461,8 @@ arrowThenExprR:
| RARROW typedSequentialExprBlockR
{ let mArrow = rhs parseState 1
let expr = $2 mArrow
- SynExpr.YieldOrReturn((true, false), expr, unionRanges mArrow expr.Range) }
+ let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = mArrow }
+ SynExpr.YieldOrReturn((true, false), expr, (unionRanges mArrow expr.Range), trivia) }
forLoopBinder:
| parenPattern IN declExpr
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index 2b1a9483def..958a1357ac9 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -539,7 +539,7 @@
- uvolnění prázdných znaků
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- Ve specifikaci obnovitelného kódu došlo k omezené obecné konstrukci.
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- Ve specifikaci obnovitelného kódu došlo k „let rec“.
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- Je třeba inicializovat následující požadované vlastnosti:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- Neplatný obnovitelný kód. Ve specifikaci obnovitelného kódu došlo k „let rec“.
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- Zadejte typ ladění: full, portable, embedded, pdbonly. ({0} je výchozí hodnota v případě, že není zadaný žádný typ ladění, a umožňuje připojení ladicího programu ke spuštěnému programu, portable je formát pro různé platformy, embedded je formát pro různé platformy vložený do výstupního souboru).
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- Rezidentní kompilační služba se nepoužila, protože došlo k potížím při komunikaci se serverem.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- Při použití statických argumentů u poskytnutého typu došlo k chybě.
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- Základní atribut TypeProviderAssembly sestavení {0} má neplatnou hodnotu {1}. Hodnotou by měl být platný název sestavení.
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- Při použití statických argumentů u poskytnuté metody došlo k chybě.
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- Atribut CallerMemberNameAttribute použitý pro parametr {0} nebude mít žádný účinek. Přepisuje ho atribut CallerFilePathAttribute.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- Slouží k uvození bloku kódu, který může vygenerovat výjimku. Používá se společně s with nebo finally.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index a1b2532e4db..d7233a5d2fc 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -539,7 +539,7 @@
- Lockerung für Leerraum
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- In der fortsetzbaren Codespezifikation ist ein eingeschränktes generisches Konstrukt aufgetreten.
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- "Let rec" ist in der fortsetzbaren Codespezifikation aufgetreten.
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- Die folgenden erforderlichen Eigenschaften müssen initialisiert werden:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- Ungültiger fortsetzbarer Code. "Let rec" ist in der fortsetzbaren Codespezifikation aufgetreten
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- Geben Sie den Debugtyp an: full, portable, embedded, pdbonly. ("{0}" ist der Standardwert, wenn kein Debugtyp angegeben wird, und ermöglicht das Anfügen eines Debuggers an ein aktuell ausgeführtes Programm. "portable" ist ein plattformübergreifendes Format, "embedded" ein plattformübergreifendes, in die Ausgabedatei eingebettetes Format).
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- Der residente Kompilierungsdienst wurde nicht verwendet, da bei der Kommunikation mit dem Server ein Problem aufgetreten ist.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- Fehler beim Anwenden des statischen Arguments auf einen angegebenen Typ.
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- Assembly '{0}' verfügt über ein TypeProviderAssembly-Attribut mit dem ungültigen Wert '{1}'. Beim Wert sollte es sich um einen gültigen Assemblynamen handeln.
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- Fehler beim Anwenden der statischen Argumente auf eine angegebene Methode.
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- Das auf Parameter "{0}" angewendete CallerMemberNameAttribute hat keine Auswirkung. Es wird vom CallerFilePathAttribute überschrieben.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- Wird verwendet, um einen Codeblock einzuführen, der unter Umständen eine Ausnahme generiert. Wird zusammen mit "with" oder "finally" verwendet.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index dd9cbb7fec6..1b3205ffa53 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -539,7 +539,7 @@
- relajación de espacio en blanco
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- En la especificación del código resumible aparecía una construcción genérica restringida
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- Se ha producido "let rec" en la especificación de código reanudable
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- Se deben inicializar las siguientes propiedades necesarias:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- Código reanudable no válido. Se ha producido "let rec" en la especificación de código reanudable
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- Especifique el tipo de depuración: full, portable, embedded, pdbonly. ('{0}' es el valor predeterminado si no se especifica ningún tipo de depuración y permite conectar un depurador a un programa en ejecución, 'portable' es un formato multiplataforma, 'embedded' es un formato multiplataforma insertado en el archivo de salida).
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- El servicio de compilación residente no se usó porque se produjo un problema en la comunicación con el servidor.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- Error al aplicar los argumentos estáticos a un tipo proporcionado.
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- El ensamblado '{0}' tiene el atributo TypeProviderAssembly con el valor '{1}' no válido. El valor debe ser un nombre de ensamblado válido.
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- Se produjo un error al aplicar los argumentos estáticos a un método proporcionado
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- El CallerMemberNameAttribute aplicado al parámetro '{0}' no tendrá ningún efecto. Este se reemplaza por CallerFilePathAttribute.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- Se usa para incluir un bloque de código que puede generar una excepción. Se usa junto con with o finally.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index 2cc92e5f4d5..018180a8fb6 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -539,7 +539,7 @@
- assouplissement de la mise en retrait avec des espaces blancs
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- Une construction générique contrainte s'est produite dans la spécification de code de reprise
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- Un «let rec» s’est produit dans la spécification de code pouvant être repris
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- Les propriétés requises suivantes doivent être initialisées :{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- Code pouvant être reprise non valide. Un «let rec» s’est produit dans la spécification de code pouvant être repris
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- Spécifiez le type de débogage : full, portable, embedded, pdbonly. ('{0}' est la valeur par défaut si aucun type de débogage n'est spécifié. Cette valeur permet d'attacher un débogueur à un programme en cours d'exécution, 'portable' est un format multiplateforme, 'embedded' est un format multiplateforme incorporé dans le fichier de sortie).
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- Le service de compilation résident n'a pas été utilisé en raison d'un problème lors de la communication avec le serveur.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- Une erreur s'est produite lors de l'application des arguments statiques à un type fourni
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- L'assembly '{0}' a un attribut TypeProviderAssembly comportant la valeur non valide '{1}'. La valeur doit être un nom d'assembly valide
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- Une erreur s'est produite durant l'application des arguments statiques à une méthode fournie
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- CallerMemberNameAttribute, qui est appliqué au paramètre '{0}', n'aura aucun effet. Il est remplacé par CallerFilePathAttribute.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- Permet d'introduire un bloc de code pouvant générer une exception. Utilisé avec with ou finally.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index 5b5793c4841..7cc3f46259b 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -539,7 +539,7 @@
- uso meno restrittivo degli spazi vuoti
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- Costrutto generico vincolato nella specifica del codice ripristinabile
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- È stata rilevata una funzione 'let rec' nella specifica del codice ripristinabile
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- È necessario inizializzare le proprietà obbligatorie seguenti:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- Codice ripristinabile non valido. È stato rilevata una funzione 'let rec' nella specifica del codice ripristinabile
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- Consente di specificare il tipo di debug: full, portable, embedded, pdbonly. '{0}' è l'impostazione predefinita se non viene specificato il tipo di debug e consente di associare un debugger a un programma in esecuzione. 'portable' è un formato multipiattaforma. 'embedded' è un formato multipiattaforma incorporato nel file di output.
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- Il servizio di compilazione residente non è stato usato perché si è verificato un problema nella comunicazione con il server.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- Errore durante l'applicazione degli argomenti statici a un tipo fornito
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- Valore '{1}' non valido dell'attributo TypeProviderAssembly nell'assembly '{0}'. Il valore deve essere un nome di assembly valido.
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- Si è verificato un errore durante l'applicazione degli argomenti statici a un metodo fornito
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- CallerMemberNameAttribute applicato al parametro '{0}' non avrà alcun effetto. CallerFilePathAttribute ne eseguirà l'override.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- Usata per introdurre un blocco di codice che potrebbe generare un'eccezione. Usata insieme a with o finally.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index d30efc74724..10c5f06f4ff 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -539,7 +539,7 @@
- 空白の緩和
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- 再開可能なコード指定で制約付きジェネリック コンストラクトが発生しました
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- 再開可能なコード仕様で 'let rec' が発生しました
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- 次の必須プロパティを初期化する必要があります:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- 再開可能なコードが無効です。再開可能なコード仕様で 'let rec' が発生しました
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- デバッグの種類 full、portable、pdbonly を指定します (デバッグの種類が指定されない場合には '{0}' が既定で、実行中のプログラムにデバッガーを付加することができます。'portable' はクロスプラットフォーム形式、'embedded' は出力ファイルに埋め込まれたクロスプラットフォーム形式です)。
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- サーバーとの通信で問題が発生したため、常駐コンパイル サービスが使用されませんでした。
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- 指定された型に静的引数を適用する際にエラーが発生しました
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- アセンブリ '{0}' の TypeProviderAssembly 属性に、無効な値 '{1}' が含まれています。この値は有効なアセンブリ名であることが必要です
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- 静的な引数を指定されたメソッドに適用する際エラーが発生しました
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- パラメーター '{0}' に適用された CallerMemberNameAttribute は、CallerFilePathAttribute.によってオーバーライドされるため無効となります。
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- 例外を生成する可能性があるコード ブロックを開始するために使用します。with または finally と一緒に使用します。
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index c9359c56807..94cd344f052 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -539,7 +539,7 @@
- 공백 완화
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- 다시 시작 가능한 코드 사양에서 제약이 있는 제네릭 구문이 발생했습니다.
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- 다시 시작 가능한 코드 사양에서 'let rec'가 발생했습니다.
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- 다음 필수 속성을 초기화해야 합니다. {0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- 다시 시작 가능한 코드가 잘못되었습니다. 다시 시작 가능한 코드 사양에서 'let rec'가 발생했습니다.
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- 디버깅 형식(full, portable, embedded, pdbonly)을 지정합니다. '{0}'은(는) 디버깅 형식을 지정하지 않은 경우 기본값이며 디버거를 실행 중인 프로그램에 연결할 수 있습니다. 'portable'은 플랫폼 간 형식이고, 'embedded'는 출력 파일에 포함된 플랫폼 간 형식입니다.
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- 서버와 통신하는 동안 문제가 발생하여 상주 컴파일 서비스를 사용하지 않았습니다.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- 제공된 형식에 정적 인수를 적용하는 동안 오류가 발생했습니다.
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- {0}' 어셈블리에 포함된 TypeProviderAssembly 특성의 값('{1}')이 잘못되었습니다. 값은 올바른 어셈블리 이름이어야 합니다.
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- 제공된 메서드에 정적 인수를 적용하는 동안 오류가 발생했습니다.
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- {0}' 매개 변수에 적용되는 CallerMemberNameAttribute는 효과가 없습니다. CallerFilePathAttribute에서 재정의합니다.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- 예외를 생성할 수 있는 코드 블록을 지정하는 데 사용됩니다. with 또는 finally와 함께 사용됩니다.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index 933379b9f7b..01f2ff1d5e3 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -539,7 +539,7 @@
- rozluźnianie reguł dotyczących odstępów
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- W specyfikacji kodu z możliwością wznowienia wystąpiła ograniczona konstrukcja ogólna
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- W specyfikacji kodu z możliwością wznowienia, wystąpił błąd "let rec"
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- Następujące wymagane właściwości muszą zostać zainicjowane:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- Nieprawidłowy kod z możliwością wznowienia. W specyfikacji kodu z możliwością wznowienia wystąpił element "let rec"
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- Określ typ debugowania: full, portable, pdbonly. Wartość „{0}” jest wartością domyślną, jeśli nie określono typu debugowania, i umożliwia dołączenie debugera do działającego programu. Wartość „portable” określa format międzyplatformowy. Wartość „embedded” określa format międzyplatformowy osadzony w pliku wyjściowym.
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- Rezydentna usługa kompilacji nie została użyta, ponieważ wystąpił problem z komunikowaniem się z serwerem.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- Wystąpił błąd podczas stosowania argumentów statycznych do udostępnionego typu
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- Zestaw „{0}” ma atrybut TypeProviderAssembly z nieprawidłową wartością „{1}”. Wartość powinna być prawidłową nazwą zestawu
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- Wystąpił błąd podczas stosowania argumentów statycznych dla podanej metody
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- Zastosowanie elementu CallerMemberNameAttribute do parametru „{0}” nie odniesie żadnego skutku. Jest on przesłaniany przez element CallerFilePathAttribute.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- Używane do wprowadzania bloku kodu, który może generować wyjątek. Używane razem ze słowem kluczowym with lub finally.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index e6480e13025..63da6a667b1 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -539,7 +539,7 @@
- atenuação de espaço em branco
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- Um constructo genérico restrito ocorreu na especificação de código retomável
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- Ocorreu um "let rec" na especificação do código retomável
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- As seguintes propriedades necessárias precisam ser inicializadas:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- Código inválido retomável. Ocorreu um "let rec" na especificação do código retomável
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- Especificar tipo de depuração: completo, portátil, incorporado, somente PDB. ('{0}' será o padrão se nenhum tipo de depuração for especificado e permite anexar um depurador a um programa em execução; 'portátil' é um formato multiplataforma; 'incorporado' é um formato multiplataforma incorporado no arquivo de saída).
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- O serviço de compilação residente não foi usado porque houve um problema de comunicação com o servidor.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- Erro ao aplicar os argumentos estáticos a um tipo fornecido
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- O assembly '{0}' possui um atributo TypeProviderAssembly com valor inválido '{1}'. O valor deve ser um nome de assembly válido
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- Ocorreu um erro ao aplicar os argumentos estáticos para um método fornecido
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- O CallerMemberNameAttribute aplicado ao parâmetro "{0}" não terá efeito. Ele é substituído pelo CallerFilePathAttribute.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- Usado para introduzir um bloco de código que pode gerar uma exceção. Usado junto com with ou finally.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index 61c03885917..231bc83103b 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -539,7 +539,7 @@
- уменьшение строгости для пробелов
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- В спецификации возобновляемого кода возникла ограниченная универсальная конструкция
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- В спецификации возобновляемого кода возникла ошибка "let rec"
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- Необходимо инициализировать следующие обязательные свойства:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- Недопустимый возобновляемый код. В спецификации возобновляемого кода возникла ошибка "let rec"
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- Укажите тип отладки: full, portable, embedded, pdbonly (если тип отладки не указан, по умолчанию используется тип "{0}", позволяющий подключить отладчик к выполняющейся программе; тип portable представляет собой кроссплатформенный формат; тип embedded — кроссплатформенный формат, встроенный в выходной файл).
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- Служба резидентной компиляции не использовалась, поскольку возникла проблема при взаимодействии с сервером.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- Ошибка при применении статических аргументов к предоставленному типу
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- У сборки "{0}" имеется атрибут TypeProviderAssembly с недопустимым значением "{1}". Значение должно представлять собой допустимое имя сборки
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- Произошла ошибка при применении статических аргументов к предоставленному методу
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- Атрибут CallerMemberNameAttribute, примененный для параметра "{0}", не будет действовать. Он будет переопределен атрибутом CallerFilePathAttribute.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- Используется для введения блока кода, который может создать исключение. Используется вместе с with или finally.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index 09c113ee3f1..a3bab7e5a92 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -539,7 +539,7 @@
- boşluk genişlemesi
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- Sürdürülebilir kod belirtiminde kısıtlanmış bir genel yapı oluştu
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- Sürdürülebilir kod belirtiminde 'let rec' oluştu
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- Aşağıdaki gerekli özelliklerin başlatılması gerekiyor:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- Geçersiz sürdürülebilir kod. Sürdürülebilir kod belirtiminde bir 'let rec' oluştu
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- Hata ayıklama türünü belirtin: full, portable, embedded, pdbonly. (Hata ayıklama türü belirtilmemişse '{0}' varsayılandır ve çalışan bir programa hata ayıklayıcı iliştirmeyi etkinleştirir. 'portable' bir çoklu platform biçimidir, 'embedded' çıkış dosyasına gömülü bir çoklu platform biçimidir).
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- Sunucuyla iletişimde bir sorun oluştuğu için yerleşik derleme hizmeti kullanılmadı.
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- Sağlanan türe statik bağımsız değişkenler uygulanırken bir hata oluştu
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- {0}' bütünleştirilmiş kodunun geçersiz '{1}' değerli TypeProviderAssembly özniteliği var. Bu değer geçerli bir bütünleştirilmiş kod adı olmalıdır
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- Sağlanan metoda statik bağımsız değişkenler uygulanırken bir sorun oluştu
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- {0}' parametresi için geçerli olan CallerMemberNameAttribute öğesinin hiçbir etkisi olmaz. CallerFilePathAttribute tarafından geçersiz kılındı.
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- Özel durum oluşturabilen bir kod bloğunu tanıtmak için kullanılır. with veya finally ile birlikte kullanılır.
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index d9573b5bed2..579ac9b79c3 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -539,7 +539,7 @@
- 空格松弛法
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- 可恢复代码规范中发生受约束的泛型构造
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- 可恢复代码规范中出现 "let rec"
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- 必须初始化以下必需属性: {0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- 可恢复代码无效。可恢复代码规范中出现 "let rec"
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- 指定调试类型: full、portable、embedded、pdbonly。(若未指定调试类型,则默认为“{0}”,它允许将调试程序附加到正在运行的程序。"portable" 是跨平台格式,"embedded" 是嵌入到输出文件中的跨平台格式)。
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- 未使用驻留编译服务,因为与服务器通信时发生问题。
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- 将静态参数应用于所提供类型时发生错误
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- 程序集“{0}”的 TypeProviderAssembly 特性具有无效值“{1}”。该值应为有效的程序集名称
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- 将静态参数应用于提供的方法时发生错误
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- 应用于参数“{0}”的 CallerMemberNameAttribute 不会起作用。它已由 CallerFilePathAttribute 替代。
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- 用于引入可能产生异常的代码块。与 with 或 finally 配合使用。
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index 1a6c3de6ccf..09818a7487b 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -539,7 +539,7 @@
- 空白字元放寬
+ whitespace relaxation
@@ -1124,7 +1124,7 @@
- 可繼續的程式碼規格中出現了限制式泛型建構
+ A constrained generic construct occurred in the resumable code specification
@@ -1139,7 +1139,7 @@
- 可繼續的程式碼規格中發生 'let rec'
+ A 'let rec' occurred in the resumable code specification
@@ -1444,7 +1444,7 @@
- 下列必要的屬性必須初始化:{0}
+ The following required properties have to be initialized:{0}
@@ -1579,7 +1579,7 @@
- 可繼續的程式碼無效。可繼續的程式碼規格中發生 'let rec'
+ Invalid resumable code. A 'let rec' occurred in the resumable code specification
@@ -5899,7 +5899,7 @@
- 指定偵錯類型: full、portable、embedded、pdbonly。(如果未指定偵錯類型,即預設為 '{0}',並允許將偵錯工具附加到正在執行的程式,'portable' 為跨平台格式,'embedded' 為輸出檔案內嵌的跨平台格式)。
+ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
@@ -7154,7 +7154,7 @@
- 未使用常駐編譯服務,因為伺服器發生通訊問題。
+ The resident compilation service was not used because a problem occurred in communicating with the server.
@@ -7354,7 +7354,7 @@
- 將靜態引數套用至提供的類型時發生錯誤
+ An error occurred applying the static arguments to a provided type
@@ -7419,7 +7419,7 @@
- 組件 '{0}' 的 TypeProviderAssembly 屬性值 '{1}' 無效。此值必須是有效的屬性名稱
+ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name
@@ -8004,7 +8004,7 @@
- 將靜態引數套用至所提供的方法時,發生錯誤
+ An error occurred applying the static arguments to a provided method
@@ -8134,7 +8134,7 @@
- 套用至參數 '{0}' 的 CallerMemberNameAttribute 將不會有作用。CallerFilePathAttribute 會加以覆寫。
+ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute.
@@ -8449,7 +8449,7 @@
- 用於引入可能會產生例外狀況的程式碼區塊。這會與 with 或 finally 並用。
+ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'.
diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf
index 810091c59f0..86a6be9d7e0 100644
--- a/src/Compiler/xlf/FSStrings.cs.xlf
+++ b/src/Compiler/xlf/FSStrings.cs.xlf
@@ -204,7 +204,7 @@
- {0} {1} se nedá definovat, protože název {2} a {3} {4} v tomto typu nebo modulu jsou v konfliktu.
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf
index 12a7cc8d720..3b7f46a9769 100644
--- a/src/Compiler/xlf/FSStrings.de.xlf
+++ b/src/Compiler/xlf/FSStrings.de.xlf
@@ -204,7 +204,7 @@
- {0} "{1}" kann nicht definiert werden, weil der Name "{2}" einen Konflikt mit {3} "{4}" in diesem Typ oder Modul verursacht.
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf
index 85b2e6b1cd4..f2b6d8ed1ca 100644
--- a/src/Compiler/xlf/FSStrings.es.xlf
+++ b/src/Compiler/xlf/FSStrings.es.xlf
@@ -204,7 +204,7 @@
- No se puede definir el {0} '{1}' porque el nombre '{2}' está en conflicto con el {3} '{4}' de este tipo o módulo.
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf
index b3627df28f8..f3621e55e63 100644
--- a/src/Compiler/xlf/FSStrings.fr.xlf
+++ b/src/Compiler/xlf/FSStrings.fr.xlf
@@ -204,7 +204,7 @@
- Impossible de définir le {0} '{1}', car le nom '{2}' est en conflit avec le {3} '{4}' dans ce type ou module
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf
index b042d7704b2..d67bbd27dca 100644
--- a/src/Compiler/xlf/FSStrings.it.xlf
+++ b/src/Compiler/xlf/FSStrings.it.xlf
@@ -204,7 +204,7 @@
- Non è possibile definire {0} '{1}' perché il nome '{2}' è in conflitto con {3} '{4}' in questo tipo o modulo
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf
index 3b9c4d98e21..486c2fac349 100644
--- a/src/Compiler/xlf/FSStrings.ja.xlf
+++ b/src/Compiler/xlf/FSStrings.ja.xlf
@@ -204,7 +204,7 @@
- 名前 '{2}' がこの型またはモジュールの {3} '{4}' と競合するため、{0} '{1}' を定義できません
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf
index 51c8cb1365f..506b9b9e2de 100644
--- a/src/Compiler/xlf/FSStrings.ko.xlf
+++ b/src/Compiler/xlf/FSStrings.ko.xlf
@@ -204,7 +204,7 @@
- 이름 '{2}'이(가) 이 형식 또는 모듈의 {3} '{4}'과(와) 충돌하므로 {0} '{1}'을(를) 정의할 수 없습니다.
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf
index 29e36ab5bc9..30f8155bfc8 100644
--- a/src/Compiler/xlf/FSStrings.pl.xlf
+++ b/src/Compiler/xlf/FSStrings.pl.xlf
@@ -204,7 +204,7 @@
- Nie można zdefiniować elementu {0} „{1}”, ponieważ nazwa „{2}” powoduje konflikt z elementem {3} „{4}” w tym typie lub module
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf
index b606d7339c5..cf7e3a94822 100644
--- a/src/Compiler/xlf/FSStrings.pt-BR.xlf
+++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf
@@ -204,7 +204,7 @@
- O {0} '{1}' não pode ser definido porque o nome '{2}' conflita com {3} '{4}' neste tipo ou módulo
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf
index 6367fb6f835..34278a4b234 100644
--- a/src/Compiler/xlf/FSStrings.ru.xlf
+++ b/src/Compiler/xlf/FSStrings.ru.xlf
@@ -204,7 +204,7 @@
- {0} "{1}" не удается определить, так как имя "{2}" конфликтует с {3} "{4}" в данном типе или модуле
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf
index 029b16cd9b5..a2601885c52 100644
--- a/src/Compiler/xlf/FSStrings.tr.xlf
+++ b/src/Compiler/xlf/FSStrings.tr.xlf
@@ -204,7 +204,7 @@
- {2}' adı bu türde veya modülde {3} '{4}' ile çakıştığı için {0} '{1}' tanımlanamıyor
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf
index 54599b23672..66a54f3d2bb 100644
--- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf
@@ -204,7 +204,7 @@
- 无法定义 {0}“{1}”,因为名称“{2}”与此类型或模块中的 {3}“{4}”冲突
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf
index c200aa576c1..35280cee60f 100644
--- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf
@@ -204,7 +204,7 @@
- 無法定義 {0} '{1}',因為名稱 '{2}' 與這個類型或模組中的 {3} '{4}' 相衝突
+ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module
diff --git a/src/FSharp.Build/FSharpEmbedResourceText.fs b/src/FSharp.Build/FSharpEmbedResourceText.fs
index ac0adf8329d..061715184de 100644
--- a/src/FSharp.Build/FSharpEmbedResourceText.fs
+++ b/src/FSharp.Build/FSharpEmbedResourceText.fs
@@ -295,7 +295,7 @@ open Printf
#endif
- static let mkFunctionValue (tys: System.Type[]) (impl:obj->obj) =
+ static let mkFunctionValue (tys: System.Type[]) (impl:objnull->objnull) =
FSharpValue.MakeFunction(FSharpType.MakeFunctionType(tys.[0],tys.[1]), impl)
static let funTyC = typeof<(obj -> obj)>.GetGenericTypeDefinition()
diff --git a/src/FSharp.Build/Fsi.fs b/src/FSharp.Build/Fsi.fs
index 4e7bd9c4e0a..dc362420db0 100644
--- a/src/FSharp.Build/Fsi.fs
+++ b/src/FSharp.Build/Fsi.fs
@@ -161,6 +161,34 @@ type public Fsi() as this =
builder
+ let mutable bufferLimit = None
+
+ let textOutput =
+ lazy System.Collections.Generic.Queue<_>(defaultArg bufferLimit 1024)
+
+ override this.LogEventsFromTextOutput(line, msgImportance) =
+ if this.CaptureTextOutput then
+ textOutput.Value.Enqueue line
+
+ match bufferLimit with
+ | Some limit when textOutput.Value.Count > limit -> textOutput.Value.Dequeue() |> ignore
+ | _ -> ()
+
+ base.LogEventsFromTextOutput(line, msgImportance)
+
+ member _.BufferLimit
+ with get () = defaultArg bufferLimit 0
+ and set limit = bufferLimit <- if limit = 0 then None else Some limit
+
+ member val CaptureTextOutput = false with get, set
+
+ [
- Dynamickému formátovacímu modulu byla předána chybná celočíselná hodnota.
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- Chybný specifikátor formátu (přesnost)
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.de.xlf b/src/FSharp.Core/xlf/FSCore.de.xlf
index df2b28aaecb..28ad0276d47 100644
--- a/src/FSharp.Core/xlf/FSCore.de.xlf
+++ b/src/FSharp.Core/xlf/FSCore.de.xlf
@@ -564,7 +564,7 @@
- Für den dynamischen Formatierer wurde ein ungültiger Integer bereitgestellt.
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- Ungültiger Formatbezeichner (precision)
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.es.xlf b/src/FSharp.Core/xlf/FSCore.es.xlf
index a1e7d0f7fa8..55f8c1c965d 100644
--- a/src/FSharp.Core/xlf/FSCore.es.xlf
+++ b/src/FSharp.Core/xlf/FSCore.es.xlf
@@ -564,7 +564,7 @@
- Se proporcionó un entero incorrecto a un formateador dinámico.
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- Especificador de formato incorrecto (precisión).
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.fr.xlf b/src/FSharp.Core/xlf/FSCore.fr.xlf
index ff8acfc83c4..a7499ae558b 100644
--- a/src/FSharp.Core/xlf/FSCore.fr.xlf
+++ b/src/FSharp.Core/xlf/FSCore.fr.xlf
@@ -564,7 +564,7 @@
- Entier incorrect fourni au formateur dynamique
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- Spécificateur de format incorrect (précision)
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.it.xlf b/src/FSharp.Core/xlf/FSCore.it.xlf
index 3643c1ce16c..a4abe452956 100644
--- a/src/FSharp.Core/xlf/FSCore.it.xlf
+++ b/src/FSharp.Core/xlf/FSCore.it.xlf
@@ -564,7 +564,7 @@
- Intero non valido fornito al formattatore dinamico
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- Identificatore di formato non valido (precision)
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.ja.xlf b/src/FSharp.Core/xlf/FSCore.ja.xlf
index 285dfb02872..147f7c018cd 100644
--- a/src/FSharp.Core/xlf/FSCore.ja.xlf
+++ b/src/FSharp.Core/xlf/FSCore.ja.xlf
@@ -564,7 +564,7 @@
- 動的フォーマッタに対して指定された整数が正しくありません
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- 書式指定子 (精度) が正しくありません
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.ko.xlf b/src/FSharp.Core/xlf/FSCore.ko.xlf
index e5a88b267b0..8341b342f7a 100644
--- a/src/FSharp.Core/xlf/FSCore.ko.xlf
+++ b/src/FSharp.Core/xlf/FSCore.ko.xlf
@@ -564,7 +564,7 @@
- 동적 포맷터에 제공된 정수가 잘못되었습니다.
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- 잘못된 형식 지정자(전체 자릿수)
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.pl.xlf b/src/FSharp.Core/xlf/FSCore.pl.xlf
index a64948b4609..6ddd003084a 100644
--- a/src/FSharp.Core/xlf/FSCore.pl.xlf
+++ b/src/FSharp.Core/xlf/FSCore.pl.xlf
@@ -564,7 +564,7 @@
- Do dynamicznego modułu formatującego została przekazana błędna liczba całkowita.
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- Błędny specyfikator formatu (dokładności).
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.pt-BR.xlf b/src/FSharp.Core/xlf/FSCore.pt-BR.xlf
index 591a8e6560f..956db72820d 100644
--- a/src/FSharp.Core/xlf/FSCore.pt-BR.xlf
+++ b/src/FSharp.Core/xlf/FSCore.pt-BR.xlf
@@ -564,7 +564,7 @@
- Inteiro incorreto fornecido a formatador dinâmico
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- Especificador de formato incorreto (precisão)
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.ru.xlf b/src/FSharp.Core/xlf/FSCore.ru.xlf
index edb281a0102..cb0ca39bd08 100644
--- a/src/FSharp.Core/xlf/FSCore.ru.xlf
+++ b/src/FSharp.Core/xlf/FSCore.ru.xlf
@@ -564,7 +564,7 @@
- Динамическому форматтеру передано неверное целое
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- Неверный спецификатор формата (точность)
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.tr.xlf b/src/FSharp.Core/xlf/FSCore.tr.xlf
index d0ab6c80129..b4c445d67ee 100644
--- a/src/FSharp.Core/xlf/FSCore.tr.xlf
+++ b/src/FSharp.Core/xlf/FSCore.tr.xlf
@@ -564,7 +564,7 @@
- Dinamik biçimlendiriciye yanlış tamsayı sağlandı
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- Hatalı biçim belirticisi (duyarlık)
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.zh-Hans.xlf b/src/FSharp.Core/xlf/FSCore.zh-Hans.xlf
index 498188f67af..dc922154be2 100644
--- a/src/FSharp.Core/xlf/FSCore.zh-Hans.xlf
+++ b/src/FSharp.Core/xlf/FSCore.zh-Hans.xlf
@@ -564,7 +564,7 @@
- 提供给动态格式化程序的整数错误
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- 错误的格式说明符(精度)
+ Bad format specifier (precision)
diff --git a/src/FSharp.Core/xlf/FSCore.zh-Hant.xlf b/src/FSharp.Core/xlf/FSCore.zh-Hant.xlf
index 7e5727be136..9d2cb35be7a 100644
--- a/src/FSharp.Core/xlf/FSCore.zh-Hant.xlf
+++ b/src/FSharp.Core/xlf/FSCore.zh-Hant.xlf
@@ -564,7 +564,7 @@
- 提供給動態格式器的整數錯誤
+ Bad integer supplied to dynamic formatter
@@ -594,7 +594,7 @@
- 不正確的格式修飾詞 (精確度)
+ Bad format specifier (precision)
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf
index 2f9b9728cd8..800c2e40248 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf
@@ -4,7 +4,7 @@
- PackageManager se nemůže odkazovat na systémový balíček {0}.
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf
index 233c6a93dd3..f3762130515 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf
@@ -4,7 +4,7 @@
- PackageManager kann nicht auf das Systempaket "{0}" verweisen.
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf
index 2f7b192634c..2851c230dab 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf
@@ -4,7 +4,7 @@
- PackageManager no puede hacer referencia al paquete del sistema "{0}".
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf
index 5d83dfd795a..8ab1dccc35f 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf
@@ -4,7 +4,7 @@
- PackageManager ne peut pas référencer le package système '{0}'
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf
index 9a40ea0246c..c605c4af3ba 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf
@@ -4,7 +4,7 @@
- PackageManager non può fare riferimento al pacchetto di sistema '{0}'
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf
index 74a4a7a452c..2e19d06a10f 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf
@@ -4,7 +4,7 @@
- PackageManager がシステム パッケージ '{0}' を参照できません
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf
index 9837ed7ad3a..01d252b6243 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf
@@ -4,7 +4,7 @@
- PackageManager에서 시스템 패키지 '{0}'을(를) 참조할 수 없습니다.
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf
index 6b7b5475c99..4ae0d2e448e 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf
@@ -4,7 +4,7 @@
- Program PacketManager nie może odwoływać się do pakietu systemowego „{0}”
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf
index 2fb1ed02a8a..7e8409fd8d7 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf
@@ -4,7 +4,7 @@
- PackageManager não pode referenciar o pacote do sistema '{0}'
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf
index c1193b57c8b..dafbfb8243d 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf
@@ -4,7 +4,7 @@
- PackageManager не может ссылаться на системный пакет "{0}"
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf
index 5a870233d01..312793af714 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf
@@ -4,7 +4,7 @@
- PackageManager, '{0}' Sistem Paketine başvuramıyor
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf
index 520ae8c35a4..7e04d921b0a 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf
@@ -4,7 +4,7 @@
- PackageManager 无法引用系统包“{0}”
+ PackageManager cannot reference the System Package '{0}'
diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf
index e8bde94aaff..d82293b0cf2 100644
--- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf
+++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf
@@ -4,7 +4,7 @@
- PackageManager 無法參考系統套件 '{0}'
+ PackageManager cannot reference the System Package '{0}'
diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs
index 50393ff9850..99d019504d6 100644
--- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs
+++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs
@@ -9,22 +9,22 @@ module Ifdef =
[]
let main _ =
#if MYDEFINE1
- printf "1"
+ 1
#else
- printf "2"
+ 2
#endif
- 0
"""
- []
- []
+ []
+ []
[]
- let ifdefTest (mydefine, expectedOutput) =
+ let ifdefTest (mydefine, expectedExitCode) =
FSharp ifdefSource
|> withDefines [mydefine]
|> compileExeAndRun
- |> verifyOutput expectedOutput
+ |> withExitCode expectedExitCode
+
let sourceExtraEndif = """
#if MYDEFINE1
@@ -54,4 +54,4 @@ module A
FSharp sourceUnknownHash
|> compile
- |> shouldSucceed
+ |> shouldSucceed
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
index f6d8a0cc530..9b7cdc5a053 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
@@ -933,3 +933,36 @@ and []
|> verifyCompile
|> shouldSucceed
#endif
+
+ [] // Regression for https://github.com/dotnet/fsharp/issues/14304
+ let ``Construct an object with default and params parameters using parameterless constructor`` () =
+ Fsx """
+open System
+open System.Runtime.InteropServices
+
+type DefaultAndParams([]x: int, [] value: string[]) =
+ inherit Attribute()
+
+type ParamsOnly([] value: string[]) =
+ inherit Attribute()
+
+type DefaultOnly([]x: int) =
+ inherit Attribute()
+
+[]
+type Q1 = struct end
+
+[] // ok
+type Q11 = struct end
+
+[] // ok
+type Q12 = struct end
+
+[]
+type Q2 = struct end
+
+[]
+type Q3 = struct end
+ """
+ |> typecheck
+ |> shouldSucceed
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/Basic.fs
index d67f22efdc8..c0a19c9ad3e 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/Basic.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/Basic.fs
@@ -144,13 +144,12 @@ module LetBindings_Basic =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
- (Error 267, Line 11, Col 18, Line 11, Col 19, "This is not a valid constant expression or custom attribute value")
- (Error 837, Line 11, Col 13, Line 11, Col 31, "This is not a valid constant expression")
- (Error 267, Line 14, Col 13, Line 14, Col 17, "This is not a valid constant expression or custom attribute value")
- (Error 267, Line 17, Col 13, Line 17, Col 15, "This is not a valid constant expression or custom attribute value")
- (Error 267, Line 20, Col 13, Line 20, Col 17, "This is not a valid constant expression or custom attribute value")
- (Error 267, Line 23, Col 13, Line 23, Col 18, "This is not a valid constant expression or custom attribute value")
- (Warning 3178, Line 26, Col 13, Line 26, Col 26, "This is not valid literal expression. The [] attribute will be ignored.")
+ (Error 267, Line 10, Col 18, Line 10, Col 19, "This is not a valid constant expression or custom attribute value")
+ (Error 837, Line 10, Col 13, Line 10, Col 31, "This is not a valid constant expression")
+ (Error 267, Line 16, Col 13, Line 16, Col 15, "This is not a valid constant expression or custom attribute value")
+ (Error 267, Line 19, Col 13, Line 19, Col 17, "This is not a valid constant expression or custom attribute value")
+ (Error 267, Line 22, Col 13, Line 22, Col 18, "This is not a valid constant expression or custom attribute value")
+ (Warning 3178, Line 25, Col 13, Line 25, Col 26, "This is not valid literal expression. The [] attribute will be ignored.")
]
// SOURCE=E_Pathological01.fs SCFLAGS=--test:ErrorRanges # E_Pathological01.fs
@@ -303,4 +302,4 @@ type C() =
|> withDiagnostics [
(Warning 3582, Line 4, Col 5, Line 4, Col 12, "This is a function definition that shadows a union case. If this is what you want, ignore or suppress this warning. If you want it to be a union case deconstruction, add parentheses.")
(Warning 3582, Line 5, Col 5, Line 5, Col 11, "This is a function definition that shadows a union case. If this is what you want, ignore or suppress this warning. If you want it to be a union case deconstruction, add parentheses.")
- ]
+ ]
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/E_Literals04.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/E_Literals04.fs
index aa3395e0b6f..c253d840657 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/E_Literals04.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/E_Literals04.fs
@@ -1,11 +1,10 @@
// #Regression #Conformance #DeclarationElements #LetBindings
-//This is not a valid constant expression or custom attribute value$
-//This is not a valid constant expression$
-//This is not a valid constant expression or custom attribute value$
-//This is not a valid constant expression or custom attribute value$
-//This is not a valid constant expression or custom attribute value$
-//This is not a valid constant expression or custom attribute value$
-//This is not valid literal expression. The \[\] attribute will be ignored\.$
+//This is not a valid constant expression or custom attribute value$
+//This is not a valid constant expression$
+//This is not a valid constant expression or custom attribute value$
+//This is not a valid constant expression or custom attribute value$
+//This is not a valid constant expression or custom attribute value$
+//This is not valid literal expression. The \[\] attribute will be ignored\.$
[]
let lit01 = (let x = "2" in x)
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs
index c34bd114f35..9c166a47aac 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs
@@ -57,4 +57,4 @@ module Tests =
let test3 () =
StaticTest.Test2 // is passing, but probably shouldn't be
-printfn "Test Passed"
+printf "TEST PASSED OK"
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Decimal/Decimal.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Decimal/Decimal.fs
new file mode 100644
index 00000000000..1f168db110f
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Decimal/Decimal.fs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace Conformance.PatternMatching
+
+open Xunit
+open FSharp.Test
+open FSharp.Test.Compiler
+
+module Decimal =
+
+ []
+ let ``Decimal - literal01.fs - --test:ErrorRanges`` compilation =
+ compilation
+ |> asFsx
+ |> withOptions ["--test:ErrorRanges";]
+ |> compile
+ |> shouldSucceed
+
+ []
+ let ``Decimal - incompleteMatchesLiteral01.fs - --test:ErrorRanges`` compilation =
+ compilation
+ |> asFs
+ |> withOptions ["--test:ErrorRanges"]
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Warning 25, Line 7, Col 11, Line 7, Col 13, "Incomplete pattern matches on this expression. For example, the value '3M' may indicate a case not covered by the pattern(s).")
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Decimal/incompleteMatchesLiteral01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Decimal/incompleteMatchesLiteral01.fs
new file mode 100644
index 00000000000..2397eeee743
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Decimal/incompleteMatchesLiteral01.fs
@@ -0,0 +1,11 @@
+[]
+let One = 1m
+[]
+let Two = 2m
+
+let test() =
+ match 3m with
+ | 0m -> false
+ | One | Two -> false
+
+exit 0
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Decimal/literal01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Decimal/literal01.fs
new file mode 100644
index 00000000000..764958b9bd7
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Decimal/literal01.fs
@@ -0,0 +1,26 @@
+// #Conformance #PatternMatching
+#light
+
+// Pattern match decimal literals
+
+[]
+let Decimal1 = 5m
+
+[]
+let Decimal2 = 42.42m
+
+let testDecimal x =
+ match x with
+ | Decimal1 -> 1
+ | Decimal2 -> 2
+ | _ -> 0
+
+if testDecimal 1m <> 0 then exit 1
+
+if testDecimal Decimal1 <> 1 then exit 1
+if testDecimal 5m <> 1 then exit 1
+
+if testDecimal Decimal2 <> 2 then exit 1
+if testDecimal 42.42m <> 2 then exit 1
+
+exit 0
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs
index b3c33031acb..c560008da0c 100644
--- a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs
@@ -45,7 +45,6 @@ else ()
|> compile
|> run
|> shouldSucceed
- |> withExitCode 0
[]
let ``Respect nowarn 957 for extension method`` () =
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs
index 9ac49148a78..d2dc41a3235 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs
@@ -176,36 +176,95 @@ let [] x = System.Int32.MaxValue + 1
}
[]
- let ``Compilation fails when using decimal arithmetic in literal``() =
+ let ``Arithmetic can be used for constructing decimal literals``() =
FSharp """
module LiteralArithmetic
-let [] x = 1m + 1m
+[]
+let x = 1m + 2m
"""
|> withLangVersion80
|> compile
- |> shouldFail
- |> withResults [
- { Error = Error 267
- Range = { StartLine = 4
- StartColumn = 21
- EndLine = 4
- EndColumn = 23 }
- Message = "This is not a valid constant expression or custom attribute value" }
- { Error = Error 267
- Range = { StartLine = 4
- StartColumn = 26
- EndLine = 4
- EndColumn = 28 }
- Message = "This is not a valid constant expression or custom attribute value" }
- { Error = Error 267
- Range = { StartLine = 4
- StartColumn = 21
- EndLine = 4
- EndColumn = 28 }
- Message = "This is not a valid constant expression or custom attribute value" }
+ |> shouldSucceed
+ |> verifyIL [
+ """.field public static initonly valuetype [runtime]System.Decimal x"""
+ """.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,
+ uint8,
+ int32,
+ int32,
+ int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00
+ 00 00 )"""
+ """.maxstack 8"""
+ """IL_0000: ldc.i4.3"""
+ """IL_0001: ldc.i4.0"""
+ """IL_0002: ldc.i4.0"""
+ """IL_0003: ldc.i4.0"""
+ """IL_0004: ldc.i4.0"""
+ """IL_0005: newobj instance void [runtime]System.Decimal::.ctor(int32,
+ int32,
+ int32,
+ bool,
+ uint8)"""
+ """IL_000a: stsfld valuetype [runtime]System.Decimal LiteralArithmetic::x"""
+ """IL_000f: ret"""
+ ]
+
+ []
+ let ``Pattern matching decimal literal``() =
+ FSharp """
+module PatternMatch
+
+[]
+let x = 5m
+
+let test () =
+ match x with
+ | 5m -> 0
+ | _ -> 1
+ """
+ |> withLangVersion80
+ |> compile
+ |> shouldSucceed
+ |> verifyIL [
+ """.field public static initonly valuetype [runtime]System.Decimal x"""
+ """ .custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,
+ uint8,
+ int32,
+ int32,
+ int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00
+ 00 00 )"""
+ """IL_0016: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal,
+ valuetype [netstandard]System.Decimal)"""
+ """.maxstack 8"""
+ """IL_0000: ldc.i4.5"""
+ """IL_0001: ldc.i4.0"""
+ """IL_0002: ldc.i4.0"""
+ """IL_0003: ldc.i4.0"""
+ """IL_0004: ldc.i4.0"""
+ """IL_0005: newobj instance void [runtime]System.Decimal::.ctor(int32,
+ int32,
+ int32,
+ bool,
+ uint8)"""
+ """IL_000a: stsfld valuetype [runtime]System.Decimal PatternMatch::x"""
+ """IL_000f: ret"""
]
+ []
+ let ``Multiple decimals literals can be created``() =
+ FSharp """
+module DecimalLiterals
+
+[]
+let x = 41m
+
+[]
+let y = 42m
+ """
+ |> withLangVersion80
+ |> compile
+ |> shouldSucceed
+
[]
let ``Compilation fails when using arithmetic with a non-literal in literal``() =
FSharp """
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericCode.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericCode.fs
new file mode 100644
index 00000000000..06c0b1f3031
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericCode.fs
@@ -0,0 +1,19 @@
+module MyLibrary
+let strictlyNotNull (x:obj) = ()
+
+let myGenericFunction1 (p:_|null) =
+ match p with
+ | null -> ()
+ | p -> strictlyNotNull p
+
+let myGenericFunction2 p =
+ match p with
+ | Null -> ()
+ | NonNull p -> strictlyNotNull p
+
+let myGenericFunction3 p =
+ match p with
+ | null -> ()
+ // By the time we typecheck `| null`, we assign T to be a nullable type. Imagine there could be plenty of code before this pattern match got to be typechecked.
+ // As of now, the inference decision in the middle of a function cannot suddenly switch from (T which supports null) (T | null, where T is not nullable)
+ | pnn -> strictlyNotNull (pnn |> Unchecked.nonNull)
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericCode.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericCode.fs.il.net472.bsl
new file mode 100644
index 00000000000..0e958b024af
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericCode.fs.il.net472.bsl
@@ -0,0 +1,222 @@
+
+
+
+
+
+.assembly extern runtime { }
+.assembly extern FSharp.Core { }
+.assembly assembly
+{
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module assembly.dll
+
+.imagebase {value}
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003
+.corflags 0x00000001
+
+
+
+
+
+.class public abstract auto ansi sealed MyLibrary
+ extends [runtime]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 )
+ .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 )
+ .method public static void strictlyNotNull(object x) cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ret
+ }
+
+ .method public static void myGenericFunction1(!!a p) cil managed
+ {
+ .param type a
+ .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 )
+ .param [1]
+ .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 )
+
+ .maxstack 3
+ .locals init (!!a V_0,
+ !!a V_1)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloc.0
+ IL_0003: box !!a
+ IL_0008: brfalse.s IL_000c
+
+ IL_000a: br.s IL_000d
+
+ IL_000c: ret
+
+ IL_000d: ldloc.0
+ IL_000e: stloc.1
+ IL_000f: ldloc.1
+ IL_0010: box !!a
+ IL_0015: call void MyLibrary::strictlyNotNull(object)
+ IL_001a: ret
+ }
+
+ .method public static void myGenericFunction2(!!a p) cil managed
+ {
+ .param type a
+ .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 )
+ .param [1]
+ .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 )
+
+ .maxstack 3
+ .locals init (!!a V_0,
+ class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2 V_1,
+ !!a V_2,
+ !!a V_3)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloc.0
+ IL_0003: stloc.2
+ IL_0004: ldloc.2
+ IL_0005: box !!a
+ IL_000a: brfalse.s IL_000e
+
+ IL_000c: br.s IL_0016
+
+ IL_000e: ldnull
+ IL_000f: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2 class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2::NewChoice1Of2(!0)
+ IL_0014: br.s IL_001c
+
+ IL_0016: ldloc.2
+ IL_0017: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2 class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2::NewChoice2Of2(!1)
+ IL_001c: stloc.1
+ IL_001d: ldloc.1
+ IL_001e: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2
+ IL_0023: brfalse.s IL_0027
+
+ IL_0025: br.s IL_0028
+
+ IL_0027: ret
+
+ IL_0028: ldloc.1
+ IL_0029: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2
+ IL_002e: call instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2::get_Item()
+ IL_0033: stloc.3
+ IL_0034: ldloc.3
+ IL_0035: box !!a
+ IL_003a: call void MyLibrary::strictlyNotNull(object)
+ IL_003f: ret
+ }
+
+ .method public static void myGenericFunction3(!!a p) cil managed
+ {
+ .param type a
+ .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 )
+ .param [1]
+ .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 )
+
+ .maxstack 3
+ .locals init (!!a V_0,
+ !!a V_1,
+ !!a V_2,
+ !!a V_3)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloc.0
+ IL_0003: box !!a
+ IL_0008: brfalse.s IL_000c
+
+ IL_000a: br.s IL_000d
+
+ IL_000c: ret
+
+ IL_000d: ldloc.0
+ IL_000e: stloc.1
+ IL_000f: ldloc.1
+ IL_0010: stloc.2
+ IL_0011: ldloc.2
+ IL_0012: stloc.3
+ IL_0013: ldloc.3
+ IL_0014: box !!a
+ IL_0019: call void MyLibrary::strictlyNotNull(object)
+ IL_001e: ret
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$MyLibrary
+ extends [runtime]System.Object
+{
+}
+
+.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute
+ extends [runtime]System.Attribute
+{
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .field public uint8[] NullableFlags
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [runtime]System.Attribute::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: ldc.i4.1
+ IL_0008: newarr [runtime]System.Byte
+ IL_000d: dup
+ IL_000e: ldc.i4.0
+ IL_000f: ldarg.1
+ IL_0010: stelem.i1
+ IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags
+ IL_0016: ret
+ }
+
+ .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [runtime]System.Attribute::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: ldarg.1
+ IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags
+ IL_000d: ret
+ }
+
+}
+
+.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute
+ extends [runtime]System.Attribute
+{
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .field public uint8 Flag
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [runtime]System.Attribute::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: ldarg.1
+ IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag
+ IL_000d: ret
+ }
+
+}
+
+
+
+
+
+
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericCode.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericCode.fs.il.netcore.bsl
new file mode 100644
index 00000000000..ca54c9be1ee
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericCode.fs.il.netcore.bsl
@@ -0,0 +1,157 @@
+
+
+
+
+
+.assembly extern runtime { }
+.assembly extern FSharp.Core { }
+.assembly assembly
+{
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module assembly.dll
+
+.imagebase {value}
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003
+.corflags 0x00000001
+
+
+
+
+
+.class public abstract auto ansi sealed MyLibrary
+ extends [runtime]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 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 )
+ .method public static void strictlyNotNull(object x) cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ret
+ }
+
+ .method public static void myGenericFunction1(!!a p) cil managed
+ {
+ .param type a
+ .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 )
+ .param [1]
+ .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 )
+
+ .maxstack 3
+ .locals init (!!a V_0,
+ !!a V_1)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloc.0
+ IL_0003: box !!a
+ IL_0008: brfalse.s IL_000c
+
+ IL_000a: br.s IL_000d
+
+ IL_000c: ret
+
+ IL_000d: ldloc.0
+ IL_000e: stloc.1
+ IL_000f: ldloc.1
+ IL_0010: box !!a
+ IL_0015: call void MyLibrary::strictlyNotNull(object)
+ IL_001a: ret
+ }
+
+ .method public static void myGenericFunction2(!!a p) cil managed
+ {
+ .param type a
+ .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 )
+ .param [1]
+ .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 )
+
+ .maxstack 3
+ .locals init (!!a V_0,
+ class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2 V_1,
+ !!a V_2,
+ !!a V_3)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloc.0
+ IL_0003: stloc.2
+ IL_0004: ldloc.2
+ IL_0005: box !!a
+ IL_000a: brfalse.s IL_000e
+
+ IL_000c: br.s IL_0016
+
+ IL_000e: ldnull
+ IL_000f: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2 class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2::NewChoice1Of2(!0)
+ IL_0014: br.s IL_001c
+
+ IL_0016: ldloc.2
+ IL_0017: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2 class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2::NewChoice2Of2(!1)
+ IL_001c: stloc.1
+ IL_001d: ldloc.1
+ IL_001e: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2
+ IL_0023: brfalse.s IL_0027
+
+ IL_0025: br.s IL_0028
+
+ IL_0027: ret
+
+ IL_0028: ldloc.1
+ IL_0029: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2
+ IL_002e: call instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2::get_Item()
+ IL_0033: stloc.3
+ IL_0034: ldloc.3
+ IL_0035: box !!a
+ IL_003a: call void MyLibrary::strictlyNotNull(object)
+ IL_003f: ret
+ }
+
+ .method public static void myGenericFunction3(!!a p) cil managed
+ {
+ .param type a
+ .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 )
+ .param [1]
+ .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 )
+
+ .maxstack 3
+ .locals init (!!a V_0,
+ !!a V_1,
+ !!a V_2,
+ !!a V_3)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloc.0
+ IL_0003: box !!a
+ IL_0008: brfalse.s IL_000c
+
+ IL_000a: br.s IL_000d
+
+ IL_000c: ret
+
+ IL_000d: ldloc.0
+ IL_000e: stloc.1
+ IL_000f: ldloc.1
+ IL_0010: stloc.2
+ IL_0011: ldloc.2
+ IL_0012: stloc.3
+ IL_0013: ldloc.3
+ IL_0014: box !!a
+ IL_0019: call void MyLibrary::strictlyNotNull(object)
+ IL_001e: ret
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$MyLibrary
+ extends [runtime]System.Object
+{
+}
+
+
+
+
+
+
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs
index 3476cf07b2e..f0ebdfa0c34 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs
@@ -89,6 +89,12 @@ let ``SupportsNull`` compilation =
|> withNoWarn 52
|> verifyCompilation DoNotOptimize
+[]
+let ``GenericCode`` compilation =
+ compilation
+ |> withNoWarn 52
+ |> verifyCompilation DoNotOptimize
+
module Interop =
open System.IO
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs
index 9a43d34d429..1e5187167a7 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs
@@ -56,9 +56,9 @@ let ``Stackoverflow reproduction`` compilation =
| CompilationResult.Success ({OutputPath = Some dllFile} as s) ->
let fsharpCoreFile = typeof>.Assembly.Location
File.Copy(fsharpCoreFile, Path.Combine(Path.GetDirectoryName(dllFile), Path.GetFileName(fsharpCoreFile)), true)
- let exitCode, _stdout, _stderr = CompilerAssert.ExecuteAndReturnResult (dllFile, isFsx=false, deps = s.Dependencies, newProcess=true)
+ let _exitCode, _stdout, stderr, _exn = CompilerAssert.ExecuteAndReturnResult (dllFile, isFsx=false, deps = s.Dependencies, newProcess=true)
- Assert.NotEqual(0,exitCode)
+ Assert.True(stderr.Contains "stack overflow" || stderr.Contains "StackOverflow")
| _ -> failwith (sprintf "%A" compilationResult)
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs
index 34263b3f7bc..53cb33b5b78 100644
--- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs
@@ -347,7 +347,7 @@ let f4 =
|> withDiagnostics [
(Error 1, Line 6, Col 9, Line 6, Col 16, "This expression was expected to have type\n 'int' \nbut here has type\n 'string' ")
(Error 1, Line 12, Col 13, Line 12, Col 16, "This expression was expected to have type\n 'int' \nbut here has type\n 'string' ")
- (Error 193, Line 21, Col 9, Line 21, Col 24, "Type constraint mismatch. The type \n 'int list' \nis not compatible with type\n 'string seq' \n")
+ (Error 193, Line 21, Col 16, Line 21, Col 24, "Type constraint mismatch. The type \n 'int list' \nis not compatible with type\n 'string seq' \n")
(Error 1, Line 28, Col 9, Line 28, Col 12, "This expression was expected to have type\n 'int64' \nbut here has type\n 'float' ")
]
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index bbd4fe0ac4d..2d26f092a9b 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -34,6 +34,7 @@
+
@@ -117,6 +118,7 @@
+
@@ -259,6 +261,7 @@
+
diff --git a/tests/FSharp.Compiler.ComponentTests/Interop/Literals.fs b/tests/FSharp.Compiler.ComponentTests/Interop/Literals.fs
new file mode 100644
index 00000000000..5eeea2822b4
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/Interop/Literals.fs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace Interop
+
+open Xunit
+open FSharp.Test.Compiler
+
+module ``Literals interop`` =
+
+ []
+ let ``Instantiate F# decimal literal from C#`` () =
+ let FSLib =
+ FSharp """
+namespace Interop.FS
+
+module DecimalLiteral =
+ []
+ let x = 7m
+ """
+ |> withName "FSLib"
+
+ let app =
+ CSharp """
+using System;
+using Interop.FS;
+public class C {
+ public Decimal y = DecimalLiteral.x;
+}
+ """
+ |> withReferences [FSLib]
+ |> withName "CSharpApp"
+
+ app
+ |> compile
+ |> shouldSucceed
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs
index dc98a4be095..90a4a188e4f 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs
@@ -39,3 +39,22 @@ let z : unit =
|> withLangVersion50
|> compileAndRun
|> shouldSucceed
+
+ []
+ let ``Quotation on decimal literal compiles and runs`` () =
+ FSharp """
+open Microsoft.FSharp.Quotations.DerivedPatterns
+
+[]
+let x = 7m
+
+let expr = <@ x @>
+
+match expr with
+| Decimal n -> printfn "%M" n
+| _ -> failwith (string expr)
+ """
+ |> asExe
+ |> withLangVersion80
+ |> compileAndRun
+ |> shouldSucceed
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs
index 319d79aa8ea..3555e97fd2d 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs
@@ -493,4 +493,236 @@ let run r2 r3 =
|> shouldFail
|> withDiagnostics [
(Error 750, Line 3, Col 5, Line 3, Col 11, "This construct may only be used within computation expressions")
+ ]
+
+ []
+ let ``This control construct may only be used if the computation expression builder defines a 'Yield' method`` () =
+ Fsx """
+let f3 =
+ async {
+ if true then
+ yield "a"
+ else
+ yield "b"
+ }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 708, Line 5, Col 13, Line 5, Col 18, "This control construct may only be used if the computation expression builder defines a 'Yield' method")
+ ]
+
+ []
+ let ``This control construct may only be used if the computation expression builder defines a 'YieldFrom' method`` () =
+ Fsx """
+let f3 =
+ async {
+ if true then
+ yield! "a"
+ else
+ yield "b"
+ }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 708, Line 5, Col 13, Line 5, Col 19, "This control construct may only be used if the computation expression builder defines a 'YieldFrom' method")
+ ]
+
+
+ []
+ let ``This control construct may only be used if the computation expression builder defines a 'Return' method`` () =
+ Fsx """
+module Result =
+ let zip x1 x2 =
+ match x1,x2 with
+ | Ok x1res, Ok x2res -> Ok (x1res, x2res)
+ | Error e, _ -> Error e
+ | _, Error e -> Error e
+
+type ResultBuilder() =
+ member _.MergeSources(t1: Result<'T,'U>, t2: Result<'T1,'U>) = Result.zip t1 t2
+ member _.BindReturn(x: Result<'T,'U>, f) = Result.map f x
+ member _.Delay(f) = f()
+
+ member _.TryWith(r: Result<'T,'U>, f) =
+ match r with
+ | Ok x -> Ok x
+ | Error e -> f e
+
+let result = ResultBuilder()
+
+let run r2 r3 =
+ result {
+ match r2 with
+ | Ok x -> return x
+ | Error e -> return e
+ }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 708, Line 24, Col 19, Line 24, Col 25, "This control construct may only be used if the computation expression builder defines a 'Return' method")
+ ]
+
+
+ []
+ let ``This control construct may only be used if the computation expression builder defines a 'ReturnFrom' method`` () =
+ Fsx """
+module Result =
+ let zip x1 x2 =
+ match x1,x2 with
+ | Ok x1res, Ok x2res -> Ok (x1res, x2res)
+ | Error e, _ -> Error e
+ | _, Error e -> Error e
+
+type ResultBuilder() =
+ member _.MergeSources(t1: Result<'T,'U>, t2: Result<'T1,'U>) = Result.zip t1 t2
+ member _.BindReturn(x: Result<'T,'U>, f) = Result.map f x
+ member _.Delay(f) = f()
+
+ member _.TryWith(r: Result<'T,'U>, f) =
+ match r with
+ | Ok x -> Ok x
+ | Error e -> f e
+
+let result = ResultBuilder()
+
+let run r2 r3 =
+ result {
+ match r2 with
+ | Ok x -> return! x
+ | Error e -> return e
+ }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 708, Line 24, Col 19, Line 24, Col 26, "This control construct may only be used if the computation expression builder defines a 'ReturnFrom' method")
+ ]
+
+ []
+ let ``Type constraint mismatch when using return!`` () =
+ Fsx """
+open System.Threading.Tasks
+
+let maybeTask = task { return false }
+
+let indexHandler (): Task =
+ task {
+ return! maybeTask
+ }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 193, Line 8, Col 17, Line 8, Col 26, "Type constraint mismatch. The type \n 'TaskCode' \nis not compatible with type\n 'TaskCode' \n")
+ ]
+
+ []
+ let ``Type constraint mismatch when using return`` () =
+ Fsx """
+open System.Threading.Tasks
+
+let maybeTask = task { return false }
+
+let indexHandler (): Task =
+ task {
+ return maybeTask
+ }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 1, Line 8, Col 16, Line 8, Col 25, "This expression was expected to have type
+ 'string'
+but here has type
+ 'Task' ")
+ ]
+
+ []
+ let ``use expressions may not be used in queries(SynExpr.Sequential)`` () =
+ Fsx """
+let x11 =
+ query { for c in [1..10] do
+ use x = { new System.IDisposable with __.Dispose() = () }
+ yield 1 }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3142, Line 4, Col 13, Line 4, Col 16, "'use' expressions may not be used in queries")
+ ]
+
+ []
+ let ``use, This control construct may only be used if the computation expression builder defines a 'Using' method`` () =
+ Fsx """
+module Result =
+ let zip x1 x2 =
+ match x1,x2 with
+ | Ok x1res, Ok x2res -> Ok (x1res, x2res)
+ | Error e, _ -> Error e
+ | _, Error e -> Error e
+
+type ResultBuilder() =
+ member _.MergeSources(t1: Result<'T,'U>, t2: Result<'T1,'U>) = Result.zip t1 t2
+ member _.BindReturn(x: Result<'T,'U>, f) = Result.map f x
+
+ member _.YieldReturn(x: Result<'T,'U>) = x
+ member _.Return(x: 'T) = Ok x
+
+let result = ResultBuilder()
+
+let run r2 r3 =
+ result {
+ use b = r2
+ return Ok 0
+ }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 708, Line 20, Col 9, Line 20, Col 12, "This control construct may only be used if the computation expression builder defines a 'Using' method")
+ ]
+
+ []
+ let ``This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.`` () =
+ Fsx """
+let x18rec2 =
+ query {
+ for d in [1..10] do
+ let rec f x = x + 1 // error expected here - no recursive functions
+ and g x = f x + 2
+ select (f d)
+ }
+
+let x18inline =
+ query {
+ for d in [1..10] do
+ let inline f x = x + 1 // error expected here - no inline functions
+ select (f d)
+ }
+
+let x18mutable =
+ query {
+ for d in [1..10] do
+ let mutable v = 1 // error expected here - no mutable values
+ select (f d)
+ }
+
+ """
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3147, Line 5, Col 17, Line 5, Col 20, "This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.")
+ (Error 3147, Line 13, Col 20, Line 13, Col 23, "This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.")
+ (Error 3147, Line 20, Col 21, Line 20, Col 22, "This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.")
]
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs
index de6d1c888ca..1edfbfd7961 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs
@@ -17,6 +17,49 @@ let typeCheckWithStrictNullness cu =
|> withNullnessOptions
|> typecheck
+
+
+[]
+let ``Can convert generic value to objnull arg`` () =
+ FSharp """module TestLib
+
+let writeObj(tw:System.IO.TextWriter, a:'a) =
+ tw.Write(a)
+
+writeObj(System.IO.TextWriter.Null,null)
+ """
+ |> asLibrary
+ |> typeCheckWithStrictNullness
+ |> shouldSucceed
+
+[]
+let ``Can pass nulll to objnull arg`` () =
+ FSharp """module TestLib
+let doStuff args =
+ let ty = typeof
+ let m = ty.GetMethod("ToString") |> Unchecked.nonNull
+ m.Invoke(null,args)
+ """
+ |> asLibrary
+ |> typeCheckWithStrictNullness
+ |> shouldSucceed
+
+[]
+let ``Can cast from objTy to interfaceTy`` () =
+ FSharp """module TestLib
+open System
+let safeHolder : IDisposable =
+ { new obj() with
+ override x.Finalize() = (x :?> IDisposable).Dispose()
+ interface IDisposable with
+ member x.Dispose() =
+ GC.SuppressFinalize x
+ }
+ """
+ |> asLibrary
+ |> typeCheckWithStrictNullness
+ |> shouldSucceed
+
[]
let ``Does not duplicate warnings`` () =
FSharp """
@@ -28,6 +71,66 @@ let getLength (x: string | null) = x.Length
|> shouldFail
|> withDiagnostics [Error 3261, Line 3, Col 36, Line 3, Col 44, "Nullness warning: The types 'string' and 'string | null' do not have compatible nullability."]
+[]
+let ``Does report warning on obj to static member`` () =
+ FSharp """
+type Test() =
+ member _.XX(o:obj) = ()
+ static member X(o: obj) = ()
+ static member XString(x:string) = ()
+let x: obj | null = null
+Test.X x // warning expected
+let y2 = Test.X(x) // warning also expected
+Test.X(null:(obj|null)) // warning also expected
+let t = Test()
+t.XX(x)
+Test.XString(null)
+Test.XString("x":(string|null))
+ """
+ |> asLibrary
+ |> typeCheckWithStrictNullness
+ |> shouldFail
+ |> withDiagnostics
+ [ Error 3261, Line 7, Col 8, Line 7, Col 9, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected."
+ Error 3261, Line 7, Col 1, Line 7, Col 9, "Nullness warning: The types 'obj' and 'obj | null' do not have compatible nullability."
+ Error 3261, Line 8, Col 17, Line 8, Col 18, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected."
+ Error 3261, Line 8, Col 10, Line 8, Col 19, "Nullness warning: The types 'obj' and 'obj | null' do not have compatible nullability."
+ Error 3261, Line 9, Col 8, Line 9, Col 23, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected."
+ Error 3261, Line 9, Col 1, Line 9, Col 24, "Nullness warning: The types 'obj' and 'obj | null' do not have compatible nullability."
+ Error 3261, Line 11, Col 6, Line 11, Col 7, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected."
+ Error 3261, Line 11, Col 1, Line 11, Col 8, "Nullness warning: The types 'obj' and 'obj | null' do not have compatible nullability."
+ Error 3261, Line 12, Col 14, Line 12, Col 18, "Nullness warning: The type 'string' does not support 'null'."
+ Error 3261, Line 13, Col 14, Line 13, Col 31, "Nullness warning: The types 'string' and 'string | null' do not have equivalent nullability."]
+
+[]
+let ``Typar infered to nonnull obj`` () =
+
+ FSharp """module Tests
+let asObj(x:obj) = x
+let asObjNull(x:objnull) = x
+
+let genericWithoutNull x = asObj x
+let genericWithNull x = asObjNull x
+
+let result0 = genericWithoutNull null
+let result1 = genericWithoutNull ("":(obj|null))
+let result2 = genericWithoutNull 15
+let result3 = genericWithoutNull "xxx"
+let result4 = genericWithoutNull ("xxx":(string|null))
+let result5 = genericWithNull null
+let result6 = genericWithNull 15
+let result7 = genericWithNull "xxx"
+let result8 = genericWithNull ("":(obj|null))
+
+ """
+ |> asLibrary
+ |> typeCheckWithStrictNullness
+ |> shouldFail
+ |> withDiagnostics
+ [ Error 43, Line 8, Col 34, Line 8, Col 38, "The constraints 'null' and 'not null' are inconsistent"
+ Error 3261, Line 9, Col 35, Line 9, Col 48, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected."
+ Error 3261, Line 12, Col 35, Line 12, Col 54, "Nullness warning: The type 'string | null' supports 'null' but a non-null type is expected."]
+
[]
let ``Cannot pass possibly null value to a strict function``() =
@@ -608,10 +711,16 @@ strictFunc("hi") |> ignore """
[]
let ``Supports null in generic code`` () =
FSharp """module MyLibrary
-let myGenericFunction p =
+let myGenericFunctionForInnerNotNull (p:_|null) =
match p with
| null -> ()
- | p -> printfn "%s" (p.ToString())
+ | nnp -> printfn "%s" (nnp.ToString())
+
+let myGenericFunctionSupportingNull (p) =
+ match p with
+ | null -> 0
+ | nnp -> hash nnp
+
[]
type X(p:int) =
@@ -619,20 +728,15 @@ type X(p:int) =
let myValOfX : X = null
-myGenericFunction "HiThere"
-myGenericFunction ("HiThere":string | null)
-myGenericFunction (System.DateTime.Now)
-myGenericFunction 123
-myGenericFunction myValOfX
+myGenericFunctionForInnerNotNull "HiThere"
+myGenericFunctionForInnerNotNull ("HiThere":string | null)
+myGenericFunctionSupportingNull myValOfX |> ignore
+myGenericFunctionSupportingNull ("HiThere":string | null) |> ignore
"""
|> asLibrary
|> typeCheckWithStrictNullness
- |> shouldFail
- |> withDiagnostics
- [Error 3261, Line 13, Col 19, Line 13, Col 28, "Nullness warning: The type 'string' does not support 'null'."
- Error 193, Line 15, Col 20, Line 15, Col 39, "The type 'System.DateTime' does not have 'null' as a proper value"
- Error 1, Line 16, Col 19, Line 16, Col 22, "The type 'int' does not have 'null' as a proper value"]
+ |> shouldSucceed
[]
let ``Null assignment in generic code`` () =
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs
index 2757ab30aea..69b554bd48f 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs
@@ -120,9 +120,9 @@ System.Console.WriteLine("a")
System.Console.WriteLine("a", (null: obj[])) // Expected to give a Nullness warning
KonsoleWithNulls.WriteLine("Hello world")
-KonsoleWithNulls.WriteLine(null) // WRONG: gives an incorrect Nullness warning for String | null and String | null
+KonsoleWithNulls.WriteLine(null)
KonsoleWithNulls.WriteLine("Hello","world")
-KonsoleWithNulls.WriteLine("Hello","world","there") // // WRONG: gives an incorrect Nullness warning for String | null and String | null
+KonsoleWithNulls.WriteLine("Hello","world","there")
KonsoleNoNulls.WriteLine("Hello world")
try
@@ -169,7 +169,7 @@ with :? System.ArgumentNullException -> ()
// Param array cases
KonsoleNoNulls.WriteLine("Hello","world","there")
-KonsoleWithNulls.WriteLine("Hello","world",null) // Expected to give a Nullness warning
+KonsoleWithNulls.WriteLine("Hello","world",null) // Expected to give no Nullness warning
KonsoleNoNulls.WriteLine("Hello","world",null) // Expected to give a Nullness warning
System.Console.WriteLine("a", (null: obj[] | null))
System.Console.WriteLine("a", (null: (obj | null)[] | null))
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl
index 5154ce43e79..709c3c309b3 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl
+++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl
@@ -31,5 +31,6 @@ using-nullness-syntax-positive.fs (154,40)-(154,44) typecheck error Nullness war
using-nullness-syntax-positive.fs (159,36)-(159,40) typecheck error Nullness warning: The type 'String' does not support 'null'.
using-nullness-syntax-positive.fs (162,41)-(162,45) typecheck error Nullness warning: The type 'String' does not support 'null'.
using-nullness-syntax-positive.fs (164,37)-(164,41) typecheck error Nullness warning: The type 'String' does not support 'null'.
+using-nullness-syntax-positive.fs (173,42)-(173,46) typecheck error The constraints 'null' and 'not null' are inconsistent
using-nullness-syntax-positive.fs (183,14)-(183,16) typecheck error Nullness warning: The type 'string' does not support 'null'.
using-nullness-syntax-positive.fs (189,17)-(189,26) typecheck error Nullness warning: The type 'String' does not support 'null'.
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs
index 982ae0c820b..8247eaf60e3 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs
@@ -442,4 +442,29 @@ let typedSeq =
|> withErrorCode 30
|> withDiagnosticMessageMatches "Value restriction: The value 'typedSeq' has an inferred generic type"
|> withDiagnosticMessageMatches "val typedSeq: '_a seq"
-
\ No newline at end of file
+
+[]
+let ``yield may only be used within list, array, and sequence expressions``() =
+ Fsx """
+let f1 = yield [ 3; 4 ]
+let f2 = yield! [ 3; 4 ]
+ """
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 747, Line 2, Col 10, Line 2, Col 15, "This construct may only be used within list, array and sequence expressions, e.g. expressions of the form 'seq { ... }', '[ ... ]' or '[| ... |]'. These use the syntax 'for ... in ... do ... yield...' to generate elements");
+ (Error 747, Line 3, Col 10, Line 3, Col 16, "This construct may only be used within list, array and sequence expressions, e.g. expressions of the form 'seq { ... }', '[ ... ]' or '[| ... |]'. These use the syntax 'for ... in ... do ... yield...' to generate elements")
+ ]
+
+[]
+let ``return may only be used within list, array, and sequence expressions``() =
+ Fsx """
+let f1 = return [ 3; 4 ]
+let f2 = return! [ 3; 4 ]
+ """
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 748, Line 2, Col 10, Line 2, Col 16, "This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'.");
+ (Error 748, Line 3, Col 10, Line 3, Col 17, "This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'.")
+ ]
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs
index 2490e301e05..3f17e0cfa11 100644
--- a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs
@@ -31,16 +31,15 @@ module ScriptRunner =
let cu = cu |> withDefines defaultDefines
match cu with
| FS fsSource ->
- File.Delete("test.ok")
let engine = createEngine (fsSource.Options |> Array.ofList,version)
let res = evalScriptFromDiskInSharedSession engine cu
match res with
| CompilationResult.Failure _ -> res
- | CompilationResult.Success s ->
- if File.Exists("test.ok") then
+ | CompilationResult.Success s ->
+ if engine.GetOutput().Contains "TEST PASSED OK" then
res
else
- failwith $"Results looked correct, but 'test.ok' file was not created. Result: %A{s}"
+ failwith $"Results looked correct, but 'TEST PASSED OK' was not printed. Result: %A{s}"
| _ -> failwith $"Compilation unit other than fsharp is not supported, cannot process %A{cu}"
diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/access.fsx b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/access.fsx
index a8c3798a685..6790e4dfbee 100644
--- a/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/access.fsx
+++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/access.fsx
@@ -278,7 +278,7 @@ let aa =
match failures.Value with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/array.fsx b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/array.fsx
index 8c55d727f92..dd61a8f7474 100644
--- a/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/array.fsx
+++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/array.fsx
@@ -1142,7 +1142,7 @@ let aa =
match failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/libtest.fsx b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/libtest.fsx
index 23c2125ab51..515e1428697 100644
--- a/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/libtest.fsx
+++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/libtest.fsx
@@ -5651,7 +5651,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs
index 9cfbbb9df80..294db344223 100644
--- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs
@@ -38,12 +38,12 @@ module CompilationFromCmdlineArgsTests =
yield! methodOptions method
|]
- let diagnostics, exitCode = checker.Compile(args) |> Async.RunSynchronously
+ let diagnostics, exn = checker.Compile(args) |> Async.RunSynchronously
for diag in diagnostics do
printfn "%A" diag
- Assert.Equal(exitCode, 0)
+ Assert.Equal(exn, None)
finally
Environment.CurrentDirectory <- oldWorkDir
diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs
index 8a1bb95b2d2..cc027d098af 100644
--- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs
+++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs
@@ -760,10 +760,9 @@ x |> Seq.iter(fun r ->
if found = expected.Length then sawExpectedOutput.Set() |> ignore
let text = "#help"
- use output = new RedirectConsoleOutput()
use script = new FSharpScript(quiet = false, langVersion = LangVersion.V47)
let mutable found = 0
- output.OutputProduced.Add (fun line -> verifyOutput line)
+ script.OutputProduced.Add (fun line -> verifyOutput line)
let opt = script.Eval(text) |> getValue
Assert.True(sawExpectedOutput.WaitOne(TimeSpan.FromSeconds(5.0)), sprintf "Expected to see error sentinel value written\nexpected:%A\nactual:%A" expected lines)
@@ -811,10 +810,9 @@ x |> Seq.iter(fun r ->
if found = expected.Length then sawExpectedOutput.Set() |> ignore
let text = "#help"
- use output = new RedirectConsoleOutput()
use script = new FSharpScript(quiet = false, langVersion = LangVersion.Preview)
let mutable found = 0
- output.OutputProduced.Add (fun line -> verifyOutput line)
+ script.OutputProduced.Add (fun line -> verifyOutput line)
let opt = script.Eval(text) |> getValue
Assert.True(sawExpectedOutput.WaitOne(TimeSpan.FromSeconds(5.0)), sprintf "Expected to see error sentinel value written\nexpected:%A\nactual:%A" expected lines)
diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs
index f7587333981..aff47308ad2 100644
--- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs
+++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs
@@ -83,9 +83,7 @@ x
[]
member _.``Capture console input``() =
- use input = new RedirectConsoleInput()
- use script = new FSharpScript()
- input.ProvideInput "stdin:1234\r\n"
+ use script = new FSharpScript(input = "stdin:1234\r\n")
let opt = script.Eval("System.Console.ReadLine()") |> getValue
let value = opt.Value
Assert.Equal(typeof, value.ReflectionType)
@@ -93,12 +91,11 @@ x
[]
member _.``Capture console output/error``() =
- use output = new RedirectConsoleOutput()
use script = new FSharpScript()
use sawOutputSentinel = new ManualResetEvent(false)
use sawErrorSentinel = new ManualResetEvent(false)
- output.OutputProduced.Add (fun line -> if line = "stdout:1234" then sawOutputSentinel.Set() |> ignore)
- output.ErrorProduced.Add (fun line -> if line = "stderr:5678" then sawErrorSentinel.Set() |> ignore)
+ script.OutputProduced.Add (fun line -> if line = "stdout:1234" then sawOutputSentinel.Set() |> ignore)
+ script.ErrorProduced.Add (fun line -> if line = "stderr:5678" then sawErrorSentinel.Set() |> ignore)
script.Eval("printfn \"stdout:1234\"; eprintfn \"stderr:5678\"") |> ignoreValue
Assert.True(sawOutputSentinel.WaitOne(TimeSpan.FromSeconds(5.0)), "Expected to see output sentinel value written")
Assert.True(sawErrorSentinel.WaitOne(TimeSpan.FromSeconds(5.0)), "Expected to see error sentinel value written")
@@ -305,11 +302,10 @@ printfn ""%A"" result
[]
member _.``Eval script with invalid PackageName should fail immediately``() =
- use output = new RedirectConsoleOutput()
use script = new FSharpScript(additionalArgs=[| |])
let mutable found = 0
let outp = System.Collections.Generic.List()
- output.OutputProduced.Add(
+ script.OutputProduced.Add(
fun line ->
if line.Contains("error NU1101:") && line.Contains("FSharp.Really.Not.A.Package") then
found <- found + 1
@@ -321,10 +317,9 @@ printfn ""%A"" result
[]
member _.``Eval script with invalid PackageName should fail immediately and resolve one time only``() =
- use output = new RedirectConsoleOutput()
use script = new FSharpScript(additionalArgs=[| |])
let mutable foundResolve = 0
- output.OutputProduced.Add (fun line -> if line.Contains("error NU1101:") then foundResolve <- foundResolve + 1)
+ script.OutputProduced.Add (fun line -> if line.Contains("error NU1101:") then foundResolve <- foundResolve + 1)
let result, errors =
script.Eval("""
#r "nuget:FSharp.Really.Not.A.Package"
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl
index da62302304a..15e1dd848e6 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl
@@ -2166,7 +2166,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
-FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
+FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],Microsoft.FSharp.Core.FSharpOption`1[System.Exception]]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] ProjectChecked
@@ -7668,8 +7668,22 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTyped(FSharp.C
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewUpcast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhile(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhileBang(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
-FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
-FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturnFrom(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
+FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia get_trivia()
+FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia trivia
+FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia get_trivia()
+FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia trivia
+FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia)
+FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturnFrom(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia)
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: FSharp.Compiler.Text.Range YieldOrReturnFromKeyword
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: FSharp.Compiler.Text.Range get_YieldOrReturnFromKeyword()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: System.String ToString()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: Void .ctor(FSharp.Compiler.Text.Range)
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia Zero
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia get_Zero()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.Text.Range YieldOrReturnKeyword
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.Text.Range get_YieldOrReturnKeyword()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: System.String ToString()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: Void .ctor(FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AddressOf
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AnonRecd
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+App
@@ -10217,7 +10231,9 @@ FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.SyntaxTrivia
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] InKeyword
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InKeyword()
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: System.String ToString()
-FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range LetOrUseKeyword
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range get_LetOrUseKeyword()
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range MatchBangKeyword
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range WithKeyword
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range get_MatchBangKeyword()
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
index da62302304a..15e1dd848e6 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
@@ -2166,7 +2166,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
-FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
+FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],Microsoft.FSharp.Core.FSharpOption`1[System.Exception]]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] ProjectChecked
@@ -7668,8 +7668,22 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTyped(FSharp.C
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewUpcast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhile(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhileBang(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
-FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
-FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturnFrom(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
+FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia get_trivia()
+FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia trivia
+FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia get_trivia()
+FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia trivia
+FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia)
+FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturnFrom(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia)
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: FSharp.Compiler.Text.Range YieldOrReturnFromKeyword
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: FSharp.Compiler.Text.Range get_YieldOrReturnFromKeyword()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: System.String ToString()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: Void .ctor(FSharp.Compiler.Text.Range)
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia Zero
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia get_Zero()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.Text.Range YieldOrReturnKeyword
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.Text.Range get_YieldOrReturnKeyword()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: System.String ToString()
+FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: Void .ctor(FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AddressOf
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AnonRecd
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+App
@@ -10217,7 +10231,9 @@ FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.SyntaxTrivia
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] InKeyword
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InKeyword()
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: System.String ToString()
-FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range LetOrUseKeyword
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range get_LetOrUseKeyword()
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range MatchBangKeyword
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range WithKeyword
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range get_MatchBangKeyword()
diff --git a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs
index e9ce93a37cd..0b30a5a61e8 100644
--- a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs
+++ b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs
@@ -514,4 +514,49 @@ let success,version = System.Version.TryParse(null)
checkResults.GetToolTip(2, 45, "let success,version = System.Version.TryParse(null)", [ "TryParse" ], FSharpTokenTag.Identifier,width=100)
|> assertAndGetSingleToolTipText
|> Assert.shouldBeEquivalentTo ("""System.Version.TryParse([] input: string | null,
- [] result: byref) : bool""" |> normalize)
\ No newline at end of file
+ [] result: byref) : bool""" |> normalize)
+
+[]
+let ``Allows ref struct is shown on BCL interface declaration`` () =
+ let source = """module Foo
+open System
+let myAction : Action | null = null
+"""
+ let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
+ checkResults.GetToolTip(3, 21, "let myAction : Action | null = null", [ "Action" ], FSharpTokenTag.Identifier)
+ |> assertAndGetSingleToolTipText
+ |> Assert.shouldStartWith ("""type Action<'T (allows ref struct)>""" |> normalize)
+
+[]
+let ``Allows ref struct is shown for each T on BCL interface declaration`` () =
+ let source = """module Foo
+open System
+let myAction : Action | null = null
+"""
+ let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
+ checkResults.GetToolTip(3, 21, "let myAction : Action | null = null", [ "Action" ], FSharpTokenTag.Identifier)
+ |> assertAndGetSingleToolTipText
+ |> Assert.shouldStartWith ("""type Action<'T1,'T2,'T3,'T4 (allows ref struct and allows ref struct and allows ref struct and allows ref struct)>""" |> normalize)
+
+[]
+let ``Allows ref struct is shown on BCL method usage`` () =
+ let source = """module Foo
+open System
+open System.Collections.Generic
+let doIt (dict:Dictionary<'a,'b>) = dict.GetAlternateLookup<'a,'b,ReadOnlySpan>()
+"""
+ let checkResults = getCheckResults source [|"--langversion:preview"|]
+ checkResults.GetToolTip(4, 59, "let doIt (dict:Dictionary<'a,'b>) = dict.GetAlternateLookup<'a,'b,ReadOnlySpan>()", [ "GetAlternateLookup" ], FSharpTokenTag.Identifier)
+ |> assertAndGetSingleToolTipText
+ |> Assert.shouldContain ("""'TAlternateKey (allows ref struct)""" |> normalize)
+
+[]
+let ``Allows ref struct is not shown on BCL interface usage`` () =
+ let source = """module Foo
+open System
+let doIt(myAction : Action) = myAction.Invoke(42)
+"""
+ let checkResults = getCheckResults source [|"--langversion:preview"|]
+ checkResults.GetToolTip(3, 43, "let doIt(myAction : Action) = myAction.Invoke(42)", [ "myAction" ], FSharpTokenTag.Identifier)
+ |> assertAndGetSingleToolTipText
+ |> Assert.shouldBeEquivalentTo ("""val myAction: Action""" |> normalize)
\ No newline at end of file
diff --git a/tests/FSharp.Test.Utilities/Assert.fs b/tests/FSharp.Test.Utilities/Assert.fs
index dfed4bf123e..fc36129666f 100644
--- a/tests/FSharp.Test.Utilities/Assert.fs
+++ b/tests/FSharp.Test.Utilities/Assert.fs
@@ -11,6 +11,12 @@ module Assert =
let inline shouldBeEquivalentTo (expected : ^T) (actual : ^U) =
actual.Should().BeEquivalentTo(expected, "") |> ignore
+
+ let inline shouldStartWith (expected : string) (actual : string) =
+ actual.Should().StartWith(expected) |> ignore
+
+ let inline shouldContain (needle : string) (haystack : string) =
+ haystack.Should().Contain(needle) |> ignore
let inline shouldBe (expected : ^T) (actual : ^U) =
actual.Should().Be(expected, "") |> ignore
diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs
index f535bc21c5a..5e5629b089f 100644
--- a/tests/FSharp.Test.Utilities/Compiler.fs
+++ b/tests/FSharp.Test.Utilities/Compiler.fs
@@ -170,10 +170,13 @@ module rec Compiler =
Message: string
SubCategory: string }
+ // This type is used either for the output of the compiler (typically in CompilationResult coming from 'compile')
+ // or for the output of the code generated by the compiler (in CompilationResult coming from 'run')
type ExecutionOutput =
- { ExitCode: int
+ { ExitCode: int option
StdOut: string
- StdErr: string }
+ StdErr: string
+ Exn: exn option }
type RunOutput =
| EvalOutput of Result
@@ -699,7 +702,7 @@ module rec Compiler =
let private compileFSharpCompilation compilation ignoreWarnings (cUnit: CompilationUnit) : CompilationResult =
use redirect = new RedirectConsole()
- let ((err: FSharpDiagnostic[], rc: int, outputFilePath: string), deps) =
+ let ((err: FSharpDiagnostic[], exn, outputFilePath: string), deps) =
CompilerAssert.CompileRaw(compilation, ignoreWarnings)
// Create and stash the console output
@@ -711,7 +714,7 @@ module rec Compiler =
Adjust = 0
PerFileErrors = diagnostics
Diagnostics = diagnostics |> List.map snd
- Output = Some (RunOutput.ExecutionOutput { ExitCode = rc; StdOut = redirect.Output(); StdErr = redirect.ErrorOutput() })
+ Output = Some (RunOutput.ExecutionOutput { ExitCode = None; StdOut = redirect.Output(); StdErr = redirect.ErrorOutput(); Exn = exn })
Compilation = cUnit
}
@@ -978,14 +981,13 @@ module rec Compiler =
| SourceCodeFileKind.Fsx _ -> true
| _ -> false
| _ -> false
- let exitCode, output, errors = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false)
+ let exitCode, output, errors, exn = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false)
printfn "---------output-------\n%s\n-------" output
printfn "---------errors-------\n%s\n-------" errors
- let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors }) }
- if exitCode = 0 then
- CompilationResult.Success executionResult
- else
- CompilationResult.Failure executionResult
+ let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors; Exn = exn }) }
+ match exn with
+ | None -> CompilationResult.Success executionResult
+ | Some _ -> CompilationResult.Failure executionResult
let compileAndRun = compile >> run
@@ -1080,27 +1082,25 @@ module rec Compiler =
opts.ToArray()
let errors, stdOut = CompilerAssert.RunScriptWithOptionsAndReturnResult options source
- let executionOutputwithStdOut: RunOutput option =
- ExecutionOutput { StdOut = stdOut; ExitCode = 0; StdErr = "" }
- |> Some
- let result =
+ let mkResult output =
{ OutputPath = None
Dependencies = []
Adjust = 0
Diagnostics = []
PerFileErrors= []
- Output = executionOutputwithStdOut
+ Output = Some output
Compilation = cUnit }
-
- if errors.Count > 0 then
- let output = ExecutionOutput {
- ExitCode = -1
- StdOut = String.Empty
- StdErr = ((errors |> String.concat "\n").Replace("\r\n","\n")) }
- CompilationResult.Failure { result with Output = Some output }
+
+ if errors.Count = 0 then
+ let output =
+ ExecutionOutput { ExitCode = None; StdOut = stdOut; StdErr = ""; Exn = None }
+ CompilationResult.Success (mkResult output)
else
- CompilationResult.Success result
-
+ let err = (errors |> String.concat "\n").Replace("\r\n","\n")
+ let output =
+ ExecutionOutput {ExitCode = None; StdOut = String.Empty; StdErr = err; Exn = None }
+ CompilationResult.Failure (mkResult output)
+
finally
disposals
|> Seq.iter (fun x -> x.Dispose())
@@ -1190,7 +1190,7 @@ Actual:
| Some p ->
match ILChecker.verifyILAndReturnActual [] p expected with
| true, _, _ -> result
- | false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput { StdOut = errorMsg; ExitCode = 0; StdErr = "" })} )
+ | false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput {ExitCode = None; StdOut = errorMsg; StdErr = ""; Exn = None })} )
| CompilationResult.Failure f -> failwith $"Result should be \"Success\" in order to get IL. Failure: {Environment.NewLine}{f}"
@@ -1706,7 +1706,7 @@ Actual:
| None -> failwith "Execution output is missing, cannot check exit code."
| Some o ->
match o with
- | ExecutionOutput e -> Assert.Equal(expectedExitCode, e.ExitCode)
+ | ExecutionOutput {ExitCode = Some exitCode} -> Assert.Equal(expectedExitCode, exitCode)
| _ -> failwith "Cannot check exit code on this run result."
result
diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs
index fc2875d8955..37a8e25e164 100644
--- a/tests/FSharp.Test.Utilities/CompilerAssert.fs
+++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs
@@ -322,7 +322,7 @@ module rec CompilerAssertHelpers =
else
entryPoint
let args = mkDefaultArgs entryPoint
- captureConsoleOutputs (fun () -> entryPoint.Invoke(Unchecked.defaultof, args) |> ignore)
+ captureConsoleOutputs (fun () -> entryPoint.Invoke(Unchecked.defaultof, args))
#if NETCOREAPP
let executeBuiltApp assembly deps isFsx =
@@ -409,8 +409,8 @@ module rec CompilerAssertHelpers =
// Generate a response file, purely for diagnostic reasons.
File.WriteAllLines(Path.ChangeExtension(outputFilePath, ".rsp"), args)
- let errors, rc = checker.Compile args |> Async.RunImmediate
- errors, rc, outputFilePath
+ let errors, ex = checker.Compile args |> Async.RunImmediate
+ errors, ex, outputFilePath
let compileDisposable (outputDirectory:DirectoryInfo) isExe options targetFramework nameOpt (sources:SourceCodeFileKind list) =
let disposeFile path =
@@ -537,7 +537,7 @@ module rec CompilerAssertHelpers =
let tmp = Path.Combine(outputPath.FullName, Path.ChangeExtension(fileName, ".dll"))
disposals.Add({ new IDisposable with member _.Dispose() = File.Delete tmp })
cmpl.EmitAsFile tmp
- (([||], 0, tmp), []), false)
+ (([||], None, tmp), []), false)
let compilationRefs =
compiledRefs
@@ -559,7 +559,7 @@ module rec CompilerAssertHelpers =
compilationRefs, deps
- let compileCompilationAux outputDirectory (disposals: ResizeArray) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * int * string) * string list =
+ let compileCompilationAux outputDirectory (disposals: ResizeArray) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * exn option * string) * string list =
let compilationRefs, deps = evaluateReferences outputDirectory disposals ignoreWarnings cmpl
let isExe, sources, options, targetFramework, name =
@@ -604,7 +604,7 @@ module rec CompilerAssertHelpers =
outputDirectory.Create()
compileCompilationAux outputDirectory (ResizeArray()) ignoreWarnings cmpl
- let captureConsoleOutputs (func: unit -> unit) =
+ let captureConsoleOutputs (func: unit -> obj) =
let out = Console.Out
let err = Console.Error
@@ -614,29 +614,30 @@ module rec CompilerAssertHelpers =
use outWriter = new StringWriter (stdout)
use errWriter = new StringWriter (stderr)
- let succeeded, exn =
+ let rc, exn =
try
try
Console.SetOut outWriter
Console.SetError errWriter
- func ()
- true, None
+ let rc = func()
+ match rc with
+ | :? int as rc -> Some rc, None
+ | _ -> None, None
with e ->
let errorMessage = if e.InnerException <> null then e.InnerException.ToString() else e.ToString()
stderr.Append errorMessage |> ignore
- false, Some e
+ None, Some e
finally
Console.SetOut out
Console.SetError err
outWriter.Close()
errWriter.Close()
- succeeded, stdout.ToString(), stderr.ToString(), exn
+ rc, stdout.ToString(), stderr.ToString(), exn
- let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) isFsx : (int * string * string) =
- let succeeded, stdout, stderr, _ = executeBuiltApp outputFilePath deps isFsx
- let exitCode = if succeeded then 0 else -1
- exitCode, stdout, stderr
+ let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) isFsx : (int option * string * string * exn option) =
+ let rc, stdout, stderr, exn = executeBuiltApp outputFilePath deps isFsx
+ rc, stdout, stderr, exn
let executeBuiltAppNewProcessAndReturnResult (outputFilePath: string) : (int * string * string) =
#if !NETCOREAPP
@@ -663,7 +664,7 @@ module rec CompilerAssertHelpers =
member _.Dispose() = try File.Delete runtimeconfigPath with | _ -> () }
#endif
let timeout = 30000
- let exitCode, output, errors = Commands.executeProcess (Some fileName) arguments (Path.GetDirectoryName(outputFilePath)) timeout
+ let exitCode, output, errors = Commands.executeProcess fileName arguments (Path.GetDirectoryName(outputFilePath)) timeout
(exitCode, output |> String.concat "\n", errors |> String.concat "\n")
open CompilerAssertHelpers
@@ -677,7 +678,7 @@ type CompilerAssert private () =
if errors.Length > 0 then
Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors)
- executeBuiltApp outputExe [] false |> ignore
+ executeBuiltApp outputExe [] false |> ignore
)
static let compileLibraryAndVerifyILWithOptions options (source: SourceCodeFileKind) (f: ILVerifier -> unit) =
@@ -739,11 +740,13 @@ Updated automatically, please check diffs in your pull request, changes must be
returnCompilation cmpl (defaultArg ignoreWarnings false)
static member ExecuteAndReturnResult (outputFilePath: string, isFsx: bool, deps: string list, newProcess: bool) =
- // If we execute in-process (true by default), then the only way of getting STDOUT is to redirect it to SB, and STDERR is from catching an exception.
if not newProcess then
- executeBuiltAppAndReturnResult outputFilePath deps isFsx
+ let entryPointReturnCode, deps, isFsx, exn = executeBuiltAppAndReturnResult outputFilePath deps isFsx
+ entryPointReturnCode, deps, isFsx, exn
else
- executeBuiltAppNewProcessAndReturnResult outputFilePath
+ let processExitCode, deps, isFsx = executeBuiltAppNewProcessAndReturnResult outputFilePath
+ Some processExitCode, deps, isFsx, None
+
static member Execute(cmpl: Compilation, ?ignoreWarnings, ?beforeExecute, ?newProcess, ?onOutput) =
@@ -767,7 +770,7 @@ Updated automatically, please check diffs in your pull request, changes must be
Assert.Fail errors
onOutput output
else
- let _succeeded, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps false
+ let _rc, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps false
exn |> Option.iter raise)
static member ExecutionHasOutput(cmpl: Compilation, expectedOutput: string) =
diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs
index 4474ef01c10..de0fbd8050b 100644
--- a/tests/FSharp.Test.Utilities/ILChecker.fs
+++ b/tests/FSharp.Test.Utilities/ILChecker.fs
@@ -16,7 +16,7 @@ module ILChecker =
let private exec exe args =
let arguments = args |> String.concat " "
let timeout = 30000
- let exitCode, _output, errors = Commands.executeProcess (Some exe) arguments "" timeout
+ let exitCode, _output, errors = Commands.executeProcess exe arguments "" timeout
let errors = errors |> String.concat Environment.NewLine
errors, exitCode
diff --git a/tests/FSharp.Test.Utilities/Peverifier.fs b/tests/FSharp.Test.Utilities/Peverifier.fs
index 35db5b208fb..f3ccc7de2b1 100644
--- a/tests/FSharp.Test.Utilities/Peverifier.fs
+++ b/tests/FSharp.Test.Utilities/Peverifier.fs
@@ -25,7 +25,7 @@ module PEVerifier =
let private exec exe args =
let arguments = args |> String.concat " "
let timeout = 30000
- let exitCode, _output, errors = Commands.executeProcess (Some exe) arguments "" timeout
+ let exitCode, _output, errors = Commands.executeProcess exe arguments "" timeout
let errors = errors |> String.concat Environment.NewLine
errors, exitCode
diff --git a/tests/FSharp.Test.Utilities/ProjectGeneration.fs b/tests/FSharp.Test.Utilities/ProjectGeneration.fs
index 78feb049435..a75784240dd 100644
--- a/tests/FSharp.Test.Utilities/ProjectGeneration.fs
+++ b/tests/FSharp.Test.Utilities/ProjectGeneration.fs
@@ -1360,9 +1360,8 @@ type ProjectWorkflowBuilder
yield! projectOptions.OtherOptions
yield! projectOptions.SourceFiles
|]
- let! _diagnostics, exitCode = checker.Compile(arguments)
- if exitCode <> 0 then
- exn $"Compilation failed with exit code {exitCode}" |> raise
+ let! _diagnostics, ex = checker.Compile(arguments)
+ if ex.IsSome then raise ex.Value
return ctx
}
diff --git a/tests/FSharp.Test.Utilities/ScriptHelpers.fs b/tests/FSharp.Test.Utilities/ScriptHelpers.fs
index aaaf5c458d8..688941934c9 100644
--- a/tests/FSharp.Test.Utilities/ScriptHelpers.fs
+++ b/tests/FSharp.Test.Utilities/ScriptHelpers.fs
@@ -3,7 +3,6 @@
namespace FSharp.Test.ScriptHelpers
open System
-open System.Collections.Generic
open System.IO
open System.Text
open System.Threading
@@ -11,7 +10,7 @@ open FSharp.Compiler
open FSharp.Compiler.Interactive.Shell
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.EditorServices
-open FSharp.Test.Utilities
+open FSharp.Test
[]
type LangVersion =
@@ -25,7 +24,26 @@ type LangVersion =
| Latest
| SupportsMl
-type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVersion) =
+type private EventedTextWriter() =
+ inherit TextWriter()
+ let sb = StringBuilder()
+ let sw = new StringWriter()
+ let lineWritten = Event()
+ member _.LineWritten = lineWritten.Publish
+ override _.Encoding = Encoding.UTF8
+ override _.Write(c: char) =
+ if c = '\n' then
+ let line =
+ let v = sb.ToString()
+ if v.EndsWith("\r") then v.Substring(0, v.Length - 1)
+ else v
+ sb.Clear() |> ignore
+ sw.WriteLine line
+ lineWritten.Trigger(line)
+ else sb.Append(c) |> ignore
+ override _.ToString() = sw.ToString()
+
+type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVersion, ?input: string) =
let additionalArgs = defaultArg additionalArgs [||]
let quiet = defaultArg quiet true
@@ -54,13 +72,32 @@ type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVer
let argv = Array.append baseArgs additionalArgs
+ let inReader = new StringReader(defaultArg input "")
+ let outWriter = new EventedTextWriter()
+ let errorWriter = new EventedTextWriter()
+
+ let previousIn, previousOut, previousError = Console.In, Console.Out, Console.Error
+
+ do
+ Console.SetIn inReader
+ Console.SetOut outWriter
+ Console.SetError errorWriter
+
let fsi = FsiEvaluationSession.Create (config, argv, stdin, stdout, stderr)
member _.ValueBound = fsi.ValueBound
member _.Fsi = fsi
- member _.Eval(code: string, ?cancellationToken: CancellationToken, ?desiredCulture: Globalization.CultureInfo) =
+ member _.OutputProduced = outWriter.LineWritten
+
+ member _.ErrorProduced = errorWriter.LineWritten
+
+ member _.GetOutput() = string outWriter
+
+ member _.GetErrorOutput() = string errorWriter
+
+ member this.Eval(code: string, ?cancellationToken: CancellationToken, ?desiredCulture: Globalization.CultureInfo) =
let originalCulture = Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentCulture <- Option.defaultValue Globalization.CultureInfo.InvariantCulture desiredCulture
@@ -88,7 +125,11 @@ type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVer
}
interface IDisposable with
- member this.Dispose() = ((this.Fsi) :> IDisposable).Dispose()
+ member this.Dispose() =
+ ((this.Fsi) :> IDisposable).Dispose()
+ Console.SetIn previousIn
+ Console.SetOut previousOut
+ Console.SetError previousError
[]
module TestHelpers =
@@ -101,15 +142,3 @@ module TestHelpers =
| Error ex -> raise ex
let ignoreValue = getValue >> ignore
-
- let getTempDir () =
- let sysTempDir = Path.GetTempPath()
- let customTempDirName = Guid.NewGuid().ToString("D")
- let fullDirName = Path.Combine(sysTempDir, customTempDirName)
- let dirInfo = Directory.CreateDirectory(fullDirName)
- { new Object() with
- member _.ToString() = dirInfo.FullName
- interface IDisposable with
- member _.Dispose() =
- dirInfo.Delete(true)
- }
diff --git a/tests/FSharp.Test.Utilities/TestFramework.fs b/tests/FSharp.Test.Utilities/TestFramework.fs
index d32ce4fcda8..dfde63f2352 100644
--- a/tests/FSharp.Test.Utilities/TestFramework.fs
+++ b/tests/FSharp.Test.Utilities/TestFramework.fs
@@ -9,6 +9,7 @@ open System.Diagnostics
open Scripting
open Xunit
open FSharp.Compiler.IO
+open Xunit.Sdk
let getShortId() = Guid.NewGuid().ToString().[..7]
@@ -62,69 +63,66 @@ module Commands =
// Execute the process pathToExe passing the arguments: arguments with the working directory: workingDir timeout after timeout milliseconds -1 = wait forever
// returns exit code, stdio and stderr as string arrays
let executeProcess pathToExe arguments workingDir (timeout:int) =
- match pathToExe with
- | Some path ->
- let commandLine = ResizeArray()
- let errorsList = ResizeArray()
- let outputList = ResizeArray()
- let errorslock = obj()
- let outputlock = obj()
- let outputDataReceived (message: string) =
- if not (isNull message) then
- lock outputlock (fun () -> outputList.Add(message))
-
- let errorDataReceived (message: string) =
- if not (isNull message) then
- lock errorslock (fun () -> errorsList.Add(message))
-
- commandLine.Add $"cd {workingDir}"
- commandLine.Add $"{path} {arguments} /bl"
-
- let psi = ProcessStartInfo()
- psi.FileName <- path
- psi.WorkingDirectory <- workingDir
- psi.RedirectStandardOutput <- true
- psi.RedirectStandardError <- true
- psi.Arguments <- arguments
- psi.CreateNoWindow <- true
- // When running tests, we want to roll forward to minor versions (including previews).
- psi.EnvironmentVariables["DOTNET_ROLL_FORWARD"] <- "LatestMajor"
- psi.EnvironmentVariables["DOTNET_ROLL_FORWARD_TO_PRERELEASE"] <- "1"
- psi.EnvironmentVariables.Remove("MSBuildSDKsPath") // Host can sometimes add this, and it can break things
- psi.UseShellExecute <- false
-
- use p = new Process()
- p.StartInfo <- psi
-
- p.OutputDataReceived.Add(fun a -> outputDataReceived a.Data)
- p.ErrorDataReceived.Add(fun a -> errorDataReceived a.Data)
-
- if p.Start() then
- p.BeginOutputReadLine()
- p.BeginErrorReadLine()
- if not(p.WaitForExit(timeout)) then
- // Timed out resolving throw a diagnostic.
- raise (new TimeoutException(sprintf "Timeout executing command '%s' '%s'" (psi.FileName) (psi.Arguments)))
- else
- p.WaitForExit()
- #if DEBUG
- let workingDir' =
- if workingDir = ""
- then
- // Assign working dir to prevent default to C:\Windows\System32
- let executionLocation = Assembly.GetExecutingAssembly().Location
- Path.GetDirectoryName executionLocation
- else
- workingDir
-
- lock gate (fun () ->
- File.WriteAllLines(Path.Combine(workingDir', "commandline.txt"), commandLine)
- File.WriteAllLines(Path.Combine(workingDir', "StandardOutput.txt"), outputList)
- File.WriteAllLines(Path.Combine(workingDir', "StandardError.txt"), errorsList)
- )
- #endif
- p.ExitCode, outputList.ToArray(), errorsList.ToArray()
- | None -> -1, Array.empty, Array.empty
+ let commandLine = ResizeArray()
+ let errorsList = ResizeArray()
+ let outputList = ResizeArray()
+ let errorslock = obj()
+ let outputlock = obj()
+ let outputDataReceived (message: string) =
+ if not (isNull message) then
+ lock outputlock (fun () -> outputList.Add(message))
+
+ let errorDataReceived (message: string) =
+ if not (isNull message) then
+ lock errorslock (fun () -> errorsList.Add(message))
+
+ commandLine.Add $"cd {workingDir}"
+ commandLine.Add $"{pathToExe} {arguments} /bl"
+
+ let psi = ProcessStartInfo()
+ psi.FileName <- pathToExe
+ psi.WorkingDirectory <- workingDir
+ psi.RedirectStandardOutput <- true
+ psi.RedirectStandardError <- true
+ psi.Arguments <- arguments
+ psi.CreateNoWindow <- true
+ // When running tests, we want to roll forward to minor versions (including previews).
+ psi.EnvironmentVariables["DOTNET_ROLL_FORWARD"] <- "LatestMajor"
+ psi.EnvironmentVariables["DOTNET_ROLL_FORWARD_TO_PRERELEASE"] <- "1"
+ psi.EnvironmentVariables.Remove("MSBuildSDKsPath") // Host can sometimes add this, and it can break things
+ psi.UseShellExecute <- false
+
+ use p = new Process()
+ p.StartInfo <- psi
+
+ p.OutputDataReceived.Add(fun a -> outputDataReceived a.Data)
+ p.ErrorDataReceived.Add(fun a -> errorDataReceived a.Data)
+
+ if p.Start() then
+ p.BeginOutputReadLine()
+ p.BeginErrorReadLine()
+ if not(p.WaitForExit(timeout)) then
+ // Timed out resolving throw a diagnostic.
+ raise (new TimeoutException(sprintf "Timeout executing command '%s' '%s'" (psi.FileName) (psi.Arguments)))
+ else
+ p.WaitForExit()
+#if DEBUG
+ let workingDir' =
+ if workingDir = ""
+ then
+ // Assign working dir to prevent default to C:\Windows\System32
+ let executionLocation = Assembly.GetExecutingAssembly().Location
+ Path.GetDirectoryName executionLocation
+ else
+ workingDir
+
+ lock gate (fun () ->
+ File.WriteAllLines(Path.Combine(workingDir', "commandline.txt"), commandLine)
+ File.WriteAllLines(Path.Combine(workingDir', "StandardOutput.txt"), outputList)
+ File.WriteAllLines(Path.Combine(workingDir', "StandardError.txt"), errorsList)
+ )
+#endif
+ p.ExitCode, outputList.ToArray(), errorsList.ToArray()
let getfullpath workDir (path:string) =
let rooted =
@@ -141,7 +139,7 @@ module Commands =
let copy workDir source dest =
log "copy /y %s %s" source dest
File.Copy( source |> getfullpath workDir, dest |> getfullpath workDir, true)
- CmdResult.Success
+ CmdResult.Success ""
let mkdir_p workDir dir =
log "mkdir %s" dir
@@ -183,19 +181,6 @@ module Commands =
let fsc workDir exec (dotNetExe: FilePath) (fscExe: FilePath) flags srcFiles =
let args = (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " "))
-#if FSC_IN_PROCESS
- // This is not yet complete
- printfn "Hosted Compiler:"
- printfn "workdir: %A\nargs: %A"workdir args
- let fscCompiler = FSharp.Compiler.Hosted.FscCompiler()
- let exitCode, _stdin, _stdout = FSharp.Compiler.Hosted.CompilerHelpers.fscCompile workDir (FSharp.Compiler.Hosted.CompilerHelpers.parseCommandLine args)
-
- match exitCode with
- | 0 -> CmdResult.Success
- | err ->
- let msg = sprintf "Error running command '%s' with args '%s' in directory '%s'" fscExe args workDir
- CmdResult.ErrorLevel (msg, err)
-#else
ignore workDir
#if NETCOREAPP
exec dotNetExe (fscExe + " " + args)
@@ -204,7 +189,6 @@ module Commands =
printfn "fscExe: %A" fscExe
printfn "args: %A" args
exec fscExe args
-#endif
#endif
let csc exec cscExe flags srcFiles =
@@ -441,15 +425,23 @@ let logConfig (cfg: TestConfig) =
log "PEVERIFY = %s" cfg.PEVERIFY
log "---------------------------------------------------------------"
+let checkOutputPassed (output: string) =
+ Assert.True(output.Contains "TEST PASSED OK", $"Output does not contain 'TEST PASSED OK':\n{output}")
+
+let checkResultPassed result =
+ match result with
+ | CmdResult.ErrorLevel (msg1, err) -> Assert.Fail (sprintf "%s. ERRORLEVEL %d" msg1 err)
+ | CmdResult.Success output -> checkOutputPassed output
+
let checkResult result =
match result with
| CmdResult.ErrorLevel (msg1, err) -> Assert.Fail (sprintf "%s. ERRORLEVEL %d" msg1 err)
- | CmdResult.Success -> ()
+ | CmdResult.Success _ -> ()
let checkErrorLevel1 result =
match result with
| CmdResult.ErrorLevel (_,1) -> ()
- | CmdResult.Success | CmdResult.ErrorLevel _ -> Assert.Fail (sprintf "Command passed unexpectedly")
+ | CmdResult.Success _ | CmdResult.ErrorLevel _ -> Assert.Fail (sprintf "Command passed unexpectedly")
let envVars () =
System.Environment.GetEnvironmentVariables ()
@@ -497,27 +489,13 @@ let createConfigWithEmptyDirectory() =
let cfg = suiteHelpers.Value
{ cfg with Directory = createTemporaryDirectory "temp" }
-[]
-type FileGuard(path: string) =
- let remove path = if FileSystem.FileExistsShim(path) then Commands.rm (Path.GetTempPath()) path
- do if not (Path.IsPathRooted(path)) then failwithf "path '%s' must be absolute" path
- do remove path
- member x.Path = path
- member x.Exists = x.Path |> FileSystem.FileExistsShim
- member x.CheckExists() =
- if not x.Exists then
- failwith (sprintf "exit code 0 but %s file doesn't exists" (x.Path |> Path.GetFileName))
-
- interface IDisposable with
- member x.Dispose () = remove path
-
-
type RedirectToType =
| Overwrite of FilePath
| Append of FilePath
type RedirectTo =
- | Inherit
+ | Ignore
+ | Collect
| Output of RedirectToType
| OutputAndError of RedirectToType * RedirectToType
| OutputAndErrorToSameFile of RedirectToType
@@ -541,8 +519,8 @@ module Command =
let redirectType = function Overwrite x -> sprintf ">%s" x | Append x -> sprintf ">>%s" x
let outF =
function
- | Inherit -> ""
- | Output r-> sprintf " 1%s" (redirectType r)
+ | Ignore | Collect -> ""
+ | Output r -> sprintf " 1%s" (redirectType r)
| OutputAndError (r1, r2) -> sprintf " 1%s 2%s" (redirectType r1) (redirectType r2)
| OutputAndErrorToSameFile r -> sprintf " 1%s 2>1" (redirectType r)
| Error r -> sprintf " 2%s" (redirectType r)
@@ -579,9 +557,12 @@ module Command =
let outF fCont cmdArgs =
match redirect.Output with
- | RedirectTo.Inherit ->
- use toLog = redirectToLog ()
- fCont { cmdArgs with RedirectOutput = Some (toLog.Post); RedirectError = Some (toLog.Post) }
+ | Ignore ->
+ fCont { cmdArgs with RedirectOutput = Some ignore; RedirectError = Some ignore }
+ | Collect ->
+ use out = redirectTo (new StringWriter())
+ use error = redirectTo (new StringWriter())
+ fCont { cmdArgs with RedirectOutput = Some out.Post; RedirectError = Some error.Post }
| Output r ->
use writer = openWrite r
use outFile = redirectTo writer
@@ -612,18 +593,21 @@ module Command =
let alwaysSuccess _ = ()
-let execArgs = { Output = Inherit; Input = None; }
+let execArgs = { Output = Ignore; Input = None; }
let execAppend cfg stdoutPath stderrPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = OutputAndError(Append(stdoutPath), Append(stderrPath)) } p >> checkResult
let execAppendIgnoreExitCode cfg stdoutPath stderrPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = OutputAndError(Append(stdoutPath), Append(stderrPath)) } p >> alwaysSuccess
let exec cfg p = Command.exec cfg.Directory cfg.EnvironmentVariables execArgs p >> checkResult
+let execAndCheckPassed cfg p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = Collect } p >> checkResultPassed
let execExpectFail cfg p = Command.exec cfg.Directory cfg.EnvironmentVariables execArgs p >> checkErrorLevel1
let execIn cfg workDir p = Command.exec workDir cfg.EnvironmentVariables execArgs p >> checkResult
-let execBothToOutNoCheck cfg workDir outFile p = Command.exec workDir cfg.EnvironmentVariables { execArgs with Output = OutputAndErrorToSameFile(Overwrite(outFile)) } p
+let execBothToOutNoCheck cfg workDir outFile p = Command.exec workDir cfg.EnvironmentVariables { execArgs with Output = OutputAndErrorToSameFile(Overwrite(outFile)) } p
let execBothToOut cfg workDir outFile p = execBothToOutNoCheck cfg workDir outFile p >> checkResult
+let execBothToOutCheckPassed cfg workDir outFile p = execBothToOutNoCheck cfg workDir outFile p >> checkResultPassed
let execBothToOutExpectFail cfg workDir outFile p = execBothToOutNoCheck cfg workDir outFile p >> checkErrorLevel1
let execAppendOutIgnoreExitCode cfg workDir outFile p = Command.exec workDir cfg.EnvironmentVariables { execArgs with Output = Output(Append(outFile)) } p >> alwaysSuccess
let execAppendErrExpectFail cfg errPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = Error(Overwrite(errPath)) } p >> checkErrorLevel1
-let execStdin cfg l p = Command.exec cfg.Directory cfg.EnvironmentVariables { Output = Inherit; Input = Some(RedirectInput(l)) } p >> checkResult
+let execStdin cfg l p = Command.exec cfg.Directory cfg.EnvironmentVariables { Output = Ignore; Input = Some(RedirectInput(l)) } p >> checkResult
+let execStdinCheckPassed cfg l p = Command.exec cfg.Directory cfg.EnvironmentVariables { Output = Collect; Input = Some(RedirectInput(l)) } p >> checkResultPassed
let execStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { Output = OutputAndError(Append(stdoutPath), Append(stderrPath)); Input = Some(RedirectInput(stdinPath)) } p >> alwaysSuccess
let fsc cfg arg = Printf.ksprintf (Commands.fsc cfg.Directory (exec cfg) cfg.DotNetExe cfg.FSC) arg
let fscIn cfg workDir arg = Printf.ksprintf (Commands.fsc workDir (execIn cfg workDir) cfg.DotNetExe cfg.FSC) arg
@@ -639,6 +623,7 @@ let ilasm cfg arg = Printf.ksprintf (Commands.ilasm (exec cfg) cfg.ILASM) arg
let peverify _cfg _test = printfn "PEVerify is disabled, need to migrate to ILVerify instead, see https://github.com/dotnet/fsharp/issues/13854" //Commands.peverify (exec cfg) cfg.PEVERIFY "/nologo"
let peverifyWithArgs _cfg _args _test = printfn "PEVerify is disabled, need to migrate to ILVerify instead, see https://github.com/dotnet/fsharp/issues/13854" //Commands.peverify (exec cfg) cfg.PEVERIFY args
let fsi cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSI)
+let fsiCheckPassed cfg = Printf.ksprintf (Commands.fsi (execAndCheckPassed cfg) cfg.FSI)
#if !NETCOREAPP
let fsiAnyCpu cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSIANYCPU)
let sn cfg = Printf.ksprintf (Commands.sn (exec cfg) cfg.SN)
@@ -646,10 +631,10 @@ let sn cfg = Printf.ksprintf (Commands.sn (exec cfg) cfg.SN)
let fsi_script cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSI_FOR_SCRIPTS)
let fsiExpectFail cfg = Printf.ksprintf (Commands.fsi (execExpectFail cfg) cfg.FSI)
let fsiAppendIgnoreExitCode cfg stdoutPath stderrPath = Printf.ksprintf (Commands.fsi (execAppendIgnoreExitCode cfg stdoutPath stderrPath) cfg.FSI)
-let fileguard cfg fileName = Commands.getfullpath cfg.Directory fileName |> (fun x -> new FileGuard(x))
let getfullpath cfg = Commands.getfullpath cfg.Directory
let fileExists cfg fileName = Commands.fileExists cfg.Directory fileName |> Option.isSome
let fsiStdin cfg stdinPath = Printf.ksprintf (Commands.fsi (execStdin cfg stdinPath) cfg.FSI)
+let fsiStdinCheckPassed cfg stdinPath = Printf.ksprintf (Commands.fsi (execStdinCheckPassed cfg stdinPath) cfg.FSI)
let fsiStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath = Printf.ksprintf (Commands.fsi (execStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath) cfg.FSI)
let rm cfg x = Commands.rm cfg.Directory x
let rmdir cfg x = Commands.rmdir cfg.Directory x
diff --git a/tests/FSharp.Test.Utilities/Utilities.fs b/tests/FSharp.Test.Utilities/Utilities.fs
index 199f047dfd1..1a6d0ff60f8 100644
--- a/tests/FSharp.Test.Utilities/Utilities.fs
+++ b/tests/FSharp.Test.Utilities/Utilities.fs
@@ -38,86 +38,23 @@ type FactForDESKTOPAttribute() =
do base.Skip <- "NETCOREAPP is not supported runtime for this kind of test, it is intended for DESKTOP only"
#endif
-
// This file mimics how Roslyn handles their compilation references for compilation testing
module Utilities =
-
- type CapturedTextReader() =
- inherit TextReader()
- let queue = Queue()
- member _.ProvideInput(text: string) =
- for c in text.ToCharArray() do
- queue.Enqueue(c)
- override _.Peek() =
- if queue.Count > 0 then queue.Peek() |> int else -1
- override _.Read() =
- if queue.Count > 0 then queue.Dequeue() |> int else -1
-
- type RedirectConsoleInput() =
- let oldStdIn = Console.In
- let newStdIn = new CapturedTextReader()
- do Console.SetIn(newStdIn)
- member _.ProvideInput(text: string) =
- newStdIn.ProvideInput(text)
- interface IDisposable with
- member _.Dispose() =
- Console.SetIn(oldStdIn)
- newStdIn.Dispose()
-
- type EventedTextWriter() =
- inherit TextWriter()
- let sb = StringBuilder()
- let lineWritten = Event()
- member _.LineWritten = lineWritten.Publish
- override _.Encoding = Encoding.UTF8
- override _.Write(c: char) =
- if c = '\n' then
- let line =
- let v = sb.ToString()
- if v.EndsWith("\r") then v.Substring(0, v.Length - 1)
- else v
- sb.Clear() |> ignore
- lineWritten.Trigger(line)
- else sb.Append(c) |> ignore
-
- type RedirectConsoleOutput() =
- let outputProduced = Event()
- let errorProduced = Event()
+ type RedirectConsole() =
let oldStdOut = Console.Out
let oldStdErr = Console.Error
- let newStdOut = new EventedTextWriter()
- let newStdErr = new EventedTextWriter()
-
- do newStdOut.LineWritten.Add outputProduced.Trigger
- do newStdErr.LineWritten.Add errorProduced.Trigger
+ let newStdOut = new StringWriter()
+ let newStdErr = new StringWriter()
do Console.SetOut(newStdOut)
do Console.SetError(newStdErr)
+ member _.Output () = string newStdOut
- member _.OutputProduced = outputProduced.Publish
-
- member _.ErrorProduced = errorProduced.Publish
+ member _.ErrorOutput () =string newStdErr
interface IDisposable with
member _.Dispose() =
Console.SetOut(oldStdOut)
Console.SetError(oldStdErr)
- newStdOut.Dispose()
- newStdErr.Dispose()
-
- type RedirectConsole() =
- let redirector = new RedirectConsoleOutput()
- let outputLines = StringBuilder()
- let errorLines = StringBuilder()
-
- do redirector.OutputProduced.Add (fun line -> lock outputLines <| fun () -> outputLines.AppendLine line |>ignore)
- do redirector.ErrorProduced.Add(fun line -> lock errorLines <| fun () -> errorLines.AppendLine line |>ignore)
-
- member _.Output () = lock outputLines outputLines.ToString
-
- member _.ErrorOutput () = lock errorLines errorLines.ToString
-
- interface IDisposable with
- member _.Dispose() = (redirector :> IDisposable).Dispose()
type Async with
static member RunImmediate (computation: Async<'T>, ?cancellationToken ) =
@@ -308,7 +245,7 @@ let main argv = 0"""
File.WriteAllText(directoryBuildTargetsFileName, directoryBuildTargets)
let timeout = 120000
- let exitCode, dotnetoutput, dotneterrors = Commands.executeProcess (Some config.DotNetExe) "build" projectDirectory timeout
+ let exitCode, dotnetoutput, dotneterrors = Commands.executeProcess config.DotNetExe "build" projectDirectory timeout
if exitCode <> 0 || errors.Length > 0 then
errors <- dotneterrors
diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticMember.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticMember.fs
index 464b7ca7d13..078cffd9e60 100644
--- a/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticMember.fs
+++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticMember.fs
@@ -481,7 +481,7 @@ let _ =
if !failures then (System.Console.Out.WriteLine "Test Failed"; exit 1)
do (System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK" ;
exit 0)
""",
(fun verifier -> verifier.VerifyIL [
diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj
index 36f26235ac1..6673da9f911 100644
--- a/tests/fsharp/FSharpSuite.Tests.fsproj
+++ b/tests/fsharp/FSharpSuite.Tests.fsproj
@@ -3,7 +3,7 @@
net472;$(FSharpNetCoreProductTargetFramework)
- $(FSharpNetCoreProductTargetFramework)
+ $(FSharpNetCoreProductTargetFramework)
win-x86;win-x64
$(AssetTargetFallback);portable-net45+win8+wp8+wpa81
true
diff --git a/tests/fsharp/TypeProviderTests.fs b/tests/fsharp/TypeProviderTests.fs
index ba3d43037e6..ab9f2e7e5ef 100644
--- a/tests/fsharp/TypeProviderTests.fs
+++ b/tests/fsharp/TypeProviderTests.fs
@@ -69,11 +69,9 @@ let diamondAssembly () =
exec cfg ("." ++ "test3.exe") ""
- use testOkFile = fileguard cfg "test.ok"
+
- fsi cfg "%s" cfg.fsi_flags ["test3.fsx"]
-
- testOkFile.CheckExists()
+ fsiCheckPassed cfg "%s" cfg.fsi_flags ["test3.fsx"]
[]
let globalNamespace () =
@@ -286,18 +284,16 @@ let splitAssembly subdir project =
fsc cfg "--out:test.exe -r:provider.dll" ["test.fsx"]
begin
- use testOkFile = fileguard cfg "test.ok"
+
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
end
begin
- use testOkFile = fileguard cfg "test.ok"
+
- fsi cfg "%s" cfg.fsi_flags ["test.fsx"]
- testOkFile.CheckExists()
+ fsiCheckPassed cfg "%s" cfg.fsi_flags ["test.fsx"]
end
// Do the same thing with different load locations for the type provider design-time component
@@ -326,19 +322,16 @@ let splitAssembly subdir project =
fsc cfg "--out:test.exe -r:provider.dll" ["test.fsx"]
- begin
- use testOkFile = fileguard cfg "test.ok"
+ begin
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
end
begin
- use testOkFile = fileguard cfg "test.ok"
+
- fsi cfg "%s" cfg.fsi_flags ["test.fsx"]
- testOkFile.CheckExists()
+ fsiCheckPassed cfg "%s" cfg.fsi_flags ["test.fsx"]
end
clean()
diff --git a/tests/fsharp/core/access/test.fsx b/tests/fsharp/core/access/test.fsx
index 21a8c056ee0..3a8bfd0e6f3 100644
--- a/tests/fsharp/core/access/test.fsx
+++ b/tests/fsharp/core/access/test.fsx
@@ -274,7 +274,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK";
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/anon/test.fsx b/tests/fsharp/core/anon/test.fsx
index 580772b3446..6b065cdd7f0 100644
--- a/tests/fsharp/core/anon/test.fsx
+++ b/tests/fsharp/core/anon/test.fsx
@@ -86,7 +86,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/apporder/test.fsx b/tests/fsharp/core/apporder/test.fsx
index 7830de44c1a..5dc19b65fde 100644
--- a/tests/fsharp/core/apporder/test.fsx
+++ b/tests/fsharp/core/apporder/test.fsx
@@ -1130,7 +1130,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/array-no-dot/test.fsx b/tests/fsharp/core/array-no-dot/test.fsx
index 4cba7c3268b..569c477c5eb 100644
--- a/tests/fsharp/core/array-no-dot/test.fsx
+++ b/tests/fsharp/core/array-no-dot/test.fsx
@@ -435,7 +435,7 @@ let aa =
match failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/array/test.fsx b/tests/fsharp/core/array/test.fsx
index 69d1feada8c..ceed74ab3b4 100644
--- a/tests/fsharp/core/array/test.fsx
+++ b/tests/fsharp/core/array/test.fsx
@@ -1142,7 +1142,7 @@ let aa =
match failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/asyncStackTraces/test.fsx b/tests/fsharp/core/asyncStackTraces/test.fsx
index abbd3ec0a4b..34c82a8804c 100644
--- a/tests/fsharp/core/asyncStackTraces/test.fsx
+++ b/tests/fsharp/core/asyncStackTraces/test.fsx
@@ -176,6 +176,6 @@ let aa =
exit 1
else
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
diff --git a/tests/fsharp/core/attributes/test.fsx b/tests/fsharp/core/attributes/test.fsx
index 30509f450fd..e17fd3404f1 100644
--- a/tests/fsharp/core/attributes/test.fsx
+++ b/tests/fsharp/core/attributes/test.fsx
@@ -1358,7 +1358,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/auto-widen/5.0/test.fsx b/tests/fsharp/core/auto-widen/5.0/test.fsx
index 83d2f46ab2b..74f1af4fdb9 100644
--- a/tests/fsharp/core/auto-widen/5.0/test.fsx
+++ b/tests/fsharp/core/auto-widen/5.0/test.fsx
@@ -459,7 +459,7 @@ let aa =
match failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
printfn "Test Failed, failures = %A" failures
diff --git a/tests/fsharp/core/auto-widen/minimal/test.fsx b/tests/fsharp/core/auto-widen/minimal/test.fsx
index 92e7cfc56da..bf0e11b64a6 100644
--- a/tests/fsharp/core/auto-widen/minimal/test.fsx
+++ b/tests/fsharp/core/auto-widen/minimal/test.fsx
@@ -2,5 +2,5 @@
#r "System.Xml.XDocument.dll"
let ns : System.Xml.Linq.XNamespace = ""
-System.IO.File.WriteAllText("test.ok","ok")
+printf "TEST PASSED OK" ;
exit 0
\ No newline at end of file
diff --git a/tests/fsharp/core/auto-widen/preview-default-warns/test.fsx b/tests/fsharp/core/auto-widen/preview-default-warns/test.fsx
index 2989aa19071..ea91533c0dd 100644
--- a/tests/fsharp/core/auto-widen/preview-default-warns/test.fsx
+++ b/tests/fsharp/core/auto-widen/preview-default-warns/test.fsx
@@ -566,7 +566,7 @@ let aa =
match failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
printfn "Test Failed, failures = %A" failures
diff --git a/tests/fsharp/core/auto-widen/preview/test.fsx b/tests/fsharp/core/auto-widen/preview/test.fsx
index e5e11b074dd..50eaae85f62 100644
--- a/tests/fsharp/core/auto-widen/preview/test.fsx
+++ b/tests/fsharp/core/auto-widen/preview/test.fsx
@@ -644,7 +644,7 @@ let aa =
match failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
printfn "Test Failed, failures = %A" failures
diff --git a/tests/fsharp/core/comprehensions-hw/test.fsx b/tests/fsharp/core/comprehensions-hw/test.fsx
index 54ccfa1f167..bd47019704e 100644
--- a/tests/fsharp/core/comprehensions-hw/test.fsx
+++ b/tests/fsharp/core/comprehensions-hw/test.fsx
@@ -1048,7 +1048,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/comprehensions/test.fsx b/tests/fsharp/core/comprehensions/test.fsx
index c6cad18b75c..4d9664404cb 100644
--- a/tests/fsharp/core/comprehensions/test.fsx
+++ b/tests/fsharp/core/comprehensions/test.fsx
@@ -1488,7 +1488,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/control/test.fsx b/tests/fsharp/core/control/test.fsx
index 98db3309532..6c80ca0d72b 100644
--- a/tests/fsharp/core/control/test.fsx
+++ b/tests/fsharp/core/control/test.fsx
@@ -2100,7 +2100,7 @@ let aa =
exit 1
else
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
#endif
diff --git a/tests/fsharp/core/controlChamenos/test.fsx b/tests/fsharp/core/controlChamenos/test.fsx
index b95bfff4c80..5742662a53c 100644
--- a/tests/fsharp/core/controlChamenos/test.fsx
+++ b/tests/fsharp/core/controlChamenos/test.fsx
@@ -123,6 +123,6 @@ let aa =
exit 1
else
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
#endif
diff --git a/tests/fsharp/core/controlMailbox/test.fsx b/tests/fsharp/core/controlMailbox/test.fsx
index fc8a1cc7aea..98d6a7d2f31 100644
--- a/tests/fsharp/core/controlMailbox/test.fsx
+++ b/tests/fsharp/core/controlMailbox/test.fsx
@@ -624,6 +624,6 @@ let aa =
exit 1
else
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
#endif
diff --git a/tests/fsharp/core/controlStackOverflow/test.fsx b/tests/fsharp/core/controlStackOverflow/test.fsx
index 735b09173c9..f3678844b05 100644
--- a/tests/fsharp/core/controlStackOverflow/test.fsx
+++ b/tests/fsharp/core/controlStackOverflow/test.fsx
@@ -415,6 +415,6 @@ let aa =
else
stdout.WriteLine "Test Passed"
log "ALL OK, HAPPY HOLIDAYS, MERRY CHRISTMAS!"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
#endif
diff --git a/tests/fsharp/core/controlWebExt/test.fsx b/tests/fsharp/core/controlWebExt/test.fsx
index 42a43aed573..23e5bf5071e 100644
--- a/tests/fsharp/core/controlWebExt/test.fsx
+++ b/tests/fsharp/core/controlWebExt/test.fsx
@@ -233,7 +233,7 @@ let aa =
if not failures.IsEmpty then (stdout.WriteLine("Test Failed, failures = {0}", failures); exit 1)
else (stdout.WriteLine "Test Passed";
log "ALL OK, HAPPY HOLIDAYS, MERRY CHRISTMAS!"
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
// debug: why is the fsi test failing? is it because test.ok does not exist?
if System.IO.File.Exists("test.ok") then
stdout.WriteLine ("test.ok found at {0}", System.IO.FileInfo("test.ok").FullName)
diff --git a/tests/fsharp/core/controlWpf/test.fsx b/tests/fsharp/core/controlWpf/test.fsx
index 25ad5eff208..400f196c652 100644
--- a/tests/fsharp/core/controlWpf/test.fsx
+++ b/tests/fsharp/core/controlWpf/test.fsx
@@ -27,8 +27,8 @@ async {
printfn "Test Failed"
app.Shutdown(128)
else
- printfn "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK"
+ printf "TEST PASSED OK" ;
app.Shutdown(0)
} |> Async.StartImmediate
diff --git a/tests/fsharp/core/csext/test.fsx b/tests/fsharp/core/csext/test.fsx
index c77a7307642..224fd9dd047 100644
--- a/tests/fsharp/core/csext/test.fsx
+++ b/tests/fsharp/core/csext/test.fsx
@@ -321,7 +321,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/enum/test.fsx b/tests/fsharp/core/enum/test.fsx
index 2bc2d41d783..bf80f12bdc7 100644
--- a/tests/fsharp/core/enum/test.fsx
+++ b/tests/fsharp/core/enum/test.fsx
@@ -49,7 +49,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/events/test.fs b/tests/fsharp/core/events/test.fs
index 0050a8d5635..e9921fcbe25 100644
--- a/tests/fsharp/core/events/test.fs
+++ b/tests/fsharp/core/events/test.fs
@@ -537,5 +537,5 @@ module EventWithNonPublicDelegateTypes_DevDiv271288 =
let _ =
if failures.Length > 0 then (printfn "Tests Failed: %A" failures; exit 1)
else (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/core/fileorder/test.fsx b/tests/fsharp/core/fileorder/test.fsx
index 6981cdcc03a..8c874d7d6b5 100644
--- a/tests/fsharp/core/fileorder/test.fsx
+++ b/tests/fsharp/core/fileorder/test.fsx
@@ -19,5 +19,5 @@ let aa =
if !failures then (stdout.WriteLine "Test Failed"; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
\ No newline at end of file
diff --git a/tests/fsharp/core/forexpression/test.fsx b/tests/fsharp/core/forexpression/test.fsx
index 141fc4677e1..257cdf308f3 100644
--- a/tests/fsharp/core/forexpression/test.fsx
+++ b/tests/fsharp/core/forexpression/test.fsx
@@ -168,5 +168,5 @@ let RUN() = !failures
#else
let aa =
if !failures then stdout.WriteLine "Test Failed"; exit 1
- else stdout.WriteLine "Test Passed"; System.IO.File.WriteAllText("test.ok","ok"); exit 0
+ else stdout.WriteLine "Test Passed"; printf "TEST PASSED OK"; exit 0
#endif
diff --git a/tests/fsharp/core/fsfromcs/test.cs b/tests/fsharp/core/fsfromcs/test.cs
index 5281b3469e0..7c27491f789 100644
--- a/tests/fsharp/core/fsfromcs/test.cs
+++ b/tests/fsharp/core/fsfromcs/test.cs
@@ -311,7 +311,7 @@ static int Main()
//let tup3 = (2,3,4)
//let tup4 = (2,3,4,5)
- System.Console.WriteLine("Test Passed.");
+ System.Console.WriteLine("TEST PASSED OK");
return 0;
}
diff --git a/tests/fsharp/core/fsfromfsviacs/test.fsx b/tests/fsharp/core/fsfromfsviacs/test.fsx
index 7974a4ce47b..e7c47575bd8 100644
--- a/tests/fsharp/core/fsfromfsviacs/test.fsx
+++ b/tests/fsharp/core/fsfromfsviacs/test.fsx
@@ -487,7 +487,7 @@ let _ =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/fsi-load/test.fsx b/tests/fsharp/core/fsi-load/test.fsx
index f81654365e7..062ea882adc 100644
--- a/tests/fsharp/core/fsi-load/test.fsx
+++ b/tests/fsharp/core/fsi-load/test.fsx
@@ -17,6 +17,6 @@ module OtherModule =
let _ =
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
diff --git a/tests/fsharp/core/fsi-reference/test.fsx b/tests/fsharp/core/fsi-reference/test.fsx
index 16867d6f344..393b44151c2 100644
--- a/tests/fsharp/core/fsi-reference/test.fsx
+++ b/tests/fsharp/core/fsi-reference/test.fsx
@@ -4,5 +4,5 @@ let c = new ReferenceAssembly.MyClass()
let _ = c.X
// If this fails then the jit blows up so this file will not get written.
-let os = System.IO.File.CreateText "test.ok" in os.Close()
+printf "TEST PASSED OK" ;
exit 0
diff --git a/tests/fsharp/core/fsi-reload/load1.fsx b/tests/fsharp/core/fsi-reload/load1.fsx
index 0f7fba67329..44b24cddab5 100644
--- a/tests/fsharp/core/fsi-reload/load1.fsx
+++ b/tests/fsharp/core/fsi-reload/load1.fsx
@@ -2,4 +2,4 @@
#load "a1.fs"
#load "a2.fs"
-let os = System.IO.File.CreateText "test.ok" in os.Close()
+printf "TEST PASSED OK" ;
diff --git a/tests/fsharp/core/fsi-reload/load2.fsx b/tests/fsharp/core/fsi-reload/load2.fsx
index a30cad3826f..d87b4e10df0 100644
--- a/tests/fsharp/core/fsi-reload/load2.fsx
+++ b/tests/fsharp/core/fsi-reload/load2.fsx
@@ -2,4 +2,4 @@
#load "b1.fs"
#load "b2.fsi" "b2.fs"
-let os = System.IO.File.CreateText "test.ok" in os.Close()
+printf "TEST PASSED OK" ;
diff --git a/tests/fsharp/core/fsi-reload/test1.ml b/tests/fsharp/core/fsi-reload/test1.ml
index e9f0a57fa91..9cc77a02eb1 100644
--- a/tests/fsharp/core/fsi-reload/test1.ml
+++ b/tests/fsharp/core/fsi-reload/test1.ml
@@ -72,6 +72,6 @@ printf "x = %b\n" (X x = X 3)
printf "x = %d\n" (3 : x_t)
;;
-begin ignore (3 : x_t); ignore (3 : Nested.x_t); ignore (3 : Test1.Nested.x_t); ignore (3 : Test1.x_t); let os = System.IO.File.CreateText "test.ok" in os.Close() end;;
+begin ignore (3 : x_t); ignore (3 : Nested.x_t); ignore (3 : Test1.Nested.x_t); ignore (3 : Test1.x_t); printf "TEST PASSED OK" end;;
#quit;;
diff --git a/tests/fsharp/core/fsi-shadowcopy/test1.fsx b/tests/fsharp/core/fsi-shadowcopy/test1.fsx
index 3e34e651775..93f2765b719 100644
--- a/tests/fsharp/core/fsi-shadowcopy/test1.fsx
+++ b/tests/fsharp/core/fsi-shadowcopy/test1.fsx
@@ -23,8 +23,7 @@ let next = compiled 30000;;
//compile will fail because shadow copy is disabled
if next = false then
printfn "Succeeded -- compile fail because file locked due to --shadowcopyreferences-"
- use os = System.IO.File.CreateText "test1.ok"
- os.Close()
+ printf "TEST PASSED OK" ;
else
printfn "Failed -- compile succeeded but should have failed due to file lock because of --shadowcopyReferences-. Suspect test error";;
diff --git a/tests/fsharp/core/fsi-shadowcopy/test2.fsx b/tests/fsharp/core/fsi-shadowcopy/test2.fsx
index 34da503c636..94633d0819e 100644
--- a/tests/fsharp/core/fsi-shadowcopy/test2.fsx
+++ b/tests/fsharp/core/fsi-shadowcopy/test2.fsx
@@ -30,8 +30,7 @@ if next = true then
printfn "Succeeded -- compile worked because file not locked due to --shadowcopyReferences+"
if verifyGetEntryAssembly then
printfn "Succeeded -- GetEntryAssembly() returned not null"
- use os = System.IO.File.CreateText "test2.ok"
- os.Close()
+ printf "TEST PASSED OK" ;
else
printfn "Failed -- GetEntryAssembly() returned null"
else
diff --git a/tests/fsharp/core/fsiAndModifiers/test.fsx b/tests/fsharp/core/fsiAndModifiers/test.fsx
index 16b3d33aee0..c63ddcf384f 100644
--- a/tests/fsharp/core/fsiAndModifiers/test.fsx
+++ b/tests/fsharp/core/fsiAndModifiers/test.fsx
@@ -139,7 +139,7 @@ module PinTests =
if errors.IsEmpty then
- System.IO.File.WriteAllText("test.ok", "")
+ printf "TEST PASSED OK" ;
exit(0)
else
for error in errors do
diff --git a/tests/fsharp/core/genericmeasures/test.fsx b/tests/fsharp/core/genericmeasures/test.fsx
index b7de5c84aaa..ade03d4fb4c 100644
--- a/tests/fsharp/core/genericmeasures/test.fsx
+++ b/tests/fsharp/core/genericmeasures/test.fsx
@@ -80,7 +80,7 @@ module Core_genericMeasures =
#else
RunAll();
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
#endif
diff --git a/tests/fsharp/core/indent/version46/test.fsx b/tests/fsharp/core/indent/version46/test.fsx
index b9d41a04da5..3cc566d6981 100644
--- a/tests/fsharp/core/indent/version46/test.fsx
+++ b/tests/fsharp/core/indent/version46/test.fsx
@@ -105,7 +105,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/indent/version47/test.fsx b/tests/fsharp/core/indent/version47/test.fsx
index 9a119b4c89f..1cc563cb0aa 100644
--- a/tests/fsharp/core/indent/version47/test.fsx
+++ b/tests/fsharp/core/indent/version47/test.fsx
@@ -85,7 +85,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/innerpoly/test.fsx b/tests/fsharp/core/innerpoly/test.fsx
index e03b322d1c0..c9a8c714bc6 100644
--- a/tests/fsharp/core/innerpoly/test.fsx
+++ b/tests/fsharp/core/innerpoly/test.fsx
@@ -483,7 +483,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/int32/test.fsx b/tests/fsharp/core/int32/test.fsx
index a6dec0ea0af..1c6a500c55a 100644
--- a/tests/fsharp/core/int32/test.fsx
+++ b/tests/fsharp/core/int32/test.fsx
@@ -425,7 +425,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/large/conditionals/LargeConditionals-200.fs b/tests/fsharp/core/large/conditionals/LargeConditionals-200.fs
index d1910edcce4..330bfa99801 100644
--- a/tests/fsharp/core/large/conditionals/LargeConditionals-200.fs
+++ b/tests/fsharp/core/large/conditionals/LargeConditionals-200.fs
@@ -207,4 +207,4 @@ let expectedValues() =
if rnd.Next(3) = 1 then 1 else
4
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
\ No newline at end of file
+printf "TEST PASSED OK" ;
\ No newline at end of file
diff --git a/tests/fsharp/core/large/conditionals/LargeConditionals-maxtested.fs b/tests/fsharp/core/large/conditionals/LargeConditionals-maxtested.fs
index 40840fbdb13..71c3dec00a3 100644
--- a/tests/fsharp/core/large/conditionals/LargeConditionals-maxtested.fs
+++ b/tests/fsharp/core/large/conditionals/LargeConditionals-maxtested.fs
@@ -421,4 +421,4 @@ let expectedValues() =
if rnd.Next(3) = 1 then 1 else
4
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
\ No newline at end of file
+printf "TEST PASSED OK" ;
\ No newline at end of file
diff --git a/tests/fsharp/core/large/lets/LargeLets-500.fs b/tests/fsharp/core/large/lets/LargeLets-500.fs
index 5a1aa0697bb..d4e5f29e270 100644
--- a/tests/fsharp/core/large/lets/LargeLets-500.fs
+++ b/tests/fsharp/core/large/lets/LargeLets-500.fs
@@ -506,4 +506,4 @@ let expectedValues() =
let x = x + rnd.Next(3)
x
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
+printf "TEST PASSED OK" ;
diff --git a/tests/fsharp/core/large/lets/LargeLets-maxtested.fs b/tests/fsharp/core/large/lets/LargeLets-maxtested.fs
index 9f220268b6e..2c9a0ee6007 100644
--- a/tests/fsharp/core/large/lets/LargeLets-maxtested.fs
+++ b/tests/fsharp/core/large/lets/LargeLets-maxtested.fs
@@ -792,4 +792,4 @@ let expectedValues() =
let x = x + rnd.Next(3)
x
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
+printf "TEST PASSED OK" ;
diff --git a/tests/fsharp/core/large/lists/LargeList-500.fs b/tests/fsharp/core/large/lists/LargeList-500.fs
index b46244887a7..0b610e54c1d 100644
--- a/tests/fsharp/core/large/lists/LargeList-500.fs
+++ b/tests/fsharp/core/large/lists/LargeList-500.fs
@@ -504,4 +504,4 @@ let expectedValues =
1
]
printfn "length = %d" expectedValues.Length
-System.IO.File.WriteAllLines("test.ok", ["ok"])
\ No newline at end of file
+printf "TEST PASSED OK" ;
\ No newline at end of file
diff --git a/tests/fsharp/core/large/matches/LargeMatches-200.fs b/tests/fsharp/core/large/matches/LargeMatches-200.fs
index 4dac865609a..33624f1275b 100644
--- a/tests/fsharp/core/large/matches/LargeMatches-200.fs
+++ b/tests/fsharp/core/large/matches/LargeMatches-200.fs
@@ -306,4 +306,4 @@ let expectedValues() =
| None ->
4
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
\ No newline at end of file
+printf "TEST PASSED OK" ;
\ No newline at end of file
diff --git a/tests/fsharp/core/large/matches/LargeMatches-maxtested.fs b/tests/fsharp/core/large/matches/LargeMatches-maxtested.fs
index a220824334d..1c992ab7a43 100644
--- a/tests/fsharp/core/large/matches/LargeMatches-maxtested.fs
+++ b/tests/fsharp/core/large/matches/LargeMatches-maxtested.fs
@@ -462,4 +462,4 @@ let expectedValues() =
| None ->
4
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
\ No newline at end of file
+printf "TEST PASSED OK" ;
\ No newline at end of file
diff --git a/tests/fsharp/core/large/mixed/LargeSequentialLet-500.fs b/tests/fsharp/core/large/mixed/LargeSequentialLet-500.fs
index 404817e2a4f..966651362be 100644
--- a/tests/fsharp/core/large/mixed/LargeSequentialLet-500.fs
+++ b/tests/fsharp/core/large/mixed/LargeSequentialLet-500.fs
@@ -1008,4 +1008,4 @@ let expectedValues() =
let mutable x = x + 1
x
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
\ No newline at end of file
+printf "TEST PASSED OK" ;
\ No newline at end of file
diff --git a/tests/fsharp/core/large/mixed/LargeSequentialLet-maxtested.fs b/tests/fsharp/core/large/mixed/LargeSequentialLet-maxtested.fs
index 404817e2a4f..966651362be 100644
--- a/tests/fsharp/core/large/mixed/LargeSequentialLet-maxtested.fs
+++ b/tests/fsharp/core/large/mixed/LargeSequentialLet-maxtested.fs
@@ -1008,4 +1008,4 @@ let expectedValues() =
let mutable x = x + 1
x
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
\ No newline at end of file
+printf "TEST PASSED OK" ;
\ No newline at end of file
diff --git a/tests/fsharp/core/large/sequential/LargeSequential-500.fs b/tests/fsharp/core/large/sequential/LargeSequential-500.fs
index adfd85723c8..98709915acc 100644
--- a/tests/fsharp/core/large/sequential/LargeSequential-500.fs
+++ b/tests/fsharp/core/large/sequential/LargeSequential-500.fs
@@ -506,4 +506,4 @@ let expectedValues() =
x <- x + rnd.Next(3)
x
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
\ No newline at end of file
+printf "TEST PASSED OK" ;
\ No newline at end of file
diff --git a/tests/fsharp/core/large/sequential/LargeSequential-maxtested.fs b/tests/fsharp/core/large/sequential/LargeSequential-maxtested.fs
index e28abe4c379..b5fcb01d945 100644
--- a/tests/fsharp/core/large/sequential/LargeSequential-maxtested.fs
+++ b/tests/fsharp/core/large/sequential/LargeSequential-maxtested.fs
@@ -6712,4 +6712,4 @@ let expectedValues() =
x <- x + rnd.Next(3)
x
printfn "expectedValues() = %A" (expectedValues())
-System.IO.File.WriteAllLines("test.ok", ["ok"])
\ No newline at end of file
+printf "TEST PASSED OK" ;
\ No newline at end of file
diff --git a/tests/fsharp/core/lazy/test.fsx b/tests/fsharp/core/lazy/test.fsx
index 7b2424252df..a15a1aa33d8 100644
--- a/tests/fsharp/core/lazy/test.fsx
+++ b/tests/fsharp/core/lazy/test.fsx
@@ -78,7 +78,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/letrec-mutrec/test.fs b/tests/fsharp/core/letrec-mutrec/test.fs
index 9f571cf2a9d..720b441cb38 100644
--- a/tests/fsharp/core/letrec-mutrec/test.fs
+++ b/tests/fsharp/core/letrec-mutrec/test.fs
@@ -203,6 +203,6 @@ do
if !failures then (stdout.WriteLine "Test Failed"; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
#endif
diff --git a/tests/fsharp/core/letrec-mutrec2/test.fs b/tests/fsharp/core/letrec-mutrec2/test.fs
index e9a830ec488..c04592ad0f2 100644
--- a/tests/fsharp/core/letrec-mutrec2/test.fs
+++ b/tests/fsharp/core/letrec-mutrec2/test.fs
@@ -337,6 +337,6 @@ let aa =
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
#endif
\ No newline at end of file
diff --git a/tests/fsharp/core/letrec/test.fsx b/tests/fsharp/core/letrec/test.fsx
index 27f03ce0213..9d7ea6fbea4 100644
--- a/tests/fsharp/core/letrec/test.fsx
+++ b/tests/fsharp/core/letrec/test.fsx
@@ -812,7 +812,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/libtest/test.fsx b/tests/fsharp/core/libtest/test.fsx
index 370cb4918af..fae232ae5e9 100644
--- a/tests/fsharp/core/libtest/test.fsx
+++ b/tests/fsharp/core/libtest/test.fsx
@@ -559,9 +559,9 @@ do test "cwewvewho0" (match box(Some 3) with :? option -> false | _ -
do test "cwewvewho-" (match box([3]) with :? list as v -> (v = [3]) | _ -> false)
do test "cwewvewhoa" (match box([3]) with :? list as v -> false | _ -> true)
-do test "cwewvewhos" (match (null:obj) with :? list as v -> false | _ -> true)
+do test "cwewvewhos" (match (null:obj) with :? list as v -> false | _ -> true)
-let pattest<'a> (obj:obj) fail (succeed : 'a -> bool) = match obj with :? 'a as x -> succeed x | _ -> fail()
+let pattest<'a> (obj:objnull) fail (succeed : 'a -> bool) = match obj with :? 'a as x -> succeed x | _ -> fail()
do test "cwewvewhoq" (pattest (box(1)) (fun () -> false) (fun v -> v = 1))
do test "cwewvewhow" (pattest (null) (fun () -> true ) (fun _ -> false))
@@ -5646,7 +5646,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/lift/test.fsx b/tests/fsharp/core/lift/test.fsx
index f47e1ba5972..24ec381a256 100644
--- a/tests/fsharp/core/lift/test.fsx
+++ b/tests/fsharp/core/lift/test.fsx
@@ -64,7 +64,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/longnames/test.fsx b/tests/fsharp/core/longnames/test.fsx
index 577dc547a6d..963f31d4b25 100644
--- a/tests/fsharp/core/longnames/test.fsx
+++ b/tests/fsharp/core/longnames/test.fsx
@@ -695,7 +695,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/map/test.fsx b/tests/fsharp/core/map/test.fsx
index 2e80355e94a..b093d33ff33 100644
--- a/tests/fsharp/core/map/test.fsx
+++ b/tests/fsharp/core/map/test.fsx
@@ -177,7 +177,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/math/lalgebra/test.fsx b/tests/fsharp/core/math/lalgebra/test.fsx
index c09351a1a99..30f8dda47f6 100644
--- a/tests/fsharp/core/math/lalgebra/test.fsx
+++ b/tests/fsharp/core/math/lalgebra/test.fsx
@@ -313,7 +313,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/math/numbers/test.fsx b/tests/fsharp/core/math/numbers/test.fsx
index d9b8eb2edd7..7e1fb5ecb04 100644
--- a/tests/fsharp/core/math/numbers/test.fsx
+++ b/tests/fsharp/core/math/numbers/test.fsx
@@ -290,7 +290,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/math/numbersVS2008/test.fsx b/tests/fsharp/core/math/numbersVS2008/test.fsx
index ec3adaf70c8..d51423a94f3 100644
--- a/tests/fsharp/core/math/numbersVS2008/test.fsx
+++ b/tests/fsharp/core/math/numbersVS2008/test.fsx
@@ -276,7 +276,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/measures/test.fsx b/tests/fsharp/core/measures/test.fsx
index f1dec887c09..83357564018 100644
--- a/tests/fsharp/core/measures/test.fsx
+++ b/tests/fsharp/core/measures/test.fsx
@@ -612,7 +612,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/members/basics-hw-mutrec/test.fs b/tests/fsharp/core/members/basics-hw-mutrec/test.fs
index 5b53e85196f..cd66176d435 100644
--- a/tests/fsharp/core/members/basics-hw-mutrec/test.fs
+++ b/tests/fsharp/core/members/basics-hw-mutrec/test.fs
@@ -37,6 +37,6 @@ module StaticInitializerTest3 =
let _ =
if not failures.Value.IsEmpty then (eprintfn "Test Failed, failures = %A" failures.Value; exit 1)
else (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/core/members/basics-hw/test.fsx b/tests/fsharp/core/members/basics-hw/test.fsx
index e04a76f7ec2..641cb5dbc76 100644
--- a/tests/fsharp/core/members/basics-hw/test.fsx
+++ b/tests/fsharp/core/members/basics-hw/test.fsx
@@ -5663,7 +5663,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/members/basics/test.fs b/tests/fsharp/core/members/basics/test.fs
index efcaa000692..466e6cdd5b7 100644
--- a/tests/fsharp/core/members/basics/test.fs
+++ b/tests/fsharp/core/members/basics/test.fs
@@ -3481,7 +3481,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/members/ctree/test.fsx b/tests/fsharp/core/members/ctree/test.fsx
index 117a36d1c18..c12dcd73a61 100644
--- a/tests/fsharp/core/members/ctree/test.fsx
+++ b/tests/fsharp/core/members/ctree/test.fsx
@@ -64,7 +64,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/members/factors-mutrec/test.fs b/tests/fsharp/core/members/factors-mutrec/test.fs
index 8619ec8e785..e8532addec1 100644
--- a/tests/fsharp/core/members/factors-mutrec/test.fs
+++ b/tests/fsharp/core/members/factors-mutrec/test.fs
@@ -152,6 +152,6 @@ let Gaussian1DPriorFactorNode((var: VariableNode), mean, variance) =
let _ =
if !failures then (stdout.WriteLine "Test Failed"; exit 1)
else (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/core/members/factors/test.fsx b/tests/fsharp/core/members/factors/test.fsx
index b2ebe8dbcf4..e8b83b4fa6b 100644
--- a/tests/fsharp/core/members/factors/test.fsx
+++ b/tests/fsharp/core/members/factors/test.fsx
@@ -276,7 +276,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/members/incremental-hw-mutrec/test.fsx b/tests/fsharp/core/members/incremental-hw-mutrec/test.fsx
index d8543c40291..a661090396c 100644
--- a/tests/fsharp/core/members/incremental-hw-mutrec/test.fsx
+++ b/tests/fsharp/core/members/incremental-hw-mutrec/test.fsx
@@ -659,6 +659,6 @@ module ExceptionsWithAugmentations =
let _ =
if !failures then (stdout.WriteLine "Test Failed"; exit 1)
else (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/core/members/incremental-hw/test.fsx b/tests/fsharp/core/members/incremental-hw/test.fsx
index 0c3ede8a6b7..0fbc223b8e1 100644
--- a/tests/fsharp/core/members/incremental-hw/test.fsx
+++ b/tests/fsharp/core/members/incremental-hw/test.fsx
@@ -740,7 +740,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/members/incremental/test.fsx b/tests/fsharp/core/members/incremental/test.fsx
index 57015d42851..88b493e0cda 100644
--- a/tests/fsharp/core/members/incremental/test.fsx
+++ b/tests/fsharp/core/members/incremental/test.fsx
@@ -717,7 +717,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/members/ops-mutrec/test.fs b/tests/fsharp/core/members/ops-mutrec/test.fs
index 1ff8f31135f..b4eae93feb8 100644
--- a/tests/fsharp/core/members/ops-mutrec/test.fs
+++ b/tests/fsharp/core/members/ops-mutrec/test.fs
@@ -382,6 +382,6 @@ module TraitCallsAndConstructors =
let _ =
if !failures then (stdout.WriteLine "Test Failed"; exit 1)
else (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK"
exit 0)
diff --git a/tests/fsharp/core/members/ops/test.fsx b/tests/fsharp/core/members/ops/test.fsx
index a7b611ee9cd..c8ef75f93be 100644
--- a/tests/fsharp/core/members/ops/test.fsx
+++ b/tests/fsharp/core/members/ops/test.fsx
@@ -416,7 +416,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/members/self-identifier/version46/test.fs b/tests/fsharp/core/members/self-identifier/version46/test.fs
index 5a53a84a4cb..8bd41b0555c 100644
--- a/tests/fsharp/core/members/self-identifier/version46/test.fs
+++ b/tests/fsharp/core/members/self-identifier/version46/test.fs
@@ -54,7 +54,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/members/self-identifier/version47/test.fs b/tests/fsharp/core/members/self-identifier/version47/test.fs
index 76bc777ae0d..2a648678b4e 100644
--- a/tests/fsharp/core/members/self-identifier/version47/test.fs
+++ b/tests/fsharp/core/members/self-identifier/version47/test.fs
@@ -76,7 +76,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/nameof/preview/test.fsx b/tests/fsharp/core/nameof/preview/test.fsx
index 0a952ab823f..4921b12d53e 100644
--- a/tests/fsharp/core/nameof/preview/test.fsx
+++ b/tests/fsharp/core/nameof/preview/test.fsx
@@ -417,7 +417,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/namespaces/test2.fs b/tests/fsharp/core/namespaces/test2.fs
index 4ad843fb442..90a5d6bfe41 100644
--- a/tests/fsharp/core/namespaces/test2.fs
+++ b/tests/fsharp/core/namespaces/test2.fs
@@ -28,7 +28,7 @@ module UnionTestsWithSignature =
exit 1
else
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
#endif
diff --git a/tests/fsharp/core/nested/test.fsx b/tests/fsharp/core/nested/test.fsx
index 388db9ecc23..410d0f510a3 100644
--- a/tests/fsharp/core/nested/test.fsx
+++ b/tests/fsharp/core/nested/test.fsx
@@ -64,7 +64,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/patterns/test.fsx b/tests/fsharp/core/patterns/test.fsx
index 1eb20080910..dce360f5996 100644
--- a/tests/fsharp/core/patterns/test.fsx
+++ b/tests/fsharp/core/patterns/test.fsx
@@ -1735,7 +1735,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/pinvoke/test.fsx b/tests/fsharp/core/pinvoke/test.fsx
index 7f83b24fd41..29c079e145d 100644
--- a/tests/fsharp/core/pinvoke/test.fsx
+++ b/tests/fsharp/core/pinvoke/test.fsx
@@ -152,7 +152,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| messages ->
printfn "%A" messages
diff --git a/tests/fsharp/core/printf-interpolated/test.fsx b/tests/fsharp/core/printf-interpolated/test.fsx
index b1891f31ad9..810d7bfd675 100644
--- a/tests/fsharp/core/printf-interpolated/test.fsx
+++ b/tests/fsharp/core/printf-interpolated/test.fsx
@@ -292,7 +292,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/printf/test.fsx b/tests/fsharp/core/printf/test.fsx
index cf78d1a8cbd..a3ae40791a3 100644
--- a/tests/fsharp/core/printf/test.fsx
+++ b/tests/fsharp/core/printf/test.fsx
@@ -9339,7 +9339,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/queriesCustomQueryOps/test.fsx b/tests/fsharp/core/queriesCustomQueryOps/test.fsx
index d542e5d0f4d..4b26f71babd 100644
--- a/tests/fsharp/core/queriesCustomQueryOps/test.fsx
+++ b/tests/fsharp/core/queriesCustomQueryOps/test.fsx
@@ -459,7 +459,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/queriesLeafExpressionConvert/test.fsx b/tests/fsharp/core/queriesLeafExpressionConvert/test.fsx
index 59583445916..da0505782be 100644
--- a/tests/fsharp/core/queriesLeafExpressionConvert/test.fsx
+++ b/tests/fsharp/core/queriesLeafExpressionConvert/test.fsx
@@ -1004,7 +1004,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/queriesNullableOperators/test.fsx b/tests/fsharp/core/queriesNullableOperators/test.fsx
index 1cb230749b5..5e400fb5644 100644
--- a/tests/fsharp/core/queriesNullableOperators/test.fsx
+++ b/tests/fsharp/core/queriesNullableOperators/test.fsx
@@ -311,7 +311,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/queriesOverIEnumerable/test.fsx b/tests/fsharp/core/queriesOverIEnumerable/test.fsx
index cb77ad63828..fefcdc309f3 100644
--- a/tests/fsharp/core/queriesOverIEnumerable/test.fsx
+++ b/tests/fsharp/core/queriesOverIEnumerable/test.fsx
@@ -1002,7 +1002,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/queriesOverIQueryable/test.fsx b/tests/fsharp/core/queriesOverIQueryable/test.fsx
index c6e507dfa61..d5a8b6c6858 100644
--- a/tests/fsharp/core/queriesOverIQueryable/test.fsx
+++ b/tests/fsharp/core/queriesOverIQueryable/test.fsx
@@ -2445,7 +2445,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx
index 41efacfbc8d..7aa339449cf 100644
--- a/tests/fsharp/core/quotes/test.fsx
+++ b/tests/fsharp/core/quotes/test.fsx
@@ -5938,7 +5938,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| errs ->
printfn "Test Failed, errors = %A" errs
diff --git a/tests/fsharp/core/quotesDebugInfo/test.fsx b/tests/fsharp/core/quotesDebugInfo/test.fsx
index 63b68a71777..e2bdcd55ce3 100644
--- a/tests/fsharp/core/quotesDebugInfo/test.fsx
+++ b/tests/fsharp/core/quotesDebugInfo/test.fsx
@@ -646,7 +646,7 @@ let aa =
match !failures with
| 0 ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/quotesInMultipleModules/module2.fsx b/tests/fsharp/core/quotesInMultipleModules/module2.fsx
index 62a2f9e6e21..c24c10e54bf 100644
--- a/tests/fsharp/core/quotesInMultipleModules/module2.fsx
+++ b/tests/fsharp/core/quotesInMultipleModules/module2.fsx
@@ -37,7 +37,7 @@ if not test3 then
if test1 && test2 && test3 then
stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0
else
exit 1
diff --git a/tests/fsharp/core/recordResolution/test.fsx b/tests/fsharp/core/recordResolution/test.fsx
index 13af38e0d92..545b7b81a7b 100644
--- a/tests/fsharp/core/recordResolution/test.fsx
+++ b/tests/fsharp/core/recordResolution/test.fsx
@@ -56,5 +56,5 @@ module Ex3 =
let a2 = { FA = 1 }
let r = a2 :> A2 //this produces warnings, but proves that a2 is indeed of type A2.
-System.IO.File.WriteAllText("test.ok","ok")
+printf "TEST PASSED OK" ;
exit 0
\ No newline at end of file
diff --git a/tests/fsharp/core/reflect/test2.fs b/tests/fsharp/core/reflect/test2.fs
index 5b4a58e5b8e..78e876605a9 100644
--- a/tests/fsharp/core/reflect/test2.fs
+++ b/tests/fsharp/core/reflect/test2.fs
@@ -330,7 +330,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/refnormalization/test.fs b/tests/fsharp/core/refnormalization/test.fs
index 40c34e96927..994868999e5 100644
--- a/tests/fsharp/core/refnormalization/test.fs
+++ b/tests/fsharp/core/refnormalization/test.fs
@@ -25,5 +25,5 @@ let main args =
printfn "Actual: %A " versions
1
else
- File.WriteAllText("test.ok", "ok")
+ printf "TEST PASSED OK" ;
0
diff --git a/tests/fsharp/core/seq/test.fsx b/tests/fsharp/core/seq/test.fsx
index b62a55882aa..62f39fe5f3c 100644
--- a/tests/fsharp/core/seq/test.fsx
+++ b/tests/fsharp/core/seq/test.fsx
@@ -768,7 +768,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/state-machines/test.fsx b/tests/fsharp/core/state-machines/test.fsx
index 5fae4c96b7a..f171bfdbe7b 100644
--- a/tests/fsharp/core/state-machines/test.fsx
+++ b/tests/fsharp/core/state-machines/test.fsx
@@ -663,7 +663,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/subtype/test.fsx b/tests/fsharp/core/subtype/test.fsx
index 688682206e0..c813ee3ff3a 100644
--- a/tests/fsharp/core/subtype/test.fsx
+++ b/tests/fsharp/core/subtype/test.fsx
@@ -1768,7 +1768,7 @@ module GenericPropertyConstraintSolvedByRecord =
/// overload, even before the full signature of the trait constraint was known.
module MethodOverloadingForTraitConstraintsIsNotDeterminedUntilSignatureIsKnown =
type X =
- static member Method (a: obj) = 1
+ static member Method (a: objnull) = 1
static member Method (a: int) = 2
static member Method (a: int64) = 3
@@ -2339,7 +2339,7 @@ module TestSubtypeMatching11 =
[]
type E() = inherit A()
- let toName (x: obj * obj) =
+ let toName (x: objnull * objnull) =
match x with
| null, :? E -> "0E"
| (:? A), :? E -> "AE"
@@ -2418,7 +2418,7 @@ module TestSubtypeMatching12 =
type C() =
interface IC
- let toName (x: obj) =
+ let toName (x: objnull) =
match x with
| null -> "null"
| :? IA when false -> "IA fail"
@@ -2444,7 +2444,7 @@ module TestSubtypeMatching13 =
type C() =
interface IC
- let toName (x: obj) =
+ let toName (x: objnull) =
match x with
| null when false -> "null"
| :? IA -> "IA"
@@ -2545,7 +2545,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/syntax/test.fsx b/tests/fsharp/core/syntax/test.fsx
index c961992da28..c85225a5a73 100644
--- a/tests/fsharp/core/syntax/test.fsx
+++ b/tests/fsharp/core/syntax/test.fsx
@@ -1841,7 +1841,7 @@ let aa =
match !failures with
| false ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/tlr/test.fsx b/tests/fsharp/core/tlr/test.fsx
index bb8f1bcbf94..3d799fd1fd9 100644
--- a/tests/fsharp/core/tlr/test.fsx
+++ b/tests/fsharp/core/tlr/test.fsx
@@ -380,7 +380,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/topinit/test_deterministic_init.fs b/tests/fsharp/core/topinit/test_deterministic_init.fs
index ea3d5f9df1d..55474ff38a2 100644
--- a/tests/fsharp/core/topinit/test_deterministic_init.fs
+++ b/tests/fsharp/core/topinit/test_deterministic_init.fs
@@ -597,5 +597,5 @@ printfn "Touching value in module Lib85..."
printfn " --> Lib85.x = %A" Lib85.x
printfn "Checking this did cause initialization of module Lib85..."
checkInitialized "Lib85" InitFlag85.init
-System.IO.File.WriteAllText("test.ok","ok")
+printf "TEST PASSED OK" ;
exit 0
diff --git a/tests/fsharp/core/unicode/test.fsx b/tests/fsharp/core/unicode/test.fsx
index 10089e9dd0b..3954ee440cd 100644
--- a/tests/fsharp/core/unicode/test.fsx
+++ b/tests/fsharp/core/unicode/test.fsx
@@ -139,7 +139,7 @@ let aa =
match !failures with
| [] ->
stdout.WriteLine "Test Passed"
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
exit 0
| _ ->
stdout.WriteLine "Test Failed"
diff --git a/tests/fsharp/core/unitsOfMeasure/test.fs b/tests/fsharp/core/unitsOfMeasure/test.fs
index b2a40a8759f..fa7244122aa 100644
--- a/tests/fsharp/core/unitsOfMeasure/test.fs
+++ b/tests/fsharp/core/unitsOfMeasure/test.fs
@@ -201,7 +201,7 @@ let main argv =
// test2
for _ in CreateBadImageFormatException () do ()
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
match failures with
| [] ->
diff --git a/tests/fsharp/perf/graph/test.ml b/tests/fsharp/perf/graph/test.ml
index 1e34121064f..e19614be84e 100644
--- a/tests/fsharp/perf/graph/test.ml
+++ b/tests/fsharp/perf/graph/test.ml
@@ -538,5 +538,5 @@ end
let _ = test()
do (System.Console.WriteLine "Test Passed";
- System.IO.File.WriteAllText ("test.ok", "ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/perf/nbody/test.ml b/tests/fsharp/perf/nbody/test.ml
index 4ec5b9862a1..06b94f4c674 100644
--- a/tests/fsharp/perf/nbody/test.ml
+++ b/tests/fsharp/perf/nbody/test.ml
@@ -143,6 +143,6 @@ let _ = test "dce98nj" (main 500000 = "-0.169096567")
do (System.Console.WriteLine "Test Passed";
- System.IO.File.WriteAllText ("test.ok", "ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/regression/12322/test.fsx b/tests/fsharp/regression/12322/test.fsx
index 755937aedd4..855a3a2bb51 100644
--- a/tests/fsharp/regression/12322/test.fsx
+++ b/tests/fsharp/regression/12322/test.fsx
@@ -1489,6 +1489,6 @@ module LotsOfLets =
// This is a compilation test, not a lot actually happens in the test
do (System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK" ;
exit 0)
diff --git a/tests/fsharp/regression/12383/test.fs b/tests/fsharp/regression/12383/test.fs
index ae10696c9ae..b94d328988d 100644
--- a/tests/fsharp/regression/12383/test.fs
+++ b/tests/fsharp/regression/12383/test.fs
@@ -2940,6 +2940,6 @@ let inline translate opcode =
let translate2 opcode = translate opcode
do (System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK" ;
exit 0)
diff --git a/tests/fsharp/regression/13219/test.fsx b/tests/fsharp/regression/13219/test.fsx
index c6ff7817805..be2ff9c7421 100644
--- a/tests/fsharp/regression/13219/test.fsx
+++ b/tests/fsharp/regression/13219/test.fsx
@@ -18,5 +18,5 @@ type System.Object with
// This is a compilation test, not a lot actually happens in the test
do (System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK" ;
exit 0)
diff --git a/tests/fsharp/regression/13710/test.fsx b/tests/fsharp/regression/13710/test.fsx
index e80a3ecd54b..22b0c34dcec 100644
--- a/tests/fsharp/regression/13710/test.fsx
+++ b/tests/fsharp/regression/13710/test.fsx
@@ -12,6 +12,6 @@ printfn $"{auth.Test}"
// This is a compilation test, not a lot actually happens in the test
do (System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK" ;
exit 0)
diff --git a/tests/fsharp/regression/26/test.ml b/tests/fsharp/regression/26/test.ml
index 525ae7c5e97..287a42bed6a 100644
--- a/tests/fsharp/regression/26/test.ml
+++ b/tests/fsharp/regression/26/test.ml
@@ -27,6 +27,6 @@ let _ = if (compare [| |] [| |] <> 0) then fail "Test Failed (abcwlvero02)"
let _ = System.Console.Error.WriteLine "Test Passed"
do (System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/regression/321/test.ml b/tests/fsharp/regression/321/test.ml
index 8669efdbbb8..61f99fc21ac 100644
--- a/tests/fsharp/regression/321/test.ml
+++ b/tests/fsharp/regression/321/test.ml
@@ -25,5 +25,5 @@ exception Bad_xml_structure of string
let _ =
(System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/regression/655/main.fs b/tests/fsharp/regression/655/main.fs
index 2a5f4da2d93..424f52c3b36 100644
--- a/tests/fsharp/regression/655/main.fs
+++ b/tests/fsharp/regression/655/main.fs
@@ -6,7 +6,7 @@ let xI = x :> Datafile
let _ =
(System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK" ;
exit 0)
diff --git a/tests/fsharp/regression/656/form.fs b/tests/fsharp/regression/656/form.fs
index 70bd3f707c2..de189dba38f 100644
--- a/tests/fsharp/regression/656/form.fs
+++ b/tests/fsharp/regression/656/form.fs
@@ -928,5 +928,5 @@ do Application.Run(mainForm)
let _ =
(System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK" ;
exit 0)
diff --git a/tests/fsharp/regression/83/test.ml b/tests/fsharp/regression/83/test.ml
index 5dad355c937..1188cc35d02 100644
--- a/tests/fsharp/regression/83/test.ml
+++ b/tests/fsharp/regression/83/test.ml
@@ -41,6 +41,6 @@ let _ =
if !failures then (System.Console.Out.WriteLine "Test Failed"; exit 1)
do (System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/regression/84/test.ml b/tests/fsharp/regression/84/test.ml
index b2e868f53b8..b8f9ec7ce0c 100644
--- a/tests/fsharp/regression/84/test.ml
+++ b/tests/fsharp/regression/84/test.ml
@@ -5,7 +5,7 @@ let _ =
| true -> (System.Console.Out.WriteLine "Test Failed"; exit 1)
| false ->
(System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK";
exit 0)
let _ = (System.Console.Out.WriteLine "Test Ended"; exit 100)
diff --git a/tests/fsharp/regression/86/test.ml b/tests/fsharp/regression/86/test.ml
index 4b1abe343f6..2ec7219e0be 100644
--- a/tests/fsharp/regression/86/test.ml
+++ b/tests/fsharp/regression/86/test.ml
@@ -4,7 +4,7 @@
let _ =
if '\\' = '\092' & "\\" = "\092" then
(System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK";
exit 0)
else (System.Console.Out.WriteLine "Test Failed"; exit 1)
diff --git a/tests/fsharp/regression/OverloadResolution-bug/test.fsx b/tests/fsharp/regression/OverloadResolution-bug/test.fsx
index ff87afb18cb..c3d3669c450 100644
--- a/tests/fsharp/regression/OverloadResolution-bug/test.fsx
+++ b/tests/fsharp/regression/OverloadResolution-bug/test.fsx
@@ -31,5 +31,5 @@ module TestOfObj =
| _ -> None
- System.IO.File.WriteAllText("test.ok","ok")
+ printf "TEST PASSED OK" ;
printfn "Succeeded"
diff --git a/tests/fsharp/regression/literal-value-bug-2/test.fsx b/tests/fsharp/regression/literal-value-bug-2/test.fsx
index e529df8c863..fa15406ebcc 100644
--- a/tests/fsharp/regression/literal-value-bug-2/test.fsx
+++ b/tests/fsharp/regression/literal-value-bug-2/test.fsx
@@ -30,7 +30,7 @@ let result =
1
if result = 0 then
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
printfn "Succeeded"
else
printfn "Failed: %d" result
diff --git a/tests/fsharp/regression/struct-tuple-bug-1/test.fsx b/tests/fsharp/regression/struct-tuple-bug-1/test.fsx
index e70c5934575..88852695706 100644
--- a/tests/fsharp/regression/struct-tuple-bug-1/test.fsx
+++ b/tests/fsharp/regression/struct-tuple-bug-1/test.fsx
@@ -14,7 +14,7 @@ let _ =
printfn "Test Failed"
exit 1
else
- printfn "Test Passed"
- System.IO.File.WriteAllText("test.ok", "ok")
+ printf "TEST PASSED OK"
+ printf "TEST PASSED OK" ;
exit 0
()
\ No newline at end of file
diff --git a/tests/fsharp/regression/tuple-bug-1/test.ml b/tests/fsharp/regression/tuple-bug-1/test.ml
index d839ccd0733..bead09c38dd 100644
--- a/tests/fsharp/regression/tuple-bug-1/test.ml
+++ b/tests/fsharp/regression/tuple-bug-1/test.ml
@@ -25,6 +25,6 @@ let _ =
if !failures then (System.Console.Out.WriteLine "Test Failed"; exit 1)
else
(System.Console.Out.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok", "ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/single-test.fs b/tests/fsharp/single-test.fs
index a84de9a8c94..5869e27aee0 100644
--- a/tests/fsharp/single-test.fs
+++ b/tests/fsharp/single-test.fs
@@ -87,6 +87,9 @@ let generateOverrides =
let template = @"
+
+
+
"
template
@@ -189,7 +192,6 @@ let generateProjectArtifacts (pc:ProjectConfiguration) outputType (targetFramewo
-
"
template
|> replace "$(UTILITYSOURCEITEMS)" pc.UtilitySourceItems false false CompileItem.Compile
@@ -209,7 +211,6 @@ let generateProjectArtifacts (pc:ProjectConfiguration) outputType (targetFramewo
|> replaceTokens "$(RestoreFromArtifactsPath)" (Path.GetFullPath(__SOURCE_DIRECTORY__) + "/../../artifacts/packages/" + configuration)
generateProjBody
-let lockObj = obj()
let singleTestBuildAndRunCore cfg copyFiles p languageVersion =
let sources = []
let loadSources = []
@@ -225,22 +226,7 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion =
// targetFramework optimize = "net472" OR net5.0 etc ...
// optimize = true or false
let executeSingleTestBuildAndRun outputType compilerType targetFramework optimize buildOnly =
- let mutable result = false
- let directory =
- let mutable result = ""
- lock lockObj <| (fun () ->
- let rec loop () =
- let pathToArtifacts = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "../../../.."))
- if Path.GetFileName(pathToArtifacts) <> "artifacts" then failwith "FSharp.Cambridge did not find artifacts directory --- has the location changed????"
- let pathToTemp = Path.Combine(pathToArtifacts, "Temp")
- let projectDirectory = Path.Combine(pathToTemp, "FSharp.Cambridge", Guid.NewGuid().ToString() + ".tmp")
- if Directory.Exists(projectDirectory) then
- loop ()
- else
- Directory.CreateDirectory(projectDirectory) |>ignore
- projectDirectory
- result <- loop())
- result
+ let directory = cfg.Directory
let pc = {
OutputType = outputType
@@ -269,47 +255,30 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion =
let propsFileName = Path.Combine(directory, "Directory.Build.props")
let overridesFileName = Path.Combine(directory, "Directory.Overrides.targets")
let projectFileName = Path.Combine(directory, Guid.NewGuid().ToString() + ".tmp" + ".fsproj")
- try
- // Clean up directory
- Directory.CreateDirectory(directory) |> ignore
- copyFilesToDest cfg.Directory directory
- try File.Delete(Path.Combine(directory, "FSharp.Core.dll")) with _ -> ()
- emitFile targetsFileName targetsBody
- emitFile overridesFileName overridesBody
- let buildOutputFile = Path.Combine(directory, "buildoutput.txt")
- if outputType = OutputType.Exe then
- let executeFsc testCompilerVersion targetFramework =
- let propsBody = generateProps testCompilerVersion cfg.BUILD_CONFIG
- emitFile propsFileName propsBody
- let projectBody = generateProjectArtifacts pc outputType targetFramework cfg.BUILD_CONFIG languageVersion
- emitFile projectFileName projectBody
- use testOkFile = new FileGuard(Path.Combine(directory, "test.ok"))
- let cfg = { cfg with Directory = directory }
- let result = execBothToOutNoCheck cfg directory buildOutputFile cfg.DotNetExe (sprintf "run -f %s" targetFramework)
- if not (buildOnly) then
- result |> checkResult
- testOkFile.CheckExists()
- executeFsc compilerType targetFramework
- if buildOnly then verifyResults (findFirstSourceFile pc) buildOutputFile
- else
- let executeFsi testCompilerVersion targetFramework =
- let propsBody = generateProps testCompilerVersion cfg.BUILD_CONFIG
- emitFile propsFileName propsBody
- let projectBody = generateProjectArtifacts pc outputType targetFramework cfg.BUILD_CONFIG languageVersion
- emitFile projectFileName projectBody
- use testOkFile = new FileGuard(Path.Combine(directory, "test.ok"))
- let cfg = { cfg with Directory = directory }
- execBothToOut cfg directory buildOutputFile cfg.DotNetExe "build /t:RunFSharpScript"
- testOkFile.CheckExists()
- executeFsi compilerType targetFramework
- result <- true
- finally
- if result <> false then
- try Directory.Delete(directory, true) with _ -> ()
- else
- printfn "Configuration: %s" cfg.Directory
- printfn "Directory: %s" directory
- printfn "Filename: %s" projectFileName
+ emitFile targetsFileName targetsBody
+ emitFile overridesFileName overridesBody
+ let buildOutputFile = Path.Combine(directory, "buildoutput.txt")
+ if outputType = OutputType.Exe then
+ let executeFsc testCompilerVersion targetFramework =
+ let propsBody = generateProps testCompilerVersion cfg.BUILD_CONFIG
+ emitFile propsFileName propsBody
+ let projectBody = generateProjectArtifacts pc outputType targetFramework cfg.BUILD_CONFIG languageVersion
+ emitFile projectFileName projectBody
+ let cfg = { cfg with Directory = directory }
+ let result = execBothToOutNoCheck cfg directory buildOutputFile cfg.DotNetExe (sprintf "run -f %s" targetFramework)
+ if not (buildOnly) then
+ result |> checkResultPassed
+ executeFsc compilerType targetFramework
+ if buildOnly then verifyResults (findFirstSourceFile pc) buildOutputFile
+ else
+ let executeFsi testCompilerVersion targetFramework =
+ let propsBody = generateProps testCompilerVersion cfg.BUILD_CONFIG
+ emitFile propsFileName propsBody
+ let projectBody = generateProjectArtifacts pc outputType targetFramework cfg.BUILD_CONFIG languageVersion
+ emitFile projectFileName projectBody
+ let cfg = { cfg with Directory = directory }
+ execBothToOutCheckPassed cfg directory buildOutputFile cfg.DotNetExe $"build /t:RunFSharpScriptAndPrintOutput"
+ executeFsi compilerType targetFramework
match p with
#if NETCOREAPP
@@ -321,19 +290,15 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion =
| FSI_NETFX_STDIN ->
use _cleanup = (cleanUpFSharpCore cfg)
- use testOkFile = new FileGuard (getfullpath cfg "test.ok")
let sources = extraSources |> List.filter (fileExists cfg)
- fsiStdin cfg (sources |> List.rev |> List.head) "" [] //use last file, because `cmd < a.txt b.txt` redirect b.txt only
-
- testOkFile.CheckExists()
+ fsiStdinCheckPassed cfg (sources |> List.rev |> List.head) "" [] //use last file, because `cmd < a.txt b.txt` redirect b.txt only
| FSC_NETFX_TEST_ROUNDTRIP_AS_DLL ->
// Compile as a DLL to exercise pickling of interface data, then recompile the original source file referencing this DLL
// The second compilation will not utilize the information from the first in any meaningful way, but the
// compiler will unpickle the interface and optimization data, so we test unpickling as well.
use _cleanup = (cleanUpFSharpCore cfg)
- use testOkFile = new FileGuard (getfullpath cfg "test.ok")
let sources = extraSources |> List.filter (fileExists cfg)
@@ -343,9 +308,8 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion =
peverify cfg "test--optimize-lib.dll"
peverify cfg "test--optimize-client-of-lib.exe"
- exec cfg ("." ++ "test--optimize-client-of-lib.exe") ""
+ execAndCheckPassed cfg ("." ++ "test--optimize-client-of-lib.exe") ""
- testOkFile.CheckExists()
#endif
let singleTestBuildAndRunAux cfg p =
diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs
index 7fdab667a00..ed99adda96a 100644
--- a/tests/fsharp/tests.fs
+++ b/tests/fsharp/tests.fs
@@ -35,37 +35,32 @@ module CoreTests =
let ``subtype-langversion-checknulls`` () =
let cfg = testConfig "core/subtype"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test-checknulls.exe -g --checknulls" cfg.fsc_flags ["test.fsx"]
- exec cfg ("." ++ "test-checknulls.exe") ""
+ execAndCheckPassed cfg ("." ++ "test-checknulls.exe") ""
- testOkFile.CheckExists()
[]
let ``subtype-langversion-no-checknulls`` () =
let cfg = testConfig "core/subtype"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test-no-checknulls.exe -g --checknulls-" cfg.fsc_flags ["test.fsx"]
- exec cfg ("." ++ "test-no-checknulls.exe") ""
+ execAndCheckPassed cfg ("." ++ "test-no-checknulls.exe") ""
- testOkFile.CheckExists()
[]
let ``subtype-langversion-46`` () =
let cfg = testConfig "core/subtype"
- use testOkFile = fileguard cfg "test.ok"
-
fsc cfg "%s -o:test-langversion-46.exe -g --langversion:4.6" cfg.fsc_flags ["test.fsx"]
- exec cfg ("." ++ "test-langversion-46.exe") ""
+ execAndCheckPassed cfg ("." ++ "test-langversion-46.exe") ""
- testOkFile.CheckExists()
#endif
@@ -94,75 +89,71 @@ module CoreTests =
let cfg = { cfg with fsc_flags = sprintf "%s --preferreduilang:en-US --test:StackSpan" cfg.fsc_flags}
begin
- use testOkFile = fileguard cfg "test.ok"
+
singleNegTest cfg "test"
fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
// Execution is disabled until we can be sure .NET 4.7.2 is on the machine
- //exec cfg ("." ++ "test.exe") ""
+ //execAndCheckPassed cfg ("." ++ "test.exe") ""
- //testOkFile.CheckExists()
+ //checkPassed()
end
begin
- use testOkFile = fileguard cfg "test2.ok"
singleNegTest cfg "test2"
fsc cfg "%s -o:test2.exe -g" cfg.fsc_flags ["test2.fsx"]
// Execution is disabled until we can be sure .NET 4.7.2 is on the machine
- //exec cfg ("." ++ "test.exe") ""
+ //execAndCheckPassed cfg ("." ++ "test.exe") ""
- //testOkFile.CheckExists()
+ //checkPassed()
end
begin
- use testOkFile = fileguard cfg "test3.ok"
singleNegTest cfg "test3"
fsc cfg "%s -o:test3.exe -g" cfg.fsc_flags ["test3.fsx"]
// Execution is disabled until we can be sure .NET 4.7.2 is on the machine
- //exec cfg ("." ++ "test.exe") ""
+ //execAndCheckPassed cfg ("." ++ "test.exe") ""
- //testOkFile.CheckExists()
+ //checkPassed()
end
[]
let asyncStackTraces () =
let cfg = testConfig "core/asyncStackTraces"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe -g --tailcalls- --optimize-" cfg.fsc_flags ["test.fsx"]
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
[]
let ``state-machines-non-optimized`` () =
let cfg = testConfig "core/state-machines"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe -g --tailcalls- --optimize-" cfg.fsc_flags ["test.fsx"]
peverify cfg "test.exe"
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
[]
let ``state-machines-optimized`` () =
let cfg = testConfig "core/state-machines"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe -g --tailcalls+ --optimize+" cfg.fsc_flags ["test.fsx"]
@@ -170,7 +161,6 @@ module CoreTests =
exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
[]
let ``state-machines neg-resumable-01`` () =
@@ -186,90 +176,79 @@ module CoreTests =
[]
let ``lots-of-conditionals``() =
let cfg = testConfig "core/large/conditionals"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeConditionals-200.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
[]
let ``lots-of-conditionals-maxtested``() =
let cfg = testConfig "core/large/conditionals"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeConditionals-maxtested.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
[]
let ``lots-of-lets``() =
let cfg = testConfig "core/large/lets"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeLets-500.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
[]
let ``lots-of-lets-maxtested``() =
let cfg = testConfig "core/large/lets"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeLets-maxtested.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
[]
let ``lots-of-lists``() =
let cfg = testConfig "core/large/lists"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test-500.exe " cfg.fsc_flags ["LargeList-500.fs"]
- exec cfg ("." ++ "test-500.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test-500.exe") ""
[]
let ``lots-of-matches``() =
let cfg = testConfig "core/large/matches"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeMatches-200.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
[]
let ``lots-of-matches-maxtested``() =
let cfg = testConfig "core/large/matches"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeMatches-maxtested.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
[]
let ``lots-of-sequential-and-let``() =
let cfg = testConfig "core/large/mixed"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeSequentialLet-500.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
[]
let ``lots-of-sequential-and-let-maxtested``() =
let cfg = testConfig "core/large/mixed"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeSequentialLet-maxtested.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
[]
let ``lots-of-sequential``() =
let cfg = testConfig "core/large/sequential"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeSequential-500.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
[]
let ``lots-of-sequential-maxtested``() =
let cfg = testConfig "core/large/sequential"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeSequential-maxtested.fs"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
#endif
@@ -295,19 +274,17 @@ module CoreTests =
peverify cfg "test.exe"
begin
- use testOkFile = fileguard cfg "test.ok"
+
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
end
begin
- use testOkFile = fileguard cfg "test.ok"
+
- fsi cfg "-r:lib.dll" ["test.fsx"]
+ fsiCheckPassed cfg "-r:lib.dll" ["test.fsx"]
- testOkFile.CheckExists()
end
[]
@@ -322,13 +299,12 @@ module CoreTests =
peverify cfg "testcs.exe"
- use testOkFile = fileguard cfg "test.ok"
+
- fsi cfg "" ["test.fs"]
+ fsiCheckPassed cfg "" ["test.fs"]
- testOkFile.CheckExists()
- exec cfg ("." ++ "testcs.exe") ""
+ execAndCheckPassed cfg ("." ++ "testcs.exe") ""
//
@@ -355,7 +331,7 @@ module CoreTests =
// fsiStdin cfg "%s %s" cfg.fsi_flags flags "test1.fsx"
//
// // if NOT EXIST test1.ok goto SetError
- // testOkFile.CheckExists()
+ // checkPassed()
//
//
// []
@@ -377,7 +353,7 @@ module CoreTests =
// fsiStdin cfg "%s %s" cfg.fsi_flags flags "test2.fsx"
//
// // if NOT EXIST test2.ok goto SetError
- // testOkFile.CheckExists()
+ // checkPassed()
//
@@ -446,9 +422,9 @@ module CoreTests =
csc cfg """/nologo /r:"%s" /r:System.Core.dll /r:lib--optimize.dll /out:test--optimize.exe""" cfg.FSCOREDLLPATH ["test.cs"]
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- exec cfg ("." ++ "test--optimize.exe") ""
+ execAndCheckPassed cfg ("." ++ "test--optimize.exe") ""
[]
let fsfromfsviacs () =
@@ -467,21 +443,21 @@ module CoreTests =
peverify cfg "test.exe"
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
// Same with library references the other way around
fsc cfg "%s -r:lib.dll -r:lib3.dll -r:lib2.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
peverify cfg "test.exe"
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
// Same without the reference to lib.dll - testing an incomplete reference set, but only compiling a subset of the code
fsc cfg "%s --define:NO_LIB_REFERENCE -r:lib3.dll -r:lib2.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
peverify cfg "test.exe"
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
// some features missing in 4.7
for version in ["4.7"] do
@@ -509,35 +485,22 @@ module CoreTests =
let cfg = testConfig "core/fsi-reference"
- begin
- use testOkFile = fileguard cfg "test.ok"
+ begin
fsc cfg @"--target:library -o:ImplementationAssembly\ReferenceAssemblyExample.dll" ["ImplementationAssembly.fs"]
fsc cfg @"--target:library -o:ReferenceAssembly\ReferenceAssemblyExample.dll" ["ReferenceAssembly.fs"]
- fsiStdin cfg "test.fsx" "" []
- testOkFile.CheckExists()
+ fsiStdinCheckPassed cfg "test.fsx" "" []
end
[]
let ``fsi-reload`` () =
let cfg = testConfig "core/fsi-reload"
+
+ fsiStdinCheckPassed cfg "test1.ml" " --langversion:5.0 --mlcompatibility --maxerrors:1" []
+
+ fsiCheckPassed cfg "%s --maxerrors:1" cfg.fsi_flags ["load1.fsx"]
- begin
- use testOkFile = fileguard cfg "test.ok"
- fsiStdin cfg "test1.ml" " --langversion:5.0 --mlcompatibility --maxerrors:1" []
- testOkFile.CheckExists()
- end
-
- begin
- use testOkFile = fileguard cfg "test.ok"
- fsi cfg "%s --maxerrors:1" cfg.fsi_flags ["load1.fsx"]
- testOkFile.CheckExists()
- end
-
- begin
- use testOkFile = fileguard cfg "test.ok"
- fsi cfg "%s --maxerrors:1" cfg.fsi_flags ["load2.fsx"]
- testOkFile.CheckExists()
- end
+
+ fsiCheckPassed cfg "%s --maxerrors:1" cfg.fsi_flags ["load2.fsx"]
fsc cfg "" ["load1.fsx"]
fsc cfg "" ["load2.fsx"]
@@ -551,11 +514,7 @@ module CoreTests =
fsiStdin cfg "prepare.fsx" "--maxerrors:1" []
- use testOkFile = fileguard cfg "test.ok"
-
- fsiStdin cfg "test.fsx" "--maxerrors:1" []
-
- testOkFile.CheckExists()
+ fsiStdinCheckPassed cfg "test.fsx" "--maxerrors:1" []
[]
let ``genericmeasures-FSC_NETFX_TEST_ROUNDTRIP_AS_DLL`` () = singleTestBuildAndRun "core/genericmeasures" FSC_NETFX_TEST_ROUNDTRIP_AS_DLL
@@ -595,27 +554,24 @@ module CoreTests =
singleNegTest cfg "negativetest"
begin
- use testOkFile = fileguard cfg "test.ok"
+
- fsi cfg "%s" cfg.fsi_flags ["test.fsx"]
+ fsiCheckPassed cfg "%s" cfg.fsi_flags ["test.fsx"]
- testOkFile.CheckExists()
end
begin
- use testOkFile = fileguard cfg "test.ok"
+
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
end
begin
- use testOkFile = fileguard cfg "test.ok"
+
- exec cfg ("." ++ "test--optimize.exe") ""
+ execAndCheckPassed cfg ("." ++ "test--optimize.exe") ""
- testOkFile.CheckExists()
end
// Debug with
@@ -633,10 +589,10 @@ module CoreTests =
let ``fsi b 2>c`` =
// "%FSI%" %fsc_flags_errors_ok% --nologo z.raw.output.test.default.txt 2>&1
- let ``exec b 2>c`` (inFile, outFile, errFile) p =
+ let ``execAndCheckPassed b 2>c`` (inFile, outFile, errFile) p =
Command.exec cfg.Directory cfg.EnvironmentVariables { Output = OutputAndError(Overwrite(outFile), Overwrite(errFile)); Input = Some(RedirectInput(inFile)); } p
>> checkResult
- Printf.ksprintf (fun flags (inFile, outFile, errFile) -> Commands.fsi (``exec b 2>c`` (inFile, outFile, errFile)) cfg.FSI flags [])
+ Printf.ksprintf (fun flags (inFile, outFile, errFile) -> Commands.fsi (``execAndCheckPassed b 2>c`` (inFile, outFile, errFile)) cfg.FSI flags [])
let fsc_flags_errors_ok = ""
@@ -819,9 +775,8 @@ module CoreTests =
peverify cfg "test.exe"
begin
- use testOkFile = fileguard cfg "test.ok"
- exec cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
+
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
end
fsc cfg "%s -o:test-with-debug-data.exe --quotations-debug+ -r cslib.dll -g" cfg.fsc_flags ["test.fsx"]
@@ -833,23 +788,20 @@ module CoreTests =
peverify cfg "test--optimize.exe"
begin
- use testOkFile = fileguard cfg "test.ok"
+
- fsi cfg "%s -r cslib.dll" cfg.fsi_flags ["test.fsx"]
+ fsiCheckPassed cfg "%s -r cslib.dll" cfg.fsi_flags ["test.fsx"]
- testOkFile.CheckExists()
end
begin
- use testOkFile = fileguard cfg "test.ok"
- exec cfg ("." ++ "test-with-debug-data.exe") ""
- testOkFile.CheckExists()
+
+ execAndCheckPassed cfg ("." ++ "test-with-debug-data.exe") ""
end
begin
- use testOkFile = fileguard cfg "test.ok"
- exec cfg ("." ++ "test--optimize.exe") ""
- testOkFile.CheckExists()
+
+ execAndCheckPassed cfg ("." ++ "test--optimize.exe") ""
end
// Previously a comment here said:
@@ -948,7 +900,7 @@ module CoreTests =
peverify cfg "test.exe"
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
log "== Compiling F# Library and Code, when empty file libfile2.fs IS included"
fsc cfg "%s -a --optimize -o:lib2.dll " cfg.fsc_flags ["libfile1.fs"; "libfile2.fs"]
@@ -959,7 +911,7 @@ module CoreTests =
peverify cfg "test2.exe"
- exec cfg ("." ++ "test2.exe") ""
+ execAndCheckPassed cfg ("." ++ "test2.exe") ""
// Repro for https://github.com/dotnet/fsharp/issues/2679
[]
@@ -1008,26 +960,24 @@ module CoreTests =
let ``libtest-langversion-checknulls`` () =
let cfg = testConfig "core/libtest"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test-checknulls.exe -g --checknulls" cfg.fsc_flags ["test.fsx"]
- exec cfg ("." ++ "test-checknulls.exe") ""
+ execAndCheckPassed cfg ("." ++ "test-checknulls.exe") ""
- testOkFile.CheckExists()
[]
let ``libtest-langversion-46`` () =
let cfg = testConfig "core/libtest"
- use testOkFile = fileguard cfg "test.ok"
+
fsc cfg "%s -o:test-langversion-46.exe -g --langversion:4.6" cfg.fsc_flags ["test.fsx"]
- exec cfg ("." ++ "test-langversion-46.exe") ""
+ execAndCheckPassed cfg ("." ++ "test-langversion-46.exe") ""
- testOkFile.CheckExists()
[]
let ``no-warn-2003-tests`` () =
@@ -1240,23 +1190,14 @@ module CoreTests =
peverify cfg "test--optimize.exe"
- use testOkFile = fileguard cfg "test.ok"
+ fsiCheckPassed cfg "%s" cfg.fsi_flags ["test.fsx"]
- fsi cfg "%s" cfg.fsi_flags ["test.fsx"]
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- use testOkFile2 = fileguard cfg "test.ok"
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test--optimize.exe") ""
- testOkFile2.CheckExists()
-
- use testOkFile3 = fileguard cfg "test.ok"
-
- exec cfg ("." ++ "test--optimize.exe") ""
-
- testOkFile3.CheckExists()
[]
@@ -1271,17 +1212,11 @@ module CoreTests =
peverify cfg "test--optimize.exe"
- use testOkFile = fileguard cfg "test.ok"
- fsi cfg "%s" cfg.fsi_flags ["test.fsx"]
- testOkFile.CheckExists()
+ fsiCheckPassed cfg "%s" cfg.fsi_flags ["test.fsx"]
- use testOkFile2 = fileguard cfg "test.ok"
- exec cfg ("." ++ "test.exe") ""
- testOkFile2.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- use testOkFile3 = fileguard cfg "test.ok"
- exec cfg ("." ++ "test--optimize.exe") ""
- testOkFile3.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test--optimize.exe") ""
[]
let queriesOverIEnumerable () =
@@ -1295,23 +1230,15 @@ module CoreTests =
peverify cfg "test--optimize.exe"
- use testOkFile = fileguard cfg "test.ok"
-
- fsi cfg "%s" cfg.fsi_flags ["test.fsx"]
-
- testOkFile.CheckExists()
+
- use testOkFile2 = fileguard cfg "test.ok"
+ fsiCheckPassed cfg "%s" cfg.fsi_flags ["test.fsx"]
- exec cfg ("." ++ "test.exe") ""
- testOkFile2.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- use testOkFile3 = fileguard cfg "test.ok"
-
- exec cfg ("." ++ "test--optimize.exe") ""
+ execAndCheckPassed cfg ("." ++ "test--optimize.exe") ""
- testOkFile3.CheckExists()
[]
let queriesOverIQueryable () =
@@ -1325,23 +1252,18 @@ module CoreTests =
peverify cfg "test--optimize.exe"
- use testOkFile = fileguard cfg "test.ok"
- fsi cfg "%s" cfg.fsi_flags ["test.fsx"]
+
+ fsiCheckPassed cfg "%s" cfg.fsi_flags ["test.fsx"]
- testOkFile.CheckExists()
- use testOkFile2 = fileguard cfg "test.ok"
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile2.CheckExists()
- use testOkFile3 = fileguard cfg "test.ok"
- exec cfg ("." ++ "test--optimize.exe") ""
+ execAndCheckPassed cfg ("." ++ "test--optimize.exe") ""
- testOkFile3.CheckExists()
[]
@@ -1356,23 +1278,17 @@ module CoreTests =
peverify cfg "test--optimize.exe"
- use testOkFile = fileguard cfg "test.ok"
- fsi cfg "%s --quotations-debug+" cfg.fsi_flags ["test.fsx"]
-
- testOkFile.CheckExists()
+
+ fsiCheckPassed cfg "%s --quotations-debug+" cfg.fsi_flags ["test.fsx"]
- use testOkFile2 = fileguard cfg "test.ok"
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile2.CheckExists()
- use testOkFile3 = fileguard cfg "test.ok"
- exec cfg ("." ++ "test--optimize.exe") ""
+ execAndCheckPassed cfg ("." ++ "test--optimize.exe") ""
- testOkFile3.CheckExists()
[]
@@ -1399,30 +1315,24 @@ module CoreTests =
peverify cfg "module2-opt.exe"
- use testOkFile = fileguard cfg "test.ok"
-
- fsi cfg "%s -r module1.dll" cfg.fsi_flags ["module2.fsx"]
-
- testOkFile.CheckExists()
+
+ fsiCheckPassed cfg "%s -r module1.dll" cfg.fsi_flags ["module2.fsx"]
- use testOkFile = fileguard cfg "test.ok"
- exec cfg ("." ++ "module2.exe") ""
- testOkFile.CheckExists()
+
- use testOkFile = fileguard cfg "test.ok"
+ execAndCheckPassed cfg ("." ++ "module2.exe") ""
- exec cfg ("." ++ "module2-opt.exe") ""
+
- testOkFile.CheckExists()
+ execAndCheckPassed cfg ("." ++ "module2-opt.exe") ""
- use testOkFile = fileguard cfg "test.ok"
+
- exec cfg ("." ++ "module2-staticlink.exe") ""
+ execAndCheckPassed cfg ("." ++ "module2-staticlink.exe") ""
- testOkFile.CheckExists()
#endif
@@ -1442,26 +1352,23 @@ module CoreTests =
//TestCase1
// Build a program that references v2 of ascendent and v1 of dependent.
// Note that, even though ascendent v2 references dependent v2, the reference is marked as v1.
- use TestOk = fileguard cfg "test.ok"
+
fsc cfg @"%s -o:test1.exe -r:version1\DependentAssembly.dll -r:version2\AscendentAssembly.dll --optimize- -g" cfg.fsc_flags ["test.fs"]
- exec cfg ("." ++ "test1.exe") "DependentAssembly-1.0.0.0 AscendentAssembly-2.0.0.0"
- TestOk.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test1.exe") "DependentAssembly-1.0.0.0 AscendentAssembly-2.0.0.0"
//TestCase2
// Build a program that references v1 of ascendent and v2 of dependent.
// Note that, even though ascendent v1 references dependent v1, the reference is marked as v2 which was passed in.
- use TestOk = fileguard cfg "test.ok"
+
fsc cfg @"%s -o:test2.exe -r:version2\DependentAssembly.dll -r:version1\AscendentAssembly.dll --optimize- -g" cfg.fsc_flags ["test.fs"]
- exec cfg ("." ++ "test2.exe") "DependentAssembly-2.0.0.0 AscendentAssembly-1.0.0.0"
- TestOk.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test2.exe") "DependentAssembly-2.0.0.0 AscendentAssembly-1.0.0.0"
//TestCase3
// Build a program that references v1 of ascendent and v1 and v2 of dependent.
// Verifies that compiler uses first version of a duplicate assembly passed on command line.
- use TestOk = fileguard cfg "test.ok"
+
fsc cfg @"%s -o:test3.exe -r:version1\DependentAssembly.dll -r:version2\DependentAssembly.dll -r:version1\AscendentAssembly.dll --optimize- -g" cfg.fsc_flags ["test.fs"]
- exec cfg ("." ++ "test3.exe") "DependentAssembly-1.0.0.0 AscendentAssembly-1.0.0.0"
- TestOk.CheckExists()
+ execAndCheckPassed cfg ("." ++ "test3.exe") "DependentAssembly-1.0.0.0 AscendentAssembly-1.0.0.0"
[]
@@ -1628,11 +1535,10 @@ module CoreTests =
peverify cfg "test.exe"
- use testOkFile = fileguard cfg "test.ok"
+
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
[]
let verify () =
@@ -1867,11 +1773,10 @@ module RegressionTests =
peverify cfg "test.exe"
- use testOkFile = fileguard cfg "test.ok"
+
- exec cfg ("." ++ "test.exe") ""
+ execAndCheckPassed cfg ("." ++ "test.exe") ""
- testOkFile.CheckExists()
// This test is disabled in coreclr builds dependent on fixing : https://github.com/dotnet/fsharp/issues/2600
[]
diff --git a/tests/fsharp/tools/eval/test.fsx b/tests/fsharp/tools/eval/test.fsx
index 69431999bbc..9fb17c1d870 100644
--- a/tests/fsharp/tools/eval/test.fsx
+++ b/tests/fsharp/tools/eval/test.fsx
@@ -2797,5 +2797,5 @@ let _ =
exit 1
else
stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0
diff --git a/tests/fsharp/typeProviders/diamondAssembly/test3.fsx b/tests/fsharp/typeProviders/diamondAssembly/test3.fsx
index 51e5f1803e7..d3350294831 100644
--- a/tests/fsharp/typeProviders/diamondAssembly/test3.fsx
+++ b/tests/fsharp/typeProviders/diamondAssembly/test3.fsx
@@ -162,7 +162,7 @@ let _ =
if not failures.IsEmpty then (printfn "Test Failed, failures = %A" failures; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/typeProviders/globalNamespace/test.fsx b/tests/fsharp/typeProviders/globalNamespace/test.fsx
index 133be281594..f0201d7d252 100644
--- a/tests/fsharp/typeProviders/globalNamespace/test.fsx
+++ b/tests/fsharp/typeProviders/globalNamespace/test.fsx
@@ -24,7 +24,7 @@ let _ =
if not failures.IsEmpty then (printfn "Test Failed, failures = %A" failures; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/typeProviders/helloWorld/test.fsx b/tests/fsharp/typeProviders/helloWorld/test.fsx
index e528e8da949..59d811bc5a0 100644
--- a/tests/fsharp/typeProviders/helloWorld/test.fsx
+++ b/tests/fsharp/typeProviders/helloWorld/test.fsx
@@ -1192,7 +1192,7 @@ let _ =
if not failures.IsEmpty then (printfn "Test Failed, failures = %A" failures; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/typeProviders/helloWorldCSharp/test.fsx b/tests/fsharp/typeProviders/helloWorldCSharp/test.fsx
index 936e670a305..a4a1fbe3228 100644
--- a/tests/fsharp/typeProviders/helloWorldCSharp/test.fsx
+++ b/tests/fsharp/typeProviders/helloWorldCSharp/test.fsx
@@ -26,7 +26,7 @@ let _ =
if not failures.IsEmpty then (printfn "Test Failed, failures = %A" failures; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/typeProviders/splitAssemblyTools/test.fsx b/tests/fsharp/typeProviders/splitAssemblyTools/test.fsx
index e25871ab5f8..ba7cc6b9e34 100644
--- a/tests/fsharp/typeProviders/splitAssemblyTools/test.fsx
+++ b/tests/fsharp/typeProviders/splitAssemblyTools/test.fsx
@@ -26,7 +26,7 @@ let _ =
if not failures.IsEmpty then (printfn "Test Failed, failures = %A" failures; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/typeProviders/splitAssemblyTypeproviders/test.fsx b/tests/fsharp/typeProviders/splitAssemblyTypeproviders/test.fsx
index e25871ab5f8..ba7cc6b9e34 100644
--- a/tests/fsharp/typeProviders/splitAssemblyTypeproviders/test.fsx
+++ b/tests/fsharp/typeProviders/splitAssemblyTypeproviders/test.fsx
@@ -26,7 +26,7 @@ let _ =
if not failures.IsEmpty then (printfn "Test Failed, failures = %A" failures; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/typeProviders/wedgeAssembly/test3.fsx b/tests/fsharp/typeProviders/wedgeAssembly/test3.fsx
index 7e6125c4be9..1a3c546d17a 100644
--- a/tests/fsharp/typeProviders/wedgeAssembly/test3.fsx
+++ b/tests/fsharp/typeProviders/wedgeAssembly/test3.fsx
@@ -108,7 +108,7 @@ let _ =
if not failures.IsEmpty then (printfn "Test Failed, failures = %A" failures; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/fsharp/typecheck/full-rank-arrays/test.fsx b/tests/fsharp/typecheck/full-rank-arrays/test.fsx
index 0a062adae4a..d8800170979 100644
--- a/tests/fsharp/typecheck/full-rank-arrays/test.fsx
+++ b/tests/fsharp/typecheck/full-rank-arrays/test.fsx
@@ -107,5 +107,5 @@ let _ =
let x = Class1()
x.RunTests()
System.Console.WriteLine "Test Passed";
- System.IO.File.WriteAllText ("test.ok", "ok");
+ printf "TEST PASSED OK"
exit 0
diff --git a/tests/fsharp/typecheck/misc/test.ml b/tests/fsharp/typecheck/misc/test.ml
index 4a2e5c89332..14bc16ae51f 100644
--- a/tests/fsharp/typecheck/misc/test.ml
+++ b/tests/fsharp/typecheck/misc/test.ml
@@ -33,5 +33,5 @@ let _ =
* So avoid using ;;
*)
System.Console.WriteLine "Test Passed";
- System.IO.File.WriteAllText ("test.ok", "ok");
+ printf "TEST PASSED OK";
exit 0
diff --git a/tests/fsharp/typecheck/sigs/neg104.vsbsl b/tests/fsharp/typecheck/sigs/neg104.vsbsl
index 8a6059aa128..165b4348e35 100644
--- a/tests/fsharp/typecheck/sigs/neg104.vsbsl
+++ b/tests/fsharp/typecheck/sigs/neg104.vsbsl
@@ -27,4 +27,4 @@ neg104.fs(20,9,20,15): typecheck error FS0025: Incomplete pattern matches on thi
neg104.fs(23,9,23,15): typecheck error FS0025: Incomplete pattern matches on this expression.
-neg104.fs(35,9,35,18): typecheck error FS0748: This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'.
+neg104.fs(35,9,35,15): typecheck error FS0748: This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'.
diff --git a/tests/fsharp/typecheck/sigs/neg107.bsl b/tests/fsharp/typecheck/sigs/neg107.bsl
index 30b24d25c59..580233b4775 100644
--- a/tests/fsharp/typecheck/sigs/neg107.bsl
+++ b/tests/fsharp/typecheck/sigs/neg107.bsl
@@ -33,11 +33,11 @@ neg107.fsx(28,55,28,66): typecheck error FS0425: The type of a first-class funct
neg107.fsx(30,49,30,54): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
-neg107.fsx(30,57,30,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+neg107.fsx(30,64,30,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(31,70,31,75): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
-neg107.fsx(31,78,31,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+neg107.fsx(31,85,31,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(32,13,32,30): typecheck error FS3301: The function or method has an invalid return type 'Async>'. This is not permitted by the rules of Common IL.
@@ -49,13 +49,13 @@ neg107.fsx(32,48,32,53): typecheck error FS0406: The byref-typed variable 'a' is
neg107.fsx(32,48,32,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(32,56,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+neg107.fsx(32,63,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(32,56,32,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+neg107.fsx(32,63,32,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
-neg107.fsx(32,56,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+neg107.fsx(32,63,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(32,56,32,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs
+neg107.fsx(32,63,32,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(32,48,32,53): typecheck error FS0425: The type of a first-class function cannot contain byrefs
@@ -69,13 +69,13 @@ neg107.fsx(33,56,33,61): typecheck error FS0406: The byref-typed variable 'a' is
neg107.fsx(33,56,33,61): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(33,64,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+neg107.fsx(33,71,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(33,64,33,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+neg107.fsx(33,71,33,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
-neg107.fsx(33,64,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+neg107.fsx(33,71,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(33,64,33,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs
+neg107.fsx(33,71,33,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(33,56,33,61): typecheck error FS0425: The type of a first-class function cannot contain byrefs
diff --git a/tests/fsharp/typecheck/sigs/neg107.vsbsl b/tests/fsharp/typecheck/sigs/neg107.vsbsl
index 30b24d25c59..580233b4775 100644
--- a/tests/fsharp/typecheck/sigs/neg107.vsbsl
+++ b/tests/fsharp/typecheck/sigs/neg107.vsbsl
@@ -33,11 +33,11 @@ neg107.fsx(28,55,28,66): typecheck error FS0425: The type of a first-class funct
neg107.fsx(30,49,30,54): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
-neg107.fsx(30,57,30,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+neg107.fsx(30,64,30,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(31,70,31,75): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
-neg107.fsx(31,78,31,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+neg107.fsx(31,85,31,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(32,13,32,30): typecheck error FS3301: The function or method has an invalid return type 'Async>'. This is not permitted by the rules of Common IL.
@@ -49,13 +49,13 @@ neg107.fsx(32,48,32,53): typecheck error FS0406: The byref-typed variable 'a' is
neg107.fsx(32,48,32,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(32,56,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+neg107.fsx(32,63,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(32,56,32,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+neg107.fsx(32,63,32,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
-neg107.fsx(32,56,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+neg107.fsx(32,63,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(32,56,32,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs
+neg107.fsx(32,63,32,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(32,48,32,53): typecheck error FS0425: The type of a first-class function cannot contain byrefs
@@ -69,13 +69,13 @@ neg107.fsx(33,56,33,61): typecheck error FS0406: The byref-typed variable 'a' is
neg107.fsx(33,56,33,61): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(33,64,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+neg107.fsx(33,71,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(33,64,33,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+neg107.fsx(33,71,33,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
-neg107.fsx(33,64,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+neg107.fsx(33,71,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
-neg107.fsx(33,64,33,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs
+neg107.fsx(33,71,33,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(33,56,33,61): typecheck error FS0425: The type of a first-class function cannot contain byrefs
diff --git a/tests/fsharp/typecheck/sigs/neg20.bsl b/tests/fsharp/typecheck/sigs/neg20.bsl
index ea20ab65acf..5229dcaacf6 100644
--- a/tests/fsharp/typecheck/sigs/neg20.bsl
+++ b/tests/fsharp/typecheck/sigs/neg20.bsl
@@ -67,7 +67,7 @@ but given a
'B list'
The type 'A' does not match the type 'B'
-neg20.fs(80,23,80,39): typecheck error FS0193: Type constraint mismatch. The type
+neg20.fs(80,30,80,39): typecheck error FS0193: Type constraint mismatch. The type
'C list'
is not compatible with type
'B seq'
diff --git a/tests/fsharp/typecheck/sigs/neg59.bsl b/tests/fsharp/typecheck/sigs/neg59.bsl
index 624750b9352..77a9c8caf46 100644
--- a/tests/fsharp/typecheck/sigs/neg59.bsl
+++ b/tests/fsharp/typecheck/sigs/neg59.bsl
@@ -33,14 +33,14 @@ neg59.fs(89,15,89,18): typecheck error FS3141: 'try/finally' expressions may not
neg59.fs(95,15,95,18): typecheck error FS3141: 'try/finally' expressions may not be used in queries
-neg59.fs(102,15,102,64): typecheck error FS3142: 'use' expressions may not be used in queries
+neg59.fs(102,15,102,18): typecheck error FS3142: 'use' expressions may not be used in queries
-neg59.fs(108,15,108,64): typecheck error FS3142: 'use' expressions may not be used in queries
+neg59.fs(108,15,108,18): typecheck error FS3142: 'use' expressions may not be used in queries
neg59.fs(113,15,113,25): typecheck error FS3140: 'while' expressions may not be used in queries
neg59.fs(118,15,118,25): typecheck error FS3140: 'while' expressions may not be used in queries
-neg59.fs(124,17,124,25): typecheck error FS3144: 'return' and 'return!' may not be used in queries
+neg59.fs(124,17,124,23): typecheck error FS3144: 'return' and 'return!' may not be used in queries
-neg59.fs(128,17,128,26): typecheck error FS3144: 'return' and 'return!' may not be used in queries
+neg59.fs(128,17,128,24): typecheck error FS3144: 'return' and 'return!' may not be used in queries
diff --git a/tests/fsharp/typecheck/sigs/neg61.bsl b/tests/fsharp/typecheck/sigs/neg61.bsl
index 91291a6cb94..d7011cef5ef 100644
--- a/tests/fsharp/typecheck/sigs/neg61.bsl
+++ b/tests/fsharp/typecheck/sigs/neg61.bsl
@@ -57,15 +57,15 @@ neg61.fs(79,13,79,16): typecheck error FS3146: 'try/with' expressions may not be
neg61.fs(86,13,86,16): typecheck error FS3141: 'try/finally' expressions may not be used in queries
-neg61.fs(92,13,92,70): typecheck error FS3142: 'use' expressions may not be used in queries
+neg61.fs(92,13,92,16): typecheck error FS3142: 'use' expressions may not be used in queries
neg61.fs(97,13,97,17): typecheck error FS3143: 'let!', 'use!' and 'do!' expressions may not be used in queries
neg61.fs(102,13,102,16): typecheck error FS3143: 'let!', 'use!' and 'do!' expressions may not be used in queries
-neg61.fs(107,13,107,21): typecheck error FS3144: 'return' and 'return!' may not be used in queries
+neg61.fs(107,13,107,19): typecheck error FS3144: 'return' and 'return!' may not be used in queries
-neg61.fs(111,13,111,24): typecheck error FS3144: 'return' and 'return!' may not be used in queries
+neg61.fs(111,13,111,20): typecheck error FS3144: 'return' and 'return!' may not be used in queries
neg61.fs(114,13,114,21): typecheck error FS3145: This is not a known query operator. Query operators are identifiers such as 'select', 'where', 'sortBy', 'thenBy', 'groupBy', 'groupValBy', 'join', 'groupJoin', 'sumBy' and 'averageBy', defined using corresponding methods on the 'QueryBuilder' type.
diff --git a/tests/fsharp/typecheck/sigs/version50/neg20.bsl b/tests/fsharp/typecheck/sigs/version50/neg20.bsl
index 169c18e8573..394f7777b2a 100644
--- a/tests/fsharp/typecheck/sigs/version50/neg20.bsl
+++ b/tests/fsharp/typecheck/sigs/version50/neg20.bsl
@@ -98,7 +98,7 @@ but given a
'B list'
The type 'A' does not match the type 'B'
-neg20.fs(80,23,80,39): typecheck error FS0193: Type constraint mismatch. The type
+neg20.fs(80,30,80,39): typecheck error FS0193: Type constraint mismatch. The type
'C list'
is not compatible with type
'B seq'
diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturn.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturn.fs
index a0bb521f1af..5010e70386b 100644
--- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturn.fs
+++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturn.fs
@@ -1,6 +1,6 @@
// #Regression #Conformance #DataExpressions #ComputationExpressions
// Regression test for FSHARP1.0:6149
-//This control construct may only be used if the computation expression builder defines a 'Return' method$
+//This control construct may only be used if the computation expression builder defines a 'Return' method$
type R = S of string
diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturnFrom.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturnFrom.fs
index 24f20ffb9ac..f8185a9b7fa 100644
--- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturnFrom.fs
+++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturnFrom.fs
@@ -1,6 +1,6 @@
// #Regression #Conformance #DataExpressions #ComputationExpressions
// Regression test for FSHARP1.0:6149
-//This control construct may only be used if the computation expression builder defines a 'ReturnFrom' method$
+//This control construct may only be used if the computation expression builder defines a 'ReturnFrom' method$
type R = S of string
diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs
index 90018a3a6a5..e83604cfdf9 100644
--- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs
+++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs
@@ -1,6 +1,6 @@
// #Regression #Conformance #DataExpressions #ComputationExpressions
// Regression test for FSHARP1.0:6149
-//This control construct may only be used if the computation expression builder defines a 'Using' method$
+//This control construct may only be used if the computation expression builder defines a 'Using' method$
type R = S of string
diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYield.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYield.fs
index b731412bfa6..7251faf3978 100644
--- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYield.fs
+++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYield.fs
@@ -1,6 +1,6 @@
// #Regression #Conformance #DataExpressions #ComputationExpressions
// Regression test for FSHARP1.0:6149
-//This control construct may only be used if the computation expression builder defines a 'Yield' method$
+//This control construct may only be used if the computation expression builder defines a 'Yield' method$
type R = S of string
diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYieldFrom.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYieldFrom.fs
index 63ada5cd6be..3777c375f2b 100644
--- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYieldFrom.fs
+++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYieldFrom.fs
@@ -1,6 +1,6 @@
// #Regression #Conformance #DataExpressions #ComputationExpressions
// Regression test for FSHARP1.0:6149
-//This control construct may only be used if the computation expression builder defines a 'YieldFrom' method$
+//This control construct may only be used if the computation expression builder defines a 'YieldFrom' method$
type R = S of string
diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/backtickmoduleandtypenames.fsx b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/backtickmoduleandtypenames.fsx
index 20aede76c20..47debdeb71f 100644
--- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/backtickmoduleandtypenames.fsx
+++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/backtickmoduleandtypenames.fsx
@@ -75,5 +75,5 @@ let aa =
if !failures then (stdout.WriteLine "Test Failed"; exit 1)
do (stdout.WriteLine "Test Passed";
- System.IO.File.WriteAllText("test.ok","ok");
+ printf "TEST PASSED OK";
exit 0)
diff --git a/tests/scripts/scriptlib.fsx b/tests/scripts/scriptlib.fsx
index b074b78ba25..853aecb496e 100644
--- a/tests/scripts/scriptlib.fsx
+++ b/tests/scripts/scriptlib.fsx
@@ -82,7 +82,7 @@ module Scripting =
type FilePath = string
type CmdResult =
- | Success
+ | Success of output: string
| ErrorLevel of string * int
type CmdArguments =
@@ -156,7 +156,8 @@ module Scripting =
p.WaitForExit()
match p.ExitCode with
- | 0 -> Success
+ | 0 ->
+ Success(string out)
| errCode ->
let msg = sprintf "Error running command '%s' with args '%s' in directory '%s'.\n---- stdout below --- \n%s\n---- stderr below --- \n%s " exePath arguments workDir (out.ToString()) (err.ToString())
ErrorLevel (msg, errCode)
diff --git a/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl b/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl
index 5a7bf976186..596eb100812 100644
--- a/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl
+++ b/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl
@@ -44,11 +44,12 @@ ImplFile
{ LeadingKeyword = Let (3,4--3,7)
InlineKeyword = Some (3,8--3,14)
EqualsRange = Some (3,21--3,22) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,11--2,16), NoneAtLet, { LeadingKeyword = Let (2,0--2,3)
- InlineKeyword = Some (2,4--2,10)
- EqualsRange = Some (2,17--2,18) })],
- (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,11--2,16), NoneAtLet,
+ { LeadingKeyword = Let (2,0--2,3)
+ InlineKeyword = Some (2,4--2,10)
+ EqualsRange = Some (2,17--2,18) })], (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl
index 844946e66c3..e3156b5c3b5 100644
--- a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl
+++ b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl
@@ -20,8 +20,9 @@ ImplFile
Yes (3,4--3,13), { LeadingKeyword = Let (3,4--3,7)
InlineKeyword = None
EqualsRange = Some (3,10--3,11) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,0--4,6)), (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl
index b0e567ed3bd..93dabea4c82 100644
--- a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl
+++ b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl
@@ -30,8 +30,9 @@ ImplFile
{ LeadingKeyword = Let (3,4--3,7)
InlineKeyword = None
EqualsRange = Some (3,15--3,16) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,0--4,6)), (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl b/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl
index 31febede5b6..86775dec80c 100644
--- a/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl
+++ b/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl
@@ -34,11 +34,12 @@ ImplFile
NoneAtLet, { LeadingKeyword = Let (3,4--3,7)
InlineKeyword = None
EqualsRange = Some (3,12--3,13) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,4--2,5), NoneAtLet, { LeadingKeyword = Let (2,0--2,3)
- InlineKeyword = None
- EqualsRange = Some (2,6--2,7) })],
- (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,4--2,5), NoneAtLet,
+ { LeadingKeyword = Let (2,0--2,3)
+ InlineKeyword = None
+ EqualsRange = Some (2,6--2,7) })], (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl b/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl
index 72f8528c23f..16e62c6c1aa 100644
--- a/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl
+++ b/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl
@@ -39,10 +39,12 @@ ImplFile
(5,4--5,24), { AndBangKeyword = (5,4--5,8)
EqualsRange = (5,13--5,14)
InKeyword = None })],
- YieldOrReturn ((false, true), Ident bar, (6,4--6,14)),
- (3,4--6,14), { LetOrUseBangKeyword = (3,4--3,8)
- EqualsRange = Some (3,13--3,14) }),
- (2,6--7,1)), (2,0--7,1)), (2,0--7,1))], PreXmlDocEmpty, [],
- None, (2,0--7,1), { LeadingKeyword = None })], (true, true),
+ YieldOrReturn
+ ((false, true), Ident bar, (6,4--6,14),
+ { YieldOrReturnKeyword = (6,4--6,10) }), (3,4--6,14),
+ { LetOrUseBangKeyword = (3,4--3,8)
+ EqualsRange = Some (3,13--3,14) }), (2,6--7,1)),
+ (2,0--7,1)), (2,0--7,1))], PreXmlDocEmpty, [], None, (2,0--7,1),
+ { LeadingKeyword = None })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl b/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl
index d0dd3083e64..9ee7e15f532 100644
--- a/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl
+++ b/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl
@@ -28,10 +28,12 @@ ImplFile
(5,4--5,24), { AndBangKeyword = (5,4--5,8)
EqualsRange = (5,13--5,14)
InKeyword = None })],
- YieldOrReturn ((false, true), Ident bar, (7,4--7,14)),
- (3,4--7,14), { LetOrUseBangKeyword = (3,4--3,8)
- EqualsRange = Some (3,13--3,14) }),
- (2,6--8,1)), (2,0--8,1)), (2,0--8,1))], PreXmlDocEmpty, [],
- None, (2,0--8,1), { LeadingKeyword = None })], (true, true),
+ YieldOrReturn
+ ((false, true), Ident bar, (7,4--7,14),
+ { YieldOrReturnKeyword = (7,4--7,10) }), (3,4--7,14),
+ { LetOrUseBangKeyword = (3,4--3,8)
+ EqualsRange = Some (3,13--3,14) }), (2,6--8,1)),
+ (2,0--8,1)), (2,0--8,1))], PreXmlDocEmpty, [], None, (2,0--8,1),
+ { LeadingKeyword = None })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Expression/List - Comprehension 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/List - Comprehension 01.fs.bsl
index 7cc9b348848..517c835a63a 100644
--- a/tests/service/data/SyntaxTree/Expression/List - Comprehension 01.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/List - Comprehension 01.fs.bsl
@@ -12,8 +12,9 @@ ImplFile
Named (SynIdent (x, None), false, None, (3,6--3,7)),
ArrayOrList (false, [], (3,11--3,13)),
YieldOrReturn
- ((true, false), Const (Unit, (3,17--3,19)), (3,14--3,19)),
- (3,2--3,19)), (3,0--3,21)), (3,0--3,21))],
+ ((true, false), Const (Unit, (3,17--3,19)), (3,14--3,19),
+ { YieldOrReturnKeyword = (3,14--3,16) }), (3,2--3,19)),
+ (3,0--3,21)), (3,0--3,21))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--3,21), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Expression/List - Comprehension 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/List - Comprehension 02.fs.bsl
index 1a89da1b0fb..9897592fb0a 100644
--- a/tests/service/data/SyntaxTree/Expression/List - Comprehension 02.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/List - Comprehension 02.fs.bsl
@@ -15,7 +15,8 @@ ImplFile
((true, false),
ArbitraryAfterError
("typedSequentialExprBlockR1", (3,16--3,16)),
- (3,14--3,16)), (3,2--3,16)), (3,0--3,18)), (3,0--3,18))],
+ (3,14--3,16), { YieldOrReturnKeyword = (3,14--3,16) }),
+ (3,2--3,16)), (3,0--3,18)), (3,0--3,18))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--3,18), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
index 132e7030303..791f6099b9e 100644
--- a/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
@@ -55,8 +55,10 @@ ImplFile
[Some (OriginalNotation "+")]), None,
(5,6--5,7)), Ident x, (5,4--5,7)), Ident y,
(5,4--5,9)), (4,4--5,9),
- { InKeyword = Some (4,14--4,16) }), (3,4--5,9),
- { InKeyword = Some (3,14--3,16) }), (2,4--2,8), NoneAtLet,
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = Some (4,14--4,16) }), (3,4--5,9),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = Some (3,14--3,16) }), (2,4--2,8), NoneAtLet,
{ LeadingKeyword = Let (2,0--2,3)
InlineKeyword = None
EqualsRange = Some (2,9--2,10) })], (2,0--5,9))],
diff --git a/tests/service/data/SyntaxTree/Expression/Rarrow 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/Rarrow 01.fs.bsl
index 9d7e7af2125..c3c454436ce 100644
--- a/tests/service/data/SyntaxTree/Expression/Rarrow 01.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/Rarrow 01.fs.bsl
@@ -5,8 +5,8 @@ ImplFile
([Module], false, NamedModule,
[Expr
(YieldOrReturn
- ((true, true), Const (Int32 1, (3,3--3,4)), (3,0--3,4)),
- (3,0--3,4))],
+ ((true, true), Const (Int32 1, (3,3--3,4)), (3,0--3,4),
+ { YieldOrReturnKeyword = (3,0--3,2) }), (3,0--3,4))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--3,4), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Expression/Rarrow 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/Rarrow 02.fs.bsl
index 54570b38728..3a0af632862 100644
--- a/tests/service/data/SyntaxTree/Expression/Rarrow 02.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/Rarrow 02.fs.bsl
@@ -7,7 +7,7 @@ ImplFile
(YieldOrReturn
((true, true),
ArbitraryAfterError ("typedSequentialExprBlockR1", (3,2--3,2)),
- (3,0--3,2)), (3,0--3,2))],
+ (3,0--3,2), { YieldOrReturnKeyword = (3,0--3,2) }), (3,0--3,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--3,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Expression/Rarrow 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/Rarrow 03.fs.bsl
index e0d4104ac0a..ceae74bf09b 100644
--- a/tests/service/data/SyntaxTree/Expression/Rarrow 03.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/Rarrow 03.fs.bsl
@@ -9,8 +9,9 @@ ImplFile
YieldOrReturn
((true, true),
ArbitraryAfterError
- ("typedSequentialExprBlockR1", (3,5--3,5)), (3,3--3,5)),
- (3,0--3,5)), (3,0--3,5))],
+ ("typedSequentialExprBlockR1", (3,5--3,5)), (3,3--3,5),
+ { YieldOrReturnKeyword = (3,3--3,5) }), (3,0--3,5),
+ { YieldOrReturnKeyword = (3,0--3,2) }), (3,0--3,5))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--3,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl
index a0f54029820..0264686482c 100644
--- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl
@@ -26,10 +26,11 @@ ImplFile
EqualsRange = (4,11--4,12)
InKeyword = None })],
YieldOrReturn
- ((false, true), Const (Unit, (5,11--5,13)), (5,4--5,13)),
- (3,4--5,13), { LetOrUseBangKeyword = (3,4--3,8)
- EqualsRange = Some (3,11--3,12) }),
- (2,5--6,1)), (2,0--6,1)), (2,0--6,1))], PreXmlDocEmpty, [],
- None, (2,0--6,1), { LeadingKeyword = None })], (true, true),
+ ((false, true), Const (Unit, (5,11--5,13)), (5,4--5,13),
+ { YieldOrReturnKeyword = (5,4--5,10) }), (3,4--5,13),
+ { LetOrUseBangKeyword = (3,4--3,8)
+ EqualsRange = Some (3,11--3,12) }), (2,5--6,1)),
+ (2,0--6,1)), (2,0--6,1))], PreXmlDocEmpty, [], None, (2,0--6,1),
+ { LeadingKeyword = None })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
index f9ce333429a..5408f5d71d1 100644
--- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
@@ -19,7 +19,8 @@ ImplFile
InlineKeyword = None
EqualsRange = Some (2,6--2,7) })],
Const (Unit, (2,13--2,15)), (2,0--2,15),
- { InKeyword = Some (2,10--2,12) }), (2,0--2,15))],
+ { LetOrUseKeyword = (2,0--2,3)
+ InKeyword = Some (2,10--2,12) }), (2,0--2,15))],
PreXmlDocEmpty, [], None, (2,0--2,15), { LeadingKeyword = None })],
(true, true), { ConditionalDirectives = []
CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl
index 54c3f8180e4..bb9dcafe15f 100644
--- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl
@@ -21,8 +21,9 @@ ImplFile
Yes (3,0--3,9), { LeadingKeyword = Let (3,0--3,3)
InlineKeyword = None
EqualsRange = Some (3,6--3,7) })],
- Const (Unit, (4,0--4,2)), (3,0--4,2), { InKeyword = None }),
- (2,0--4,2)), (2,0--4,2))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,0--4,2)), (3,0--4,2),
+ { LetOrUseKeyword = (3,0--3,3)
+ InKeyword = None }), (2,0--4,2)), (2,0--4,2))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl
index a5d102356f1..554f4eb21ef 100644
--- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl
@@ -40,7 +40,8 @@ ImplFile
SynLongIdent
([e1; Value], [(4,10--4,11)], [None; None]), None,
(4,8--4,16))], [(4,6--4,7)], (4,0--4,16)),
- (3,0--4,16), { InKeyword = None }), (2,0--4,16)),
+ (3,0--4,16), { LetOrUseKeyword = (3,0--3,3)
+ InKeyword = None }), (2,0--4,16)),
(2,0--4,16))], PreXmlDocEmpty, [], None, (2,0--5,0),
{ LeadingKeyword = None })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl
index 72352706810..8b57f33b953 100644
--- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl
@@ -35,7 +35,8 @@ ImplFile
InlineKeyword = None
EqualsRange = Some (4,10--4,11) })],
Const (Unit, (5,4--5,6)), (3,4--5,6),
- { InKeyword = Some (4,15--4,17) }), (2,0--5,6)), (2,0--5,6))],
+ { LetOrUseKeyword = (3,4--3,11)
+ InKeyword = Some (4,15--4,17) }), (2,0--5,6)), (2,0--5,6))],
PreXmlDocEmpty, [], None, (2,0--6,0), { LeadingKeyword = None })],
(true, true), { ConditionalDirectives = []
CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl b/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl
index 94ee31ce8d1..74221e70a5f 100644
--- a/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl
@@ -19,7 +19,8 @@ ImplFile
InlineKeyword = None
EqualsRange = Some (5,6--5,7) })],
ArbitraryAfterError ("seqExpr", (5,10--5,10)), (5,0--5,10),
- { InKeyword = None }), [], (3,0--5,10), Yes (3,0--3,3),
+ { LetOrUseKeyword = (5,0--5,3)
+ InKeyword = None }), [], (3,0--5,10), Yes (3,0--3,3),
Yes (5,10--5,10), { TryKeyword = (3,0--3,3)
TryToWithRange = (3,0--5,10)
WithKeyword = (5,10--5,10)
diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 01.fs.bsl
index 936525524f3..deb6d27aa83 100644
--- a/tests/service/data/SyntaxTree/Expression/WhileBang 01.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/WhileBang 01.fs.bsl
@@ -13,8 +13,9 @@ ImplFile
(false,
YieldOrReturn
((false, true), Const (Bool true, (3,22--3,26)),
- (3,15--3,26)), (3,13--3,28)), (3,7--3,28)),
- Const (Int32 2, (4,4--4,5)), (3,0--4,5)), (3,0--4,5));
+ (3,15--3,26), { YieldOrReturnKeyword = (3,15--3,21) }),
+ (3,13--3,28)), (3,7--3,28)), Const (Int32 2, (4,4--4,5)),
+ (3,0--4,5)), (3,0--4,5));
Expr (Const (Int32 3, (6,0--6,1)), (6,0--6,1))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 02.fs.bsl
index b12f9b0df18..52eaca7bfdc 100644
--- a/tests/service/data/SyntaxTree/Expression/WhileBang 02.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/WhileBang 02.fs.bsl
@@ -13,8 +13,9 @@ ImplFile
(false,
YieldOrReturn
((false, true), Const (Bool true, (3,22--3,26)),
- (3,15--3,26)), (3,13--3,28)), (3,7--3,28)),
- Const (Int32 2, (4,4--4,5)), (3,0--5,4)), (3,0--5,4));
+ (3,15--3,26), { YieldOrReturnKeyword = (3,15--3,21) }),
+ (3,13--3,28)), (3,7--3,28)), Const (Int32 2, (4,4--4,5)),
+ (3,0--5,4)), (3,0--5,4));
Expr (Const (Int32 3, (7,0--7,1)), (7,0--7,1))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 03.fs.bsl
index a5793465b34..437c23a2c6b 100644
--- a/tests/service/data/SyntaxTree/Expression/WhileBang 03.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/WhileBang 03.fs.bsl
@@ -20,7 +20,9 @@ ImplFile
(false,
YieldOrReturn
((false, true), Const (Bool true, (4,26--4,30)),
- (4,19--4,30)), (4,17--4,32)), (4,11--4,32)),
+ (4,19--4,30),
+ { YieldOrReturnKeyword = (4,19--4,25) }),
+ (4,17--4,32)), (4,11--4,32)),
ArbitraryAfterError ("whileBody1", (6,0--6,1)), (4,4--4,35)),
(3,4--3,5), Yes (3,0--4,35), { LeadingKeyword = Let (3,0--3,3)
InlineKeyword = None
diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 04.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 04.fs.bsl
index 863c8aaabfe..70db990cb0e 100644
--- a/tests/service/data/SyntaxTree/Expression/WhileBang 04.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/WhileBang 04.fs.bsl
@@ -20,7 +20,9 @@ ImplFile
(false,
YieldOrReturn
((false, true), Const (Bool true, (4,26--4,30)),
- (4,19--4,30)), (4,17--4,32)), (4,11--4,32)),
+ (4,19--4,30),
+ { YieldOrReturnKeyword = (4,19--4,25) }),
+ (4,17--4,32)), (4,11--4,32)),
ArbitraryAfterError ("whileBody1", (5,0--5,0)), (4,4--4,35)),
(3,4--3,5), Yes (3,0--4,35), { LeadingKeyword = Let (3,0--3,3)
InlineKeyword = None
diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 05.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 05.fs.bsl
index e2f5875ef4b..a8b4a21543b 100644
--- a/tests/service/data/SyntaxTree/Expression/WhileBang 05.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/WhileBang 05.fs.bsl
@@ -20,7 +20,9 @@ ImplFile
(false,
YieldOrReturn
((false, true), Const (Bool true, (4,26--4,30)),
- (4,19--4,30)), (4,17--4,32)), (4,11--4,32)),
+ (4,19--4,30),
+ { YieldOrReturnKeyword = (4,19--4,25) }),
+ (4,17--4,32)), (4,11--4,32)),
Const (Int32 2, (5,8--5,9)), (4,4--5,9)), (3,4--3,5),
Yes (3,0--5,9), { LeadingKeyword = Let (3,0--3,3)
InlineKeyword = None
diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 06.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 06.fs.bsl
index 3c8ef1cbebf..df87ceb6a9d 100644
--- a/tests/service/data/SyntaxTree/Expression/WhileBang 06.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/WhileBang 06.fs.bsl
@@ -20,7 +20,9 @@ ImplFile
(false,
YieldOrReturn
((false, true), Const (Bool true, (4,26--4,30)),
- (4,19--4,30)), (4,17--4,32)), (4,11--4,32)),
+ (4,19--4,30),
+ { YieldOrReturnKeyword = (4,19--4,25) }),
+ (4,17--4,32)), (4,11--4,32)),
Const (Int32 2, (5,4--5,5)), (4,4--5,5)), (3,4--3,5),
Yes (3,0--5,5), { LeadingKeyword = Let (3,0--3,3)
InlineKeyword = None
diff --git a/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl b/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl
index b2b3420c806..4571189344f 100644
--- a/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl
@@ -22,8 +22,9 @@ ImplFile
{ LeadingKeyword = Use (3,4--3,7)
InlineKeyword = None
EqualsRange = Some (3,10--3,11) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,0--4,6)), (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl b/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl
index 7dbbc35edd7..ac1d1ce9819 100644
--- a/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl
@@ -22,8 +22,9 @@ ImplFile
{ LeadingKeyword = UseRec ((3,4--3,7), (3,8--3,11))
InlineKeyword = None
EqualsRange = Some (3,14--3,15) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,11)
+ InKeyword = None }), (2,0--4,6)), (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl b/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl
index 84ce5019498..f4b3b9f7a39 100644
--- a/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl
+++ b/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl
@@ -25,7 +25,8 @@ ImplFile
EqualsRange = Some (3,16--3,17) })],
App
(NonAtomic, false, Ident Some, Ident content, (4,4--4,16)),
- (3,4--4,16), { InKeyword = None }),
+ (3,4--4,16), { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }),
[SynMatchClause
(Named (SynIdent (ex, None), false, None, (6,2--6,4)), None,
Sequential
diff --git a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl
index dfa2ad58587..324463e7b2e 100644
--- a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl
+++ b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl
@@ -25,7 +25,8 @@ ImplFile
EqualsRange = Some (3,16--3,17) })],
App
(NonAtomic, false, Ident Some, Ident content, (4,4--4,16)),
- (3,4--4,16), { InKeyword = None }),
+ (3,4--4,16), { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }),
[SynMatchClause
(Named (SynIdent (ex, None), false, None, (5,5--5,7)), None,
Sequential
diff --git a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl
index ea10cf70558..132cbd01cc0 100644
--- a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl
+++ b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl
@@ -25,7 +25,8 @@ ImplFile
EqualsRange = Some (3,16--3,17) })],
App
(NonAtomic, false, Ident Some, Ident content, (4,4--4,16)),
- (3,4--4,16), { InKeyword = None }),
+ (3,4--4,16), { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }),
[SynMatchClause
(Named (SynIdent (ex, None), false, None, (6,2--6,4)), None,
Const (Unit, (7,4--7,6)), (6,2--7,6), Yes,
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl
index 54749497087..7bd27b958c6 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl
@@ -30,7 +30,8 @@ ImplFile
InlineKeyword = None
EqualsRange = None })],
ArbitraryAfterError ("seqExpr", (4,10--4,10)),
- (4,4--4,10), { InKeyword = None }), (4,4--4,10)),
+ (4,4--4,10), { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (4,4--4,10)),
(3,0--4,10)), (3,0--4,10))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--4,10), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl
index 55a07b60288..6120ff4f5fd 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl
@@ -26,8 +26,9 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = Some (4,11--4,12) })],
- Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }),
- (3,0--6,6)), (3,0--6,6))],
+ Const (Unit, (6,4--6,6)), (4,4--6,6),
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl
index 89a4af5ce5c..0f2e4604d2b 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl
@@ -25,7 +25,8 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = None })], Const (Unit, (6,4--6,6)),
- (4,4--6,6), { InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
+ (4,4--6,6), { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl
index f3fa83db96a..5e8ab0f26fd 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl
@@ -24,8 +24,9 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = Some (4,13--4,14) })],
- Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }),
- (3,0--6,6)), (3,0--6,6))],
+ Const (Unit, (6,4--6,6)), (4,4--6,6),
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl
index e89431a48e0..dbf43bcf3b1 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl
@@ -30,8 +30,9 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = Some (4,15--4,16) })],
- Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }),
- (3,0--6,6)), (3,0--6,6))],
+ Const (Unit, (6,4--6,6)), (4,4--6,6),
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl
index 97ad7191e25..416dc67c859 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl
@@ -38,8 +38,9 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = Some (4,18--4,19) })],
- Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }),
- (3,0--6,6)), (3,0--6,6))],
+ Const (Unit, (6,4--6,6)), (4,4--6,6),
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl b/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl
index d91bffd331d..1dfe5586b56 100644
--- a/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl
+++ b/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl
@@ -31,7 +31,8 @@ ImplFile
{ LeadingKeyword = Let (2,4--2,7)
InlineKeyword = None
EqualsRange = Some (2,10--2,11) })], Ident b,
- (2,4--5,5), { InKeyword = None }), (1,4--1,5), NoneAtLet,
+ (2,4--5,5), { LetOrUseKeyword = (2,4--2,7)
+ InKeyword = None }), (1,4--1,5), NoneAtLet,
{ LeadingKeyword = Let (1,0--1,3)
InlineKeyword = None
EqualsRange = Some (1,6--1,7) })], (1,0--5,5))],
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.cs.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.cs.xlf
index d43dc577c61..b969107b017 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.cs.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.cs.xlf
@@ -744,7 +744,7 @@
- Můžete upravit obsah elementu pole pomocí operátoru přiřazení s šipkou doleva.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- Rozlišované sjednocení může také představovat hodnotu hrací karty.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- Při vyjadřování dat se běžně používají záznamy i rozlišovaná sjednocení.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- Rozlišovaná sjednocení podporují i rekurzivní definice.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf
index a8a789025d7..e2023a345a0 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf
@@ -744,7 +744,7 @@
- Sie können die Inhalte eines Arrayelements mithilfe des Zuweisungsoperators "Pfeil nach links" ändern.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- Eine diskriminierte Union kann auch verwendet werden, um den Rang einer Spielkarte darzustellen.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- Beim Darstellen von Daten werden häufig sowohl Datensätze als auch diskriminierte Unions verwendet.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- Diskriminierte Unions unterstützen auch rekursive Definitionen.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.es.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.es.xlf
index 3041197dd6c..ce9964fbe25 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.es.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.es.xlf
@@ -744,7 +744,7 @@
- Puede modificar el contenido de un elemento de matriz mediante el operador de asignación de flecha izquierda.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- También se puede usar una unión discriminada para representar el rango de una carta.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- Es habitual utilizar tanto registros como uniones discriminadas cuando se representan datos.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- Las uniones discriminadas admiten también definiciones recursivas.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.fr.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.fr.xlf
index 79b126ad3f4..3c515e263e8 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.fr.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.fr.xlf
@@ -744,7 +744,7 @@
- Vous pouvez modifier le contenu d'un élément de tableau à l'aide de l'opérateur d'assignation flèche gauche.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- Une union discriminée peut également servir à représenter le rang d'une carte à jouer.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- Il est fréquent d'utiliser à la fois des enregistrements et des unions discriminées pour représenter des données.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- Les unions discriminées prennent également en charge les définitions récursives.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf
index 5b17d36350e..79c43274cc4 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf
@@ -744,7 +744,7 @@
- È possibile modificare il contenuto di un elemento di matrice usando l'operatore di assegnazione freccia sinistra.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- È possibile usare un'unione discriminata anche per rappresentare il valore di una carta da gioco.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- Per la rappresentazione dei dati si usano in genere record e unioni discriminate.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- Le unioni discriminate supportano anche definizioni ricorsive.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf
index 3275255ba6a..33ba6422ea1 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf
@@ -744,7 +744,7 @@
- 左矢印代入演算子を使用して、配列要素の内容を変更できます。
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- 判別共用体はトランプのランクを表すためにも使用できます。
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- データを表すときには、レコードと判別共用体の両方を使用するのが一般的です。
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- 判別共用体は再帰的な定義もサポートしています。
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf
index f6668949ef9..c5f198ffa1b 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf
@@ -744,7 +744,7 @@
- 왼쪽 화살표 대입 연산자를 사용하여 배열 요소의 내용을 수정할 수 있습니다.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- 구분된 공용 구조체를 사용하여 플레잉 카드의 순위를 나타낼 수도 있습니다.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- 일반적으로 레코드와 구분된 공용 구조체를 모두 사용하여 데이터를 나타냅니다.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- 구분된 공용 구조체는 재귀 정의도 지원합니다.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pl.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pl.xlf
index 80135046c87..5bdcd939c42 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pl.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pl.xlf
@@ -744,7 +744,7 @@
- Możesz zmodyfikować zawartość elementu tablicy za pomocą operatora przypisania „strzałka w lewo”.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- Unii rozłącznej można również użyć do reprezentowania wartości karty do gry.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- Często używa się rekordów i unii rozłącznych w przypadku reprezentowania danych.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- Unie rozłączne obsługują również definicje rekursywne.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf
index 433113974ba..736952384fc 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf
@@ -744,7 +744,7 @@
- Você pode modificar o conteúdo de um elemento de matriz usando o operador de atribuição de seta para a esquerda.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- Uma União Discriminada também pode ser usada para representar a classificação de uma carta de baralho.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- É comum usar Registros e Uniões Discriminadas ao representar dados.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- Uniões Discriminadas também dão suporte a definições recursivas.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ru.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ru.xlf
index 21d0c088dd7..85b57d7d25a 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ru.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ru.xlf
@@ -744,7 +744,7 @@
- Изменить содержимое элемента массива можно с помощью оператора присваивания в виде стрелки влево.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- Размеченное объединение также может использоваться для представления ранга игральной карты.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- Как правило, при представлении данных используются как записи, так и размеченные объединения.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- Размеченные объединения также поддерживают рекурсивные определения.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf
index e16ddac1fd6..31a61d248a3 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf
@@ -744,7 +744,7 @@
- Bir dizi öğesinin içeriğini sol ok atama işlecini kullanarak değiştirebilirsiniz.
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- Bir iskambil kartının sırasını göstermek için bir Ayırt Edici Birleşim de kullanılabilir.
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- Verileri temsil ederken Kayıtları ve Ayırt Edici Birleşimleri birlikte kullanmak yaygındır.
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- Ayırt Edici Birleşimler ayrıca özyinelemeli tanımları da destekler.
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf
index 070f72756fa..3520e8975c5 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf
@@ -744,7 +744,7 @@
- 可使用左箭头赋值运算符来修改数组元素的内容。
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- 可区分联合还可用来表示纸牌的设置级别。
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- 表示数据时同时使用记录和可区分联合是很常见的。
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- 可区分联合还支持递归定义。
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf
index 9dc5b4cb19b..ceef6ffcd83 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf
@@ -744,7 +744,7 @@
- 您可以使用向左鍵指派運算子來修改陣列元素的內容。
+ You can modify the contents of an array element by using the left arrow assignment operator.
@@ -1009,7 +1009,7 @@
- 差異聯集也可用以代表一張撲克牌的順位。
+ A Discriminated Union can also be used to represent the rank of a playing card.
@@ -1029,7 +1029,7 @@
- 代表資料時,通常會使用記錄與差異聯集。
+ It's common to use both Records and Discriminated Unions when representing data.
@@ -1089,7 +1089,7 @@
- 差異聯集也支援遞迴定義。
+ Discriminated Unions also support recursive definitions.
diff --git a/vsintegration/src/FSharp.Editor/CodeFixes/RemoveReturnOrYield.fs b/vsintegration/src/FSharp.Editor/CodeFixes/RemoveReturnOrYield.fs
index cbc22219a12..ec376552709 100644
--- a/vsintegration/src/FSharp.Editor/CodeFixes/RemoveReturnOrYield.fs
+++ b/vsintegration/src/FSharp.Editor/CodeFixes/RemoveReturnOrYield.fs
@@ -30,7 +30,11 @@ type internal RemoveReturnOrYieldCodeFixProvider [] () =
parseResults.TryRangeOfExprInYieldOrReturn errorRange.Start
|> ValueOption.ofOption
|> ValueOption.map (fun exprRange -> RoslynHelpers.FSharpRangeToTextSpan(sourceText, exprRange))
- |> ValueOption.map (fun exprSpan -> [ TextChange(context.Span, sourceText.GetSubText(exprSpan).ToString()) ])
+ |> ValueOption.map (fun exprSpan ->
+ [
+ // meaning: keyword + spacing before the expression
+ TextChange(TextSpan(context.Span.Start, exprSpan.Start - context.Span.Start), "")
+ ])
|> ValueOption.map (fun changes ->
let title =
let text = sourceText.GetSubText(context.Span).ToString()
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf
index 918eaa00dd1..03000fae564 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf
@@ -79,7 +79,7 @@
- Soubor {0} se nedá uložit, protože není otevřený v editoru.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf
index 2e55caa77b9..6fad4701b9b 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf
@@ -79,7 +79,7 @@
- {0} kann nicht gespeichert werden, da sie nicht im Editor geöffnet ist.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf
index 653231ad5ac..be43129d5dd 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf
@@ -79,7 +79,7 @@
- No se puede guardar '{0}' mientras no esté abierto en el editor.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf
index e9adf9f0495..d39840bf98d 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf
@@ -79,7 +79,7 @@
- Impossible d'enregistrer '{0}', car il n'est pas ouvert dans l'éditeur.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf
index 898ffd57a94..a670ee0b5eb 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf
@@ -79,7 +79,7 @@
- Non è possibile salvare '{0}' perché non è aperto nell'editor.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf
index 083d889314f..71c72fab37b 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf
@@ -79,7 +79,7 @@
- '{0}' はエディターで開かれていないため、保存できません。
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf
index 55f3e53d51b..fe6c1427f3a 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf
@@ -79,7 +79,7 @@
- '{0}'은(는) 편집기에 열려 있지 않으므로 저장할 수 없습니다.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf
index 18625d46839..c04569fb685 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf
@@ -79,7 +79,7 @@
- Nie można zapisać pliku „{0}”, ponieważ nie jest on otwarty w edytorze.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf
index 9fa73a42708..3675c79cfac 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf
@@ -79,7 +79,7 @@
- Não é possível salvar '{0}' porque não está aberto no editor.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf
index 72a92f4a0da..05086731665 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf
@@ -79,7 +79,7 @@
- Не удается сохранить "{0}": файл не открыт в редакторе.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf
index 54aaf598233..0951ab5fd9c 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf
@@ -79,7 +79,7 @@
- '{0}' düzenleyicide açık olmadığından kaydedilemedi.
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf
index ab86371cb21..43915ea3d1b 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf
@@ -79,7 +79,7 @@
- 无法保存“{0}”,因为它未在编辑器中打开。
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf
index c0d9d60d48c..e1e78242403 100644
--- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf
@@ -79,7 +79,7 @@
- 因為 '{0}' 不是在編輯器中開啟的,所以無法儲存。
+ Cannot save '{0}' as it is not open in the editor.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.cs.xlf
index d21bda7ce61..25314d551e8 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.cs.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.cs.xlf
@@ -159,7 +159,7 @@
- Pro zobrazení operací služby vyberte její kontrakt.
+ Pro zobrazení operací služby vyberte její kontrakt.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.de.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.de.xlf
index 8708f62ecc4..26a027b9373 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.de.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.de.xlf
@@ -159,7 +159,7 @@
- Wählen Sie einen Dienstvertrag aus, um seine Abläufe anzuzeigen.
+ Wählen Sie einen Dienstvertrag aus, um seine Abläufe anzuzeigen.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.es.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.es.xlf
index 38b3575e7b2..f3cc2f9d02f 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.es.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.es.xlf
@@ -159,7 +159,7 @@
- Seleccione un contrato de servicio para ver sus operaciones.
+ Seleccione un contrato de servicio para ver sus operaciones.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.fr.xlf
index 114ba9c1282..45939fa9731 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.fr.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.fr.xlf
@@ -159,7 +159,7 @@
- Sélectionnez un contrat de service pour afficher ses opérations.
+ Sélectionnez un contrat de service pour afficher ses opérations.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.it.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.it.xlf
index 21ad2a8ed21..0c089a12fad 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.it.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.it.xlf
@@ -159,7 +159,7 @@
- Selezionare un contratto di servizio per visualizzarne le operazioni.
+ Selezionare un contratto di servizio per visualizzarne le operazioni.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf
index c9eb3786c4e..a8cf12c61fc 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf
@@ -159,7 +159,7 @@
- サービス コントラクトを選択して操作を表示します。
+ サービス コントラクトを選択して操作を表示します。
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf
index 4034e9c1db5..1e50815dd99 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf
@@ -159,7 +159,7 @@
- 서비스 계약을 선택하여 해당 작업을 확인하세요.
+ 서비스 계약을 선택하여 해당 작업을 확인하세요.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pl.xlf
index 617b27ff745..3bba978e142 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pl.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pl.xlf
@@ -159,7 +159,7 @@
- Wybierz kontrakt usługi, aby wyświetlić jego operacje.
+ Wybierz kontrakt usługi, aby wyświetlić jego operacje.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pt-BR.xlf
index 3192d1ed7d5..a4409c25843 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pt-BR.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pt-BR.xlf
@@ -159,7 +159,7 @@
- Selecione um contrato de serviço para exibir as operações.
+ Selecione um contrato de serviço para exibir as operações.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ru.xlf
index 0452ba7258a..59ca2f46eed 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ru.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ru.xlf
@@ -159,7 +159,7 @@
- Чтобы просмотреть операции службы, выберете контракт службы.
+ Чтобы просмотреть операции службы, выберете контракт службы.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.tr.xlf
index 26d060af8d0..e701e4334aa 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.tr.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.tr.xlf
@@ -159,7 +159,7 @@
- İşlemlerini görüntülemek için bir hizmet sözleşmesi seçin.
+ İşlemlerini görüntülemek için bir hizmet sözleşmesi seçin.
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hans.xlf
index cbdbf10daa2..a0d96560d7e 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hans.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hans.xlf
@@ -159,7 +159,7 @@
- 选择服务协定可查看其操作。
+ 选择服务协定可查看其操作。
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf
index 7c896bf2e6c..bfc580c97b4 100644
--- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf
+++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf
@@ -159,7 +159,7 @@
- 選取要檢視其作業的服務合約。
+ 選取要檢視其作業的服務合約。
This is the message displayed when user selects non-contract nodes.
diff --git a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveReturnOrYieldTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveReturnOrYieldTests.fs
index 23d5908d557..a93bd4f6a3a 100644
--- a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveReturnOrYieldTests.fs
+++ b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveReturnOrYieldTests.fs
@@ -102,3 +102,50 @@ let answer question =
let actual = codeFix |> tryFix code Auto
Assert.Equal(expected, actual)
+
+[]
+let ``Handles spaces`` () =
+ let code =
+ """
+let answer question =
+ yield 42
+"""
+
+ let expected =
+ Some
+ {
+ Message = "Remove 'yield'"
+ FixedCode =
+ """
+let answer question =
+ 42
+"""
+ }
+
+ let actual = codeFix |> tryFix code Auto
+
+ Assert.Equal(expected, actual)
+
+[]
+let ``Handles new lines`` () =
+ let code =
+ """
+let answer question =
+ return!
+ 42
+"""
+
+ let expected =
+ Some
+ {
+ Message = "Remove 'return!'"
+ FixedCode =
+ """
+let answer question =
+ 42
+"""
+ }
+
+ let actual = codeFix |> tryFix code Auto
+
+ Assert.Equal(expected, actual)