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 @@ whitespace relaxation - uvolnění prázdných znaků + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 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 @@ A 'let rec' occurred in the resumable code specification - Ve specifikaci obnovitelného kódu došlo k „let rec“. + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Je třeba inicializovat následující požadované vlastnosti:{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 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 @@ 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). - 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 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 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 @@ An error occurred applying the static arguments to a provided type - 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 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 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 @@ An error occurred applying the static arguments to a provided method - 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 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 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 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 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 @@ whitespace relaxation - Lockerung für Leerraum + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 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 @@ A 'let rec' occurred in the resumable code specification - "Let rec" ist in der fortsetzbaren Codespezifikation aufgetreten. + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Die folgenden erforderlichen Eigenschaften müssen initialisiert werden:{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 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 @@ 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). - 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 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 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 @@ An error occurred applying the static arguments to a provided type - 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}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 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 @@ An error occurred applying the static arguments to a provided method - 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 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 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 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 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 @@ whitespace relaxation - relajación de espacio en blanco + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 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 @@ A 'let rec' occurred in the resumable code specification - 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 @@ The following required properties have to be initialized:{0} - Se deben inicializar las siguientes propiedades necesarias:{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 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 @@ 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). - 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 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 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 @@ An error occurred applying the static arguments to a provided type - 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 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 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 @@ An error occurred applying the static arguments to a provided method - 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 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 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 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 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 @@ whitespace relaxation - assouplissement de la mise en retrait avec des espaces blancs + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 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 @@ A 'let rec' occurred in the resumable code specification - 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 @@ The following required properties have to be initialized:{0} - Les propriétés requises suivantes doivent être initialisées :{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 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 @@ 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). - 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 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 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 @@ An error occurred applying the static arguments to a provided type - 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 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 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 @@ An error occurred applying the static arguments to a provided method - 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 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 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 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 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 @@ whitespace relaxation - uso meno restrittivo degli spazi vuoti + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - Costrutto generico vincolato nella specifica del codice ripristinabile + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - È stata rilevata una funzione 'let rec' nella specifica del codice ripristinabile + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - È necessario inizializzare le proprietà obbligatorie seguenti:{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 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 @@ 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). - 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 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 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 @@ An error occurred applying the static arguments to a provided type - 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 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 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 @@ An error occurred applying the static arguments to a provided method - 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 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 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 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 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 - 空白の緩和 + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 再開可能なコード指定で制約付きジェネリック コンストラクトが発生しました + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - 再開可能なコード仕様で 'let rec' が発生しました + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - 次の必須プロパティを初期化する必要があります:{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 再開可能なコードが無効です。再開可能なコード仕様で 'let rec' が発生しました + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5899,7 +5899,7 @@ 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). - デバッグの種類 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. - サーバーとの通信で問題が発生したため、常駐コンパイル サービスが使用されませんでした。 + 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 - 指定された型に静的引数を適用する際にエラーが発生しました + An error occurred applying the static arguments to a provided type @@ -7419,7 +7419,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - アセンブリ '{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 - 静的な引数を指定されたメソッドに適用する際エラーが発生しました + An error occurred applying the static arguments to a provided method @@ -8134,7 +8134,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - パラメーター '{0}' に適用された CallerMemberNameAttribute は、CallerFilePathAttribute.によってオーバーライドされるため無効となります。 + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8449,7 +8449,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 例外を生成する可能性があるコード ブロックを開始するために使用します。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 - 공백 완화 + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 다시 시작 가능한 코드 사양에서 제약이 있는 제네릭 구문이 발생했습니다. + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - 다시 시작 가능한 코드 사양에서 'let rec'가 발생했습니다. + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - 다음 필수 속성을 초기화해야 합니다. {0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 다시 시작 가능한 코드가 잘못되었습니다. 다시 시작 가능한 코드 사양에서 'let rec'가 발생했습니다. + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5899,7 +5899,7 @@ 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). - 디버깅 형식(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. - 서버와 통신하는 동안 문제가 발생하여 상주 컴파일 서비스를 사용하지 않았습니다. + 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 - 제공된 형식에 정적 인수를 적용하는 동안 오류가 발생했습니다. + An error occurred applying the static arguments to a provided type @@ -7419,7 +7419,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - {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 - 제공된 메서드에 정적 인수를 적용하는 동안 오류가 발생했습니다. + An error occurred applying the static arguments to a provided method @@ -8134,7 +8134,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - {0}' 매개 변수에 적용되는 CallerMemberNameAttribute는 효과가 없습니다. CallerFilePathAttribute에서 재정의합니다. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8449,7 +8449,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 예외를 생성할 수 있는 코드 블록을 지정하는 데 사용됩니다. 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 @@ whitespace relaxation - rozluźnianie reguł dotyczących odstępów + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 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 @@ A 'let rec' occurred in the resumable code specification - 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 @@ The following required properties have to be initialized:{0} - 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 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 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 @@ 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). - 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 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 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 @@ An error occurred applying the static arguments to a provided type - 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 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 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 @@ An error occurred applying the static arguments to a provided method - 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 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 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 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 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 @@ whitespace relaxation - atenuação de espaço em branco + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 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 @@ A 'let rec' occurred in the resumable code specification - 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 @@ The following required properties have to be initialized:{0} - As seguintes propriedades necessárias precisam ser inicializadas:{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 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 @@ 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). - 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 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 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 @@ An error occurred applying the static arguments to a provided type - 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 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 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 @@ An error occurred applying the static arguments to a provided method - 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 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 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 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 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 - уменьшение строгости для пробелов + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - В спецификации возобновляемого кода возникла ограниченная универсальная конструкция + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - В спецификации возобновляемого кода возникла ошибка "let rec" + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Необходимо инициализировать следующие обязательные свойства:{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Недопустимый возобновляемый код. В спецификации возобновляемого кода возникла ошибка "let rec" + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5899,7 +5899,7 @@ 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). - Укажите тип отладки: 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. - Служба резидентной компиляции не использовалась, поскольку возникла проблема при взаимодействии с сервером. + 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 - Ошибка при применении статических аргументов к предоставленному типу + An error occurred applying the static arguments to a provided type @@ -7419,7 +7419,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - У сборки "{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 - Произошла ошибка при применении статических аргументов к предоставленному методу + An error occurred applying the static arguments to a provided method @@ -8134,7 +8134,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - Атрибут CallerMemberNameAttribute, примененный для параметра "{0}", не будет действовать. Он будет переопределен атрибутом CallerFilePathAttribute. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8449,7 +8449,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Используется для введения блока кода, который может создать исключение. Используется вместе с 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 @@ whitespace relaxation - boşluk genişlemesi + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 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 @@ A 'let rec' occurred in the resumable code specification - Sürdürülebilir kod belirtiminde 'let rec' oluştu + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Aşağıdaki gerekli özelliklerin başlatılması gerekiyor:{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 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 @@ 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). - 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 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 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 @@ An error occurred applying the static arguments to a provided type - 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 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - {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 @@ An error occurred applying the static arguments to a provided method - 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 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - {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 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Ö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 - 空格松弛法 + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 可恢复代码规范中发生受约束的泛型构造 + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - 可恢复代码规范中出现 "let rec" + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - 必须初始化以下必需属性: {0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 可恢复代码无效。可恢复代码规范中出现 "let rec" + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5899,7 +5899,7 @@ 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). - 指定调试类型: 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. - 未使用驻留编译服务,因为与服务器通信时发生问题。 + 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 - 将静态参数应用于所提供类型时发生错误 + An error occurred applying the static arguments to a provided type @@ -7419,7 +7419,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 程序集“{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 - 将静态参数应用于提供的方法时发生错误 + An error occurred applying the static arguments to a provided method @@ -8134,7 +8134,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 应用于参数“{0}”的 CallerMemberNameAttribute 不会起作用。它已由 CallerFilePathAttribute 替代。 + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8449,7 +8449,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 用于引入可能产生异常的代码块。与 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 - 空白字元放寬 + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 可繼續的程式碼規格中出現了限制式泛型建構 + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - 可繼續的程式碼規格中發生 'let rec' + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - 下列必要的屬性必須初始化:{0} + The following required properties have to be initialized:{0} @@ -1579,7 +1579,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 可繼續的程式碼無效。可繼續的程式碼規格中發生 'let rec' + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5899,7 +5899,7 @@ 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). - 指定偵錯類型: 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. - 未使用常駐編譯服務,因為伺服器發生通訊問題。 + 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 - 將靜態引數套用至提供的類型時發生錯誤 + An error occurred applying the static arguments to a provided type @@ -7419,7 +7419,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 組件 '{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 - 將靜態引數套用至所提供的方法時,發生錯誤 + An error occurred applying the static arguments to a provided method @@ -8134,7 +8134,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 套用至參數 '{0}' 的 CallerMemberNameAttribute 將不會有作用。CallerFilePathAttribute 會加以覆寫。 + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8449,7 +8449,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 用於引入可能會產生例外狀況的程式碼區塊。這會與 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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - {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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - {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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 名前 '{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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 이름 '{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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - {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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - {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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 无法定义 {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 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 無法定義 {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 + + [] + member this.TextOutput = + if this.CaptureTextOutput then + textOutput.Value |> String.concat Environment.NewLine + else + String.Empty + // --codepage : Specify the codepage to use when opening source files member _.CodePage with get () = codePage diff --git a/src/FSharp.Build/Microsoft.FSharp.NetSdk.props b/src/FSharp.Build/Microsoft.FSharp.NetSdk.props index c4b5228dfd4..71dfca26382 100644 --- a/src/FSharp.Build/Microsoft.FSharp.NetSdk.props +++ b/src/FSharp.Build/Microsoft.FSharp.NetSdk.props @@ -131,6 +131,10 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and true + + CompileFirst + + CompileBefore diff --git a/src/FSharp.Core/xlf/FSCore.cs.xlf b/src/FSharp.Core/xlf/FSCore.cs.xlf index 436ba705358..a122fa694dd 100644 --- a/src/FSharp.Core/xlf/FSCore.cs.xlf +++ b/src/FSharp.Core/xlf/FSCore.cs.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Dynamickému formátovacímu modulu byla předána chybná celočíselná hodnota. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 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 @@ Bad integer supplied to dynamic formatter - Für den dynamischen Formatierer wurde ein ungültiger Integer bereitgestellt. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 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 @@ Bad integer supplied to dynamic formatter - Se proporcionó un entero incorrecto a un formateador dinámico. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 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 @@ Bad integer supplied to dynamic formatter - Entier incorrect fourni au formateur dynamique + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 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 @@ Bad integer supplied to dynamic formatter - Intero non valido fornito al formattatore dinamico + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 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 - 動的フォーマッタに対して指定された整数が正しくありません + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 書式指定子 (精度) が正しくありません + 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 - 동적 포맷터에 제공된 정수가 잘못되었습니다. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 잘못된 형식 지정자(전체 자릿수) + 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 @@ Bad integer supplied to dynamic formatter - Do dynamicznego modułu formatującego została przekazana błędna liczba całkowita. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 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 @@ Bad integer supplied to dynamic formatter - Inteiro incorreto fornecido a formatador dinâmico + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 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 - Динамическому форматтеру передано неверное целое + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Неверный спецификатор формата (точность) + 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 @@ Bad integer supplied to dynamic formatter - Dinamik biçimlendiriciye yanlış tamsayı sağlandı + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 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 - 提供给动态格式化程序的整数错误 + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 错误的格式说明符(精度) + 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 - 提供給動態格式器的整數錯誤 + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 不正確的格式修飾詞 (精確度) + 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 @@ PackageManager cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 cannot reference the System Package '{0}' - 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 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 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 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 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 @@ It's common to use both Records and Discriminated Unions when representing data. - 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 @@ Discriminated Unions also support recursive definitions. - 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 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 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 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 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 @@ It's common to use both Records and Discriminated Unions when representing data. - 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 @@ Discriminated Unions also support recursive definitions. - 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 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 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 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 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 @@ It's common to use both Records and Discriminated Unions when representing data. - 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 @@ Discriminated Unions also support recursive definitions. - 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 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 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 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 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 @@ It's common to use both Records and Discriminated Unions when representing data. - 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 @@ Discriminated Unions also support recursive definitions. - 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 @@ You can modify the contents of an array element by using the left arrow assignment operator. - È 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 @@ A Discriminated Union can also be used to represent the rank of a playing card. - È 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 @@ It's common to use both Records and Discriminated Unions when representing data. - 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 @@ Discriminated Unions also support recursive definitions. - 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. - 左矢印代入演算子を使用して、配列要素の内容を変更できます。 + 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. - 判別共用体はトランプのランクを表すためにも使用できます。 + 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. - データを表すときには、レコードと判別共用体の両方を使用するのが一般的です。 + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - 判別共用体は再帰的な定義もサポートしています。 + 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. - 왼쪽 화살표 대입 연산자를 사용하여 배열 요소의 내용을 수정할 수 있습니다. + 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. - 구분된 공용 구조체를 사용하여 플레잉 카드의 순위를 나타낼 수도 있습니다. + 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. - 일반적으로 레코드와 구분된 공용 구조체를 모두 사용하여 데이터를 나타냅니다. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - 구분된 공용 구조체는 재귀 정의도 지원합니다. + 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 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 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 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 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 @@ It's common to use both Records and Discriminated Unions when representing data. - 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 @@ Discriminated Unions also support recursive definitions. - 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 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 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 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 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 @@ It's common to use both Records and Discriminated Unions when representing data. - É 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 @@ Discriminated Unions also support recursive definitions. - 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. - Изменить содержимое элемента массива можно с помощью оператора присваивания в виде стрелки влево. + 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. - Размеченное объединение также может использоваться для представления ранга игральной карты. + 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. - Как правило, при представлении данных используются как записи, так и размеченные объединения. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Размеченные объединения также поддерживают рекурсивные определения. + 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 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 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 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 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 @@ It's common to use both Records and Discriminated Unions when representing data. - 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 @@ Discriminated Unions also support recursive definitions. - 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. - 可使用左箭头赋值运算符来修改数组元素的内容。 + 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. - 可区分联合还可用来表示纸牌的设置级别。 + 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. - 表示数据时同时使用记录和可区分联合是很常见的。 + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - 可区分联合还支持递归定义。 + 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. - 您可以使用向左鍵指派運算子來修改陣列元素的內容。 + 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. - 差異聯集也可用以代表一張撲克牌的順位。 + 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. - 代表資料時,通常會使用記錄與差異聯集。 + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - 差異聯集也支援遞迴定義。 + 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 @@ Cannot save '{0}' as it is not open in the editor. - 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 @@ Cannot save '{0}' as it is not open in the editor. - {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 @@ Cannot save '{0}' as it is not open in the editor. - 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 @@ Cannot save '{0}' as it is not open in the editor. - 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 @@ Cannot save '{0}' as it is not open in the editor. - 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 @@ Cannot save '{0}' as it is not open in the editor. - '{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 @@ Cannot save '{0}' as it is not open in the editor. - '{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 @@ Cannot save '{0}' as it is not open in the editor. - 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 @@ Cannot save '{0}' as it is not open in the editor. - 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 @@ Cannot save '{0}' as it is not open in the editor. - Не удается сохранить "{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 @@ Cannot save '{0}' as it is not open in the editor. - '{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 @@ Cannot save '{0}' as it is not open in the editor. - 无法保存“{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 @@ Cannot save '{0}' as it is not open in the editor. - 因為 '{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 @@ Select a service contract to view its operations. - 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 @@ Select a service contract to view its operations. - 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 @@ Select a service contract to view its operations. - 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 @@ Select a service contract to view its operations. - 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 @@ Select a service contract to view its operations. - 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 @@ Select a service contract to view its operations. - サービス コントラクトを選択して操作を表示します。 + サービス コントラクトを選択して操作を表示します。 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 @@ Select a service contract to view its operations. - 서비스 계약을 선택하여 해당 작업을 확인하세요. + 서비스 계약을 선택하여 해당 작업을 확인하세요. 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 @@ Select a service contract to view its operations. - 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 @@ Select a service contract to view its operations. - 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 @@ Select a service contract to view its operations. - Чтобы просмотреть операции службы, выберете контракт службы. + Чтобы просмотреть операции службы, выберете контракт службы. 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 @@ Select a service contract to view its operations. - İş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 @@ Select a service contract to view its operations. - 选择服务协定可查看其操作。 + 选择服务协定可查看其操作。 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 @@ Select a service contract to view its operations. - 選取要檢視其作業的服務合約。 + 選取要檢視其作業的服務合約。 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)