From 7b958fdc29a92f11dbeeb1b858d9a4af4a54e10d Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Fri, 24 Jan 2020 21:04:16 +0100 Subject: [PATCH 01/60] add a failing test exhibiting issue #8351 --- tests/FSharp.TestHelpers/TestFramework.fs | 12 +++++++++++- .../fsharp/core/members/set-only-property/cs.cs | 7 +++++++ .../fsharp/core/members/set-only-property/fs.fs | 16 ++++++++++++++++ .../fsharp/core/members/set-only-property/vb.vb | 10 ++++++++++ tests/fsharp/tests.fs | 11 ++++++++++- 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 tests/fsharp/core/members/set-only-property/cs.cs create mode 100644 tests/fsharp/core/members/set-only-property/fs.fs create mode 100644 tests/fsharp/core/members/set-only-property/vb.vb diff --git a/tests/FSharp.TestHelpers/TestFramework.fs b/tests/FSharp.TestHelpers/TestFramework.fs index 63ab601024b..4392998973e 100644 --- a/tests/FSharp.TestHelpers/TestFramework.fs +++ b/tests/FSharp.TestHelpers/TestFramework.fs @@ -96,6 +96,9 @@ module Commands = let csc exec cscExe flags srcFiles = exec cscExe (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " ")) + let vbc exec vbcExe flags srcFiles = + exec vbcExe (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " ")) + let fsi exec fsiExe flags sources = exec fsiExe (sprintf "%s %s" flags (sources |> Seq.ofList |> String.concat " ")) @@ -123,6 +126,8 @@ type TestConfig = { EnvironmentVariables : Map CSC : string csc_flags : string + VBC : string + vbc_flags : string BUILD_CONFIG : string FSC : string fsc_flags : string @@ -183,11 +188,13 @@ let config configurationName envVars = let artifactsBinPath = artifactsPath ++ "bin" let coreClrRuntimePackageVersion = "3.0.0-preview-27318-01" let csc_flags = "/nologo" + let vbc_flags = "/nologo" let fsc_flags = "-r:System.Core.dll --nowarn:20 --define:COMPILED" let fsi_flags = "-r:System.Core.dll --nowarn:20 --define:INTERACTIVE --maxerrors:1 --abortonerror" let Is64BitOperatingSystem = WindowsPlatform.Is64BitOperatingSystem envVars let architectureMoniker = if Is64BitOperatingSystem then "x64" else "x86" let CSC = requireFile (packagesDir ++ "Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "csc.exe") + let VBC = requireFile (packagesDir ++ "Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "vbc.exe") let ILDASM = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.ILDAsm") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "ildasm.exe") let ILASM = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.ILAsm") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "ilasm.exe") let coreclrdll = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.Runtime.CoreCLR") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "coreclr.dll") @@ -223,6 +230,7 @@ let config configurationName envVars = ILDASM = ILDASM ILASM = ILASM PEVERIFY = PEVERIFY + VBC = VBC CSC = CSC BUILD_CONFIG = configurationName FSC = FSC @@ -235,7 +243,8 @@ let config configurationName envVars = FSharpCompilerInteractiveSettings = FSharpCompilerInteractiveSettings csc_flags = csc_flags fsc_flags = fsc_flags - fsi_flags = fsi_flags + fsi_flags = fsi_flags + vbc_flags = vbc_flags Directory="" DotNetExe = dotNetExe DefaultPlatform = defaultPlatform } @@ -462,6 +471,7 @@ let fscBothToOut cfg out arg = Printf.ksprintf (Commands.fsc cfg.Directory (exec let fscBothToOutExpectFail cfg out arg = Printf.ksprintf (Commands.fsc cfg.Directory (execBothToOutExpectFail cfg cfg.Directory out) cfg.DotNetExe cfg.FSC) arg let fscAppendErrExpectFail cfg errPath arg = Printf.ksprintf (Commands.fsc cfg.Directory (execAppendErrExpectFail cfg errPath) cfg.DotNetExe cfg.FSC) arg let csc cfg arg = Printf.ksprintf (Commands.csc (exec cfg) cfg.CSC) arg +let vbc cfg arg = Printf.ksprintf (Commands.vbc (exec cfg) cfg.VBC) arg let ildasm cfg arg = Printf.ksprintf (Commands.ildasm (exec cfg) cfg.ILDASM) arg let ilasm cfg arg = Printf.ksprintf (Commands.ilasm (exec cfg) cfg.ILASM) arg let peverify cfg = Commands.peverify (exec cfg) cfg.PEVERIFY "/nologo" diff --git a/tests/fsharp/core/members/set-only-property/cs.cs b/tests/fsharp/core/members/set-only-property/cs.cs new file mode 100644 index 00000000000..5323a3ffb96 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/cs.cs @@ -0,0 +1,7 @@ +namespace csharp +{ + public class Class + { + public int Prop { set; private get; } + } +} \ No newline at end of file diff --git a/tests/fsharp/core/members/set-only-property/fs.fs b/tests/fsharp/core/members/set-only-property/fs.fs new file mode 100644 index 00000000000..c259737a126 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/fs.fs @@ -0,0 +1,16 @@ +type Class () = + let mutable v = 0 + member x.Prop with set(value) = v <- value + +let a = csharp.Class(Prop=1) +let b = basic.BasicClass(Prop=1) +let c = Class(Prop=1) + +type Maker = + static member mkCs () = csharp.Class() + static member mkVb () = basic.BasicClass() + static member mkFs () = Class() + +let aa = Maker.mkCs(Prop=1) +let bb = Maker.mkVb(Prop=1) +let cc = Maker.mkFs(Prop=1) \ No newline at end of file diff --git a/tests/fsharp/core/members/set-only-property/vb.vb b/tests/fsharp/core/members/set-only-property/vb.vb new file mode 100644 index 00000000000..5985cda5a32 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/vb.vb @@ -0,0 +1,10 @@ +namespace basic + public class BasicClass + dim v as integer + public writeonly property Prop as integer + set(value as integer) + v = value + end set + end property + end class +end namespace \ No newline at end of file diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 19e8c725f48..c04f80ac438 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -288,7 +288,7 @@ module CoreTests = testOkFile.CheckExists() end - + [] let span () = @@ -1813,6 +1813,15 @@ module CoreTests = fsc cfg "%s -o:xmlverify.exe -g" cfg.fsc_flags ["xmlverify.fs"] peverifyWithArgs cfg "/nologo" "xmlverify.exe" + + + [] + let ``property setter in method or constructor`` () = + let cfg = testConfig "core/members/set-only-property" + csc cfg @"%s /target:library /out:cs.dll" cfg.csc_flags ["cs.cs"] + vbc cfg @"%s /target:library /out:vb.dll" cfg.vbc_flags ["vb.vb"] + fsc cfg @"%s -r:cs.dll -r:vb.dll -o:fs.exe" cfg.fsc_flags ["fs.fs"] + #endif module VersionTests = From 827e5b86e1bf851e800aaf00e0c1b517e1884f41 Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Sat, 25 Jan 2020 00:49:57 +0100 Subject: [PATCH 02/60] updating VB and F# code to have private getter as well, VB has same issue as C#. --- tests/fsharp/core/members/set-only-property/fs.fs | 1 + tests/fsharp/core/members/set-only-property/vb.vb | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/fsharp/core/members/set-only-property/fs.fs b/tests/fsharp/core/members/set-only-property/fs.fs index c259737a126..a1ef197b533 100644 --- a/tests/fsharp/core/members/set-only-property/fs.fs +++ b/tests/fsharp/core/members/set-only-property/fs.fs @@ -1,6 +1,7 @@ type Class () = let mutable v = 0 member x.Prop with set(value) = v <- value + and private get () = v let a = csharp.Class(Prop=1) let b = basic.BasicClass(Prop=1) diff --git a/tests/fsharp/core/members/set-only-property/vb.vb b/tests/fsharp/core/members/set-only-property/vb.vb index 5985cda5a32..6cd42330603 100644 --- a/tests/fsharp/core/members/set-only-property/vb.vb +++ b/tests/fsharp/core/members/set-only-property/vb.vb @@ -1,7 +1,10 @@ namespace basic public class BasicClass dim v as integer - public writeonly property Prop as integer + public property Prop as integer + private get + return v + end get set(value as integer) v = value end set From b5e59d5c4fe197d88e932d21fcde447232d9374e Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Sat, 25 Jan 2020 18:14:52 +0100 Subject: [PATCH 03/60] Furthering the test, all languages exhibit the same issue. Added another property that is expected to fail, exhibiting inconsistencies in how the error is reported depending if the type is defined in F# or not. --- .../core/members/set-only-property/calls.bsl | 20 ++++++++++++++++ .../core/members/set-only-property/calls.fsx | 24 +++++++++++++++++++ .../core/members/set-only-property/cs.cs | 5 ++-- .../core/members/set-only-property/fs.fs | 19 ++++----------- .../core/members/set-only-property/vb.vb | 10 +++++++- tests/fsharp/tests.fs | 5 ++-- 6 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 tests/fsharp/core/members/set-only-property/calls.bsl create mode 100644 tests/fsharp/core/members/set-only-property/calls.fsx diff --git a/tests/fsharp/core/members/set-only-property/calls.bsl b/tests/fsharp/core/members/set-only-property/calls.bsl new file mode 100644 index 00000000000..202d99e89be --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/calls.bsl @@ -0,0 +1,20 @@ + +calls.fsx(9,22,9,27): typecheck error FS0495: The object constructor 'Class' has no argument or settable return property 'Prop1'. The required signature is csharp.Class() : csharp.Class. + +calls.fsx(10,26,10,31): typecheck error FS0495: The object constructor 'BasicClass' has no argument or settable return property 'Prop1'. The required signature is basic.BasicClass() : basic.BasicClass. + +calls.fsx(13,21,13,26): typecheck error FS0495: The member or object constructor 'mkCs' has no argument or settable return property 'Prop1'. The required signature is static member Maker.mkCs : unit -> csharp.Class. + +calls.fsx(14,21,14,26): typecheck error FS0495: The member or object constructor 'mkVb' has no argument or settable return property 'Prop1'. The required signature is static member Maker.mkVb : unit -> basic.BasicClass. + +calls.fsx(18,30,18,31): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(19,34,19,35): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(20,24,20,29): typecheck error FS0495: The object constructor 'Class' has no argument or settable return property 'Prop2'. The required signature is new : unit -> fsharp.Class. + +calls.fsx(22,29,22,30): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(23,29,23,30): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(24,23,24,28): typecheck error FS0495: The member or object constructor 'mkFs' has no argument or settable return property 'Prop2'. The required signature is static member Maker.mkFs : unit -> fsharp.Class. diff --git a/tests/fsharp/core/members/set-only-property/calls.fsx b/tests/fsharp/core/members/set-only-property/calls.fsx new file mode 100644 index 00000000000..0d811993ee2 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/calls.fsx @@ -0,0 +1,24 @@ +#r "cs.dll" +#r "vb.dll" +#r "fs.dll" +type Maker = + static member mkCs () = csharp.Class() + static member mkVb () = basic.BasicClass() + static member mkFs () = fsharp.Class() +// so long https://github.com/dotnet/fsharp/issues/8351 isn't fixed, Prop1 setters are failing +let a = csharp.Class(Prop1=1) +let b = basic.BasicClass(Prop1=1) +let c = fsharp.Class(Prop1=1) + +let aa = Maker.mkCs(Prop1=1) +let bb = Maker.mkVb(Prop1=1) +let cc = Maker.mkFs(Prop1=1) + +// those are expected to fail, albeit with inconsistent error messages / marked ranges +let aaa = csharp.Class(Prop2=1) +let bbb = basic.BasicClass(Prop2=1) +let ccc = fsharp.Class(Prop2=1) + +let aaaa = Maker.mkCs(Prop2=1) +let bbbb = Maker.mkVb(Prop2=1) +let cccc = Maker.mkFs(Prop2=1) diff --git a/tests/fsharp/core/members/set-only-property/cs.cs b/tests/fsharp/core/members/set-only-property/cs.cs index 5323a3ffb96..18818edcf45 100644 --- a/tests/fsharp/core/members/set-only-property/cs.cs +++ b/tests/fsharp/core/members/set-only-property/cs.cs @@ -2,6 +2,7 @@ namespace csharp { public class Class { - public int Prop { set; private get; } - } + public int Prop1 { set; private get; } + public int Prop2 { private set; get; } + } } \ No newline at end of file diff --git a/tests/fsharp/core/members/set-only-property/fs.fs b/tests/fsharp/core/members/set-only-property/fs.fs index a1ef197b533..9b05bc67e70 100644 --- a/tests/fsharp/core/members/set-only-property/fs.fs +++ b/tests/fsharp/core/members/set-only-property/fs.fs @@ -1,17 +1,8 @@ +namespace fsharp type Class () = let mutable v = 0 - member x.Prop with set(value) = v <- value - and private get () = v + member x.Prop1 with set(value) = v <- value + and private get () = v -let a = csharp.Class(Prop=1) -let b = basic.BasicClass(Prop=1) -let c = Class(Prop=1) - -type Maker = - static member mkCs () = csharp.Class() - static member mkVb () = basic.BasicClass() - static member mkFs () = Class() - -let aa = Maker.mkCs(Prop=1) -let bb = Maker.mkVb(Prop=1) -let cc = Maker.mkFs(Prop=1) \ No newline at end of file + member x.Prop2 with private set(value) = v <- value + and public get () = v diff --git a/tests/fsharp/core/members/set-only-property/vb.vb b/tests/fsharp/core/members/set-only-property/vb.vb index 6cd42330603..c6a4865c012 100644 --- a/tests/fsharp/core/members/set-only-property/vb.vb +++ b/tests/fsharp/core/members/set-only-property/vb.vb @@ -1,7 +1,7 @@ namespace basic public class BasicClass dim v as integer - public property Prop as integer + public property Prop1 as integer private get return v end get @@ -9,5 +9,13 @@ namespace basic v = value end set end property + public property Prop2 as integer + get + return v + end get + private set(value as integer) + v = value + end set + end property end class end namespace \ No newline at end of file diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index c04f80ac438..0d05effa61c 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -288,7 +288,7 @@ module CoreTests = testOkFile.CheckExists() end - + [] let span () = @@ -1820,7 +1820,8 @@ module CoreTests = let cfg = testConfig "core/members/set-only-property" csc cfg @"%s /target:library /out:cs.dll" cfg.csc_flags ["cs.cs"] vbc cfg @"%s /target:library /out:vb.dll" cfg.vbc_flags ["vb.vb"] - fsc cfg @"%s -r:cs.dll -r:vb.dll -o:fs.exe" cfg.fsc_flags ["fs.fs"] + fsc cfg @"%s /target:library /out:fs.dll" cfg.fsc_flags ["fs.fs"] + singleNegTest cfg "calls" #endif From cccb3da801086ddd02d20ee46f4909adebb1ee8a Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Sat, 25 Jan 2020 18:20:24 +0100 Subject: [PATCH 04/60] F# setter on Prop1 works, despite the getter is internal --- tests/fsharp/core/members/set-only-property/calls.fsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fsharp/core/members/set-only-property/calls.fsx b/tests/fsharp/core/members/set-only-property/calls.fsx index 0d811993ee2..ddd6b365cb3 100644 --- a/tests/fsharp/core/members/set-only-property/calls.fsx +++ b/tests/fsharp/core/members/set-only-property/calls.fsx @@ -8,11 +8,11 @@ type Maker = // so long https://github.com/dotnet/fsharp/issues/8351 isn't fixed, Prop1 setters are failing let a = csharp.Class(Prop1=1) let b = basic.BasicClass(Prop1=1) -let c = fsharp.Class(Prop1=1) +let c = fsharp.Class(Prop1=1) // this one works, inconsistent but correct. let aa = Maker.mkCs(Prop1=1) let bb = Maker.mkVb(Prop1=1) -let cc = Maker.mkFs(Prop1=1) +let cc = Maker.mkFs(Prop1=1) // this one works, inconsistent but correct. // those are expected to fail, albeit with inconsistent error messages / marked ranges let aaa = csharp.Class(Prop2=1) From 598642718dbb8ba398d0bac20aa30cf01cbd5be5 Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Sat, 25 Jan 2020 23:23:20 +0100 Subject: [PATCH 05/60] fix for 8351 (/!\ may break other things) --- src/fsharp/AccessibilityLogic.fs | 22 ++++++++++++------- .../core/members/set-only-property/calls.bsl | 8 ------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/fsharp/AccessibilityLogic.fs b/src/fsharp/AccessibilityLogic.fs index 05325646d11..70569feeba0 100644 --- a/src/fsharp/AccessibilityLogic.fs +++ b/src/fsharp/AccessibilityLogic.fs @@ -249,12 +249,15 @@ let private IsILMethInfoAccessible g amap m adType ad ilminfo = let GetILAccessOfILPropInfo (ILPropInfo(tinfo, pdef)) = let tdef = tinfo.RawMetadata let ilAccess = - match pdef.GetMethod with - | Some mref -> (resolveILMethodRef tdef mref).Access - | None -> - match pdef.SetMethod with - | None -> ILMemberAccess.Public - | Some mref -> (resolveILMethodRef tdef mref).Access + match pdef.GetMethod, pdef.SetMethod with + | Some mref, None + | None, Some mref -> (resolveILMethodRef tdef mref).Access + | Some mrefGet, Some mrefSet -> + let getA = (resolveILMethodRef tdef mrefGet).Access + let setA = (resolveILMethodRef tdef mrefSet).Access + // pick most accessible + max getA setA + | None, None -> ILMemberAccess.Public ilAccess let IsILPropInfoAccessible g amap m ad pinfo = @@ -323,8 +326,11 @@ let IsMethInfoAccessible amap m ad minfo = IsTypeAndMethInfoAccessible amap m ad let IsPropInfoAccessible g amap m ad = function | ILProp ilpinfo -> IsILPropInfoAccessible g amap m ad ilpinfo - | FSProp (_, _, Some vref, _) - | FSProp (_, _, _, Some vref) -> IsValAccessible ad vref + | FSProp (_, _, Some vref, None) + | FSProp (_, _, None, Some vref) -> IsValAccessible ad vref + | FSProp (_, _, Some vrefGet, Some vrefSet) -> + // pick most accessible + IsValAccessible ad vrefGet || IsValAccessible ad vrefSet #if !NO_EXTENSIONTYPING | ProvidedProp (amap, tppi, m) as pp-> let access = diff --git a/tests/fsharp/core/members/set-only-property/calls.bsl b/tests/fsharp/core/members/set-only-property/calls.bsl index 202d99e89be..52a50afe857 100644 --- a/tests/fsharp/core/members/set-only-property/calls.bsl +++ b/tests/fsharp/core/members/set-only-property/calls.bsl @@ -1,12 +1,4 @@ -calls.fsx(9,22,9,27): typecheck error FS0495: The object constructor 'Class' has no argument or settable return property 'Prop1'. The required signature is csharp.Class() : csharp.Class. - -calls.fsx(10,26,10,31): typecheck error FS0495: The object constructor 'BasicClass' has no argument or settable return property 'Prop1'. The required signature is basic.BasicClass() : basic.BasicClass. - -calls.fsx(13,21,13,26): typecheck error FS0495: The member or object constructor 'mkCs' has no argument or settable return property 'Prop1'. The required signature is static member Maker.mkCs : unit -> csharp.Class. - -calls.fsx(14,21,14,26): typecheck error FS0495: The member or object constructor 'mkVb' has no argument or settable return property 'Prop1'. The required signature is static member Maker.mkVb : unit -> basic.BasicClass. - calls.fsx(18,30,18,31): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location calls.fsx(19,34,19,35): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location From b799113435a8905314a5934db808a623ff69f9b7 Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Sun, 26 Jan 2020 00:46:00 +0100 Subject: [PATCH 06/60] reshuffle ILMemberAccess so plain comparison works --- src/absil/il.fs | 4 ++-- src/absil/il.fsi | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/absil/il.fs b/src/absil/il.fs index 791629a9df3..4c3f1ab6783 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -1243,12 +1243,12 @@ type ILMethodBody = [] type ILMemberAccess = - | Assembly | CompilerControlled + | Private | FamilyAndAssembly + | Assembly | FamilyOrAssembly | Family - | Private | Public [] diff --git a/src/absil/il.fsi b/src/absil/il.fsi index efed0413a67..759f197dd04 100644 --- a/src/absil/il.fsi +++ b/src/absil/il.fsi @@ -727,16 +727,17 @@ type ILMethodBody = SourceMarker: ILSourceMarker option } /// Member Access +// important: order of definition matters for AccessibilityLogic.GetILAccessOfILPropInfo [] type ILMemberAccess = - | Assembly | CompilerControlled + | Private | FamilyAndAssembly + | Assembly | FamilyOrAssembly | Family - | Private - | Public - + | Public + [] type ILAttribElem = /// Represents a custom attribute parameter of type 'string'. These may be null, in which case they are encoded in a special From 8f94aff5e0c4a784cecb503876a3e964e765d2ba Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Wed, 10 Jun 2020 01:54:20 -0700 Subject: [PATCH 07/60] testConfig has a new version --- tests/fsharp/tests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 0d05effa61c..3c6318d9fe1 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -1817,7 +1817,7 @@ module CoreTests = [] let ``property setter in method or constructor`` () = - let cfg = testConfig "core/members/set-only-property" + let cfg = testConfig' "core/members/set-only-property" csc cfg @"%s /target:library /out:cs.dll" cfg.csc_flags ["cs.cs"] vbc cfg @"%s /target:library /out:vb.dll" cfg.vbc_flags ["vb.vb"] fsc cfg @"%s /target:library /out:fs.dll" cfg.fsc_flags ["fs.fs"] From 399f0591064abe7e5cba22f7f0b802d7ff751cb2 Mon Sep 17 00:00:00 2001 From: Lukas Rieger Date: Thu, 11 Jun 2020 01:06:09 -0700 Subject: [PATCH 08/60] Allow implementing the same interface at different generic instantiations in the same type --- src/fsharp/FSComp.txt | 2 + src/fsharp/IlxGen.fs | 6 +- src/fsharp/MethodOverrides.fs | 23 +++- src/fsharp/PostInferenceChecks.fs | 123 ++++++++++++++---- src/fsharp/TypeChecker.fs | 7 +- src/fsharp/TypedTreeOps.fs | 41 +++++- src/fsharp/TypedTreeOps.fsi | 8 ++ src/fsharp/xlf/FSComp.txt.cs.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.de.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.es.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.fr.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.it.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.ja.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.ko.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.pl.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.ru.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.tr.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 10 ++ src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 10 ++ .../Compiler/Language/InterfaceTests.fs | 42 ++++++ tests/fsharp/FSharpSuite.Tests.fsproj | 1 + .../CompiledNameAttribute04.il.bsl | 4 +- .../ComputationExpr05.il.bsl | 4 +- .../E_ObjExprWithSameInterface01.fs | 2 +- .../E_ClassConsumeMultipleInterfaceFromCS.fs | 3 +- .../E_ConsumeMultipleInterfaceFromCS.fs | 9 +- .../E_ImplementGenIFaceTwice01.fs | 2 +- .../E_ImplementGenIFaceTwice02.fs | 6 +- .../Inheritance_OverrideInterface.fs | 55 ++++++++ .../InterfaceMember_NameCollisions.fs | 45 +++++++ .../InterfaceTypes/MultipleInst01.fs | 4 +- .../InterfaceTypes/MultipleInst04.fs | 5 +- .../InterfaceTypes/MultipleInst06.fs | 27 ++++ .../InterfaceTypes/MultipleInst07.fs | 20 +++ .../InterfaceTypes/env.lst | 7 +- ...InterfaceWithDifferentGenInstantiations.fs | 4 +- tests/service/ProjectAnalysisTests.fs | 8 +- 38 files changed, 525 insertions(+), 63 deletions(-) create mode 100644 tests/fsharp/Compiler/Language/InterfaceTests.fs create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/InterfaceMember_NameCollisions.fs create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst06.fs create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst07.fs diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 6dcf26f7c22..0f944c81b99 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1513,3 +1513,5 @@ featureAndBang,"applicative computation expressions" featureNullableOptionalInterop,"nullable optional interop" featureDefaultInterfaceMemberConsumption,"default interface member consumption" featureWitnessPassing,"witness passing" +3360,typrelInterfaceWithConcreteAndVariable,"'%s' cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify." +3361,typrelInterfaceWithConcreteAndVariableObjectExpression,"You cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify." \ No newline at end of file diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index f029114e1e2..3ab22eaedf5 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -4298,8 +4298,10 @@ and GenActualSlotsig m cenv eenv (TSlotSig(_, ty, ctps, mtps, ilSlotParams, ilSl and GenNameOfOverridingMethod cenv (useMethodImpl, slotsig) = let (TSlotSig(nameOfOverridenMethod, enclTypOfOverridenMethod, _, _, _, _)) = slotsig - if useMethodImpl then qualifiedMangledNameOfTyconRef (tcrefOfAppTy cenv.g enclTypOfOverridenMethod) nameOfOverridenMethod - else nameOfOverridenMethod + if useMethodImpl then + qualifiedMangledNameOfTyconRef (tcrefOfAppTy cenv.g enclTypOfOverridenMethod) nameOfOverridenMethod + else + nameOfOverridenMethod and GenMethodImpl cenv eenv (useMethodImpl, (TSlotSig(nameOfOverridenMethod, _, _, _, _, _) as slotsig)) m = let ilOverrideTy, ilOverrideParams, ilOverrideRet = GenFormalSlotsig m cenv eenv slotsig diff --git a/src/fsharp/MethodOverrides.fs b/src/fsharp/MethodOverrides.fs index 0826749fd65..d84e89b5611 100644 --- a/src/fsharp/MethodOverrides.fs +++ b/src/fsharp/MethodOverrides.fs @@ -628,18 +628,33 @@ module DispatchSlotChecking = else acc ) (i, reqdTy, m, reduced)) - // Find the full set of most derived interfaces, used roots to search for default interface implementations of interface methods. - let mostSpecificOverrides = GetMostSpecificOverrideInterfaceMethodSets infoReader allReqdTys - // Get the SlotImplSet for each implemented type // This contains the list of required members and the list of available members - [ for (i, reqdTy, reqdTyRange, impliedTys) in reqdTyInfos do + for (_i, reqdTy, reqdTyRange, impliedTys) in reqdTyInfos do // Check that, for each implemented type, at least one implemented type is implied. This is enough to capture // duplicates. if isInterfaceTy g reqdTy && isNil impliedTys then errorR(Error(FSComp.SR.typrelDuplicateInterface(), reqdTyRange)) + // Check that no interface type is implied twice + // + // Note complexity O(reqdTy*reqdTy) + for (i, _reqdTy, reqdTyRange, impliedTys) in reqdTyInfos do + for (j,_,_,impliedTys2) in reqdTyInfos do + if i > j then + let overlap = ListSet.intersect (TypesFeasiblyEquiv 0 g amap reqdTyRange) impliedTys impliedTys2 + for overlappingTy in overlap do + if not (isNil (GetImmediateIntrinsicMethInfosOfType (None,AccessibleFromSomewhere) g amap reqdTyRange overlappingTy |> List.filter (fun minfo -> minfo.IsVirtual))) then + errorR(Error(FSComp.SR.typrelNeedExplicitImplementation(NicePrint.minimalStringOfType denv (List.head overlap)),reqdTyRange)) + + // Find the full set of most derived interfaces, used roots to search for default interface implementations of interface methods. + let mostSpecificOverrides = GetMostSpecificOverrideInterfaceMethodSets infoReader allReqdTys + + // Get the SlotImplSet for each implemented type + // This contains the list of required members and the list of available members + [ for (i,reqdTy,reqdTyRange,impliedTys) in reqdTyInfos do + // Build a set of the implied interface types, for quicker lookup, by nominal type let isImpliedInterfaceTable = impliedTys diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 87d4bcbe4f0..3fe8f5f6975 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -681,23 +681,102 @@ let CheckNoReraise cenv freesOpt (body: Expr) = /// Check if a function is a quotation splice operator let isSpliceOperator g v = valRefEq g v g.splice_expr_vref || valRefEq g v g.splice_raw_expr_vref -/// Check conditions associated with implementing multiple instantiations of a generic interface -let CheckMultipleInterfaceInstantiations cenv interfaces m = - let keyf ty = assert isAppTy cenv.g ty; (tcrefOfAppTy cenv.g ty).Stamp - let table = interfaces |> MultiMap.initBy keyf - let firstInterfaceWithMultipleGenericInstantiations = - interfaces |> List.tryPick (fun typ1 -> - table |> MultiMap.find (keyf typ1) |> List.tryPick (fun typ2 -> - if // same nominal type - tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && - // different instantiations - not (typeEquivAux EraseNone cenv.g typ1 typ2) - then Some (typ1, typ2) - else None)) - match firstInterfaceWithMultipleGenericInstantiations with + +/// Examples: +/// I & I => ExactlyEqual. +/// I & I => NotEqual. +/// I & I<'T> => ``Equal except for TType_var or Measure or Alias``. +/// with '[] type kg': I< int > & I => ``Equal except for TType_var or Measure or Alias``. +/// with 'type MyInt = int': I & I => ``Equal except for TType_var or Measure or Alias``. +/// +/// The differences could also be nested, example: +/// I> vs I> => ``Equal except for TType_var or Measure or Alias``. +type TTypeEquality = +| ExactlyEqual +| ``Equal except for TType_var or Measure or Alias`` +| NotEqual + +let compareTypesWithRegardToTypeVariablesAndMeasures g typ1 typ2 = + + // compare the two types twice + // first pass: only generics are detected, aliases/measures would return 'NotEqual' + // IF the first pass returned 'NotEqual', compare them a second time: + // second pass: all aliases and measures are stripped. + + let rec compare stripMeasuresAndAliases g typ1 typ2 : TTypeEquality = + + let stripAll = (stripTyEqnsWrtErasure EraseAll g) >> stripMeasuresFromTType g + + let typ1 = if stripMeasuresAndAliases then stripAll typ1 else typ1 + let typ2 = if stripMeasuresAndAliases then stripAll typ2 else typ2 + + match typ1, typ2 with + + | TType_var v1, TType_var v2 when v1.Name = v2.Name -> ExactlyEqual + + | TType_var _, _ + | _, TType_var _ -> + ``Equal except for TType_var or Measure or Alias`` + + | TType_app (a1, []), TType_app (a2, []) -> + if tyconRefEq g a1 a2 then ExactlyEqual else NotEqual + + | TType_app (a1, ag1), TType_app (a2, ag2) -> + if not (tyconRefEq g a1 a2) then NotEqual else + if ag1.Length <> ag2.Length then NotEqual else + // outer types and number of parameters are equal - compare each parameter + let results = + (ag1, ag2) ||> Seq.map2 (compare stripMeasuresAndAliases g) |> set + if results = set [ ExactlyEqual ] then + ExactlyEqual + else if results |> Set.contains NotEqual then + NotEqual + else + ``Equal except for TType_var or Measure or Alias`` + + | _ -> if typeEquivAux Erasure.EraseNone g typ1 typ2 then ExactlyEqual else NotEqual + + let preStrip = compare false g typ1 typ2 + match preStrip with + | ExactlyEqual -> ExactlyEqual + | ``Equal except for TType_var or Measure or Alias`` -> ``Equal except for TType_var or Measure or Alias`` + | NotEqual -> + let stripped = compare true g typ1 typ2 + match stripped with + | ExactlyEqual -> ``Equal except for TType_var or Measure or Alias`` + | ``Equal except for TType_var or Measure or Alias`` -> ``Equal except for TType_var or Measure or Alias`` + | NotEqual -> NotEqual + +/// Check conditions associated with implementing multiple instantiations of a interface (either non-generic, or with exactly the same generic parameters) +let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list) isObjectExpression m = + let keyf ty = + assert isAppTy cenv.g ty + (tcrefOfAppTy cenv.g ty).Stamp + let groups = interfaces |> List.groupBy keyf + let errors = seq { + for (_, items) in groups do + for i1 in 0 .. items.Length - 1 do + for i2 in i1 + 1 .. items.Length - 1 do + let typ1 = items.[i1] + let typ2 = items.[i2] + let tcRef1 = tcrefOfAppTy cenv.g typ1 + if tyconRefEq cenv.g tcRef1 (tcrefOfAppTy cenv.g typ2) then + // same nominal type -> check generic args + match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g typ1 typ2 with + | ExactlyEqual -> () // exact duplicates are checked in another place + | ``Equal except for TType_var or Measure or Alias`` -> + let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 + let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 + if isObjectExpression then + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariableObjectExpression(tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + else + let typStr = NicePrint.minimalStringOfType cenv.denv typ + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + | NotEqual -> () + } + match Seq.tryHead errors with | None -> () - | Some (typ1, typ2) -> - errorR(Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations((NicePrint.minimalStringOfType cenv.denv typ1), (NicePrint.minimalStringOfType cenv.denv typ2)), m)) + | Some e -> errorR(e) /// Check an expression, where the expression is in a position where byrefs can be generated let rec CheckExprNoByrefs cenv env expr = @@ -1006,7 +1085,7 @@ and CheckExpr (cenv: cenv) (env: env) origExpr (context: PermitByRefExpr) : Limi yield! AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes ty ] |> List.filter (isInterfaceTy g) - CheckMultipleInterfaceInstantiations cenv interfaces m + CheckMultipleInterfaceInstantiations cenv ty interfaces true m NoLimit // Allow base calls to F# methods @@ -2232,11 +2311,11 @@ let CheckEntityDefn cenv env (tycon: Entity) = if cenv.reportErrors then if not tycon.IsTypeAbbrev then - let immediateInterfaces = GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g cenv.amap m ty - let interfaces = - [ for ty in immediateInterfaces do - yield! AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes ty ] - CheckMultipleInterfaceInstantiations cenv interfaces m + let interfaces = + GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g cenv.amap m ty + |> List.collect (AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes) + |> List.filter (isInterfaceTy g) + CheckMultipleInterfaceInstantiations cenv ty interfaces false m // Check struct fields. We check these late because we have to have first checked that the structs are // free of cycles diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 0cb1515cbfe..bbe4d19b6c6 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -1054,8 +1054,13 @@ let MakeMemberDataAndMangledNameForMemberVal(g, tcref, isExtrinsic, attrs, optIm let text = if memberFlags.MemberKind <> MemberKind.Constructor && memberFlags.MemberKind <> MemberKind.ClassConstructor && not memberFlags.IsInstance then text + ".Static" else text let text = if memberFlags.IsOverrideOrExplicitImpl then text + ".Override" else text text + else if not optIntfSlotTys.IsEmpty then + // interface implementation + if optIntfSlotTys.Length > 1 then + failwithf "unexpected: optIntfSlotTys.Length > 1 (== %i) in MakeMemberDataAndMangledNameForMemberVal for '%s'" optIntfSlotTys.Length logicalName + qualifiedInterfaceImplementationName g optIntfSlotTys.Head logicalName else - List.foldBack (tcrefOfAppTy g >> qualifiedMangledNameOfTyconRef) optIntfSlotTys logicalName + List.foldBack (fun x -> qualifiedMangledNameOfTyconRef (tcrefOfAppTy g x)) optIntfSlotTys logicalName if not isCompGen && IsMangledOpName id.idText && IsInfixOperator id.idText then let m = id.idRange diff --git a/src/fsharp/TypedTreeOps.fs b/src/fsharp/TypedTreeOps.fs index 71792597a69..c2bc49cd954 100644 --- a/src/fsharp/TypedTreeOps.fs +++ b/src/fsharp/TypedTreeOps.fs @@ -878,6 +878,17 @@ let convertToTypeWithMetadataIfPossible g ty = mkAppTy g.fastFunc_tcr [a; b] else ty +//--------------------------------------------------------------------------- +// TType modifications +//--------------------------------------------------------------------------- + +let stripMeasuresFromTType g tt = + match tt with + | TType_app(a,b) -> + let b' = b |> List.filter (isMeasureTy g >> not) + TType_app(a, b') + | _ -> tt + //--------------------------------------------------------------------------- // Equivalence of types up to alpha-equivalence //--------------------------------------------------------------------------- @@ -2904,12 +2915,36 @@ let fullDisplayTextOfValRefAsLayout (vref: ValRef) = pathText ^^ SepL.dot ^^ wordL n //pathText +.+ vref.DisplayName - -let fullMangledPathToTyconRef (tcref: TyconRef) = +let fullMangledPathToTyconRef (tcref:TyconRef) = match tcref with | ERefLocal _ -> (match tcref.PublicPath with None -> [| |] | Some pp -> pp.EnclosingPath) | ERefNonLocal nlr -> nlr.EnclosingMangledPath - + +/// generates a name like 'System.IComparable.Get' +/// for types in the global namespace, `global is prepended (note the backtick) +let qualifiedInterfaceImplementationName g (tt:TType) memberName = + let rec TType_ToCodeLikeString (x:TType) : string = + let TyconRefToFullName (tc:TyconRef) = + let namespaceParts = + // we need to ensure there are no collisions between (for example) + // - ``IB`` (non-generic) + // - IB<'T> instantiated with 'T = GlobalType + // This is only an issue for types inside the global namespace, because '.' is invalid even in a quoted identifier. + // So if the type is in the global namespace, prepend 'global`', because '`' is also illegal -> there can be no quoted identifer with that name. + match fullMangledPathToTyconRef tc with + | [||] -> [| "global`" |] + | ns -> ns + seq { yield! namespaceParts; yield tc.DisplayName } |> String.concat "." + match x with + | TType_app (a,[]) -> TyconRefToFullName a + | TType_app (a,b) -> + let genericParameters = b |> Seq.map (stripTyEqnsAndErase true g >> stripMeasuresFromTType g >> TType_ToCodeLikeString) |> String.concat ", " + sprintf "%s<%s>" (TyconRefToFullName a) genericParameters + | TType_var (v) -> "'" + v.Name + | _ -> failwithf "unexpected: expected TType_app but got %O" (x.GetType()) + let interfaceName = tt |> stripTyEqnsAndErase true g |> stripMeasuresFromTType g |> TType_ToCodeLikeString + sprintf "%s.%s" interfaceName memberName + let qualifiedMangledNameOfTyconRef tcref nm = String.concat "-" (Array.toList (fullMangledPathToTyconRef tcref) @ [ tcref.LogicalName + "-" + nm ]) diff --git a/src/fsharp/TypedTreeOps.fsi b/src/fsharp/TypedTreeOps.fsi index 416d04b520e..e14407d951a 100755 --- a/src/fsharp/TypedTreeOps.fsi +++ b/src/fsharp/TypedTreeOps.fsi @@ -802,6 +802,12 @@ val freeInModuleTy: ModuleOrNamespaceType -> FreeTyvars val isDimensionless : TcGlobals -> TType -> bool +//--------------------------------------------------------------------------- +// TType modifications and comparisons +//--------------------------------------------------------------------------- + +val stripMeasuresFromTType : TcGlobals -> TType -> TType + //------------------------------------------------------------------------- // Equivalence of types (up to substitution of type variables in the left-hand type) //------------------------------------------------------------------------- @@ -1015,6 +1021,8 @@ val ticksAndArgCountTextOfTyconRef : TyconRef -> string /// A unique qualified name for each type definition, used to qualify the names of interface implementation methods val qualifiedMangledNameOfTyconRef : TyconRef -> string -> string +val qualifiedInterfaceImplementationName : TcGlobals -> TType -> string -> string + val trimPathByDisplayEnv : DisplayEnv -> string list -> string val prefixOfStaticReq : TyparStaticReq -> string diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index f7ae174868e..1eca65edee0 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -242,6 +242,16 @@ Typ {0} nedefinuje pole, konstruktor ani člen {1}. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. Není definovaný obor názvů {0}. diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index e086596e7b4..d71a1ddc530 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -242,6 +242,16 @@ Der Typ "{0}" definiert nicht das Feld, den Konstruktor oder den Member "{1}". + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. Der Namespace "{0}" ist nicht definiert. diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 1eb408ff3f1..8d9abbb8d3b 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -242,6 +242,16 @@ El tipo "{0}" no define el campo, constructor o miembro "{1}". + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. El espacio de nombres "{0}" no está definido. diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index 15bc9610834..c259497b594 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -242,6 +242,16 @@ Le type '{0}' ne définit pas le champ, le constructeur ou le membre '{1}'. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. L'espace de noms '{0}' n'est pas défini. diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 41a4e672b8d..69cb8046e5a 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -242,6 +242,16 @@ Il tipo '{0}' non definisce il campo, il costruttore o il membro '{1}'. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. Lo spazio dei nomi '{0}' non è definito. diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 1dd7c03f820..55c211c39f8 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -242,6 +242,16 @@ 型 '{0}' は、フィールド、コンストラクター、またはメンバー '{1}' を定義していません。 + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. 名前空間 '{0}' が定義されていません。 diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index b20e9912bbb..01a87309978 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -242,6 +242,16 @@ '{0}' 형식은 '{1}' 필드, 생성자 또는 멤버를 정의하지 않습니다. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. '{0}' 네임스페이스가 정의되지 않았습니다. diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index c05715de16d..33efa06c927 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -242,6 +242,16 @@ Typ „{0}” nie definiuje pola, konstruktora lub składowej „{1}”. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. Nie zdefiniowano przestrzeni nazw „{0}”. diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index 1e0e527e15f..cc13c3ab323 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -242,6 +242,16 @@ O tipo '{0}' não define o campo, o construtor ou o membro '{1}'. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. O namespace '{0}' não está definido. diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 21cef4e9e7e..502ae25bedf 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -242,6 +242,16 @@ Тип "{0}" не определяет поле, конструктор или член "{1}". + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. Пространство имен "{0}" не определено. diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 136b9f3b8f5..1122b6c3fb3 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -242,6 +242,16 @@ '{0}' türü; alanı, oluşturucuyu veya '{1}' üyesini tanımlamıyor. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. '{0}' ad alanı tanımlı değil. diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 0a1d50ac1bb..5e5693c74da 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -242,6 +242,16 @@ 类型“{0}”未定义字段、构造函数或成员“{1}”。 + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. 未定义命名空间“{0}”。 diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 3da0fb2cca2..5c6083c9d64 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -242,6 +242,16 @@ 類型 '{0}' 未定義欄位、建構函式或成員 '{1}'。 + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The namespace '{0}' is not defined. 未定義命名空間 '{0}'。 diff --git a/tests/fsharp/Compiler/Language/InterfaceTests.fs b/tests/fsharp/Compiler/Language/InterfaceTests.fs new file mode 100644 index 00000000000..e8b3d72b35c --- /dev/null +++ b/tests/fsharp/Compiler/Language/InterfaceTests.fs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open FSharp.Compiler.SourceCodeServices +open NUnit.Framework +open FSharp.TestHelpers + +[] +module InterfaceTests = + + [] + let ShouldWork() = + CompilerAssert.Pass + """ +type IGet<'T> = + abstract member Get : unit -> 'T + +type GetTuple() = + interface IGet with + member x.Get() = 1, 2 + +type GetFunction() = + interface IGetint> with + member x.Get() = fun () -> 1 + +type GetAnonymousRecord() = + interface IGet<{| X : int |}> with + member x.Get() = {| X = 1 |} + +type GetNativePtr() = + interface IGet> with + member x.Get() = failwith "not implemented" + +type TUnion = A | B of int + +type GetUnion() = + interface IGet with + member x.Get() = B 2 + +exit 0 + """ \ No newline at end of file diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index fa8e78dd251..4768af4448b 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -67,6 +67,7 @@ + diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute04.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute04.il.bsl index 6007efcdfb7..71f865a4cfa 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute04.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute04.il.bsl @@ -327,7 +327,7 @@ } // end of method a@49::.ctor .method private hidebysig newslot virtual final - instance int32 'CompiledNameAttribute04-ITestInterface-M'(int32 x) cil managed + instance int32 CompiledNameAttribute04.ITestInterface.M(int32 x) cil managed { .custom instance void [mscorlib]System.Runtime.InteropServices.PreserveSigAttribute::.ctor() = ( 01 00 00 00 ) .override CompiledNameAttribute04/ITestInterface::M @@ -338,7 +338,7 @@ IL_0001: ldc.i4.1 IL_0002: add IL_0003: ret - } // end of method a@49::'CompiledNameAttribute04-ITestInterface-M' + } // end of method a@49::CompiledNameAttribute04.ITestInterface.M } // end of class a@49 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr05.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr05.il.bsl index 8f5858d32b2..02f3be89cbd 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr05.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr05.il.bsl @@ -73,7 +73,7 @@ } // end of method 'res5@9-1'::.ctor .method private hidebysig newslot virtual final - instance void 'System-IDisposable-Dispose'() cil managed + instance void System.IDisposable.Dispose() cil managed { .override [mscorlib]System.IDisposable::Dispose // Code size 1 (0x1) @@ -81,7 +81,7 @@ .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' .line 9,9 : 68,70 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr05.fs' IL_0000: ret - } // end of method 'res5@9-1'::'System-IDisposable-Dispose' + } // end of method 'res5@9-1'::System.IDisposable.Dispose } // end of class 'res5@9-1' diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs index 45f0de9b487..5a4b6b0c7f7 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DataExpressions #ObjectConstructors // This was Dev10:854519 and Dev11:5525. The fix was to make this a compile error to avoid a runtime exception. -//This type implements the same interface at different generic instantiations 'IQueue<'T>' and 'IQueue'\. This is not permitted in this version of F#\.$ +//You cannot implement the interface 'IQueue<_>' with the two instantiations 'IQueue<'T>' and 'IQueue' because they may unify. type IQueue<'a> = abstract Addd: 'a -> IQueue<'a> diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs index ed87e24dbda..4201b76d68e 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs @@ -1,10 +1,9 @@ // #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT -// This type implements the same interface at different generic instantiations 'I_002\' and 'I_002\'\. This is not permitted in this version of F#\. +// It is now allowed to implement the same interface multiple times (RFC FS-1031). #light let mutable res = true -// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type type D() = inherit T() interface I_003 with diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs index ce206ece82f..351fffc6c91 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs @@ -1,6 +1,5 @@ // #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT -// This type implements the same interface at different generic instantiations 'I_002\' and 'I_002\'\. This is not permitted in this version of F#\. -// This type implements the same interface at different generic instantiations 'I_002\' and 'I_002\'\. This is not permitted in this version of F#\. +// It is now allowed to implement the same interface multiple times (RFC FS-1031). #light let mutable res = true @@ -17,7 +16,7 @@ if (t.Home(0) <> 0) then System.Console.WriteLine("t.Home failed") res <- false -// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression implementing a C# interface type +// Check we can implement an interface inheriting from multiple instantiations of an interface when defining an object expression implementing a C# interface type if ( {new I_003 with member xxx.Home(i) = i member xxx.Me(c:char) = 0 @@ -29,7 +28,7 @@ if ( {new I_003 with System.Console.WriteLine("I_003.Home failed") res <- false -// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type +// Check we can implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type if (({new T() with member x.ToString() = "a" interface I_003 with @@ -49,7 +48,7 @@ if T().Home(4) <> 0 then res <- false -// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type +// Check we can implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type type D() = inherit T() interface I_003 with diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs index 10927e41457..87180b9906d 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs @@ -3,7 +3,7 @@ // Verify error when trying to implement the same generic interface twice. // Regression for FSB 3574, PE Verification failure when implementing multiple generic interfaces (one generic, one specifc) -//This type implements the same interface at different generic instantiations 'IA' and 'IA<'b>'\. This is not permitted in this version of F# +//'IB<'b>' cannot implement the interface 'IA<_>' with the two instantiations 'IA' and 'IA<'b>' because they may unify. type IA<'b> = interface diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs index 560cb715586..f81306b0eb1 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs @@ -1,7 +1,5 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// Verify error when trying to implement the same generic -// interface twice -//This type implements the same interface at different generic instantiations 'IFoo' and 'IFoo'\. This is not permitted in this version of F# +// It is now allowed to implement the same interface multiple times (RFC FS-1031). type IFoo<'a> = interface @@ -19,4 +17,4 @@ let t = new Bar() (t :> IFoo).DoStuff() (t :> IFoo).DoStuff() -exit 1 +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs new file mode 100644 index 00000000000..29ee78f8743 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs @@ -0,0 +1,55 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// It should be possible to override interface implementations + + +type MyInt = int +[] type kg + +type IB<'a> = + interface + abstract X : unit -> int + end + +type CBase() = + interface IB with + member x.X() = 1 + interface IB with + member x.X() = 2 + +type C2() = + inherit CBase() + interface IB with + member x.X() = 3 + +type C3() = + inherit C2() + interface IB with + member x.X() = 4 + +type C4() = + inherit C3() + interface IB with + member x.X() = 5 + interface IB with + member x.X() = 6 + interface IB with + member x.X() = 7 + +type C5() = + inherit C4() + interface IB with + member x.X() = 8 + interface IB> with + member x.X() = 9 + interface IB with + member x.X() = 10 + +// see https://github.com/fsharp/fslang-design/issues/185#issuecomment-331737819 +// currently fails to compile +// open question whether "by-design" or bug +//type C6<'T>() = +// inherit C5() +// interface IB<'T> with +// member x.X() = 11 + +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/InterfaceMember_NameCollisions.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/InterfaceMember_NameCollisions.fs new file mode 100644 index 00000000000..ba560d0b300 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/InterfaceMember_NameCollisions.fs @@ -0,0 +1,45 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// There should be no method-name duplication + +// we need to ensure there are no collisions between (for example) +// - ``IB`` (non-generic) +// - IB<'T> instantiated with 'T = GlobalType +// This is only an issue for types inside the global namespace, because '.' is invalid even in a quoted identifier. +// So if the type is in the global namespace, prepend 'global`', because '`' is also illegal -> there can be no quoted identifer with that name. + +// without the prefix, the compiler would error out with +//> output error FS2014: A problem occurred writing the binary 'FsTest.exe': Error in pass2 for type C, error: duplicate entry 'IB.X' in method table + +namespace global + +type GlobalType() = class end + + +type ``IB`` = + interface + abstract X : unit -> int + end + +type IB<'a> = + interface + abstract X : unit -> int + end + +type C() = + interface ``IB`` with + member x.X() = 1 + interface IB with + member x.X() = 2 + +module M = + + let c = C() + let x1 = (c :> ``IB``).X() + let x2 = (c :> IB).X() + + if x1 <> 1 then + failwithf "expected 1, but got %i" x1 + + if x2 <> 2 then + failwithf "expected 2, but got %i" x2 + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs index 057d2da039d..e599cefd5fa 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs @@ -1,7 +1,5 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// Regression test for FSHARP1.0:5540 -// It is forbidden to implement an interface at multiple instantiations -//This type implements the same interface at different generic instantiations 'IA' and 'IA'\. This is not permitted in this version of F#\.$ +// It is now allowed to implement the same interface multiple times (RFC FS-1031). type IA<'a> = interface diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs index f1a2bc33753..2837a78ea59 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs @@ -1,8 +1,5 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// Regression test for FSHARP1.0:5540 -// It is forbidden to implement an interface at multiple instantiations -//This type implements the same interface at different generic instantiations 'IA' and 'IA'\. This is not permitted in this version of F#\.$ - +// It is now allowed to implement the same interface multiple times (RFC FS-1031). type IA<'a, 'b> = interface diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst06.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst06.fs new file mode 100644 index 00000000000..53d943f2c9b --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst06.fs @@ -0,0 +1,27 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// Aliased types should correctly unify + +// These errors could be improved, but verify that it errors out at all. +//Duplicate specification of an interface +//Duplicate or redundant interface +//Duplicate or redundant interface +//No abstract or interface member was found that corresponds to this override +//No abstract or interface member was found that corresponds to this override + + +type MyInt = int + + +type IB<'a> = + interface + abstract X : unit -> int + end + +type C() = + interface IB with + member x.X() = 1 + interface IB with + member x.X() = 2 + +exit 1 + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst07.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst07.fs new file mode 100644 index 00000000000..d89c7763eef --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst07.fs @@ -0,0 +1,20 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// Aliased types should correctly unify, even in combination with a measure. + +//'C' cannot implement the interface 'IB<_>' with the two instantiations 'IB' and 'IB>' because they may unify. + +type MyInt = int +[] type kg + +type IB<'a> = + interface + abstract X : unit -> int + end + +type C() = + interface IB> with + member x.X() = 1 + interface IB with + member x.X() = 2 + +exit 1 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst index 864b76bfbc8..96497eb1643 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst @@ -4,13 +4,18 @@ SOURCE=ObjImplementsInterfaceGenWithConstraint.fs COMPILE_ONLY=1 # ObjImplementsInterfaceGenWithConstraint.fs + SOURCE=InterfaceMember_NameCollisions.fs SCFLAGS=--test:ErrorRanges # InterfaceMember_NameCollisions.fs + SOURCE=MultipleInst01.fs SCFLAGS=--test:ErrorRanges # MultipleInst01.fs SOURCE=MultipleInst02.fs SCFLAGS=--test:ErrorRanges # MultipleInst02.fs SOURCE=MultipleInst03.fs SCFLAGS=--test:ErrorRanges # MultipleInst03.fs SOURCE=MultipleInst04.fs SCFLAGS=--test:ErrorRanges # MultipleInst04.fs SOURCE=MultipleInst05.fs SCFLAGS=--test:ErrorRanges # MultipleInst05.fs + SOURCE=MultipleInst06.fs SCFLAGS=--test:ErrorRanges # MultipleInst06.fs + SOURCE=MultipleInst07.fs SCFLAGS=--test:ErrorRanges # MultipleInst07.fs - SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs + SOURCE=Inheritance_OverrideInterface.fs # Inheritance_OverrideInterface.fs + SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs SOURCE=E_InterfaceNotFullyImpl01.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl01.fs SOURCE=E_InterfaceNotFullyImpl02.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl02.fs SOURCE=E_InterfaceNotFullyImpl03.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl03.fs diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs index b948171d4d1..653b7d19bec 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs @@ -1,13 +1,13 @@ // #Regression #Conformance #UnitsOfMeasure #TypeInference #TypeConstraints // Regression test for FSHARP1.0:4782 // It is illegal to implement or inherit the same interface at different generic instantiations -//This type implements the same interface at different generic instantiations 'IA' and 'IA<'b>'\. This is not permitted in this version of F# +//'IB<'b>' cannot implement the interface 'IA<_>' with the two instantiations 'IA' and 'IA<'b>' because they may unify. [] type kg type IA<[] 'b> = interface - abstract Foo : float <'b> -> int + abstract Foo : float<'b> -> int end type IB<[] 'b> = diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs index 0f26b4f166a..1e6b1c418cc 100644 --- a/tests/service/ProjectAnalysisTests.fs +++ b/tests/service/ProjectAnalysisTests.fs @@ -4862,15 +4862,15 @@ let ``Test project38 abstract slot information`` () = [| ".ctor", [] "Generic", ["type OverrideTests.B<'YY> original generics: <'Y> with member Generic : 'Y -> Microsoft.FSharp.Core.unit"] - "OverrideTests-I`1-Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic : named:'X -> Microsoft.FSharp.Core.unit"] - "OverrideTests-I`1-Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic<'Y> : 'X * 'Y -> Microsoft.FSharp.Core.unit"] + "OverrideTests.I<'XX>.Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic : named:'X -> Microsoft.FSharp.Core.unit"] + "OverrideTests.I<'XX>.Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic<'Y> : 'X * 'Y -> Microsoft.FSharp.Core.unit"] "Method", ["type OverrideTests.B<'YY> original generics: <'Y> with member Method : () -> Microsoft.FSharp.Core.unit"] - "OverrideTests-I`1-Method", ["type OverrideTests.I<'XX> original generics: <'X> with member Method : () -> Microsoft.FSharp.Core.unit"] + "OverrideTests.I<'XX>.Method", ["type OverrideTests.I<'XX> original generics: <'X> with member Method : () -> Microsoft.FSharp.Core.unit"] "NotOverride", [] "add_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member add_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] - "OverrideTests-I`1-get_Property", ["type OverrideTests.I<'XX> original generics: <'X> with member get_Property : () -> Microsoft.FSharp.Core.int"] + "OverrideTests.I<'XX>.get_Property", ["type OverrideTests.I<'XX> original generics: <'X> with member get_Property : () -> Microsoft.FSharp.Core.int"] "remove_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member remove_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] From b5f5f6a4d6c51c10ed6d89d3893066a430b4d304 Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Thu, 11 Jun 2020 19:02:26 -0700 Subject: [PATCH 09/60] adding basic test around ILMemberAccess items being comparable to each other --- tests/fsharp/Compiler/ILMemberAccessTests.fs | 64 ++++++++++++++++++++ tests/fsharp/FSharpSuite.Tests.fsproj | 1 + 2 files changed, 65 insertions(+) create mode 100644 tests/fsharp/Compiler/ILMemberAccessTests.fs diff --git a/tests/fsharp/Compiler/ILMemberAccessTests.fs b/tests/fsharp/Compiler/ILMemberAccessTests.fs new file mode 100644 index 00000000000..b0c25b9d797 --- /dev/null +++ b/tests/fsharp/Compiler/ILMemberAccessTests.fs @@ -0,0 +1,64 @@ +namespace FSharp.Compiler.UnitTests +open FSharp.Reflection +open NUnit.Framework + +[] +module ILMemberAccessTests = + open FSharp.Compiler.AbstractIL.IL + [] + let ``ILMemberAccess exhaustively OK for comparison`` () = + + let allCases = + let allCasesInfos = FSharpType.GetUnionCases (typeof) + allCasesInfos + |> Array.map (fun caseInfo -> + FSharpValue.MakeUnion(caseInfo, [||]) :?> ILMemberAccess + ) + |> Set.ofArray + + let addItem, checkedCases = + let mutable items = Set.empty + (fun item -> items <- Set.add item items) + , (fun () -> items) + + let expectedComparisons = + let rec cummulativeSum n = + match n with + | 0 | 1 -> 1 + | _ -> n + cummulativeSum(n-1) + cummulativeSum (allCases.Count - 1) + + let mutable comparisonsCount = 0 + let compareIsGreater a b = + if a > b then + addItem a + addItem b + comparisonsCount <- comparisonsCount + 1 + else + failwithf "%A > %A didn't hold" a b + + compareIsGreater ILMemberAccess.Public ILMemberAccess.Family + compareIsGreater ILMemberAccess.Public ILMemberAccess.FamilyOrAssembly + compareIsGreater ILMemberAccess.Public ILMemberAccess.Assembly + compareIsGreater ILMemberAccess.Public ILMemberAccess.FamilyAndAssembly + compareIsGreater ILMemberAccess.Public ILMemberAccess.Private + compareIsGreater ILMemberAccess.Public ILMemberAccess.CompilerControlled + compareIsGreater ILMemberAccess.Family ILMemberAccess.FamilyOrAssembly + compareIsGreater ILMemberAccess.Family ILMemberAccess.Assembly + compareIsGreater ILMemberAccess.Family ILMemberAccess.FamilyAndAssembly + compareIsGreater ILMemberAccess.Family ILMemberAccess.Private + compareIsGreater ILMemberAccess.Family ILMemberAccess.CompilerControlled + compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.Assembly + compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.FamilyAndAssembly + compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.Private + compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.CompilerControlled + compareIsGreater ILMemberAccess.Assembly ILMemberAccess.FamilyAndAssembly + compareIsGreater ILMemberAccess.Assembly ILMemberAccess.Private + compareIsGreater ILMemberAccess.Assembly ILMemberAccess.CompilerControlled + compareIsGreater ILMemberAccess.FamilyAndAssembly ILMemberAccess.Private + compareIsGreater ILMemberAccess.FamilyAndAssembly ILMemberAccess.CompilerControlled + compareIsGreater ILMemberAccess.Private ILMemberAccess.CompilerControlled + + let checkedCases = checkedCases () + Assert.IsTrue((checkedCases = allCases), sprintf "all cases weren't checked: %A versus %A" checkedCases allCases) + Assert.AreEqual(expectedComparisons, comparisonsCount) \ No newline at end of file diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index 46cab3c2a27..7e1cce8b67d 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -27,6 +27,7 @@ + From 1ccb4b1443445bb31f55e6426ea2c8c4b016fbae Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Thu, 11 Jun 2020 19:07:12 -0700 Subject: [PATCH 10/60] ceci n'est pas une fonction factorielle --- tests/fsharp/Compiler/ILMemberAccessTests.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/fsharp/Compiler/ILMemberAccessTests.fs b/tests/fsharp/Compiler/ILMemberAccessTests.fs index b0c25b9d797..f5a530bdc41 100644 --- a/tests/fsharp/Compiler/ILMemberAccessTests.fs +++ b/tests/fsharp/Compiler/ILMemberAccessTests.fs @@ -24,7 +24,8 @@ module ILMemberAccessTests = let expectedComparisons = let rec cummulativeSum n = match n with - | 0 | 1 -> 1 + | 0 -> 0 + | 1 -> 1 | _ -> n + cummulativeSum(n-1) cummulativeSum (allCases.Count - 1) From b024d51cabd6786cbc00b39f0478593ef8cf3e85 Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Thu, 11 Jun 2020 19:50:27 -0700 Subject: [PATCH 11/60] codereview: redefine order of ILMemberAccess to match roslyn codebase --- src/absil/il.fs | 8 ++++---- src/absil/il.fsi | 8 ++++---- tests/fsharp/Compiler/ILMemberAccessTests.fs | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/absil/il.fs b/src/absil/il.fs index 4c3f1ab6783..feb1fdd1181 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -1245,10 +1245,10 @@ type ILMethodBody = type ILMemberAccess = | CompilerControlled | Private - | FamilyAndAssembly - | Assembly - | FamilyOrAssembly - | Family + | FamilyAndAssembly // protected and internal + | Family // protected + | Assembly // internal + | FamilyOrAssembly // protected or internal | Public [] diff --git a/src/absil/il.fsi b/src/absil/il.fsi index 759f197dd04..523e8a864e5 100644 --- a/src/absil/il.fsi +++ b/src/absil/il.fsi @@ -732,10 +732,10 @@ type ILMethodBody = type ILMemberAccess = | CompilerControlled | Private - | FamilyAndAssembly - | Assembly - | FamilyOrAssembly - | Family + | FamilyAndAssembly // protected and internal + | Family // protected + | Assembly // internal + | FamilyOrAssembly // protected or internal | Public [] diff --git a/tests/fsharp/Compiler/ILMemberAccessTests.fs b/tests/fsharp/Compiler/ILMemberAccessTests.fs index f5a530bdc41..378794a6d55 100644 --- a/tests/fsharp/Compiler/ILMemberAccessTests.fs +++ b/tests/fsharp/Compiler/ILMemberAccessTests.fs @@ -38,24 +38,24 @@ module ILMemberAccessTests = else failwithf "%A > %A didn't hold" a b - compareIsGreater ILMemberAccess.Public ILMemberAccess.Family compareIsGreater ILMemberAccess.Public ILMemberAccess.FamilyOrAssembly + compareIsGreater ILMemberAccess.Public ILMemberAccess.Family compareIsGreater ILMemberAccess.Public ILMemberAccess.Assembly compareIsGreater ILMemberAccess.Public ILMemberAccess.FamilyAndAssembly compareIsGreater ILMemberAccess.Public ILMemberAccess.Private compareIsGreater ILMemberAccess.Public ILMemberAccess.CompilerControlled - compareIsGreater ILMemberAccess.Family ILMemberAccess.FamilyOrAssembly - compareIsGreater ILMemberAccess.Family ILMemberAccess.Assembly - compareIsGreater ILMemberAccess.Family ILMemberAccess.FamilyAndAssembly - compareIsGreater ILMemberAccess.Family ILMemberAccess.Private - compareIsGreater ILMemberAccess.Family ILMemberAccess.CompilerControlled compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.Assembly + compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.Family compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.FamilyAndAssembly compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.Private compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.CompilerControlled + compareIsGreater ILMemberAccess.Assembly ILMemberAccess.Family compareIsGreater ILMemberAccess.Assembly ILMemberAccess.FamilyAndAssembly compareIsGreater ILMemberAccess.Assembly ILMemberAccess.Private compareIsGreater ILMemberAccess.Assembly ILMemberAccess.CompilerControlled + compareIsGreater ILMemberAccess.Family ILMemberAccess.FamilyAndAssembly + compareIsGreater ILMemberAccess.Family ILMemberAccess.Private + compareIsGreater ILMemberAccess.Family ILMemberAccess.CompilerControlled compareIsGreater ILMemberAccess.FamilyAndAssembly ILMemberAccess.Private compareIsGreater ILMemberAccess.FamilyAndAssembly ILMemberAccess.CompilerControlled compareIsGreater ILMemberAccess.Private ILMemberAccess.CompilerControlled From 790821b310f649994d01b2a398141390a36cc62e Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Fri, 12 Jun 2020 03:12:16 -0700 Subject: [PATCH 12/60] updates --- src/fsharp/FSComp.txt | 3 +- src/fsharp/IlxGen.fs | 2 +- src/fsharp/LanguageFeatures.fs | 3 + src/fsharp/LanguageFeatures.fsi | 1 + src/fsharp/MethodOverrides.fs | 23 +----- src/fsharp/PostInferenceChecks.fs | 55 ++++++++++--- src/fsharp/TypedTreeOps.fs | 3 + src/fsharp/xlf/FSComp.txt.cs.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.de.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.es.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.fr.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.it.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.ja.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.ko.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.pl.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.ru.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.tr.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 5 ++ .../Compiler/Language/InterfaceTests.fs | 81 ++++++++++++++++++- 21 files changed, 201 insertions(+), 35 deletions(-) diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 0f944c81b99..e7c0cdb52cd 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1514,4 +1514,5 @@ featureNullableOptionalInterop,"nullable optional interop" featureDefaultInterfaceMemberConsumption,"default interface member consumption" featureWitnessPassing,"witness passing" 3360,typrelInterfaceWithConcreteAndVariable,"'%s' cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify." -3361,typrelInterfaceWithConcreteAndVariableObjectExpression,"You cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify." \ No newline at end of file +3361,typrelInterfaceWithConcreteAndVariableObjectExpression,"You cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify." +featureInterfacesWithMultipleGenericInstantiation,"interfaces with multiple generic instantiation" \ No newline at end of file diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 3ab22eaedf5..054dcd94a78 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -4299,7 +4299,7 @@ and GenActualSlotsig m cenv eenv (TSlotSig(_, ty, ctps, mtps, ilSlotParams, ilSl and GenNameOfOverridingMethod cenv (useMethodImpl, slotsig) = let (TSlotSig(nameOfOverridenMethod, enclTypOfOverridenMethod, _, _, _, _)) = slotsig if useMethodImpl then - qualifiedMangledNameOfTyconRef (tcrefOfAppTy cenv.g enclTypOfOverridenMethod) nameOfOverridenMethod + qualifiedInterfaceImplementationName cenv.g enclTypOfOverridenMethod nameOfOverridenMethod else nameOfOverridenMethod diff --git a/src/fsharp/LanguageFeatures.fs b/src/fsharp/LanguageFeatures.fs index 83172b8605b..bcc4234264c 100644 --- a/src/fsharp/LanguageFeatures.fs +++ b/src/fsharp/LanguageFeatures.fs @@ -32,6 +32,7 @@ type LanguageFeature = | NullableOptionalInterop | DefaultInterfaceMemberConsumption | WitnessPassing + | InterfacesWithMultipleGenericInstantiation /// LanguageVersion management type LanguageVersion (specifiedVersionAsString) = @@ -69,6 +70,7 @@ type LanguageVersion (specifiedVersionAsString) = LanguageFeature.NullableOptionalInterop, previewVersion LanguageFeature.DefaultInterfaceMemberConsumption, previewVersion LanguageFeature.WitnessPassing, previewVersion + LanguageFeature.InterfacesWithMultipleGenericInstantiation, previewVersion ] let specified = @@ -138,6 +140,7 @@ type LanguageVersion (specifiedVersionAsString) = | LanguageFeature.NullableOptionalInterop -> FSComp.SR.featureNullableOptionalInterop() | LanguageFeature.DefaultInterfaceMemberConsumption -> FSComp.SR.featureDefaultInterfaceMemberConsumption() | LanguageFeature.WitnessPassing -> FSComp.SR.featureWitnessPassing() + | LanguageFeature.InterfacesWithMultipleGenericInstantiation -> FSComp.SR.featureInterfacesWithMultipleGenericInstantiation() /// Get a version string associated with the given feature. member _.GetFeatureVersionString feature = diff --git a/src/fsharp/LanguageFeatures.fsi b/src/fsharp/LanguageFeatures.fsi index 5eb13e885a9..e616a3a9c3e 100644 --- a/src/fsharp/LanguageFeatures.fsi +++ b/src/fsharp/LanguageFeatures.fsi @@ -20,6 +20,7 @@ type LanguageFeature = | NullableOptionalInterop | DefaultInterfaceMemberConsumption | WitnessPassing + | InterfacesWithMultipleGenericInstantiation /// LanguageVersion management type LanguageVersion = diff --git a/src/fsharp/MethodOverrides.fs b/src/fsharp/MethodOverrides.fs index d84e89b5611..0826749fd65 100644 --- a/src/fsharp/MethodOverrides.fs +++ b/src/fsharp/MethodOverrides.fs @@ -628,33 +628,18 @@ module DispatchSlotChecking = else acc ) (i, reqdTy, m, reduced)) + // Find the full set of most derived interfaces, used roots to search for default interface implementations of interface methods. + let mostSpecificOverrides = GetMostSpecificOverrideInterfaceMethodSets infoReader allReqdTys + // Get the SlotImplSet for each implemented type // This contains the list of required members and the list of available members - for (_i, reqdTy, reqdTyRange, impliedTys) in reqdTyInfos do + [ for (i, reqdTy, reqdTyRange, impliedTys) in reqdTyInfos do // Check that, for each implemented type, at least one implemented type is implied. This is enough to capture // duplicates. if isInterfaceTy g reqdTy && isNil impliedTys then errorR(Error(FSComp.SR.typrelDuplicateInterface(), reqdTyRange)) - // Check that no interface type is implied twice - // - // Note complexity O(reqdTy*reqdTy) - for (i, _reqdTy, reqdTyRange, impliedTys) in reqdTyInfos do - for (j,_,_,impliedTys2) in reqdTyInfos do - if i > j then - let overlap = ListSet.intersect (TypesFeasiblyEquiv 0 g amap reqdTyRange) impliedTys impliedTys2 - for overlappingTy in overlap do - if not (isNil (GetImmediateIntrinsicMethInfosOfType (None,AccessibleFromSomewhere) g amap reqdTyRange overlappingTy |> List.filter (fun minfo -> minfo.IsVirtual))) then - errorR(Error(FSComp.SR.typrelNeedExplicitImplementation(NicePrint.minimalStringOfType denv (List.head overlap)),reqdTyRange)) - - // Find the full set of most derived interfaces, used roots to search for default interface implementations of interface methods. - let mostSpecificOverrides = GetMostSpecificOverrideInterfaceMethodSets infoReader allReqdTys - - // Get the SlotImplSet for each implemented type - // This contains the list of required members and the list of available members - [ for (i,reqdTy,reqdTyRange,impliedTys) in reqdTyInfos do - // Build a set of the implied interface types, for quicker lookup, by nominal type let isImpliedInterfaceTable = impliedTys diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 3fe8f5f6975..7aca9fb55e1 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -13,6 +13,7 @@ open FSharp.Compiler.AbstractIL.Internal open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.AccessibilityLogic open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features open FSharp.Compiler.Infos open FSharp.Compiler.InfoReader open FSharp.Compiler.Lib @@ -748,7 +749,27 @@ let compareTypesWithRegardToTypeVariablesAndMeasures g typ1 typ2 = | NotEqual -> NotEqual /// Check conditions associated with implementing multiple instantiations of a interface (either non-generic, or with exactly the same generic parameters) -let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list) isObjectExpression m = + +// Check conditions associated with implementing multiple instantiations of a generic interface +(* +let CheckMultipleInterfaceInstantiations cenv interfaces m = + let keyf ty = assert isAppTy cenv.g ty; (tcrefOfAppTy cenv.g ty).Stamp + let table = interfaces |> MultiMap.initBy keyf + let firstInterfaceWithMultipleGenericInstantiations = + interfaces |> List.tryPick (fun typ1 -> + table |> MultiMap.find (keyf typ1) |> List.tryPick (fun typ2 -> + if // same nominal type + tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && + // different instantiations + not (typeEquivAux EraseNone cenv.g typ1 typ2) + then Some (typ1, typ2) + else None)) + match firstInterfaceWithMultipleGenericInstantiations with + +*) + +let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list) isObjectExpression m = + let langVersion = cenv.g.langVersion let keyf ty = assert isAppTy cenv.g ty (tcrefOfAppTy cenv.g ty).Stamp @@ -761,18 +782,26 @@ let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list let typ2 = items.[i2] let tcRef1 = tcrefOfAppTy cenv.g typ1 if tyconRefEq cenv.g tcRef1 (tcrefOfAppTy cenv.g typ2) then - // same nominal type -> check generic args - match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g typ1 typ2 with - | ExactlyEqual -> () // exact duplicates are checked in another place - | ``Equal except for TType_var or Measure or Alias`` -> - let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 - let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 - if isObjectExpression then - yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariableObjectExpression(tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) - else - let typStr = NicePrint.minimalStringOfType cenv.denv typ - yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) - | NotEqual -> () + if not(langVersion.SupportsFeature LanguageFeature.InterfacesWithMultipleGenericInstantiation) then + if // same nominal type -> not allowed in earlier versions of F# language + tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && + // different instantiations + not (typeEquivAux EraseNone cenv.g typ1 typ2) + then + yield (Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations((NicePrint.minimalStringOfType cenv.denv typ1), (NicePrint.minimalStringOfType cenv.denv typ2)), m)) + else + // same nominal type -> check generic args + match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g typ1 typ2 with + | ExactlyEqual -> () // exact duplicates are checked in another place + | ``Equal except for TType_var or Measure or Alias`` -> + let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 + let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 + if isObjectExpression then + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariableObjectExpression(tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + else + let typStr = NicePrint.minimalStringOfType cenv.denv typ + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + | NotEqual -> () } match Seq.tryHead errors with | None -> () diff --git a/src/fsharp/TypedTreeOps.fs b/src/fsharp/TypedTreeOps.fs index c2bc49cd954..c0afdb11439 100644 --- a/src/fsharp/TypedTreeOps.fs +++ b/src/fsharp/TypedTreeOps.fs @@ -2937,6 +2937,9 @@ let qualifiedInterfaceImplementationName g (tt:TType) memberName = seq { yield! namespaceParts; yield tc.DisplayName } |> String.concat "." match x with | TType_app (a,[]) -> TyconRefToFullName a + | TType_anon (a,b) -> + let genericParameters = b |> Seq.map (stripTyEqnsAndErase true g >> stripMeasuresFromTType g >> TType_ToCodeLikeString) |> String.concat ", " + sprintf "%s<%s>" (a.ILTypeRef.FullName) genericParameters | TType_app (a,b) -> let genericParameters = b |> Seq.map (stripTyEqnsAndErase true g >> stripMeasuresFromTType g >> TType_ToCodeLikeString) |> String.concat ", " sprintf "%s<%s>" (TyconRefToFullName a) genericParameters diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 1eca65edee0..476b03476ef 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index d71a1ddc530..e3632d2b916 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 8d9abbb8d3b..1cbe9afc421 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index c259497b594..9519ef3d5e3 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 69cb8046e5a..1f2b602ac2d 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 55c211c39f8..5c328eccea2 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index 01a87309978..cb11bcb15c9 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index 33efa06c927..04f45fe290c 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index cc13c3ab323..032ff6ccc90 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 502ae25bedf..8e32921814c 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 1122b6c3fb3..18be2d7c497 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 5e5693c74da..4159ba2aa5a 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 5c6083c9d64..f83afb6c205 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof diff --git a/tests/fsharp/Compiler/Language/InterfaceTests.fs b/tests/fsharp/Compiler/Language/InterfaceTests.fs index e8b3d72b35c..db75917dfc9 100644 --- a/tests/fsharp/Compiler/Language/InterfaceTests.fs +++ b/tests/fsharp/Compiler/Language/InterfaceTests.fs @@ -39,4 +39,83 @@ type GetUnion() = member x.Get() = B 2 exit 0 - """ \ No newline at end of file + """ + + + let multiTypedInterfaceSource = """ +open System +type AnEnum = + | One + | Two + +type AClass = + val value: int + + new(value) = { value = value } + +type IInterface<'a> = + abstract GetIt: 'a -> 'a + +type implementation () = + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x + +let x = implementation () +let assertion v assertIt = + if not (assertIt(v)) then + raise (new Exception (sprintf "Failed to retrieve %A from implementation" v)) + +// Ensure we can invoke the method and get the value back for each native F# type + +assertion true (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 1uy (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 2y (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 3s (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 4us (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 5l (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 6ul (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 7n (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 8un (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 9L (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 10UL (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 12.12 (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 13I (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 14M (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 'A' (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 'a'B (fun v -> (x :> IInterface).GetIt(v) = v) +assertion "16"B (fun v -> (x :> IInterface).GetIt(v) = v) +assertion AnEnum.Two (fun v -> (x :> IInterface).GetIt(v) = v) +""" + + [] + let MultipleTypedInterfacesFSharp50() = + CompilerAssert.PassWithOptions + [| "--langversion:preview" |] + multiTypedInterfaceSource + + [] + let MultipleTypedInterfacesFSharp47() = + CompilerAssert.TypeCheckWithErrorsAndOptions + [| "--langversion:4.7" |] + multiTypedInterfaceSource + [| + (FSharpErrorSeverity.Error, 443, (15,6,15,20), "This type implements the same interface at different generic instantiations 'IInterface' and 'IInterface'. This is not permitted in this version of F#.") + |] + From 7e19f476c1c67d2482b689423604fbe7248c3b4f Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Fri, 12 Jun 2020 16:27:32 -0700 Subject: [PATCH 13/60] Feedback + fsharpqa --- src/fsharp/PostInferenceChecks.fs | 8 ++++---- src/fsharp/fscmain.fs | 6 +++++- .../ObjectExpressions/E_ObjExprWithSameInterface01.fs | 2 +- .../DataExpressions/ObjectExpressions/env.lst | 2 +- .../E_ClassConsumeMultipleInterfaceFromCS.fs | 3 ++- .../InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs | 9 +++++---- .../InterfaceTypes/E_ImplementGenIFaceTwice01.fs | 2 +- .../InterfaceTypes/E_ImplementGenIFaceTwice02.fs | 6 ++++-- .../InterfaceTypes/MultipleInst01.fs | 4 +++- .../InterfaceTypes/MultipleInst04.fs | 5 ++++- .../ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst | 6 +++--- .../E_GenInterfaceWithDifferentGenInstantiations.fs | 2 +- .../Conformance/UnitsOfMeasure/TypeChecker/env.lst | 2 +- 13 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 7aca9fb55e1..9abb52150e6 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -783,12 +783,12 @@ let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list let tcRef1 = tcrefOfAppTy cenv.g typ1 if tyconRefEq cenv.g tcRef1 (tcrefOfAppTy cenv.g typ2) then if not(langVersion.SupportsFeature LanguageFeature.InterfacesWithMultipleGenericInstantiation) then - if // same nominal type -> not allowed in earlier versions of F# language + // same nominal type -> not allowed in earlier versions of F# language + let hasMultipleGenericInterfaceInstantiations = tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && - // different instantiations not (typeEquivAux EraseNone cenv.g typ1 typ2) - then - yield (Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations((NicePrint.minimalStringOfType cenv.denv typ1), (NicePrint.minimalStringOfType cenv.denv typ2)), m)) + if hasMultipleGenericInterfaceInstantiations then + yield (Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations((NicePrint.minimalStringOfType cenv.denv typ1), (NicePrint.minimalStringOfType cenv.denv typ2)), m)) else // same nominal type -> check generic args match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g typ1 typ2 with diff --git a/src/fsharp/fscmain.fs b/src/fsharp/fscmain.fs index f4c6b87c283..7d27423747b 100644 --- a/src/fsharp/fscmain.fs +++ b/src/fsharp/fscmain.fs @@ -13,14 +13,18 @@ open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.ILBinaryReader open FSharp.Compiler.ErrorLogger + open FSharp.Compiler.Driver open FSharp.Compiler.Lib + open FSharp.Compiler.Range open FSharp.Compiler.CompileOps open FSharp.Compiler.AbstractIL.Internal.Library open Internal.Utilities -[] +[< + Dependency("FSharp.Compiler.Private",LoadHint.Always) +>] do () diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs index 5a4b6b0c7f7..45f0de9b487 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DataExpressions #ObjectConstructors // This was Dev10:854519 and Dev11:5525. The fix was to make this a compile error to avoid a runtime exception. -//You cannot implement the interface 'IQueue<_>' with the two instantiations 'IQueue<'T>' and 'IQueue' because they may unify. +//This type implements the same interface at different generic instantiations 'IQueue<'T>' and 'IQueue'\. This is not permitted in this version of F#\.$ type IQueue<'a> = abstract Addd: 'a -> IQueue<'a> diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst index 3d53d8a24bf..5b5ecc0f1bf 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst @@ -17,5 +17,5 @@ SOURCE=ObjExprWithOverride01.fs # ObjExprWithOverride01.fs SOURCE=E_ObjExprWithOverride01.fs SCFLAGS="-r:Helper.dll --test:ErrorRanges" PRECMD="\$CSC_PIPE /t:library Helper.cs" # E_ObjExprWithOverride01.fs SOURCE=InterfaceObjectExpression01.fs # InterfaceObjectExpression01.fs - SOURCE=E_ObjExprWithSameInterface01.fs SCFLAGS="--test:ErrorRanges" # E_ObjExprWithSameInterface01.fs + SOURCE=E_ObjExprWithSameInterface01.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_ObjExprWithSameInterface01.fs SOURCE=MultipleInterfacesInObjExpr.fs # MultipleInterfacesInObjExpr.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs index 4201b76d68e..ed87e24dbda 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs @@ -1,9 +1,10 @@ // #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT -// It is now allowed to implement the same interface multiple times (RFC FS-1031). +// This type implements the same interface at different generic instantiations 'I_002\' and 'I_002\'\. This is not permitted in this version of F#\. #light let mutable res = true +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type type D() = inherit T() interface I_003 with diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs index 351fffc6c91..ce206ece82f 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs @@ -1,5 +1,6 @@ // #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT -// It is now allowed to implement the same interface multiple times (RFC FS-1031). +// This type implements the same interface at different generic instantiations 'I_002\' and 'I_002\'\. This is not permitted in this version of F#\. +// This type implements the same interface at different generic instantiations 'I_002\' and 'I_002\'\. This is not permitted in this version of F#\. #light let mutable res = true @@ -16,7 +17,7 @@ if (t.Home(0) <> 0) then System.Console.WriteLine("t.Home failed") res <- false -// Check we can implement an interface inheriting from multiple instantiations of an interface when defining an object expression implementing a C# interface type +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression implementing a C# interface type if ( {new I_003 with member xxx.Home(i) = i member xxx.Me(c:char) = 0 @@ -28,7 +29,7 @@ if ( {new I_003 with System.Console.WriteLine("I_003.Home failed") res <- false -// Check we can implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type if (({new T() with member x.ToString() = "a" interface I_003 with @@ -48,7 +49,7 @@ if T().Home(4) <> 0 then res <- false -// Check we can implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type type D() = inherit T() interface I_003 with diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs index 87180b9906d..10927e41457 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs @@ -3,7 +3,7 @@ // Verify error when trying to implement the same generic interface twice. // Regression for FSB 3574, PE Verification failure when implementing multiple generic interfaces (one generic, one specifc) -//'IB<'b>' cannot implement the interface 'IA<_>' with the two instantiations 'IA' and 'IA<'b>' because they may unify. +//This type implements the same interface at different generic instantiations 'IA' and 'IA<'b>'\. This is not permitted in this version of F# type IA<'b> = interface diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs index f81306b0eb1..560cb715586 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs @@ -1,5 +1,7 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// It is now allowed to implement the same interface multiple times (RFC FS-1031). +// Verify error when trying to implement the same generic +// interface twice +//This type implements the same interface at different generic instantiations 'IFoo' and 'IFoo'\. This is not permitted in this version of F# type IFoo<'a> = interface @@ -17,4 +19,4 @@ let t = new Bar() (t :> IFoo).DoStuff() (t :> IFoo).DoStuff() -exit 0 +exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs index e599cefd5fa..057d2da039d 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs @@ -1,5 +1,7 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// It is now allowed to implement the same interface multiple times (RFC FS-1031). +// Regression test for FSHARP1.0:5540 +// It is forbidden to implement an interface at multiple instantiations +//This type implements the same interface at different generic instantiations 'IA' and 'IA'\. This is not permitted in this version of F#\.$ type IA<'a> = interface diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs index 2837a78ea59..f1a2bc33753 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs @@ -1,5 +1,8 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// It is now allowed to implement the same interface multiple times (RFC FS-1031). +// Regression test for FSHARP1.0:5540 +// It is forbidden to implement an interface at multiple instantiations +//This type implements the same interface at different generic instantiations 'IA' and 'IA'\. This is not permitted in this version of F#\.$ + type IA<'a, 'b> = interface diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst index 96497eb1643..34fa7745323 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst @@ -6,13 +6,13 @@ SOURCE=InterfaceMember_NameCollisions.fs SCFLAGS=--test:ErrorRanges # InterfaceMember_NameCollisions.fs - SOURCE=MultipleInst01.fs SCFLAGS=--test:ErrorRanges # MultipleInst01.fs + SOURCE=MultipleInst01.fs SCFLAGS=--test:ErrorRanges --langversion:4.7 # MultipleInst01.fs SOURCE=MultipleInst02.fs SCFLAGS=--test:ErrorRanges # MultipleInst02.fs SOURCE=MultipleInst03.fs SCFLAGS=--test:ErrorRanges # MultipleInst03.fs - SOURCE=MultipleInst04.fs SCFLAGS=--test:ErrorRanges # MultipleInst04.fs + SOURCE=MultipleInst04.fs SCFLAGS=--test:ErrorRanges --langversion:4.7 # MultipleInst04.fs SOURCE=MultipleInst05.fs SCFLAGS=--test:ErrorRanges # MultipleInst05.fs SOURCE=MultipleInst06.fs SCFLAGS=--test:ErrorRanges # MultipleInst06.fs - SOURCE=MultipleInst07.fs SCFLAGS=--test:ErrorRanges # MultipleInst07.fs + SOURCE=MultipleInst07.fs SCFLAGS=--test:ErrorRanges --langversion:preview # MultipleInst07.fs SOURCE=Inheritance_OverrideInterface.fs # Inheritance_OverrideInterface.fs SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs index 653b7d19bec..485d8a2f5e9 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #UnitsOfMeasure #TypeInference #TypeConstraints // Regression test for FSHARP1.0:4782 // It is illegal to implement or inherit the same interface at different generic instantiations -//'IB<'b>' cannot implement the interface 'IA<_>' with the two instantiations 'IA' and 'IA<'b>' because they may unify. +//'IB<'b>' cannot implement the interface 'IA<_>' with the two instantiations 'IA' and 'IA<'b>' because they may unify. [] type kg diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/env.lst b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/env.lst index d93fddc74b6..0927b9895fb 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/env.lst +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/env.lst @@ -5,7 +5,7 @@ SOURCE=Generalization01.fs SCFLAGS=--warnaserror # Generalization01.fs - SOURCE=E_GenInterfaceWithDifferentGenInstantiations.fs SCFLAGS="--test:ErrorRanges" # E_GenInterfaceWithDifferentGenInstantiations.fs + SOURCE=E_GenInterfaceWithDifferentGenInstantiations.fs SCFLAGS="--test:ErrorRanges --langversion:preview" # E_GenInterfaceWithDifferentGenInstantiations.fs SOURCE=TypeAbbreviation_decimal_01.fs # TypeAbbreviation_decimal_01.fs SOURCE=TypeAbbreviation_float32_01.fs # TypeAbbreviation_float32_01.fs From c18eae1643ae1e89fe2367b4e8fcdd74e4773b54 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Fri, 12 Jun 2020 19:40:01 -0700 Subject: [PATCH 14/60] feedback --- src/fsharp/PostInferenceChecks.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 9abb52150e6..93b05ab7088 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -693,9 +693,9 @@ let isSpliceOperator g v = valRefEq g v g.splice_expr_vref || valRefEq g v g.spl /// The differences could also be nested, example: /// I> vs I> => ``Equal except for TType_var or Measure or Alias``. type TTypeEquality = -| ExactlyEqual -| ``Equal except for TType_var or Measure or Alias`` -| NotEqual + | ExactlyEqual + | ``Equal except for TType_var or Measure or Alias`` + | NotEqual let compareTypesWithRegardToTypeVariablesAndMeasures g typ1 typ2 = From b88ba3c973dda57061708b97bd25894a9b96f662 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Mon, 15 Jun 2020 02:06:31 -0700 Subject: [PATCH 15/60] Update for fix8351 --- src/absil/il.fs | 8 +- src/absil/il.fsi | 15 +- src/fsharp/AccessibilityLogic.fs | 24 +- .../Properties/ILMemberAccessTests.fs | 214 ++++++++++++++++++ tests/fsharp/Compiler/ILMemberAccessTests.fs | 65 ------ tests/fsharp/FSharpSuite.Tests.fsproj | 2 +- 6 files changed, 248 insertions(+), 80 deletions(-) create mode 100644 tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs delete mode 100644 tests/fsharp/Compiler/ILMemberAccessTests.fs diff --git a/src/absil/il.fs b/src/absil/il.fs index feb1fdd1181..791629a9df3 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -1243,12 +1243,12 @@ type ILMethodBody = [] type ILMemberAccess = + | Assembly | CompilerControlled + | FamilyAndAssembly + | FamilyOrAssembly + | Family | Private - | FamilyAndAssembly // protected and internal - | Family // protected - | Assembly // internal - | FamilyOrAssembly // protected or internal | Public [] diff --git a/src/absil/il.fsi b/src/absil/il.fsi index 523e8a864e5..efed0413a67 100644 --- a/src/absil/il.fsi +++ b/src/absil/il.fsi @@ -727,17 +727,16 @@ type ILMethodBody = SourceMarker: ILSourceMarker option } /// Member Access -// important: order of definition matters for AccessibilityLogic.GetILAccessOfILPropInfo [] type ILMemberAccess = + | Assembly | CompilerControlled - | Private - | FamilyAndAssembly // protected and internal - | Family // protected - | Assembly // internal - | FamilyOrAssembly // protected or internal - | Public - + | FamilyAndAssembly + | FamilyOrAssembly + | Family + | Private + | Public + [] type ILAttribElem = /// Represents a custom attribute parameter of type 'string'. These may be null, in which case they are encoded in a special diff --git a/src/fsharp/AccessibilityLogic.fs b/src/fsharp/AccessibilityLogic.fs index 70569feeba0..ae9cbea64fe 100644 --- a/src/fsharp/AccessibilityLogic.fs +++ b/src/fsharp/AccessibilityLogic.fs @@ -252,12 +252,32 @@ let GetILAccessOfILPropInfo (ILPropInfo(tinfo, pdef)) = match pdef.GetMethod, pdef.SetMethod with | Some mref, None | None, Some mref -> (resolveILMethodRef tdef mref).Access + | Some mrefGet, Some mrefSet -> let getA = (resolveILMethodRef tdef mrefGet).Access let setA = (resolveILMethodRef tdef mrefSet).Access - // pick most accessible - max getA setA + + // use the accessors to determine the visibility of the property + match getA, setA with + | ILMemberAccess.Public, _ + | _, ILMemberAccess.Public -> ILMemberAccess.Public + + | ILMemberAccess.FamilyOrAssembly, _ + | _, ILMemberAccess.FamilyOrAssembly -> ILMemberAccess.FamilyOrAssembly + + | ILMemberAccess.Assembly, _ + | _, ILMemberAccess.Assembly -> ILMemberAccess.Assembly + + | ILMemberAccess.Family, _ + | _, ILMemberAccess.Family -> ILMemberAccess.Family + + | ILMemberAccess.FamilyAndAssembly, _ + | _, ILMemberAccess.FamilyAndAssembly -> ILMemberAccess.FamilyAndAssembly + + | _ -> ILMemberAccess.Private + | None, None -> ILMemberAccess.Public + ilAccess let IsILPropInfoAccessible g amap m ad pinfo = diff --git a/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs b/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs new file mode 100644 index 00000000000..44e92e4724d --- /dev/null +++ b/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs @@ -0,0 +1,214 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open FSharp.Compiler.SourceCodeServices +open FSharp.Reflection +open FSharp.TestHelpers +open FSharp.TestHelpers.Utilities +open NUnit.Framework + +[] +module ILMemberAccessTests = + + let csharpBaseClass = """ +namespace ExhaustiveCombinations +{ + public class CSharpBaseClass + { + public string GetPublicSetInternal { get; internal set; } + public string GetPublicSetProtected { get; protected set; } + public string GetPublicSetPrivateProtected { get; private protected set; } + public string GetPublicSetProtectedInternal { get; protected internal set; } + public string GetPublicSetPrivate { get; private set; } + + public string SetPublicGetInternal { internal get; set; } + public string SetPublicGetProtected { protected get; set; } + public string SetPublicGetPrivateProtected { private protected get; set; } + public string SetPublicGetProtectedInternal { protected internal get; set; } + public string SetPublicGetPrivate { private get; set; } + } +} +""" + + let fsharpBaseClass = """ +namespace ExhaustiveCombinations + +open System + +type FSharpBaseClass () = + + member this.GetPublicSetInternal with public get() = "" and internal set (parameter:string) = ignore parameter + member this.GetPublicSetPrivate with public get() = "" and private set (parameter:string) = ignore parameter + member this.SetPublicGetInternal with internal get() = "" and public set (parameter:string) = ignore parameter + member this.SetPublicGetPrivate with private get() = "" and public set (parameter:string) = ignore parameter + +""" + + + [] + let ``VerifyVisibility of Properties C# class F# derived class -- AccessPublicStuff`` () = + + let fsharpSource = + fsharpBaseClass + """ +open System +open ExhaustiveCombinations + +type MyFSharpClass () = + inherit CSharpBaseClass() + + member this.AccessPublicStuff() = + + this.GetPublicSetInternal <- "1" // Inaccessible + let _ = this.GetPublicSetInternal // Accessible + + this.GetPublicSetPrivateProtected <- "1" // Accessible + let _ = this.GetPublicSetPrivateProtected // Accessible + + this.GetPublicSetProtectedInternal <- "1" // Accessible + let _ = this.GetPublicSetProtectedInternal // Accessible + + this.GetPublicSetProtected <- "1" // Accessible + let _ = this.GetPublicSetProtected // Accessible + + this.GetPublicSetPrivate <- "1" // Inaccessible + let _ = this.GetPublicSetPrivate // Accessible + () +""" + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpBaseClass, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpErrorSeverity.Error, 491, (22, 9, 22, 41), + "The member or object constructor 'GetPublicSetInternal' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions."); + (FSharpErrorSeverity.Error, 491, (25, 9, 25, 49), + "The member or object constructor 'GetPublicSetPrivateProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions."); + (FSharpErrorSeverity.Error, 491, (34, 9, 34, 40), + "The member or object constructor 'GetPublicSetPrivate' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.")|]) + + [] + let ``VerifyVisibility of Properties C# class F# non-derived class -- AccessPublicStuff`` () = + + let fsharpSource = + fsharpBaseClass + """ +open System +open ExhaustiveCombinations + +type MyFSharpClass () = + + member _.AccessPublicStuff() = + let bc = new CSharpBaseClass() + + bc.GetPublicSetInternal <- "1" // Inaccessible + let _ = bc.GetPublicSetInternal // Accessible + + bc.GetPublicSetPrivateProtected <- "1" // Inaccessible + let _ = bc.GetPublicSetPrivateProtected // Accessible + + bc.GetPublicSetProtectedInternal <- "1" // Accessible + let _ = bc.GetPublicSetProtectedInternal // Inaccessible + + bc.GetPublicSetProtected <- "1" // Inaccessible + let _ = bc.SetPublicGetProtected // Accessible + + bc.GetPublicSetPrivate <- "1" // Inaccessible + let _ = bc.GetPublicSetPrivate // Accessible + () +""" + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpBaseClass, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpErrorSeverity.Error, 491, (22, 9, 22, 39), + "The member or object constructor 'GetPublicSetInternal' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions."); + (FSharpErrorSeverity.Error, 491, (25, 9, 25, 47), + "The member or object constructor 'GetPublicSetPrivateProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions."); + (FSharpErrorSeverity.Error, 491, (28, 9, 28, 48), + "The member or object constructor 'GetPublicSetProtectedInternal' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions."); + (FSharpErrorSeverity.Error, 491, (31, 9, 31, 40), + "The member or object constructor 'GetPublicSetProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions."); + (FSharpErrorSeverity.Error, 491, (32, 17, 32, 41), + "The member or object constructor 'SetPublicGetProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions."); + (FSharpErrorSeverity.Error, 491, (34, 9, 34, 38), + "The member or object constructor 'GetPublicSetPrivate' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.")|]) + + + [] + let ``VerifyVisibility of Properties F# base F# derived class -- AccessPublicStuff`` () = + + let fsharpSource = + fsharpBaseClass + """ +open System +open ExhaustiveCombinations + +type MyFSharpClass () = + inherit FSharpBaseClass() + + member this.AccessPublicStuff() = + + this.GetPublicSetInternal <- "1" // Inaccessible + let _ = this.GetPublicSetInternal // Accessible + + this.GetPublicSetPrivate <- "1" // Inaccessible + let _ = this.GetPublicSetPrivate // Accessible + () +""" + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpBaseClass, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpErrorSeverity.Error, 810, (25, 9, 25, 33), + "Property 'GetPublicSetPrivate' cannot be set") + |]) + + + [] + let ``VerifyVisibility of Properties F# class F# non-derived class -- AccessPublicStuff`` () = + + let fsharpSource = + fsharpBaseClass + """ +open System +open ExhaustiveCombinations + +type MyFSharpClass () = + + member _.AccessPublicStuff() = + let bc = new FSharpBaseClass() + + bc.GetPublicSetInternal <- "1" // Inaccessible + let _ = bc.GetPublicSetInternal // Accessible + + bc.GetPublicSetPrivate <- "1" // Inaccessible + let _ = bc.GetPublicSetPrivate // Accessible + () +""" + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpBaseClass, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpErrorSeverity.Error, 810, (25, 9, 25, 31), + "Property 'GetPublicSetPrivate' cannot be set")|]) + + + +// Todo: Repeat these tests with a seperate F# assembly \ No newline at end of file diff --git a/tests/fsharp/Compiler/ILMemberAccessTests.fs b/tests/fsharp/Compiler/ILMemberAccessTests.fs deleted file mode 100644 index 378794a6d55..00000000000 --- a/tests/fsharp/Compiler/ILMemberAccessTests.fs +++ /dev/null @@ -1,65 +0,0 @@ -namespace FSharp.Compiler.UnitTests -open FSharp.Reflection -open NUnit.Framework - -[] -module ILMemberAccessTests = - open FSharp.Compiler.AbstractIL.IL - [] - let ``ILMemberAccess exhaustively OK for comparison`` () = - - let allCases = - let allCasesInfos = FSharpType.GetUnionCases (typeof) - allCasesInfos - |> Array.map (fun caseInfo -> - FSharpValue.MakeUnion(caseInfo, [||]) :?> ILMemberAccess - ) - |> Set.ofArray - - let addItem, checkedCases = - let mutable items = Set.empty - (fun item -> items <- Set.add item items) - , (fun () -> items) - - let expectedComparisons = - let rec cummulativeSum n = - match n with - | 0 -> 0 - | 1 -> 1 - | _ -> n + cummulativeSum(n-1) - cummulativeSum (allCases.Count - 1) - - let mutable comparisonsCount = 0 - let compareIsGreater a b = - if a > b then - addItem a - addItem b - comparisonsCount <- comparisonsCount + 1 - else - failwithf "%A > %A didn't hold" a b - - compareIsGreater ILMemberAccess.Public ILMemberAccess.FamilyOrAssembly - compareIsGreater ILMemberAccess.Public ILMemberAccess.Family - compareIsGreater ILMemberAccess.Public ILMemberAccess.Assembly - compareIsGreater ILMemberAccess.Public ILMemberAccess.FamilyAndAssembly - compareIsGreater ILMemberAccess.Public ILMemberAccess.Private - compareIsGreater ILMemberAccess.Public ILMemberAccess.CompilerControlled - compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.Assembly - compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.Family - compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.FamilyAndAssembly - compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.Private - compareIsGreater ILMemberAccess.FamilyOrAssembly ILMemberAccess.CompilerControlled - compareIsGreater ILMemberAccess.Assembly ILMemberAccess.Family - compareIsGreater ILMemberAccess.Assembly ILMemberAccess.FamilyAndAssembly - compareIsGreater ILMemberAccess.Assembly ILMemberAccess.Private - compareIsGreater ILMemberAccess.Assembly ILMemberAccess.CompilerControlled - compareIsGreater ILMemberAccess.Family ILMemberAccess.FamilyAndAssembly - compareIsGreater ILMemberAccess.Family ILMemberAccess.Private - compareIsGreater ILMemberAccess.Family ILMemberAccess.CompilerControlled - compareIsGreater ILMemberAccess.FamilyAndAssembly ILMemberAccess.Private - compareIsGreater ILMemberAccess.FamilyAndAssembly ILMemberAccess.CompilerControlled - compareIsGreater ILMemberAccess.Private ILMemberAccess.CompilerControlled - - let checkedCases = checkedCases () - Assert.IsTrue((checkedCases = allCases), sprintf "all cases weren't checked: %A versus %A" checkedCases allCases) - Assert.AreEqual(expectedComparisons, comparisonsCount) \ No newline at end of file diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index 7e1cce8b67d..b40ab84729d 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -27,7 +27,6 @@ - @@ -35,6 +34,7 @@ + From 2b6a416c28d94d205a8c7197c53b9589dec9ac94 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Mon, 15 Jun 2020 15:35:44 +0100 Subject: [PATCH 16/60] simplifications to code --- src/fsharp/TypedTreeOps.fs | 48 ++++++++++++++------------- src/fsharp/fscmain.fs | 6 +--- src/fsharp/xlf/FSComp.txt.cs.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.de.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.es.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.fr.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.it.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.ja.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.ko.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.pl.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.ru.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.tr.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 15 --------- src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 15 --------- 15 files changed, 26 insertions(+), 223 deletions(-) diff --git a/src/fsharp/TypedTreeOps.fs b/src/fsharp/TypedTreeOps.fs index c0afdb11439..229f75fb32a 100644 --- a/src/fsharp/TypedTreeOps.fs +++ b/src/fsharp/TypedTreeOps.fs @@ -2921,31 +2921,33 @@ let fullMangledPathToTyconRef (tcref:TyconRef) = | ERefNonLocal nlr -> nlr.EnclosingMangledPath /// generates a name like 'System.IComparable.Get' +let tyconRefToFullName (tc:TyconRef) = + let namespaceParts = + // we need to ensure there are no collisions between (for example) + // - ``IB`` (non-generic) + // - IB<'T> instantiated with 'T = GlobalType + // This is only an issue for types inside the global namespace, because '.' is invalid even in a quoted identifier. + // So if the type is in the global namespace, prepend 'global`', because '`' is also illegal -> there can be no quoted identifer with that name. + match fullMangledPathToTyconRef tc with + | [||] -> [| "global`" |] + | ns -> ns + seq { yield! namespaceParts; yield tc.DisplayName } |> String.concat "." + +let rec qualifiedInterfaceImplementationNameAux g (x:TType) : string = + match stripMeasuresFromTType g (stripTyEqnsAndErase true g x) with + | TType_app (a,[]) -> tyconRefToFullName a + | TType_anon (a,b) -> + let genericParameters = b |> Seq.map (qualifiedInterfaceImplementationNameAux g) |> String.concat ", " + sprintf "%s<%s>" (a.ILTypeRef.FullName) genericParameters + | TType_app (a,b) -> + let genericParameters = b |> Seq.map (qualifiedInterfaceImplementationNameAux g) |> String.concat ", " + sprintf "%s<%s>" (tyconRefToFullName a) genericParameters + | TType_var (v) -> "'" + v.Name + | _ -> failwithf "unexpected: expected TType_app but got %O" (x.GetType()) + /// for types in the global namespace, `global is prepended (note the backtick) let qualifiedInterfaceImplementationName g (tt:TType) memberName = - let rec TType_ToCodeLikeString (x:TType) : string = - let TyconRefToFullName (tc:TyconRef) = - let namespaceParts = - // we need to ensure there are no collisions between (for example) - // - ``IB`` (non-generic) - // - IB<'T> instantiated with 'T = GlobalType - // This is only an issue for types inside the global namespace, because '.' is invalid even in a quoted identifier. - // So if the type is in the global namespace, prepend 'global`', because '`' is also illegal -> there can be no quoted identifer with that name. - match fullMangledPathToTyconRef tc with - | [||] -> [| "global`" |] - | ns -> ns - seq { yield! namespaceParts; yield tc.DisplayName } |> String.concat "." - match x with - | TType_app (a,[]) -> TyconRefToFullName a - | TType_anon (a,b) -> - let genericParameters = b |> Seq.map (stripTyEqnsAndErase true g >> stripMeasuresFromTType g >> TType_ToCodeLikeString) |> String.concat ", " - sprintf "%s<%s>" (a.ILTypeRef.FullName) genericParameters - | TType_app (a,b) -> - let genericParameters = b |> Seq.map (stripTyEqnsAndErase true g >> stripMeasuresFromTType g >> TType_ToCodeLikeString) |> String.concat ", " - sprintf "%s<%s>" (TyconRefToFullName a) genericParameters - | TType_var (v) -> "'" + v.Name - | _ -> failwithf "unexpected: expected TType_app but got %O" (x.GetType()) - let interfaceName = tt |> stripTyEqnsAndErase true g |> stripMeasuresFromTType g |> TType_ToCodeLikeString + let interfaceName = tt |> qualifiedInterfaceImplementationNameAux g sprintf "%s.%s" interfaceName memberName let qualifiedMangledNameOfTyconRef tcref nm = diff --git a/src/fsharp/fscmain.fs b/src/fsharp/fscmain.fs index 7d27423747b..f4c6b87c283 100644 --- a/src/fsharp/fscmain.fs +++ b/src/fsharp/fscmain.fs @@ -13,18 +13,14 @@ open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.ILBinaryReader open FSharp.Compiler.ErrorLogger - open FSharp.Compiler.Driver open FSharp.Compiler.Lib - open FSharp.Compiler.Range open FSharp.Compiler.CompileOps open FSharp.Compiler.AbstractIL.Internal.Library open Internal.Utilities -[< - Dependency("FSharp.Compiler.Private",LoadHint.Always) ->] +[] do () diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 476b03476ef..f7ae174868e 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ Typ {0} nedefinuje pole, konstruktor ani člen {1}. - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. Není definovaný obor názvů {0}. diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index e3632d2b916..e086596e7b4 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ Der Typ "{0}" definiert nicht das Feld, den Konstruktor oder den Member "{1}". - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. Der Namespace "{0}" ist nicht definiert. diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 1cbe9afc421..1eb408ff3f1 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ El tipo "{0}" no define el campo, constructor o miembro "{1}". - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. El espacio de nombres "{0}" no está definido. diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index 9519ef3d5e3..15bc9610834 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ Le type '{0}' ne définit pas le champ, le constructeur ou le membre '{1}'. - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. L'espace de noms '{0}' n'est pas défini. diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 1f2b602ac2d..41a4e672b8d 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ Il tipo '{0}' non definisce il campo, il costruttore o il membro '{1}'. - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. Lo spazio dei nomi '{0}' non è definito. diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 5c328eccea2..1dd7c03f820 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ 型 '{0}' は、フィールド、コンストラクター、またはメンバー '{1}' を定義していません。 - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. 名前空間 '{0}' が定義されていません。 diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index cb11bcb15c9..b20e9912bbb 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ '{0}' 형식은 '{1}' 필드, 생성자 또는 멤버를 정의하지 않습니다. - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. '{0}' 네임스페이스가 정의되지 않았습니다. diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index 04f45fe290c..c05715de16d 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ Typ „{0}” nie definiuje pola, konstruktora lub składowej „{1}”. - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. Nie zdefiniowano przestrzeni nazw „{0}”. diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index 032ff6ccc90..1e0e527e15f 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ O tipo '{0}' não define o campo, o construtor ou o membro '{1}'. - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. O namespace '{0}' não está definido. diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 8e32921814c..21cef4e9e7e 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ Тип "{0}" не определяет поле, конструктор или член "{1}". - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. Пространство имен "{0}" не определено. diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 18be2d7c497..136b9f3b8f5 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ '{0}' türü; alanı, oluşturucuyu veya '{1}' üyesini tanımlamıyor. - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. '{0}' ad alanı tanımlı değil. diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 4159ba2aa5a..0a1d50ac1bb 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ 类型“{0}”未定义字段、构造函数或成员“{1}”。 - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. 未定义命名空间“{0}”。 diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index f83afb6c205..3da0fb2cca2 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -102,11 +102,6 @@ implicit yield - - interfaces with multiple generic instantiation - interfaces with multiple generic instantiation - - nameof nameof @@ -247,16 +242,6 @@ 類型 '{0}' 未定義欄位、建構函式或成員 '{1}'。 - - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. - - - - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. - - The namespace '{0}' is not defined. 未定義命名空間 '{0}'。 From c5345f8b8831b60e9ab26c624c4825605f7dfa4b Mon Sep 17 00:00:00 2001 From: Don Syme Date: Mon, 15 Jun 2020 15:49:09 +0100 Subject: [PATCH 17/60] try simplify type logic --- src/fsharp/PostInferenceChecks.fs | 149 ++++++++++-------------------- 1 file changed, 47 insertions(+), 102 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 93b05ab7088..1931e3dac77 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -686,114 +686,59 @@ let isSpliceOperator g v = valRefEq g v g.splice_expr_vref || valRefEq g v g.spl /// Examples: /// I & I => ExactlyEqual. /// I & I => NotEqual. -/// I & I<'T> => ``Equal except for TType_var or Measure or Alias``. -/// with '[] type kg': I< int > & I => ``Equal except for TType_var or Measure or Alias``. -/// with 'type MyInt = int': I & I => ``Equal except for TType_var or Measure or Alias``. +/// I & I<'T> => FeasiblyEqual. +/// with '[] type kg': I< int > & I => FeasiblyEqual. +/// with 'type MyInt = int': I & I => FeasiblyEqual. /// /// The differences could also be nested, example: -/// I> vs I> => ``Equal except for TType_var or Measure or Alias``. +/// I> vs I> => FeasiblyEqual. type TTypeEquality = | ExactlyEqual - | ``Equal except for TType_var or Measure or Alias`` + | FeasiblyEqual | NotEqual -let compareTypesWithRegardToTypeVariablesAndMeasures g typ1 typ2 = +let compareTypesWithRegardToTypeVariablesAndMeasures g amap m typ1 typ2 = + + if (typeEquiv g typ1 typ2) then ExactlyEqual else + + let typ1 = typ1 |> stripTyEqnsWrtErasure EraseAll g |> stripMeasuresFromTType g + let typ2 = typ2 |> stripTyEqnsWrtErasure EraseAll g |> stripMeasuresFromTType g + if (typeEquiv g typ1 typ2 || TypesFeasiblyEquiv 0 g amap m typ1 typ2) then + FeasiblyEqual + else + NotEqual - // compare the two types twice - // first pass: only generics are detected, aliases/measures would return 'NotEqual' - // IF the first pass returned 'NotEqual', compare them a second time: - // second pass: all aliases and measures are stripped. - - let rec compare stripMeasuresAndAliases g typ1 typ2 : TTypeEquality = - - let stripAll = (stripTyEqnsWrtErasure EraseAll g) >> stripMeasuresFromTType g - - let typ1 = if stripMeasuresAndAliases then stripAll typ1 else typ1 - let typ2 = if stripMeasuresAndAliases then stripAll typ2 else typ2 - - match typ1, typ2 with - - | TType_var v1, TType_var v2 when v1.Name = v2.Name -> ExactlyEqual - - | TType_var _, _ - | _, TType_var _ -> - ``Equal except for TType_var or Measure or Alias`` - - | TType_app (a1, []), TType_app (a2, []) -> - if tyconRefEq g a1 a2 then ExactlyEqual else NotEqual - - | TType_app (a1, ag1), TType_app (a2, ag2) -> - if not (tyconRefEq g a1 a2) then NotEqual else - if ag1.Length <> ag2.Length then NotEqual else - // outer types and number of parameters are equal - compare each parameter - let results = - (ag1, ag2) ||> Seq.map2 (compare stripMeasuresAndAliases g) |> set - if results = set [ ExactlyEqual ] then - ExactlyEqual - else if results |> Set.contains NotEqual then - NotEqual - else - ``Equal except for TType_var or Measure or Alias`` - - | _ -> if typeEquivAux Erasure.EraseNone g typ1 typ2 then ExactlyEqual else NotEqual - - let preStrip = compare false g typ1 typ2 - match preStrip with - | ExactlyEqual -> ExactlyEqual - | ``Equal except for TType_var or Measure or Alias`` -> ``Equal except for TType_var or Measure or Alias`` - | NotEqual -> - let stripped = compare true g typ1 typ2 - match stripped with - | ExactlyEqual -> ``Equal except for TType_var or Measure or Alias`` - | ``Equal except for TType_var or Measure or Alias`` -> ``Equal except for TType_var or Measure or Alias`` - | NotEqual -> NotEqual - -/// Check conditions associated with implementing multiple instantiations of a interface (either non-generic, or with exactly the same generic parameters) - -// Check conditions associated with implementing multiple instantiations of a generic interface -(* -let CheckMultipleInterfaceInstantiations cenv interfaces m = - let keyf ty = assert isAppTy cenv.g ty; (tcrefOfAppTy cenv.g ty).Stamp - let table = interfaces |> MultiMap.initBy keyf - let firstInterfaceWithMultipleGenericInstantiations = - interfaces |> List.tryPick (fun typ1 -> - table |> MultiMap.find (keyf typ1) |> List.tryPick (fun typ2 -> - if // same nominal type - tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && - // different instantiations - not (typeEquivAux EraseNone cenv.g typ1 typ2) - then Some (typ1, typ2) - else None)) - match firstInterfaceWithMultipleGenericInstantiations with - -*) - let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list) isObjectExpression m = - let langVersion = cenv.g.langVersion - let keyf ty = - assert isAppTy cenv.g ty - (tcrefOfAppTy cenv.g ty).Stamp - let groups = interfaces |> List.groupBy keyf - let errors = seq { - for (_, items) in groups do - for i1 in 0 .. items.Length - 1 do - for i2 in i1 + 1 .. items.Length - 1 do - let typ1 = items.[i1] - let typ2 = items.[i2] - let tcRef1 = tcrefOfAppTy cenv.g typ1 - if tyconRefEq cenv.g tcRef1 (tcrefOfAppTy cenv.g typ2) then - if not(langVersion.SupportsFeature LanguageFeature.InterfacesWithMultipleGenericInstantiation) then - // same nominal type -> not allowed in earlier versions of F# language - let hasMultipleGenericInterfaceInstantiations = - tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && - not (typeEquivAux EraseNone cenv.g typ1 typ2) - if hasMultipleGenericInterfaceInstantiations then - yield (Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations((NicePrint.minimalStringOfType cenv.denv typ1), (NicePrint.minimalStringOfType cenv.denv typ2)), m)) - else + let keyf ty = assert isAppTy cenv.g ty; (tcrefOfAppTy cenv.g ty).Stamp + if not(cenv.g.langVersion.SupportsFeature LanguageFeature.InterfacesWithMultipleGenericInstantiation) then + let table = interfaces |> MultiMap.initBy keyf + let firstInterfaceWithMultipleGenericInstantiations = + interfaces |> List.tryPick (fun typ1 -> + table |> MultiMap.find (keyf typ1) |> List.tryPick (fun typ2 -> + if // same nominal type + tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && + // different instantiations + not (typeEquivAux EraseNone cenv.g typ1 typ2) + then Some (typ1, typ2) + else None)) + match firstInterfaceWithMultipleGenericInstantiations with + | None -> () + | Some (typ1, typ2) -> + errorR(Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations((NicePrint.minimalStringOfType cenv.denv typ1), (NicePrint.minimalStringOfType cenv.denv typ2)), m)) + else + let groups = interfaces |> List.groupBy keyf + let errors = seq { + for (_, items) in groups do + for i1 in 0 .. items.Length - 1 do + for i2 in i1 + 1 .. items.Length - 1 do + let typ1 = items.[i1] + let typ2 = items.[i2] + let tcRef1 = tcrefOfAppTy cenv.g typ1 + if tyconRefEq cenv.g tcRef1 (tcrefOfAppTy cenv.g typ2) then // same nominal type -> check generic args - match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g typ1 typ2 with + match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g cenv.amap m typ1 typ2 with | ExactlyEqual -> () // exact duplicates are checked in another place - | ``Equal except for TType_var or Measure or Alias`` -> + | FeasiblyEqual -> let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 if isObjectExpression then @@ -802,10 +747,10 @@ let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list let typStr = NicePrint.minimalStringOfType cenv.denv typ yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) | NotEqual -> () - } - match Seq.tryHead errors with - | None -> () - | Some e -> errorR(e) + } + match Seq.tryHead errors with + | None -> () + | Some e -> errorR(e) /// Check an expression, where the expression is in a position where byrefs can be generated let rec CheckExprNoByrefs cenv env expr = From 1baa001d88dc9cc9a0d490607a4bf346b2931bc6 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Mon, 15 Jun 2020 16:08:55 +0100 Subject: [PATCH 18/60] try simplify type logic --- src/fsharp/PostInferenceChecks.fs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 1931e3dac77..7a005a3bc0f 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -724,7 +724,9 @@ let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list match firstInterfaceWithMultipleGenericInstantiations with | None -> () | Some (typ1, typ2) -> - errorR(Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations((NicePrint.minimalStringOfType cenv.denv typ1), (NicePrint.minimalStringOfType cenv.denv typ2)), m)) + let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 + let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 + errorR(Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations(typ1Str, typ2Str), m)) else let groups = interfaces |> List.groupBy keyf let errors = seq { @@ -734,19 +736,17 @@ let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list let typ1 = items.[i1] let typ2 = items.[i2] let tcRef1 = tcrefOfAppTy cenv.g typ1 - if tyconRefEq cenv.g tcRef1 (tcrefOfAppTy cenv.g typ2) then - // same nominal type -> check generic args - match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g cenv.amap m typ1 typ2 with - | ExactlyEqual -> () // exact duplicates are checked in another place - | FeasiblyEqual -> - let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 - let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 - if isObjectExpression then - yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariableObjectExpression(tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) - else - let typStr = NicePrint.minimalStringOfType cenv.denv typ - yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) - | NotEqual -> () + match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g cenv.amap m typ1 typ2 with + | ExactlyEqual -> () // exact duplicates are checked in another place + | FeasiblyEqual -> + let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 + let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 + if isObjectExpression then + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariableObjectExpression(tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + else + let typStr = NicePrint.minimalStringOfType cenv.denv typ + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + | NotEqual -> () } match Seq.tryHead errors with | None -> () From 49d99be1a90b036b09eef8cf3aeaf474d1d6c215 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Mon, 15 Jun 2020 23:34:24 -0700 Subject: [PATCH 19/60] feedback --- src/fsharp/AccessibilityLogic.fs | 18 +++++++++++++++++- .../Properties/ILMemberAccessTests.fs | 13 +++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/fsharp/AccessibilityLogic.fs b/src/fsharp/AccessibilityLogic.fs index ae9cbea64fe..5ba665da000 100644 --- a/src/fsharp/AccessibilityLogic.fs +++ b/src/fsharp/AccessibilityLogic.fs @@ -254,6 +254,19 @@ let GetILAccessOfILPropInfo (ILPropInfo(tinfo, pdef)) = | None, Some mref -> (resolveILMethodRef tdef mref).Access | Some mrefGet, Some mrefSet -> + // + // Dotnet properties have a getter and a setter method, each of which can have a separate visibility public, protected, private etc ... + // This code computes the visibility for the property by choosing the most visible method. This approximation is usefull for cases + // where the compiler needs to know the visibility of the property. + // The specific ordering for choosing the most visible is: + // ILMemberAccess.Public, + // ILMemberAccess.FamilyOrAssembly + // ILMemberAccess.Assembly + // ILMemberAccess.Family + // ILMemberAccess.FamilyAndAssembly + // ILMemberAccess.Private + // ILMemberAccess.CompilerControlled + // let getA = (resolveILMethodRef tdef mrefGet).Access let setA = (resolveILMethodRef tdef mrefSet).Access @@ -274,7 +287,10 @@ let GetILAccessOfILPropInfo (ILPropInfo(tinfo, pdef)) = | ILMemberAccess.FamilyAndAssembly, _ | _, ILMemberAccess.FamilyAndAssembly -> ILMemberAccess.FamilyAndAssembly - | _ -> ILMemberAccess.Private + | ILMemberAccess.Private, _ + | _, ILMemberAccess.Private -> ILMemberAccess.Private + + | _ -> ILMemberAccess.CompilerControlled | None, None -> ILMemberAccess.Public diff --git a/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs b/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs index 44e92e4724d..b88ca7988f1 100644 --- a/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs +++ b/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs @@ -91,6 +91,7 @@ type MyFSharpClass () = (FSharpErrorSeverity.Error, 491, (34, 9, 34, 40), "The member or object constructor 'GetPublicSetPrivate' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.")|]) + [] let ``VerifyVisibility of Properties C# class F# non-derived class -- AccessPublicStuff`` () = @@ -161,6 +162,13 @@ type MyFSharpClass () = this.GetPublicSetPrivate <- "1" // Inaccessible let _ = this.GetPublicSetPrivate // Accessible + + this.SetPublicGetInternal <- "1" // Accessible + let _ = this.SetPublicGetInternal // Inaccessible + + this.SetPublicGetPrivate <- "1" // Accessible + let _ = this.SetPublicGetPrivate // accessible + () """ @@ -173,7 +181,9 @@ type MyFSharpClass () = CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 810, (25, 9, 25, 33), - "Property 'GetPublicSetPrivate' cannot be set") + "Property 'GetPublicSetPrivate' cannot be set"); + (FSharpErrorSeverity.Error, 807, (32, 17, 32, 41), + "Property 'SetPublicGetPrivate' is not readable") |]) @@ -211,4 +221,3 @@ type MyFSharpClass () = -// Todo: Repeat these tests with a seperate F# assembly \ No newline at end of file From 90f1d0717654b85f30a81a3975112bc538fee20b Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Wed, 17 Jun 2020 23:01:46 -0700 Subject: [PATCH 20/60] moar tests --- .../Compiler/Language/InterfaceTests.fs | 124 ++++++++++++++---- 1 file changed, 97 insertions(+), 27 deletions(-) diff --git a/tests/fsharp/Compiler/Language/InterfaceTests.fs b/tests/fsharp/Compiler/Language/InterfaceTests.fs index db75917dfc9..561d86e2a53 100644 --- a/tests/fsharp/Compiler/Language/InterfaceTests.fs +++ b/tests/fsharp/Compiler/Language/InterfaceTests.fs @@ -10,9 +10,8 @@ open FSharp.TestHelpers module InterfaceTests = [] - let ShouldWork() = - CompilerAssert.Pass - """ + let ShouldnWork() = + CompilerAssert.Pass """ type IGet<'T> = abstract member Get : unit -> 'T @@ -41,13 +40,18 @@ type GetUnion() = exit 0 """ + let ``Many Instantiations of the same interface`` = """ +module Program - let multiTypedInterfaceSource = """ open System + type AnEnum = | One | Two +[] +type AStructRecord = { Forename:string; Surname:string } + type AClass = val value: int @@ -57,33 +61,44 @@ type IInterface<'a> = abstract GetIt: 'a -> 'a type implementation () = - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x - interface IInterface with member _.GetIt(x) = x + interface IInterface with member _.GetIt(x) = x // bool + interface IInterface with member _.GetIt(x) = x // byte + interface IInterface with member _.GetIt(x) = x // byte array + interface IInterface with member _.GetIt(x) = x // sbyte + interface IInterface with member _.GetIt(x) = x // int 16 + interface IInterface with member _.GetIt(x) = x // uint16 + interface IInterface with member _.GetIt(x) = x // int + interface IInterface with member _.GetIt(x) = x // uint32 + interface IInterface with member _.GetIt(x) = x // int64 + interface IInterface with member _.GetIt(x) = x // uint64 + interface IInterface with member _.GetIt(x) = x // nativeint + interface IInterface with member _.GetIt(x) = x // unativeint + interface IInterface with member _.GetIt(x) = x // char + interface IInterface with member _.GetIt(x) = x // string + interface IInterface with member _.GetIt(x) = x // single + interface IInterface with member _.GetIt(x) = x // double + interface IInterface with member _.GetIt(x) = x // decimal + interface IInterface with member _.GetIt(x) = x // bigint + interface IInterface with member _.GetIt(x) = x // struct tuple + interface IInterface with member _.GetIt(x) = x // enum + interface IInterface> with member _.GetIt(x) = x // struct union + interface IInterface with member _.GetIt(x) = x // struct record +#if !NO_ANONYMOUS // Anonymous records are non-deterministic So don't include for il comparison + interface IInterface with member _.GetIt(x) = x // Anonymous record +#endif + interface IInterface int> with member _.GetIt(x) = x // func + interface IInterface float> with member _.GetIt(x) = x // func let x = implementation () let assertion v assertIt = if not (assertIt(v)) then raise (new Exception (sprintf "Failed to retrieve %A from implementation" v)) -// Ensure we can invoke the method and get the value back for each native F# type +let assertionRecord v assertIt = + if not (assertIt(v)) then + raise (new Exception (sprintf "Failed to retrieve %A from implementation" v)) +// Ensure we can invoke the method and get the value back for each native F# type assertion true (fun v -> (x :> IInterface).GetIt(v) = v) assertion 1uy (fun v -> (x :> IInterface).GetIt(v) = v) assertion 2y (fun v -> (x :> IInterface).GetIt(v) = v) @@ -102,20 +117,75 @@ assertion 'A' (fun v -> (x :> IInterface).GetIt(v) = v) assertion 'a'B (fun v -> (x :> IInterface).GetIt(v) = v) assertion "16"B (fun v -> (x :> IInterface).GetIt(v) = v) assertion AnEnum.Two (fun v -> (x :> IInterface).GetIt(v) = v) +assertion (ValueSome "7") (fun v -> (x :> IInterface>).GetIt(v) = v) +assertion struct (1,2) (fun v -> (x :> IInterface).GetIt(v) = v) +assertion { Forename="Forename"; Surname="Surname" } (fun v -> (x :> IInterface).GetIt(v) = v) +#if !NO_ANONYMOUS // Anonymous records are non-deterministic So don't include for il comparison +assertion struct {|First=2; Second=3 |} (fun (v:struct {|First:int; Second:int|}) -> (x :> IInterface).GetIt(v) = v) +#endif +assertion (fun x -> x * 2) (fun v -> + let f = (x :> IInterface int>).GetIt(v) + f(7) = 14) +assertion (fun (x:float) -> x * 3.0) (fun v -> + let f = (x :> IInterface float>).GetIt(v) + f(2.0) = 6.0) """ [] let MultipleTypedInterfacesFSharp50() = CompilerAssert.PassWithOptions [| "--langversion:preview" |] - multiTypedInterfaceSource + ``Many Instantiations of the same interface`` [] let MultipleTypedInterfacesFSharp47() = CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:4.7" |] - multiTypedInterfaceSource + ``Many Instantiations of the same interface`` [| - (FSharpErrorSeverity.Error, 443, (15,6,15,20), "This type implements the same interface at different generic instantiations 'IInterface' and 'IInterface'. This is not permitted in this version of F#.") + (FSharpErrorSeverity.Error, 443, (21,6,21,20), "This type implements the same interface at different generic instantiations 'IInterface' and 'IInterface'. This is not permitted in this version of F#.") |] + [] + let MultipleTypedInterfacesFSharp50VerifyIl() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions + [| "--langversion:preview"; "--deterministic+"; "--define:NO_ANONYMOUS" |] + ``Many Instantiations of the same interface`` + (fun verifier -> verifier.VerifyIL [""" +.class auto ansi serializable nested public implementation + extends [mscorlib]System.Object + implements class Program/IInterface`1>, + class Program/IInterface`1>, + class Program/IInterface`1, + class Program/IInterface`1>, + class Program/IInterface`1,""" + +#if NETSTANDARD + """ + class Program/IInterface`1>, + class Program/IInterface`1, + class Program/IInterface`1,""" + +#else + """ + class Program/IInterface`1>, + class Program/IInterface`1, + class Program/IInterface`1,""" + +#endif + """ + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1 +{ +"""] ) From e32447764ef2db0352027b213c94bec87ad471a8 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Fri, 19 Jun 2020 01:06:22 -0700 Subject: [PATCH 21/60] dim tests --- .../Compiler/Language/InterfaceTests.fs | 86 ++++++++++++++++--- 1 file changed, 75 insertions(+), 11 deletions(-) diff --git a/tests/fsharp/Compiler/Language/InterfaceTests.fs b/tests/fsharp/Compiler/Language/InterfaceTests.fs index 561d86e2a53..5ebdf284395 100644 --- a/tests/fsharp/Compiler/Language/InterfaceTests.fs +++ b/tests/fsharp/Compiler/Language/InterfaceTests.fs @@ -5,6 +5,7 @@ namespace FSharp.Compiler.UnitTests open FSharp.Compiler.SourceCodeServices open NUnit.Framework open FSharp.TestHelpers +open FSharp.TestHelpers.Utilities [] module InterfaceTests = @@ -38,12 +39,27 @@ type GetUnion() = member x.Get() = B 2 exit 0 - """ +""" + + let ``C# base with dim`` = """ +using System; + +namespace CSharpTest +{ + public interface ITestDim + { + int GetIt(int x) { return x; } + } +} +""" - let ``Many Instantiations of the same interface`` = """ + let ``Many Instantiations of the same interface - SetUp`` = """ module Program open System +#if TEST_DIMS +open CSharpTest +#endif type AnEnum = | One @@ -61,6 +77,10 @@ type IInterface<'a> = abstract GetIt: 'a -> 'a type implementation () = +// DIMs only available on netcoreapp 3 +#if TEST_DIMS + interface ITestDim +#endif interface IInterface with member _.GetIt(x) = x // bool interface IInterface with member _.GetIt(x) = x // byte interface IInterface with member _.GetIt(x) = x // byte array @@ -83,12 +103,15 @@ type implementation () = interface IInterface with member _.GetIt(x) = x // enum interface IInterface> with member _.GetIt(x) = x // struct union interface IInterface with member _.GetIt(x) = x // struct record -#if !NO_ANONYMOUS // Anonymous records are non-deterministic So don't include for il comparison + // Anonymous records are non-deterministic So don't include for il comparison +#if !NO_ANONYMOUS interface IInterface with member _.GetIt(x) = x // Anonymous record #endif interface IInterface int> with member _.GetIt(x) = x // func interface IInterface float> with member _.GetIt(x) = x // func +""" + let ``Many Instantiations of the same interface - Asserts`` = """ let x = implementation () let assertion v assertIt = if not (assertIt(v)) then @@ -99,6 +122,10 @@ let assertionRecord v assertIt = raise (new Exception (sprintf "Failed to retrieve %A from implementation" v)) // Ensure we can invoke the method and get the value back for each native F# type +#if TEST_DIMS +assertion 7 (fun v -> (x :> ITestDim).GetIt(v) = v) +#endif + assertion true (fun v -> (x :> IInterface).GetIt(v) = v) assertion 1uy (fun v -> (x :> IInterface).GetIt(v) = v) assertion 2y (fun v -> (x :> IInterface).GetIt(v) = v) @@ -107,7 +134,7 @@ assertion 4us (fun v -> (x :> IInterface).GetIt(v) = v) assertion 5l (fun v -> (x :> IInterface).GetIt(v) = v) assertion 6ul (fun v -> (x :> IInterface).GetIt(v) = v) assertion 7n (fun v -> (x :> IInterface).GetIt(v) = v) -assertion 8un (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 8un (fun v -> (x :> IInterface).GetIt(v) = v) assertion 9L (fun v -> (x :> IInterface).GetIt(v) = v) assertion 10UL (fun v -> (x :> IInterface).GetIt(v) = v) assertion 12.12 (fun v -> (x :> IInterface).GetIt(v) = v) @@ -131,26 +158,63 @@ assertion (fun (x:float) -> x * 3.0) (fun v -> f(2.0) = 6.0) """ + let ``Many Instantiations of the same interface`` = + ``Many Instantiations of the same interface - SetUp`` + ``Many Instantiations of the same interface - Asserts`` + + [] let MultipleTypedInterfacesFSharp50() = - CompilerAssert.PassWithOptions - [| "--langversion:preview" |] - ``Many Instantiations of the same interface`` + +#if NETSTANDARD + let csCmpl = + CompilationUtil.CreateCSharpCompilation(``C# base with dim``, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30) + |> CompilationReference.Create +#endif + + let fsCmpl = + Compilation.Create( + ``Many Instantiations of the same interface - SetUp`` + + ``Many Instantiations of the same interface - Asserts``, + Fs, Library, + options = [| + "--langversion:preview"; +#if !NETSTANDARD + |]) +#else + "--define:NETSTANDARD"; + "--define:TEST_DIMS"; + |], + cmplRefs = [csCmpl]) +#endif + + CompilerAssert.Compile fsCmpl [] let MultipleTypedInterfacesFSharp47() = CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:4.7" |] + [| + "--langversion:4.7"; +#if NETSTANDARD + "--define:NETSTANDARD"; +#endif + |] ``Many Instantiations of the same interface`` [| - (FSharpErrorSeverity.Error, 443, (21,6,21,20), "This type implements the same interface at different generic instantiations 'IInterface' and 'IInterface'. This is not permitted in this version of F#.") + (FSharpErrorSeverity.Error, 443, (24, 6, 24, 20), "This type implements the same interface at different generic instantiations 'IInterface<(float -> float)>' and 'IInterface<(int -> int)>'. This is not permitted in this version of F#.") |] [] let MultipleTypedInterfacesFSharp50VerifyIl() = CompilerAssert.CompileLibraryAndVerifyILWithOptions - [| "--langversion:preview"; "--deterministic+"; "--define:NO_ANONYMOUS" |] - ``Many Instantiations of the same interface`` + [| + "--langversion:preview"; + "--deterministic+"; + "--define:NO_ANONYMOUS"; +#if NETSTANDARD + "--define:NETSTANDARD"; +#endif + |] + ``Many Instantiations of the same interface - SetUp`` (fun verifier -> verifier.VerifyIL [""" .class auto ansi serializable nested public implementation extends [mscorlib]System.Object From 2feab1d7c90df97a32228e5bef486f395fd8f0da Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Fri, 19 Jun 2020 01:36:39 -0700 Subject: [PATCH 22/60] Update InterfaceTests.fs --- tests/fsharp/Compiler/Language/InterfaceTests.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fsharp/Compiler/Language/InterfaceTests.fs b/tests/fsharp/Compiler/Language/InterfaceTests.fs index 5ebdf284395..aaecd4bfce5 100644 --- a/tests/fsharp/Compiler/Language/InterfaceTests.fs +++ b/tests/fsharp/Compiler/Language/InterfaceTests.fs @@ -4,8 +4,8 @@ namespace FSharp.Compiler.UnitTests open FSharp.Compiler.SourceCodeServices open NUnit.Framework -open FSharp.TestHelpers -open FSharp.TestHelpers.Utilities +open FSharp.Test +open FSharp.Test.Utilities [] module InterfaceTests = From e2703e33b6f8f2dde0747f74051f1b1a56744e63 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Fri, 19 Jun 2020 21:34:43 -0700 Subject: [PATCH 23/60] Get namespace right --- tests/fsharp/Compiler/Language/InterfaceTests.fs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/fsharp/Compiler/Language/InterfaceTests.fs b/tests/fsharp/Compiler/Language/InterfaceTests.fs index aaecd4bfce5..e18d1a9fa48 100644 --- a/tests/fsharp/Compiler/Language/InterfaceTests.fs +++ b/tests/fsharp/Compiler/Language/InterfaceTests.fs @@ -6,6 +6,9 @@ open FSharp.Compiler.SourceCodeServices open NUnit.Framework open FSharp.Test open FSharp.Test.Utilities +open FSharp.Test.Utilities.Utilities + + [] module InterfaceTests = From fb3c52bb9f987980f585500097f84710c3fdfa94 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Sat, 20 Jun 2020 00:42:59 -0700 Subject: [PATCH 24/60] Update src/fsharp/AccessibilityLogic.fs Co-authored-by: Gauthier Segay --- src/fsharp/AccessibilityLogic.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsharp/AccessibilityLogic.fs b/src/fsharp/AccessibilityLogic.fs index 5ba665da000..498103a9f51 100644 --- a/src/fsharp/AccessibilityLogic.fs +++ b/src/fsharp/AccessibilityLogic.fs @@ -270,7 +270,8 @@ let GetILAccessOfILPropInfo (ILPropInfo(tinfo, pdef)) = let getA = (resolveILMethodRef tdef mrefGet).Access let setA = (resolveILMethodRef tdef mrefSet).Access - // use the accessors to determine the visibility of the property + // Use the accessors to determine the visibility of the property. + // N.B. It is critical to keep the ordering in decreasing visibility order in the following match expression match getA, setA with | ILMemberAccess.Public, _ | _, ILMemberAccess.Public -> ILMemberAccess.Public @@ -385,4 +386,3 @@ let IsPropInfoAccessible g amap m ad = function let IsFieldInfoAccessible ad (rfref:RecdFieldInfo) = IsAccessible ad rfref.RecdField.Accessibility - From 37be39e032ce100bffa222b9beb040fb023e46cb Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Sat, 20 Jun 2020 01:44:44 -0700 Subject: [PATCH 25/60] merge --- tests/FSharp.Test.Utilities/TestFramework.fs | 4 ++-- .../Compiler/Conformance/Properties/ILMemberAccessTests.fs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/FSharp.Test.Utilities/TestFramework.fs b/tests/FSharp.Test.Utilities/TestFramework.fs index 38e29d1de28..7650ee38168 100644 --- a/tests/FSharp.Test.Utilities/TestFramework.fs +++ b/tests/FSharp.Test.Utilities/TestFramework.fs @@ -229,7 +229,7 @@ let config configurationName envVars = let requirePackage = requireFile packagesDir let requireArtifact = requireFile artifactsBinPath let CSC = requirePackage ("Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "csc.exe") - let VBC = requireFile (packagesDir ++ "Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "vbc.exe") + let VBC = requirePackage ("Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "vbc.exe") let ILDASM_EXE = if operatingSystem = "win" then "ildasm.exe" else "ildasm" let ILDASM = requirePackage (("runtime." + operatingSystem + "-" + architectureMoniker + ".Microsoft.NETCore.ILDAsm") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ (operatingSystem + "-" + architectureMoniker) ++ "native" ++ ILDASM_EXE) let ILASM_EXE = if operatingSystem = "win" then "ilasm.exe" else "ilasm" @@ -238,7 +238,7 @@ let config configurationName envVars = let coreclrdll = requirePackage (("runtime." + operatingSystem + "-" + architectureMoniker + ".Microsoft.NETCore.Runtime.CoreCLR") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ (operatingSystem + "-" + architectureMoniker) ++ "native" ++ CORECLR_DLL) let PEVERIFY_EXE = if operatingSystem = "win" then "PEVerify.exe" else "PEVerify" let PEVERIFY = requireArtifact ("PEVerify" ++ configurationName ++ peverifyArchitecture ++ PEVERIFY_EXE) - let FSI_FOR_SCRIPTS = artifactsBinPath ++ "fsi" ++ configurationName ++ fsiArchitecture ++ "fsi.exe" +// let FSI_FOR_SCRIPTS = artifactsBinPath ++ "fsi" ++ configurationName ++ fsiArchitecture ++ "fsi.exe" let FSharpBuild = requireArtifact ("FSharp.Build" ++ configurationName ++ fsharpBuildArchitecture ++ "FSharp.Build.dll") let FSharpCompilerInteractiveSettings = requireArtifact ("FSharp.Compiler.Interactive.Settings" ++ configurationName ++ fsharpCompilerInteractiveSettingsArchitecture ++ "FSharp.Compiler.Interactive.Settings.dll") diff --git a/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs b/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs index b88ca7988f1..e421db9e534 100644 --- a/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs +++ b/tests/fsharp/Compiler/Conformance/Properties/ILMemberAccessTests.fs @@ -4,8 +4,9 @@ namespace FSharp.Compiler.UnitTests open FSharp.Compiler.SourceCodeServices open FSharp.Reflection -open FSharp.TestHelpers -open FSharp.TestHelpers.Utilities +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Test.Utilities.Utilities open NUnit.Framework [] From 24b4d2823af9a4b301fca1fd36467a7f216db80e Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Mon, 22 Jun 2020 14:07:31 -0700 Subject: [PATCH 26/60] Update --- src/fsharp/AccessibilityLogic.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fsharp/AccessibilityLogic.fs b/src/fsharp/AccessibilityLogic.fs index 498103a9f51..3d5aadc98cc 100644 --- a/src/fsharp/AccessibilityLogic.fs +++ b/src/fsharp/AccessibilityLogic.fs @@ -291,7 +291,8 @@ let GetILAccessOfILPropInfo (ILPropInfo(tinfo, pdef)) = | ILMemberAccess.Private, _ | _, ILMemberAccess.Private -> ILMemberAccess.Private - | _ -> ILMemberAccess.CompilerControlled + | ILMemberAccess.CompilerControlled, _ + | _, ILMemberAccess.CompilerControlled -> ILMemberAccess.CompilerControlled | None, None -> ILMemberAccess.Public From 26d7cc51c0ed0eda116ee376088fd2cd43d43eed Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Tue, 23 Jun 2020 10:42:48 -0700 Subject: [PATCH 27/60] Update language version status of some features (#9507) * Update language status * fsharpqa baselines for langversion * Update LanguageFeatures.fs --- src/fsharp/LanguageFeatures.fs | 14 +-- .../BasicGrammarElements/BasicConstants.fs | 8 +- .../Language/DefaultInterfaceMemberTests.fs | 114 +++++++++--------- .../Compiler/Language/OptionalInteropTests.fs | 2 +- .../langversion/langversionhelp.437.1033.bsl | 3 +- .../langversion/langversionhelp.437.1033.bsl | 3 +- .../FSharp.PropertiesPages.vbproj | 44 ++----- 7 files changed, 84 insertions(+), 104 deletions(-) diff --git a/src/fsharp/LanguageFeatures.fs b/src/fsharp/LanguageFeatures.fs index 83172b8605b..5987bca1a61 100644 --- a/src/fsharp/LanguageFeatures.fs +++ b/src/fsharp/LanguageFeatures.fs @@ -46,7 +46,7 @@ type LanguageVersion (specifiedVersionAsString) = static let latestMajorVersion = languageVersion47 // Language version when latestmajor specified static let validOptions = [| "preview"; "default"; "latest"; "latestmajor" |] - static let languageVersions = set [| languageVersion46; languageVersion47 (*; languageVersion50 *) |] + static let languageVersions = set [| languageVersion46; languageVersion47 ; languageVersion50 |] static let features = dict [ @@ -58,17 +58,17 @@ type LanguageVersion (specifiedVersionAsString) = // F# 5.0 LanguageFeature.FixedIndexSlice3d4d, languageVersion50 - LanguageFeature.FromEndSlicing, languageVersion50 LanguageFeature.DotlessFloat32Literal, languageVersion50 + LanguageFeature.AndBang, languageVersion50 + LanguageFeature.NullableOptionalInterop, languageVersion50 + LanguageFeature.DefaultInterfaceMemberConsumption, languageVersion50 // F# preview - LanguageFeature.NameOf, previewVersion + LanguageFeature.FromEndSlicing, previewVersion LanguageFeature.OpenStaticClasses, previewVersion LanguageFeature.PackageManagement, previewVersion - LanguageFeature.AndBang, previewVersion - LanguageFeature.NullableOptionalInterop, previewVersion - LanguageFeature.DefaultInterfaceMemberConsumption, previewVersion LanguageFeature.WitnessPassing, previewVersion + LanguageFeature.NameOf, previewVersion ] let specified = @@ -80,7 +80,7 @@ type LanguageVersion (specifiedVersionAsString) = | "latestmajor" -> latestMajorVersion | "4.6" -> languageVersion46 | "4.7" -> languageVersion47 -(* | "5.0" -> languageVersion50 *) + | "5.0" -> languageVersion50 | _ -> 0m let versionToString v = diff --git a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/BasicConstants.fs b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/BasicConstants.fs index 912fb29091f..68dda297ece 100644 --- a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/BasicConstants.fs +++ b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/BasicConstants.fs @@ -177,7 +177,7 @@ printfn "%A" x14 """ [] let ``dotless float``() = - CompilerAssert.CompileExeWithOptions [|"--langversion:preview"|] + CompilerAssert.CompileExeWithOptions [|"--langversion:5.0"|] """ let x = 42f printfn "%A" x @@ -193,7 +193,7 @@ printfn "%A" x [] let ``dotted floats should be equal to dotless floats``() = - CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:preview"|] + CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:5.0"|] """ if 1.0f <> 1f then failwith "1.0f <> 1f" """ @@ -214,14 +214,14 @@ if 1e1f <> 10.f then failwith "1e1f <> 10.f" [] let ``exponent dotted floats should be equal to dotless floats``() = - CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:preview"|] + CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:5.0"|] """ if 1.0e1f <> 10f then failwith "1.0e1f <> 10f" """ [] let ``exponent dotless floats should be equal to dotless floats``() = - CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:preview"|] + CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:5.0"|] """ if 1e1f <> 10f then failwith "1e1f <> 10f" """ diff --git a/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs b/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs index fbd968178f1..d64067ddfa9 100644 --- a/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs +++ b/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs @@ -11,7 +11,7 @@ open FSharp.Compiler.SourceCodeServices module private DefaultInterfaceMemberConsumptionLanguageVersion = [] - let targetVersion = "'preview'" + let targetVersion = "5.0" #if NETCOREAPP @@ -1125,7 +1125,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 366, (8, 15, 8, 20), "No implementation was given for 'ITest.NonDefaultMethod() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") @@ -1175,7 +1175,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "I1.+1") @@ -1225,7 +1225,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "DefaultMethod-NonDefaultMethod") @@ -1299,7 +1299,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "ProtectedProtected-ProtectedOverrideProtectedOverride") @@ -1362,7 +1362,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "ObjExprProtectedObjExprProtected-ObjExprProtected2ObjExprProtected2") @@ -1437,7 +1437,7 @@ let f () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 491, (26, 5, 26, 15), "The member or object constructor 'M1' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.") @@ -1517,7 +1517,7 @@ type Test2 () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 629, (10, 9, 10, 27), "Method 'M1' is not accessible from this code location") @@ -1570,7 +1570,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "NonDefaultMethod") @@ -1619,7 +1619,7 @@ let f () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 39, (16, 10, 16, 23), "The type 'ITest' does not define the field, constructor or member 'DefaultMethod'. Maybe you want one of the following: @@ -1669,7 +1669,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 855, (11, 19, 11, 32), "No abstract or interface member was found that corresponds to this override") @@ -1726,7 +1726,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl], name = "Test") + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl], name = "Test") CompilerAssert.ExecutionHasOutput(fsCmpl, "IVT-NonDefaultMethod") @@ -1765,7 +1765,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "DefaultMethod") @@ -1808,7 +1808,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "DefaultMethod-ObjExpr") @@ -1847,7 +1847,7 @@ let test = { new ITest } |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 366, (7, 12, 7, 25), "No implementation was given for 'ITest.NonDefaultMethod() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") @@ -1902,7 +1902,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "OverrideDefaultMethod-NonDefaultMethod") @@ -1950,7 +1950,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "ObjExprOverrideDefaultMethod-ObjExprNonDefaultMethod") @@ -2010,7 +2010,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "FromITest2-Method1-FromITest2-Method2") @@ -2078,7 +2078,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 363, (9, 15, 9, 21), "The interface 'ITest1' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface.") @@ -2161,7 +2161,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 3352, (9, 15, 9, 21), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") @@ -2239,7 +2239,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 3352, (9, 15, 9, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") @@ -2317,7 +2317,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 3352, (13, 15, 13, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") @@ -2389,7 +2389,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 3352, (13, 15, 13, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") @@ -2455,7 +2455,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 3352, (13, 15, 13, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") @@ -2544,7 +2544,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "FSharpICombinedTest-Method1-FSharpICombinedTest-Method2") @@ -2614,7 +2614,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "FSharpICombinedTest-Method1-FSharpICombinedTest-Method2") @@ -2693,7 +2693,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "FSharpExplicitTest-Method1-FSharpExplicitTest-Method2") @@ -2755,7 +2755,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 3352, (14, 15, 14, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") @@ -2844,7 +2844,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "CSharpICombinedTest-Method1-CSharpICombinedTest-Method2") @@ -2969,7 +2969,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "CSharpIFinalCombinedTest-Method1-CSharpIFinalCombinedTest-Method2") @@ -3080,7 +3080,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "CSharpIFinalCombinedTest-Method1-") @@ -3192,7 +3192,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "CSharpIFinalCombinedTest-Method1-CSharpIFinalCombinedTest-Method2") @@ -3308,7 +3308,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "IBase-IB1-IA1-IC1-") @@ -3414,7 +3414,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "123XYZ") @@ -3517,7 +3517,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "-") @@ -3616,7 +3616,7 @@ type Test2 () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 366, (10, 15, 10, 32), "No implementation was given for 'ITest1.Method2() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") @@ -3663,7 +3663,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "A-NonDefaultMethod") @@ -3710,7 +3710,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "OverrideA-NonDefaultMethod") @@ -3773,7 +3773,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "") @@ -3840,7 +3840,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "IA.MA-IB1.IB.MB-IB1.IB.MB") @@ -3888,7 +3888,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 363, (8, 15, 8, 17), "The interface 'IA' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface.") @@ -3943,7 +3943,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 3352, (10, 15, 10, 17), "Interface member 'IA.M() : unit' does not have a most specific implementation.") @@ -4008,7 +4008,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "MMM") @@ -4098,7 +4098,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "M123456floatfs_single") @@ -4176,7 +4176,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 366, (12, 15, 12, 17), "No implementation was given for 'IA.M(x: float32) : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") @@ -4273,7 +4273,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "InTestInTest123456789111STRING-STRINGABC222FSharpABC333CSharpM(U, T)M(U, T)") @@ -4368,7 +4368,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "Test.String-Test.Prop2") @@ -4455,7 +4455,7 @@ type Test () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 3352, (12, 15, 12, 25), "Interface member 'IA.set_Prop2(value: string) : unit' does not have a most specific implementation.") @@ -4505,7 +4505,7 @@ let test = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 363, (8, 7, 8, 21), "The interface 'IA' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface.") @@ -4568,7 +4568,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "IB.IA.M") @@ -4624,7 +4624,7 @@ let main _ = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "IB.IA.M") @@ -4688,7 +4688,7 @@ f () |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "1011") @@ -4748,7 +4748,7 @@ f3 () |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.ExecutionHasOutput(fsCmpl, "359") @@ -4793,7 +4793,7 @@ let f () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 39, (6, 17, 6, 29), "The type 'CSharpClass' does not define the field, constructor or member 'StaticMethod'.") @@ -4843,7 +4843,7 @@ let f () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 39, (11, 17, 11, 29), "The type 'FSharpClass' does not define the field, constructor or member 'StaticMethod'.") @@ -4893,7 +4893,7 @@ let f () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 1, (9, 5, 9, 15), "The type 'CSharpClass' does not support the operator 'StaticMethod'") @@ -4946,7 +4946,7 @@ let f () = |> CompilationReference.Create let fsCmpl = - Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl]) + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) CompilerAssert.CompileWithErrors(fsCmpl, [| (FSharpErrorSeverity.Error, 1, (14, 5, 14, 15), "The type 'FSharpClass' does not support the operator 'StaticMethod'") diff --git a/tests/fsharp/Compiler/Language/OptionalInteropTests.fs b/tests/fsharp/Compiler/Language/OptionalInteropTests.fs index 443c4f47468..a4e4d498400 100644 --- a/tests/fsharp/Compiler/Language/OptionalInteropTests.fs +++ b/tests/fsharp/Compiler/Language/OptionalInteropTests.fs @@ -43,5 +43,5 @@ Test.M(x = Some 1) CompilationUtil.CreateCSharpCompilation(csSrc, CSharpLanguageVersion.CSharp8, TargetFramework.NetStandard20, additionalReferences = ImmutableArray.CreateRange [fsharpCoreAssembly]) |> CompilationReference.Create - let fs = Compilation.Create(fsSrc, SourceKind.Fsx, CompileOutput.Exe, options = [|"--langversion:preview"|], cmplRefs = [cs]) + let fs = Compilation.Create(fsSrc, SourceKind.Fsx, CompileOutput.Exe, options = [|"--langversion:5.0"|], cmplRefs = [cs]) CompilerAssert.Compile fs diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl index 83fd0bfa996..35fc56a3abe 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl @@ -4,4 +4,5 @@ default latest latestmajor 4.6 -4.7 (Default) \ No newline at end of file +4.7 (Default) +5.0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl index 83fd0bfa996..35fc56a3abe 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl @@ -4,4 +4,5 @@ default latest latestmajor 4.6 -4.7 (Default) \ No newline at end of file +4.7 (Default) +5.0 \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.PropertiesPages.vbproj b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.PropertiesPages.vbproj index 716a450a971..855ef4c5c21 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.PropertiesPages.vbproj +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.PropertiesPages.vbproj @@ -92,46 +92,24 @@ - - UserControl - - - UserControl - - - Form - + + + - - UserControl - - - UserControl - - - UserControl - + + + - - UserControl - - - UserControl - + + - - Form - + - - Form - - - UserControl - + + From 3a067f415a3dd6f59417852141df62d296107eb9 Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Tue, 23 Jun 2020 19:47:46 +0200 Subject: [PATCH 28/60] Consolidate Compiler ErrorMessage tests under one suite. (#9525) * Consolidate ErrorMessages compiler tests under component tests suite * Fix newlines in the assertion * Cleaned up test list; Make RIDs conditional as well Co-authored-by: Thorsten Reichert --- tests/Directory.Build.targets | 2 - .../AccessOfTypeAbbreviationTests.fs | 75 ++++++++++++++++++ .../ErrorMessages/AssignmentErrorTests.fs | 8 +- .../ErrorMessages/ClassesTests.fs | 27 +++---- .../ErrorMessages/ConfusingTypeName.fs | 67 ++++++++++++++++ .../ErrorMessages/ConstructorTests.fs | 28 +++---- .../ErrorMessages/DontSuggestTests.fs | 13 ++- .../ElseBranchHasWrongTypeTests.fs | 26 +++--- .../InvalidNumericLiteralTests.fs | 4 +- .../ErrorMessages/MissingElseBranch.fs | 11 ++- .../ErrorMessages/MissingExpressionTests.fs | 8 +- .../ErrorMessages/ModuleAbbreviationTests.fs | 8 +- .../ErrorMessages/NameResolutionTests.fs | 13 ++- .../ErrorMessages/SuggestionsTests.fs | 79 +++++++++---------- .../ErrorMessages/TypeMismatchTests.fs | 29 ++++--- .../ErrorMessages/UnitGenericAbstactType.fs | 8 +- .../ErrorMessages/UpcastDowncastTests.fs | 11 ++- .../ErrorMessages/WarnExpressionTests.fs | 30 +++---- .../ErrorMessages/WrongSyntaxInForLoop.fs | 8 +- .../FSharp.Compiler.ComponentTests.fsproj | 22 +++++- tests/FSharp.Test.Utilities/CompilerAssert.fs | 6 +- .../FSharp.Test.Utilities.fsproj | 6 +- tests/FSharp.Test.Utilities/Utilities.fs | 7 +- .../AccessOfTypeAbbreviationTests.fs | 76 ------------------ tests/fsharp/FSharpSuite.Tests.fsproj | 16 ---- .../ErrorMessages/ConfusingTypeName/app.fs | 22 ------ .../ConfusingTypeName/compile.bat | 6 -- .../ErrorMessages/ConfusingTypeName/env.lst | 3 - .../ConfusingTypeName/liba-and-b.cs | 2 - .../ErrorMessages/ConfusingTypeName/libc.fs | 3 - .../ErrorMessages/ConfusingTypeName/libd.fs | 3 - tests/fsharpqa/Source/test.lst | 2 - 32 files changed, 329 insertions(+), 300 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/ErrorMessages/AccessOfTypeAbbreviationTests.fs rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/AssignmentErrorTests.fs (86%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/ClassesTests.fs (82%) create mode 100644 tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConfusingTypeName.fs rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/ConstructorTests.fs (88%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/DontSuggestTests.fs (84%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/ElseBranchHasWrongTypeTests.fs (96%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/MissingElseBranch.fs (93%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/MissingExpressionTests.fs (89%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/ModuleAbbreviationTests.fs (87%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/NameResolutionTests.fs (72%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/SuggestionsTests.fs (62%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/TypeMismatchTests.fs (84%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/UnitGenericAbstactType.fs (91%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/UpcastDowncastTests.fs (94%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/WarnExpressionTests.fs (97%) rename tests/{fsharp/Compiler => FSharp.Compiler.ComponentTests}/ErrorMessages/WrongSyntaxInForLoop.fs (86%) delete mode 100644 tests/fsharp/Compiler/ErrorMessages/AccessOfTypeAbbreviationTests.fs delete mode 100644 tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/app.fs delete mode 100644 tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/compile.bat delete mode 100644 tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/env.lst delete mode 100644 tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/liba-and-b.cs delete mode 100644 tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libc.fs delete mode 100644 tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libd.fs diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets index 6df5fdfa9c7..1108759d4a2 100644 --- a/tests/Directory.Build.targets +++ b/tests/Directory.Build.targets @@ -3,13 +3,11 @@ - - diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AccessOfTypeAbbreviationTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AccessOfTypeAbbreviationTests.fs new file mode 100644 index 00000000000..416c62d63f6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AccessOfTypeAbbreviationTests.fs @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ErrorMessages.ComponentTests + +open Xunit +open FSharp.Test.Utilities +open FSharp.Compiler.SourceCodeServices + +module ``Access Of Type Abbreviation`` = + + [] + let ``Private type produces warning when trying to export``() = + CompilerAssert.TypeCheckSingleError + """ +module Library = + type private Hidden = Hidden of unit + type Exported = Hidden + """ + FSharpErrorSeverity.Warning + 44 + (4, 8, 4, 16) + ("This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in." + System.Environment.NewLine + "As of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors.") + + [] + let ``Internal type passes when abbrev is internal``() = + CompilerAssert.Pass + """ +module Library = + type internal Hidden = Hidden of unit + type internal Exported = Hidden + """ + + [] + let ``Internal type produces warning when trying to export``() = + CompilerAssert.TypeCheckSingleError + """ +module Library = + type internal Hidden = Hidden of unit + type Exported = Hidden + """ + FSharpErrorSeverity.Warning + 44 + (4, 8, 4, 16) + ("This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in." + System.Environment.NewLine + "As of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors.") + + [] + let ``Private type produces warning when abbrev is internal``() = + CompilerAssert.TypeCheckSingleError + """ +module Library = + type private Hidden = Hidden of unit + type internal Exported = Hidden + """ + FSharpErrorSeverity.Warning + 44 + (4, 17, 4, 25) + ("This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in." + System.Environment.NewLine + "As of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors.") + + [] + let ``Private type passes when abbrev is private``() = + CompilerAssert.Pass + """ +module Library = + type private Hidden = Hidden of unit + type private Exported = Hidden + """ + + [] + let ``Default access type passes when abbrev is default``() = + CompilerAssert.Pass + """ +module Library = + type Hidden = Hidden of unit + type Exported = Hidden + """ diff --git a/tests/fsharp/Compiler/ErrorMessages/AssignmentErrorTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AssignmentErrorTests.fs similarity index 86% rename from tests/fsharp/Compiler/ErrorMessages/AssignmentErrorTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/AssignmentErrorTests.fs index c1226c4ff93..f2f598d9dba 100644 --- a/tests/fsharp/Compiler/ErrorMessages/AssignmentErrorTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AssignmentErrorTests.fs @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] + module ``Errors assigning to mutable objects`` = - [] + [] let ``Assign to immutable error``() = CompilerAssert.TypeCheckSingleError """ diff --git a/tests/fsharp/Compiler/ErrorMessages/ClassesTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs similarity index 82% rename from tests/fsharp/Compiler/ErrorMessages/ClassesTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs index f02837ef0c3..a51e92ed944 100644 --- a/tests/fsharp/Compiler/ErrorMessages/ClassesTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] module ``Classes`` = - [] + [] let ``Tuple In Abstract Method``() = CompilerAssert.TypeCheckWithErrors """ @@ -27,7 +26,7 @@ let x = FSharpErrorSeverity.Error, 783, (6, 9, 6, 19), "At least one override did not correctly implement its corresponding abstract member" |] - [] + [] let ``Wrong Arity``() = CompilerAssert.TypeCheckSingleError """ @@ -43,7 +42,7 @@ MyType.MyMember("", 0, 0) (7, 1, 7, 26) "A member or object constructor 'MyMember' taking 3 arguments is not accessible from this code location. All accessible versions of method 'MyMember' take 2 arguments." - [] + [] let ``Method Is Not Static``() = CompilerAssert.TypeCheckSingleError """ @@ -57,7 +56,7 @@ let x = Class1.X() (5, 9, 5, 17) "Method or object constructor 'X' is not static" - [] + [] let ``Matching Method With Same Name Is Not Abstract``() = CompilerAssert.TypeCheckWithErrors """ @@ -75,7 +74,7 @@ let foo = FSharpErrorSeverity.Error, 783, (6, 11, 6, 14), "At least one override did not correctly implement its corresponding abstract member" |] - [] + [] let ``No Matching Abstract Method With Same Name``() = CompilerAssert.TypeCheckWithErrors """ @@ -89,13 +88,13 @@ let x = } """ [| - FSharpErrorSeverity.Error, 767, (8, 14, 8, 34), "The member 'Function' does not correspond to any abstract or virtual method available to override or implement. Maybe you want one of the following:\r\n MyFunction" + FSharpErrorSeverity.Error, 767, (8, 14, 8, 34), "The member 'Function' does not correspond to any abstract or virtual method available to override or implement. Maybe you want one of the following:" + System.Environment.NewLine + " MyFunction" FSharpErrorSeverity.Error, 17, (8, 19, 8, 27), "The member 'Function : 'a * 'b -> unit' does not have the correct type to override any given virtual method" - FSharpErrorSeverity.Error, 366, (7, 3, 9, 4), "No implementation was given for those members: \r\n\t'abstract member IInterface.MyFunction : int32 * int32 -> unit'\r\n\t'abstract member IInterface.SomeOtherFunction : int32 * int32 -> unit'\r\nNote that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'." + FSharpErrorSeverity.Error, 366, (7, 3, 9, 4), "No implementation was given for those members: " + System.Environment.NewLine + "\t'abstract member IInterface.MyFunction : int32 * int32 -> unit'" + System.Environment.NewLine + "\t'abstract member IInterface.SomeOtherFunction : int32 * int32 -> unit'" + System.Environment.NewLine + "Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'." FSharpErrorSeverity.Error, 783, (7, 9, 7, 19), "At least one override did not correctly implement its corresponding abstract member" |] - [] + [] let ``Member Has Multiple Possible Dispatch Slots``() = CompilerAssert.TypeCheckWithErrors """ @@ -108,11 +107,11 @@ type Overload = override __.Bar _ = 1 """ [| - FSharpErrorSeverity.Error, 366, (7, 15, 7, 24), "No implementation was given for those members: \r\n\t'abstract member IOverload.Bar : double -> int'\r\n\t'abstract member IOverload.Bar : int -> int'\r\nNote that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'." - FSharpErrorSeverity.Error, 3213, (8, 21, 8, 24), "The member 'Bar<'a0> : 'a0 -> int' matches multiple overloads of the same method.\nPlease restrict it to one of the following:\r\n Bar : double -> int\r\n Bar : int -> int." + FSharpErrorSeverity.Error, 366, (7, 15, 7, 24), "No implementation was given for those members: " + System.Environment.NewLine + "\t'abstract member IOverload.Bar : double -> int'" + System.Environment.NewLine + "\t'abstract member IOverload.Bar : int -> int'" + System.Environment.NewLine + "Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'." + FSharpErrorSeverity.Error, 3213, (8, 21, 8, 24), "The member 'Bar<'a0> : 'a0 -> int' matches multiple overloads of the same method.\nPlease restrict it to one of the following:" + System.Environment.NewLine + " Bar : double -> int" + System.Environment.NewLine + " Bar : int -> int." |] - [] + [] let ``Do Cannot Have Visibility Declarations``() = CompilerAssert.ParseWithErrors """ diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConfusingTypeName.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConfusingTypeName.fs new file mode 100644 index 00000000000..b67a75ec601 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConfusingTypeName.fs @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ErrorMessages.ComponentTests + +open Xunit +open FSharp.Test.Utilities +open FSharp.Test.Utilities.Utilities +open FSharp.Compiler.SourceCodeServices + +module ``Confusing Type Name`` = + + [] + let ``Checks expected types with multiple references``() = + let csLibAB = """ +public class A { } +public class B { } + """ + let csLibACmpl = + CompilationUtil.CreateCSharpCompilation(csLibAB, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30, name = "libA") + |> CompilationReference.Create + + let csLibBCmpl = + CompilationUtil.CreateCSharpCompilation(csLibAB, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30, name = "libB") + |> CompilationReference.Create + + let fsLibC = """ +module AMaker +let makeA () : A = A() +let makeB () = B<_>() + """ + + let fsLibD = """ +module OtherAMaker +let makeOtherA () : A = A() +let makeOtherB () = B<_>() + """ + + let fsLibCCmpl = + Compilation.Create(fsLibC, Fs, Library, cmplRefs = [csLibACmpl], name = "libC") + |> CompilationReference.CreateFSharp + + let fsLibDCmpl = + Compilation.Create(fsLibD, Fs, Library, cmplRefs = [csLibBCmpl], name = "libD") + |> CompilationReference.CreateFSharp + + let app = """ +module ConfusingTypeName +let a = AMaker.makeA() +let otherA = OtherAMaker.makeOtherA() +printfn "%A %A" (a.GetType().AssemblyQualifiedName) (otherA.GetType().AssemblyQualifiedName) +printfn "%A" (a = otherA) + +let b = AMaker.makeB() +let otherB = OtherAMaker.makeOtherB() +printfn "%A %A" (b.GetType().AssemblyQualifiedName) (otherB.GetType().AssemblyQualifiedName) +printfn "%A" (b = otherB) + """ + + let appCmpl = + Compilation.Create(app, Fs, Library, cmplRefs = [csLibACmpl; csLibBCmpl; fsLibCCmpl; fsLibDCmpl]) + + CompilerAssert.CompileWithErrors( + appCmpl, + [| + (FSharpErrorSeverity.Error, 1, (6, 19, 6, 25), ("This expression was expected to have type\n 'A (libA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' \nbut here has type\n 'A (libB, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' ")) + (FSharpErrorSeverity.Error, 1, (11, 19, 11, 25), ("This expression was expected to have type\n 'B (libA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' \nbut here has type\n 'B (libB, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' ")) + |], true) diff --git a/tests/fsharp/Compiler/ErrorMessages/ConstructorTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConstructorTests.fs similarity index 88% rename from tests/fsharp/Compiler/ErrorMessages/ConstructorTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConstructorTests.fs index be7e5823391..c9636e711a5 100644 --- a/tests/fsharp/Compiler/ErrorMessages/ConstructorTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConstructorTests.fs @@ -1,29 +1,27 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] module ``Constructor`` = - [] + [] let ``Invalid Record``() = CompilerAssert.TypeCheckWithErrors """ type Record = {field1:int; field2:int} let doSomething (xs) = List.map (fun {field1=x} -> x) xs - doSomething {Record.field1=0; field2=0} """ [| - FSharpErrorSeverity.Error, 1, (5, 13, 5, 40), "This expression was expected to have type\n 'Record list' \nbut here has type\n 'Record' " - FSharpErrorSeverity.Warning, 20, (5, 1, 5, 40), "The result of this expression has type 'int list' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." + FSharpErrorSeverity.Error, 1, (4, 13, 4, 40), "This expression was expected to have type\n 'Record list' \nbut here has type\n 'Record' " + FSharpErrorSeverity.Warning, 20, (4, 1, 4, 40), "The result of this expression has type 'int list' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." |] - [] + [] let ``Comma In Rec Ctor``() = CompilerAssert.TypeCheckWithErrors """ @@ -31,11 +29,11 @@ type Person = { Name : string; Age : int; City : string } let x = { Name = "Isaac", Age = 21, City = "London" } """ [| - FSharpErrorSeverity.Error, 1, (3, 18, 3, 52), "This expression was expected to have type\n 'string' \nbut here has type\n ''a * 'b * 'c' \r\nA ';' is used to separate field values in records. Consider replacing ',' with ';'." + FSharpErrorSeverity.Error, 1, (3, 18, 3, 52), "This expression was expected to have type\n 'string' \nbut here has type\n ''a * 'b * 'c' " + System.Environment.NewLine + "A ';' is used to separate field values in records. Consider replacing ',' with ';'." FSharpErrorSeverity.Error, 764, (3, 9, 3, 54), "No assignment given for field 'Age' of type 'Test.Person'" |] - [] + [] let ``Missing Comma In Ctor``() = CompilerAssert.TypeCheckWithErrors """ @@ -48,13 +46,13 @@ let p = Age = 18) """ [| - FSharpErrorSeverity.Error, 39, (7, 12, 7, 16), "The value or constructor 'Name' is not defined. Maybe you want one of the following:\r\n nan" + FSharpErrorSeverity.Error, 39, (7, 12, 7, 16), "The value or constructor 'Name' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " nan" FSharpErrorSeverity.Warning, 20, (7, 12, 7, 25), "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'." FSharpErrorSeverity.Error, 39, (8, 12, 8, 15), "The value or constructor 'Age' is not defined." FSharpErrorSeverity.Error, 501, (7, 5, 8, 21), "The object constructor 'Person' takes 0 argument(s) but is here given 1. The required signature is 'new : unit -> Person'. If some of the arguments are meant to assign values to properties, consider separating those arguments with a comma (',')." |] - [] + [] let ``Missing Ctor Value``() = CompilerAssert.TypeCheckSingleError """ @@ -71,7 +69,7 @@ let p = (7, 5, 8, 21) "The member or object constructor 'Person' requires 1 argument(s). The required signature is 'new : x:int -> Person'." - [] + [] let ``Extra Argument In Ctor``() = CompilerAssert.TypeCheckSingleError """ @@ -87,7 +85,7 @@ let p = (7, 5, 7, 14) "The object constructor 'Person' takes 0 argument(s) but is here given 1. The required signature is 'new : unit -> Person'." - [] + [] let ``Extra Argument In Ctor2``() = CompilerAssert.TypeCheckSingleError """ @@ -105,7 +103,7 @@ let p = (9, 5, 9, 16) "The object constructor 'Person' takes 0 argument(s) but is here given 1. The required signature is 'new : unit -> Person'." - [] + [] let ``Valid Comma In Rec Ctor``() = CompilerAssert.Pass """ diff --git a/tests/fsharp/Compiler/ErrorMessages/DontSuggestTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DontSuggestTests.fs similarity index 84% rename from tests/fsharp/Compiler/ErrorMessages/DontSuggestTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/DontSuggestTests.fs index f7b3cc2cb05..13a6f6b0dcc 100644 --- a/tests/fsharp/Compiler/ErrorMessages/DontSuggestTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DontSuggestTests.fs @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] module ``Don't Suggest`` = - [] + [] let ``Dont Suggest Completely Wrong Stuff``() = CompilerAssert.TypeCheckSingleError """ @@ -18,9 +17,9 @@ let _ = Path.GetFullPath "images" FSharpErrorSeverity.Error 39 (2, 9, 2, 13) - "The value, namespace, type or module 'Path' is not defined. Maybe you want one of the following:\r\n Math" + ("The value, namespace, type or module 'Path' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " Math") - [] + [] let ``Dont Suggest When Things Are Open``() = CompilerAssert.ParseWithErrors """ @@ -37,7 +36,7 @@ let x = N. FSharpErrorSeverity.Error, 222, (2, 1, 3, 1), "Files in libraries or multiple-file applications must begin with a namespace or module declaration. When using a module declaration at the start of a file the '=' sign is not allowed. If this is a top-level module, consider removing the = to resolve this error." |] - [] + [] let ``Dont Suggest Intentionally Unused Variables``() = CompilerAssert.TypeCheckSingleError """ diff --git a/tests/fsharp/Compiler/ErrorMessages/ElseBranchHasWrongTypeTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ElseBranchHasWrongTypeTests.fs similarity index 96% rename from tests/fsharp/Compiler/ErrorMessages/ElseBranchHasWrongTypeTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/ElseBranchHasWrongTypeTests.fs index ed5b9a44863..54d5c41a68c 100644 --- a/tests/fsharp/Compiler/ErrorMessages/ElseBranchHasWrongTypeTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ElseBranchHasWrongTypeTests.fs @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] + module ``Else branch has wrong type`` = - [] + [] let ``Else branch is int while if branch is string``() = CompilerAssert.TypeCheckSingleError """ @@ -23,7 +23,7 @@ let y = (5, 10, 5, 13) "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'string'. This branch returns a value of type 'int'." - [] + [] let ``Else branch is a function that returns int while if branch is string``() = CompilerAssert.TypeCheckSingleError """ @@ -39,7 +39,7 @@ let y = "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'string'. This branch returns a value of type 'int'." - [] + [] let ``Else branch is a sequence of expressions that returns int while if branch is string``() = CompilerAssert.TypeCheckSingleError """ @@ -58,7 +58,7 @@ let y = "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'string'. This branch returns a value of type 'int'." - [] + [] let ``Else branch is a longer sequence of expressions that returns int while if branch is string``() = CompilerAssert.TypeCheckSingleError """ @@ -79,7 +79,7 @@ let y = "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'string'. This branch returns a value of type 'int'." - [] + [] let ``Else branch context doesn't propagate into function application``() = CompilerAssert.TypeCheckSingleError """ @@ -95,7 +95,7 @@ let y = (7, 11, 7, 14) "This expression was expected to have type\n 'string' \nbut here has type\n 'int' " - [] + [] let ``Else branch context doesn't propagate into function application even if not last expr``() = CompilerAssert.TypeCheckSingleError """ @@ -112,7 +112,7 @@ let y = (7, 11, 7, 14) "This expression was expected to have type\n 'string' \nbut here has type\n 'int' " - [] + [] let ``Else branch context doesn't propagate into for loop``() = CompilerAssert.TypeCheckSingleError """ @@ -131,7 +131,7 @@ let y = (7, 14, 7, 22) "This expression was expected to have type\n 'int' \nbut here has type\n 'string' " - [] + [] let ``Else branch context doesn't propagate to lines before last line``() = CompilerAssert.TypeCheckSingleError """ @@ -149,7 +149,7 @@ let y = (7, 22, 7, 23) "This expression was expected to have type\n 'string' \nbut here has type\n 'int' " - [] + [] let ``Else branch should not have wrong context type``() = CompilerAssert.TypeCheckWithErrors """ @@ -162,7 +162,7 @@ let y : bool = FSharpErrorSeverity.Error, 1, (5, 10, 5, 13), "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'bool'. This branch returns a value of type 'string'." |] - [] + [] let ``Else branch has wrong type in nested if``() = CompilerAssert.TypeCheckWithErrors """ diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs index c6631ab629e..a20dd899762 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.ComponentTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -module ``Invalid Numeric Literal`` = +module ``Numeric Literals`` = [] let ``1up is invalid Numeric Literal``() = diff --git a/tests/fsharp/Compiler/ErrorMessages/MissingElseBranch.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingElseBranch.fs similarity index 93% rename from tests/fsharp/Compiler/ErrorMessages/MissingElseBranch.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingElseBranch.fs index 370b4c24053..9ab09f8a9ea 100644 --- a/tests/fsharp/Compiler/ErrorMessages/MissingElseBranch.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingElseBranch.fs @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] module ``Else branch is missing`` = - [] + [] let ``Fail if else branch is missing``() = CompilerAssert.TypeCheckSingleError """ @@ -22,7 +21,7 @@ let y = (4, 19, 4, 25) "This 'if' expression is missing an 'else' branch. Because 'if' is an expression, and not a statement, add an 'else' branch which also returns a value of type 'string'." - [] + [] let ``Fail on type error in condition``() = CompilerAssert.TypeCheckSingleError """ @@ -37,7 +36,7 @@ let y = (5, 14, 5, 20) "This expression was expected to have type\n 'int' \nbut here has type\n 'string' " - [] + [] let ``Fail if else branch is missing in nesting``() = CompilerAssert.TypeCheckSingleError """ diff --git a/tests/fsharp/Compiler/ErrorMessages/MissingExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingExpressionTests.fs similarity index 89% rename from tests/fsharp/Compiler/ErrorMessages/MissingExpressionTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingExpressionTests.fs index b00833e418a..802bcfd6750 100644 --- a/tests/fsharp/Compiler/ErrorMessages/MissingExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingExpressionTests.fs @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] + module ``Missing Expression`` = - [] + [] let ``Missing Expression after let``() = CompilerAssert.TypeCheckSingleError """ diff --git a/tests/fsharp/Compiler/ErrorMessages/ModuleAbbreviationTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleAbbreviationTests.fs similarity index 87% rename from tests/fsharp/Compiler/ErrorMessages/ModuleAbbreviationTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleAbbreviationTests.fs index b67bb8ca8b5..5c9647fb070 100644 --- a/tests/fsharp/Compiler/ErrorMessages/ModuleAbbreviationTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleAbbreviationTests.fs @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] + module ``Module Abbreviations`` = - [] + [] let ``Public Module Abbreviation``() = CompilerAssert.TypeCheckSingleError """ diff --git a/tests/fsharp/Compiler/ErrorMessages/NameResolutionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs similarity index 72% rename from tests/fsharp/Compiler/ErrorMessages/NameResolutionTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs index 4a94339fe18..c48a5c9113b 100644 --- a/tests/fsharp/Compiler/ErrorMessages/NameResolutionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] module NameResolutionTests = - [] + [] let FieldNotInRecord () = CompilerAssert.TypeCheckSingleError """ @@ -25,9 +24,9 @@ let r:F = { Size=3; Height=4; Wall=1 } FSharpErrorSeverity.Error 1129 (9, 31, 9, 35) - "The record type 'F' does not contain a label 'Wall'. Maybe you want one of the following:\r\n Wallis" + ("The record type 'F' does not contain a label 'Wall'. Maybe you want one of the following:" + System.Environment.NewLine + " Wallis") - [] + [] let RecordFieldProposal () = CompilerAssert.TypeCheckSingleError """ @@ -43,4 +42,4 @@ let r = { Size=3; Height=4; Wall=1 } FSharpErrorSeverity.Error 39 (9, 29, 9, 33) - "The record label 'Wall' is not defined. Maybe you want one of the following:\r\n Walls\r\n Wallis" + ("The record label 'Wall' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " Walls" + System.Environment.NewLine + " Wallis") diff --git a/tests/fsharp/Compiler/ErrorMessages/SuggestionsTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/SuggestionsTests.fs similarity index 62% rename from tests/fsharp/Compiler/ErrorMessages/SuggestionsTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/SuggestionsTests.fs index e6f44d2430f..bf26f8a2102 100644 --- a/tests/fsharp/Compiler/ErrorMessages/SuggestionsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/SuggestionsTests.fs @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] module Suggestions = - [] + [] let ``Field Suggestion`` () = CompilerAssert.TypeCheckSingleError """ @@ -20,10 +19,10 @@ let x = { Person.Names = "Isaac" } FSharpErrorSeverity.Error 39 (4, 18, 4, 23) - "The type 'Person' does not define the field, constructor or member 'Names'. Maybe you want one of the following:\r\n Name" + ("The type 'Person' does not define the field, constructor or member 'Names'. Maybe you want one of the following:" + System.Environment.NewLine + " Name") - [] + [] let ``Suggest Array Module Functions`` () = CompilerAssert.TypeCheckSingleError """ @@ -33,10 +32,10 @@ let f = FSharpErrorSeverity.Error 39 (3, 11, 3, 14) - "The value, constructor, namespace or type 'blt' is not defined. Maybe you want one of the following:\r\n blit" + ("The value, constructor, namespace or type 'blt' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " blit") - [] + [] let ``Suggest Async Module`` () = CompilerAssert.TypeCheckSingleError """ @@ -46,10 +45,10 @@ let f = FSharpErrorSeverity.Error 39 (3, 5, 3, 9) - "The value, namespace, type or module 'Asnc' is not defined. Maybe you want one of the following:\r\n Async\r\n async\r\n asin\r\n snd" + ("The value, namespace, type or module 'Asnc' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " Async" + System.Environment.NewLine + " async" + System.Environment.NewLine + " asin" + System.Environment.NewLine + " snd") - [] + [] let ``Suggest Attribute`` () = CompilerAssert.TypeCheckSingleError """ @@ -61,10 +60,10 @@ type MyClass<'Bar>() = FSharpErrorSeverity.Error 39 (2, 3, 2, 15) - "The type 'AbstractClas' is not defined. Maybe you want one of the following:\r\n AbstractClass\r\n AbstractClassAttribute" + ("The type 'AbstractClas' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " AbstractClass" + System.Environment.NewLine + " AbstractClassAttribute") - [] + [] let ``Suggest Double Backtick Identifiers`` () = CompilerAssert.TypeCheckSingleError """ @@ -76,10 +75,10 @@ let x = N.``longe name`` FSharpErrorSeverity.Error 39 (5, 11, 5, 25) - "The value, constructor, namespace or type 'longe name' is not defined. Maybe you want one of the following:\r\n longer name" + ("The value, constructor, namespace or type 'longe name' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " longer name") - [] + [] let ``Suggest Double Backtick Unions`` () = CompilerAssert.TypeCheckSingleError """ @@ -95,10 +94,10 @@ let x = N.MyUnion.``My Case2`` FSharpErrorSeverity.Error 39 (9, 19, 9,31) - "The type 'MyUnion' does not define the field, constructor or member 'My Case2'. Maybe you want one of the following:\r\n My Case1\r\n Case2" + ("The type 'MyUnion' does not define the field, constructor or member 'My Case2'. Maybe you want one of the following:" + System.Environment.NewLine + " My Case1" + System.Environment.NewLine + " Case2") - [] + [] let ``Suggest Fields In Constructor`` () = CompilerAssert.TypeCheckSingleError """ @@ -112,10 +111,10 @@ let c = MyClass(Property = "") FSharpErrorSeverity.Error 495 (7, 17, 7, 25) - "The object constructor 'MyClass' has no argument or settable return property 'Property'. The required signature is new : unit -> MyClass. Maybe you want one of the following:\r\n MyProperty\r\n MyProperty2\r\n ABigProperty" + ("The object constructor 'MyClass' has no argument or settable return property 'Property'. The required signature is new : unit -> MyClass. Maybe you want one of the following:" + System.Environment.NewLine + " MyProperty" + System.Environment.NewLine + " MyProperty2" + System.Environment.NewLine + " ABigProperty") - [] + [] let ``Suggest Generic Type`` () = CompilerAssert.TypeCheckSingleError """ @@ -124,10 +123,10 @@ type T = System.Collections.Generic.Dictionary FSharpErrorSeverity.Error 39 (2, 48, 2, 53) - "The type 'int11' is not defined. Maybe you want one of the following:\r\n int16\r\n int16`1\r\n int8\r\n uint16\r\n int" + ("The type 'int11' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " int16" + System.Environment.NewLine + " int16`1" + System.Environment.NewLine + " int8" + System.Environment.NewLine + " uint16" + System.Environment.NewLine + " int") - [] + [] let ``Suggest Methods`` () = CompilerAssert.TypeCheckSingleError """ @@ -143,10 +142,10 @@ module Test2 = FSharpErrorSeverity.Error 39 (9, 7, 9, 14) - "The type 'D' does not define the field, constructor or member 'Method2'. Maybe you want one of the following:\r\n Method1" + ("The type 'D' does not define the field, constructor or member 'Method2'. Maybe you want one of the following:" + System.Environment.NewLine + " Method1") - [] + [] let ``Suggest Modules`` () = CompilerAssert.TypeCheckSingleError """ @@ -159,10 +158,10 @@ open Collectons FSharpErrorSeverity.Error 39 (6, 6, 6, 16) - "The namespace or module 'Collectons' is not defined. Maybe you want one of the following:\r\n Collections" + ("The namespace or module 'Collectons' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " Collections") - [] + [] let ``Suggest Namespaces`` () = CompilerAssert.TypeCheckSingleError """ @@ -174,7 +173,7 @@ open System.Collectons "The namespace 'Collectons' is not defined." - [] + [] let ``Suggest Record Labels`` () = CompilerAssert.TypeCheckSingleError """ @@ -187,10 +186,10 @@ let x = r.ello FSharpErrorSeverity.Error 39 (6, 11, 6, 15) - "The type 'MyRecord' does not define the field, constructor or member 'ello'. Maybe you want one of the following:\r\n Hello" + ("The type 'MyRecord' does not define the field, constructor or member 'ello'. Maybe you want one of the following:" + System.Environment.NewLine + " Hello") - [] + [] let ``Suggest Record Type for RequireQualifiedAccess Records`` () = CompilerAssert.TypeCheckSingleError """ @@ -205,10 +204,10 @@ let r = { Field1 = "hallo"; Field2 = 1 } FSharpErrorSeverity.Error 39 (8, 11, 8, 17) - "The record label 'Field1' is not defined. Maybe you want one of the following:\r\n MyRecord.Field1" + ("The record label 'Field1' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " MyRecord.Field1") - [] + [] let ``Suggest To Use Indexer`` () = CompilerAssert.TypeCheckWithErrors """ @@ -227,7 +226,7 @@ let a = (f())[1] |] - [] + [] let ``Suggest Type Parameters`` () = CompilerAssert.TypeCheckSingleError """ @@ -243,7 +242,7 @@ type MyClass<'Bar>() = "The type parameter 'B is not defined." - [] + [] let ``Suggest Types in Module`` () = CompilerAssert.TypeCheckSingleError """ @@ -252,9 +251,9 @@ let x : System.Collections.Generic.Lst = ResizeArray() FSharpErrorSeverity.Error 39 (2, 36, 2, 39) - "The type 'Lst' is not defined in 'System.Collections.Generic'. Maybe you want one of the following:\r\n List\r\n IList\r\n List`1" + ("The type 'Lst' is not defined in 'System.Collections.Generic'. Maybe you want one of the following:" + System.Environment.NewLine + " List" + System.Environment.NewLine + " IList" + System.Environment.NewLine + " List`1") - [] + [] let ``Suggest Types in Namespace`` () = CompilerAssert.TypeCheckSingleError """ @@ -263,10 +262,10 @@ let x = System.DateTie.MaxValue FSharpErrorSeverity.Error 39 (2, 16, 2, 23) - "The value, constructor, namespace or type 'DateTie' is not defined. Maybe you want one of the following:\r\n DateTime\r\n DateTimeKind\r\n DateTimeOffset\r\n Data" + ("The value, constructor, namespace or type 'DateTie' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " DateTime" + System.Environment.NewLine + " DateTimeKind" + System.Environment.NewLine + " DateTimeOffset" + System.Environment.NewLine + " Data") - [] + [] let ``Suggest Union Cases`` () = CompilerAssert.TypeCheckSingleError """ @@ -279,10 +278,10 @@ let u = MyUnion.AntherCase FSharpErrorSeverity.Error 39 (6, 17, 6, 27) - "The type 'MyUnion' does not define the field, constructor or member 'AntherCase'. Maybe you want one of the following:\r\n AnotherCase" + ("The type 'MyUnion' does not define the field, constructor or member 'AntherCase'. Maybe you want one of the following:" + System.Environment.NewLine + " AnotherCase") - [] + [] let ``Suggest Union Type for RequireQualifiedAccess Unions`` () = CompilerAssert.TypeCheckSingleError """ @@ -296,10 +295,10 @@ let x : MyUnion = MyCase1 FSharpErrorSeverity.Error 39 (7, 19, 7, 26) - "The value or constructor 'MyCase1' is not defined. Maybe you want one of the following:\r\n MyUnion.MyCase1" + ("The value or constructor 'MyCase1' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " MyUnion.MyCase1") - [] + [] let ``Suggest Unions in PatternMatch`` () = CompilerAssert.TypeCheckSingleError """ @@ -318,4 +317,4 @@ let x = FSharpErrorSeverity.Error 39 (11, 15, 11, 19) - "The type 'MyUnion' does not define the field, constructor or member 'Cas1'. Maybe you want one of the following:\r\n Case1\r\n Case2" + ("The type 'MyUnion' does not define the field, constructor or member 'Cas1'. Maybe you want one of the following:" + System.Environment.NewLine + " Case1" + System.Environment.NewLine + " Case2") diff --git a/tests/fsharp/Compiler/ErrorMessages/TypeMismatchTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs similarity index 84% rename from tests/fsharp/Compiler/ErrorMessages/TypeMismatchTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs index 58557c82cd4..817e0a588c6 100644 --- a/tests/fsharp/Compiler/ErrorMessages/TypeMismatchTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] module ``Type Mismatch`` = - [] + [] let ``return Instead Of return!``() = CompilerAssert.TypeCheckSingleError """ @@ -20,7 +19,7 @@ let rec foo() = async { return foo() } (2, 32, 2, 37) "Type mismatch. Expecting a\n ''a' \nbut given a\n 'Async<'a>' \nThe types ''a' and 'Async<'a>' cannot be unified. Consider using 'return!' instead of 'return'." - [] + [] let ``yield Instead Of yield!``() = CompilerAssert.TypeCheckSingleError """ @@ -34,7 +33,7 @@ let rec f () = Foo() { yield f ()} (5, 30, 5, 34) "Type mismatch. Expecting a\n ''a' \nbut given a\n ''a list' \nThe types ''a' and ''a list' cannot be unified. Consider using 'yield!' instead of 'yield'." - [] + [] let ``Ref Cell Instead Of Not``() = CompilerAssert.TypeCheckSingleError """ @@ -45,9 +44,9 @@ if !x then FSharpErrorSeverity.Error 1 (3, 5, 3, 6) - "This expression was expected to have type\n 'bool ref' \nbut here has type\n 'bool' \r\nThe '!' operator is used to dereference a ref cell. Consider using 'not expr' here." + ("This expression was expected to have type\n 'bool ref' \nbut here has type\n 'bool' " + System.Environment.NewLine + "The '!' operator is used to dereference a ref cell. Consider using 'not expr' here.") - [] + [] let ``Ref Cell Instead Of Not 2``() = CompilerAssert.TypeCheckSingleError """ @@ -57,9 +56,9 @@ let y = !x FSharpErrorSeverity.Error 1 (3, 10, 3, 11) - "This expression was expected to have type\n ''a ref' \nbut here has type\n 'bool' \r\nThe '!' operator is used to dereference a ref cell. Consider using 'not expr' here." + ("This expression was expected to have type\n ''a ref' \nbut here has type\n 'bool' " + System.Environment.NewLine + "The '!' operator is used to dereference a ref cell. Consider using 'not expr' here.") - [] + [] let ``Guard Has Wrong Type``() = CompilerAssert.TypeCheckWithErrors """ @@ -73,7 +72,7 @@ match x with FSharpErrorSeverity.Warning, 20, (3, 1, 5, 13), "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." |] - [] + [] let ``Runtime Type Test In Pattern``() = CompilerAssert.TypeCheckWithErrors """ @@ -91,7 +90,7 @@ let c = FSharpErrorSeverity.Error, 193, (8, 5, 8, 28), "Type constraint mismatch. The type \n 'IDictionary' \nis not compatible with type\n 'Dictionary' \n" |] - [] + [] let ``Runtime Type Test In Pattern 2``() = CompilerAssert.TypeCheckWithErrors """ @@ -109,7 +108,7 @@ let c = FSharpErrorSeverity.Error, 193, (8, 5, 8, 28), "Type constraint mismatch. The type \n 'IDictionary' \nis not compatible with type\n 'Dictionary' \n" |] - [] + [] let ``Override Errors``() = CompilerAssert.TypeCheckWithErrors """ @@ -130,7 +129,7 @@ type Derived3() = override x.Member (s : string, i : int) = sprintf "Hello %s" s """ [| - FSharpErrorSeverity.Error, 856, (8, 16, 8, 22), "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:\r\n abstract member Base.Member : int * string -> string" - FSharpErrorSeverity.Error, 856, (12, 16, 12, 22), "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:\r\n abstract member Base.Member : int * string -> string" + FSharpErrorSeverity.Error, 856, (8, 16, 8, 22), "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:" + System.Environment.NewLine + " abstract member Base.Member : int * string -> string" + FSharpErrorSeverity.Error, 856, (12, 16, 12, 22), "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:" + System.Environment.NewLine + " abstract member Base.Member : int * string -> string" FSharpErrorSeverity.Error, 1, (16, 24, 16, 34), "This expression was expected to have type\n 'int' \nbut here has type\n 'string' " |] diff --git a/tests/fsharp/Compiler/ErrorMessages/UnitGenericAbstactType.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitGenericAbstactType.fs similarity index 91% rename from tests/fsharp/Compiler/ErrorMessages/UnitGenericAbstactType.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitGenericAbstactType.fs index 3fee1050ef9..11ec30ab19a 100644 --- a/tests/fsharp/Compiler/ErrorMessages/UnitGenericAbstactType.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitGenericAbstactType.fs @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] + module ``Unit generic abstract Type`` = - [] + [] let ``Unit can not be used as return type of abstract method paramete on return type``() = CompilerAssert.TypeCheckSingleError """ diff --git a/tests/fsharp/Compiler/ErrorMessages/UpcastDowncastTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UpcastDowncastTests.fs similarity index 94% rename from tests/fsharp/Compiler/ErrorMessages/UpcastDowncastTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/UpcastDowncastTests.fs index 384164bff22..79e32f9e3e0 100644 --- a/tests/fsharp/Compiler/ErrorMessages/UpcastDowncastTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UpcastDowncastTests.fs @@ -1,15 +1,14 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] module ``Upcast and Downcast`` = - [] + [] let ``Downcast Instead Of Upcast``() = CompilerAssert.TypeCheckSingleError """ @@ -23,7 +22,7 @@ let c = orig :> Dictionary (5, 9, 5, 36) "Type constraint mismatch. The type \n 'IDictionary' \nis not compatible with type\n 'Dictionary' \n" - [] + [] let ``Upcast Instead Of Downcast``() = CompilerAssert.TypeCheckWithErrors """ @@ -37,7 +36,7 @@ let c = orig :?> IDictionary FSharpErrorSeverity.Error, 3198, (5, 9, 5, 38), "The conversion from Dictionary to IDictionary is a compile-time safe upcast, not a downcast. Consider using the :> (upcast) operator instead of the :?> (downcast) operator." |] - [] + [] let ``Upcast Function Instead Of Downcast``() = CompilerAssert.TypeCheckWithErrors """ diff --git a/tests/fsharp/Compiler/ErrorMessages/WarnExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs similarity index 97% rename from tests/fsharp/Compiler/ErrorMessages/WarnExpressionTests.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs index 1df40553ce7..565e423407b 100644 --- a/tests/fsharp/Compiler/ErrorMessages/WarnExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] + module ``Warn Expression`` = - [] + [] let ``Warn If Expression Result Unused``() = CompilerAssert.TypeCheckSingleError """ @@ -21,7 +21,7 @@ printfn "%d" 3 (2, 1, 2, 6) "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." - [] + [] let ``Warn If Possible Assignment``() = CompilerAssert.TypeCheckSingleError """ @@ -37,7 +37,7 @@ let changeX() = (6, 5, 6, 11) "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then mark the value 'mutable' and use the '<-' operator e.g. 'x <- expression'." - [] + [] let ``Warn If Possible Assignment To Mutable``() = CompilerAssert.TypeCheckSingleError """ @@ -53,7 +53,7 @@ let changeX() = (6, 5, 6, 11) "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then use the '<-' operator e.g. 'x <- expression'." - [] + [] let ``Warn If Possible dotnet Property Setter``() = CompilerAssert.TypeCheckWithErrors """ @@ -71,7 +71,7 @@ let changeProperty() = FSharpErrorSeverity.Warning, 20, (8, 5, 8, 21), "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'z.Enabled <- expression'." |] - [] + [] let ``Don't Warn If Property Without Setter``() = CompilerAssert.TypeCheckSingleError """ @@ -90,7 +90,7 @@ let changeProperty() = (9, 5, 9, 23) "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'." - [] + [] let ``Warn If Implicitly Discarded``() = CompilerAssert.TypeCheckSingleError """ @@ -106,7 +106,7 @@ let changeX() = (6, 5, 6, 15) "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'." - [] + [] let ``Warn If Discarded In List``() = CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:4.6" |] @@ -128,7 +128,7 @@ let view model dispatch = "This expression returns a value of type 'int' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield'." |] - [] + [] let ``Warn If Discarded In List 2``() = CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:4.6" |] @@ -155,7 +155,7 @@ let view model dispatch = "This expression returns a value of type 'int list' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield!'." |] - [] + [] let ``Warn If Discarded In List 3``() = CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:4.6" |] @@ -182,7 +182,7 @@ let view model dispatch = "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." |] - [] + [] let ``Warn Only On Last Expression``() = CompilerAssert.TypeCheckSingleError """ @@ -197,7 +197,7 @@ while x < 1 do (6, 5, 6, 9) "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." - [] + [] let ``Warn If Possible Property Setter``() = CompilerAssert.TypeCheckSingleError """ @@ -218,7 +218,7 @@ let changeProperty() = "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'x.Property2 <- expression'." - [] + [] let ``Dont warn external function as unused``() = CompilerAssert.Pass """ diff --git a/tests/fsharp/Compiler/ErrorMessages/WrongSyntaxInForLoop.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WrongSyntaxInForLoop.fs similarity index 86% rename from tests/fsharp/Compiler/ErrorMessages/WrongSyntaxInForLoop.fs rename to tests/FSharp.Compiler.ComponentTests/ErrorMessages/WrongSyntaxInForLoop.fs index 9747bbfa6aa..d7cd6068103 100644 --- a/tests/fsharp/Compiler/ErrorMessages/WrongSyntaxInForLoop.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WrongSyntaxInForLoop.fs @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.UnitTests +namespace FSharp.Compiler.ErrorMessages.ComponentTests -open NUnit.Framework +open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices -[] + module ``Wrong syntax in for loop`` = - [] + [] let ``Equals instead of in``() = CompilerAssert.ParseWithErrors """ diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 6f9172bf9bc..e78ad8e7725 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -4,7 +4,10 @@ net472;netcoreapp3.1 + win-x86;win-x64;linux-x64;osx-x64 netcoreapp3.1 + linux-x64;osx-x64 + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81 true Library true @@ -16,7 +19,24 @@ - + + + + + + + + + + + + + + + + + + diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs index 42296116616..ac75e88ee9a 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -283,7 +283,11 @@ let main argv = 0""" | CompilationReference (cmpl, staticLink) -> compileCompilationAux outputPath disposals ignoreWarnings cmpl, staticLink | TestCompilationReference (cmpl) -> - let tmp = Path.Combine(outputPath, Path.ChangeExtension(Path.GetRandomFileName(), ".dll")) + let filename = + match cmpl with + | TestCompilation.CSharp c -> c.AssemblyName + | _ -> Path.GetRandomFileName() + let tmp = Path.Combine(outputPath, Path.ChangeExtension(filename, ".dll")) disposals.Add({ new IDisposable with member _.Dispose() = try File.Delete tmp with | _ -> () }) diff --git a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj index 8553d2cfd44..5ddfa74eb83 100644 --- a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj +++ b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj @@ -25,8 +25,12 @@ - + + + + diff --git a/tests/FSharp.Test.Utilities/Utilities.fs b/tests/FSharp.Test.Utilities/Utilities.fs index f55d1936b5c..1415fee273f 100644 --- a/tests/FSharp.Test.Utilities/Utilities.fs +++ b/tests/FSharp.Test.Utilities/Utilities.fs @@ -60,6 +60,8 @@ module Utilities = | None = 0x0 | InternalsVisibleTo = 0x1 + // TODO: this and Compilation.Compile needs to be merged for sake of consistency. + // TODO: After merging, add new type of FSharp compilation. [] type TestCompilation = | CSharp of CSharpCompilation @@ -96,18 +98,19 @@ module Utilities = [] type CompilationUtil private () = - static member CreateCSharpCompilation (source: string, lv: CSharpLanguageVersion, ?tf, ?additionalReferences) = + static member CreateCSharpCompilation (source: string, lv: CSharpLanguageVersion, ?tf, ?additionalReferences, ?name) = let lv = match lv with | CSharpLanguageVersion.CSharp8 -> LanguageVersion.CSharp8 | _ -> LanguageVersion.Default let tf = defaultArg tf TargetFramework.NetStandard20 + let n = defaultArg name (Guid.NewGuid().ToString ()) let additionalReferences = defaultArg additionalReferences ImmutableArray.Empty let references = TargetFrameworkUtil.getReferences tf let c = CSharpCompilation.Create( - Guid.NewGuid().ToString (), + n, [ CSharpSyntaxTree.ParseText (source, CSharpParseOptions lv) ], references.As().AddRange additionalReferences, CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary)) diff --git a/tests/fsharp/Compiler/ErrorMessages/AccessOfTypeAbbreviationTests.fs b/tests/fsharp/Compiler/ErrorMessages/AccessOfTypeAbbreviationTests.fs deleted file mode 100644 index f6fc14bbef5..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/AccessOfTypeAbbreviationTests.fs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Test.Utilities -open FSharp.Compiler.SourceCodeServices - -[] -module ``Access Of Type Abbreviation`` = - - [] - let ``Test1``() = - CompilerAssert.TypeCheckSingleError - """ -module Library = - type private Hidden = Hidden of unit - type Exported = Hidden - """ - FSharpErrorSeverity.Warning - 44 - (4, 8, 4, 16) - "This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in.\r\nAs of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors." - - [] - let ``Test2``() = - CompilerAssert.Pass - """ -module Library = - type internal Hidden = Hidden of unit - type internal Exported = Hidden - """ - - [] - let ``Test3``() = - CompilerAssert.TypeCheckSingleError - """ -module Library = - type internal Hidden = Hidden of unit - type Exported = Hidden - """ - FSharpErrorSeverity.Warning - 44 - (4, 8, 4, 16) - "This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in.\r\nAs of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors." - - [] - let ``Test4``() = - CompilerAssert.TypeCheckSingleError - """ -module Library = - type private Hidden = Hidden of unit - type internal Exported = Hidden - """ - FSharpErrorSeverity.Warning - 44 - (4, 17, 4, 25) - "This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in.\r\nAs of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors." - - [] - let ``Test5``() = - CompilerAssert.Pass - """ -module Library = - type private Hidden = Hidden of unit - type private Exported = Hidden - """ - - [] - let ``Test6``() = - CompilerAssert.Pass - """ -module Library = - type Hidden = Hidden of unit - type Exported = Hidden - """ diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index e3532d1ce04..ee988ae4fad 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -33,24 +33,8 @@ - - - - - - - - - - - - - - - - diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/app.fs b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/app.fs deleted file mode 100644 index 130c63a7d55..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/app.fs +++ /dev/null @@ -1,22 +0,0 @@ -//This expression was expected to have type -//'A (liba, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' -//but here has type -//'A (libb, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' - - -//This expression was expected to have type -//'B (liba, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' -//but here has type -//'B (libb, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' - - -let a = AMaker.makeA() -let otherA = OtherAMaker.makeOtherA() -printfn "%A %A" (a.GetType().AssemblyQualifiedName) (otherA.GetType().AssemblyQualifiedName) -printfn "%A" (a = otherA) - -let b = AMaker.makeB() -let otherB = OtherAMaker.makeOtherB() -printfn "%A %A" (b.GetType().AssemblyQualifiedName) (otherB.GetType().AssemblyQualifiedName) -printfn "%A" (b = otherB) - \ No newline at end of file diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/compile.bat b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/compile.bat deleted file mode 100644 index abcfa42e592..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/compile.bat +++ /dev/null @@ -1,6 +0,0 @@ -rem if you want to try it out without running the whole suite -csc -t:library -out:liba.dll liba-and-b.cs -csc -t:library -out:libb.dll liba-and-b.cs -fsc --target:library -r:liba.dll --out:libc.dll libc.fs -fsc --target:library -r:libb.dll --out:libd.dll libd.fs -fsc -r:liba.dll -r:libb.dll -r:libc.dll -r:libd.dll app.fs diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/env.lst b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/env.lst deleted file mode 100644 index 8189ed0b1f8..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/env.lst +++ /dev/null @@ -1,3 +0,0 @@ -# see compile.bat for clearer steps, aim is to get message highlighting fix for https://github.com/Microsoft/visualfsharp/issues/2561 - SOURCE="app.fs" SCFLAGS="-r:liba.dll -r:libb.dll -r:libc.dll -r:libd.dll" PRECMD="\$CSC_PIPE -t:library -out:liba.dll liba-and-b.cs && \$CSC_PIPE -t:library -out:libb.dll liba-and-b.cs && fsc --target:library -r:liba.dll --out:libc.dll libc.fs && fsc --target:library -r:libb.dll --out:libd.dll libd.fs" - \ No newline at end of file diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/liba-and-b.cs b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/liba-and-b.cs deleted file mode 100644 index 9e1d2d24b31..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/liba-and-b.cs +++ /dev/null @@ -1,2 +0,0 @@ -public class A { } -public class B { } \ No newline at end of file diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libc.fs b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libc.fs deleted file mode 100644 index 4e1450a4149..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libc.fs +++ /dev/null @@ -1,3 +0,0 @@ -module AMaker -let makeA () : A = A() -let makeB () = B<_>() diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libd.fs b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libd.fs deleted file mode 100644 index 5458451d7cb..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libd.fs +++ /dev/null @@ -1,3 +0,0 @@ -module OtherAMaker -let makeOtherA () : A = A() -let makeOtherB () = B<_>() \ No newline at end of file diff --git a/tests/fsharpqa/Source/test.lst b/tests/fsharpqa/Source/test.lst index 8a3aeac76b2..95afc5893b4 100644 --- a/tests/fsharpqa/Source/test.lst +++ b/tests/fsharpqa/Source/test.lst @@ -266,8 +266,6 @@ Misc01 Libraries\Core\Operators Misc01 Libraries\Core\Reflection Misc01 Libraries\Core\Unchecked Misc01 Warnings -Misc01 ErrorMessages\UnitGenericAbstractType -Misc01 ErrorMessages\ConfusingTypeName Misc02 Libraries\Portable Misc02 Misc From 4456e0aeb92589c8e5b7f24259c9562f1f69e4ba Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Tue, 23 Jun 2020 15:36:27 -0700 Subject: [PATCH 29/60] Better classification: such colors, much wow (#9511) * First go at updated classifications * More complete classification * More accurate classification that roughly matches glyph computations * Proper measure classification and tests * remove ze comments * Add clarifying comment * Distinguish property setter args from named argument labels * Color local values, don't color properties and property-like things that way * Dont't do the dumb * We can't distinguish between params and locals right now * Updates per feedback from myself * do discards right * Accessible colors for disposables + some fixes * Remove exports for things we don't do anymore * Softer green * Reduce diff --- src/fsharp/service/SemanticClassification.fs | 262 ++++++++++++++---- src/fsharp/service/SemanticClassification.fsi | 25 +- .../ClassificationDefinitions.fs | 120 +++----- .../SemanticColorizationServiceTests.fs | 15 +- 4 files changed, 286 insertions(+), 136 deletions(-) diff --git a/src/fsharp/service/SemanticClassification.fs b/src/fsharp/service/SemanticClassification.fs index 367d2290122..f715f26349f 100644 --- a/src/fsharp/service/SemanticClassification.fs +++ b/src/fsharp/service/SemanticClassification.fs @@ -10,7 +10,6 @@ open FSharp.Compiler open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.Infos open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Lib open FSharp.Compiler.NameResolution open FSharp.Compiler.PrettyNaming open FSharp.Compiler.Range @@ -24,10 +23,12 @@ type SemanticClassificationType = | ReferenceType | ValueType | UnionCase + | UnionCaseField | Function | Property | MutableVar | Module + | NameSpace | Printf | ComputationExpression | IntrinsicFunction @@ -35,19 +36,34 @@ type SemanticClassificationType = | Interface | TypeArgument | Operator - | Disposable + | DisposableType + | DisposableValue + | Method + | ExtensionMethod + | ConstructorForReferenceType + | ConstructorForValueType + | Literal + | RecordField + | MutableRecordField + | RecordFieldAsFunction + | Exception + | Field + | Event + | Delegate + | NamedArgument + | Value + | LocalValue + | Type + | TypeDef [] module TcResolutionsExtensions = - let (|CNR|) (cnr:CapturedNameResolution) = (cnr.Item, cnr.ItemOccurence, cnr.DisplayEnv, cnr.NameResolutionEnv, cnr.AccessorDomain, cnr.Range) type TcResolutions with - member sResolutions.GetSemanticClassification(g: TcGlobals, amap: Import.ImportMap, formatSpecifierLocations: (range * int) [], range: range option) : struct(range * SemanticClassificationType) [] = - ErrorScope.Protect Range.range0 - (fun () -> + ErrorScope.Protect Range.range0 (fun () -> let (|LegitTypeOccurence|_|) = function | ItemOccurence.UseInType | ItemOccurence.UseInAttribute @@ -56,18 +72,13 @@ module TcResolutionsExtensions = | ItemOccurence.Pattern _ -> Some() | _ -> None - let (|OptionalArgumentAttribute|_|) ttype = - match ttype with - | TType.TType_app(tref, _) when tref.Stamp = g.attrib_OptionalArgumentAttribute.TyconRef.Stamp -> Some() - | _ -> None - let (|KeywordIntrinsicValue|_|) (vref: ValRef) = if valRefEq g g.raise_vref vref || - valRefEq g g.reraise_vref vref || - valRefEq g g.typeof_vref vref || - valRefEq g g.typedefof_vref vref || - valRefEq g g.sizeof_vref vref || - valRefEq g g.nameof_vref vref then Some() + valRefEq g g.reraise_vref vref || + valRefEq g g.typeof_vref vref || + valRefEq g g.typedefof_vref vref || + valRefEq g g.sizeof_vref vref || + valRefEq g g.nameof_vref vref then Some() else None let (|EnumCaseFieldInfo|_|) (rfinfo : RecdFieldInfo) = @@ -87,7 +98,15 @@ module TcResolutionsExtensions = sResolutions.CapturedNameResolutions :> seq<_> let isDisposableTy (ty: TType) = + not (typeEquiv g ty g.system_IDisposable_ty) && protectAssemblyExplorationNoReraise false false (fun () -> Infos.ExistsHeadTypeInEntireHierarchy g amap range0 ty g.tcref_System_IDisposable) + + let isDiscard (str: string) = str.StartsWith("_") + + let isValRefDisposable (vref: ValRef) = + not (isDiscard vref.DisplayName) && + // For values, we actually do want to color things if they literally are IDisposables + protectAssemblyExplorationNoReraise false false (fun () -> Infos.ExistsHeadTypeInEntireHierarchy g amap range0 vref.Type g.tcref_System_IDisposable) let isStructTyconRef (tyconRef: TyconRef) = let ty = generalizedTyconRef tyconRef @@ -116,61 +135,206 @@ module TcResolutionsExtensions = // 'seq' in 'seq { ... }' gets colored as keywords | (Item.Value vref), ItemOccurence.Use, _, _, _, m when valRefEq g g.seq_vref vref -> add m SemanticClassificationType.ComputationExpression + | (Item.Value vref), _, _, _, _, m when isValRefMutable vref -> add m SemanticClassificationType.MutableVar + | Item.Value KeywordIntrinsicValue, ItemOccurence.Use, _, _, _, m -> add m SemanticClassificationType.IntrinsicFunction + | (Item.Value vref), _, _, _, _, m when isFunction g vref.Type -> if valRefEq g g.range_op_vref vref || valRefEq g g.range_step_op_vref vref then () elif vref.IsPropertyGetterMethod || vref.IsPropertySetterMethod then add m SemanticClassificationType.Property + elif vref.IsMember then + add m SemanticClassificationType.Method elif IsOperatorName vref.DisplayName then add m SemanticClassificationType.Operator else add m SemanticClassificationType.Function - | Item.RecdField rfinfo, _, _, _, _, m when isRecdFieldMutable rfinfo -> - add m SemanticClassificationType.MutableVar - | Item.RecdField rfinfo, _, _, _, _, m when isFunction g rfinfo.FieldType -> - add m SemanticClassificationType.Function - | Item.RecdField EnumCaseFieldInfo, _, _, _, _, m -> - add m SemanticClassificationType.Enumeration - | Item.MethodGroup _, _, _, _, _, m -> - add m SemanticClassificationType.Function - // custom builders, custom operations get colored as keywords + + | (Item.Value vref), _, _, _, _, m -> + if isValRefDisposable vref then + add m SemanticClassificationType.DisposableValue + elif Option.isSome vref.LiteralValue then + add m SemanticClassificationType.Literal + elif not vref.IsCompiledAsTopLevel && not(isDiscard vref.DisplayName) then + add m SemanticClassificationType.LocalValue + else + add m SemanticClassificationType.Value + + | Item.RecdField rfinfo, _, _, _, _, m -> + match rfinfo with + | EnumCaseFieldInfo -> + add m SemanticClassificationType.Enumeration + | _ -> + if isRecdFieldMutable rfinfo then + add m SemanticClassificationType.MutableRecordField + elif isFunTy g rfinfo.FieldType then + add m SemanticClassificationType.RecordFieldAsFunction + else + add m SemanticClassificationType.RecordField + + | Item.AnonRecdField(_, tys, idx, m), _, _, _, _, _ -> + let ty = tys.[idx] + + // It's not currently possible for anon record fields to be mutable, but they can be ref cells + if isRefCellTy g ty then + add m SemanticClassificationType.MutableRecordField + elif isFunTy g ty then + add m SemanticClassificationType.RecordFieldAsFunction + else + add m SemanticClassificationType.RecordField + + | Item.Property (_, pinfo :: _), _, _, _, _, m -> + if not pinfo.IsIndexer then + add m SemanticClassificationType.Property + + | Item.CtorGroup (_, minfos), _, _, _, _, m -> + if minfos |> List.forall (fun minfo -> isDisposableTy minfo.ApparentEnclosingType) then + add m SemanticClassificationType.DisposableType + elif minfos |> List.forall (fun minfo -> isStructTy g minfo.ApparentEnclosingType) then + add m SemanticClassificationType.ConstructorForValueType + else + add m SemanticClassificationType.ConstructorForReferenceType + + | (Item.DelegateCtor _ | Item.FakeInterfaceCtor _), _, _, _, _, m -> + add m SemanticClassificationType.ConstructorForReferenceType + + | Item.MethodGroup (_, minfos, _), _, _, _, _, m -> + if minfos |> List.forall (fun minfo -> minfo.IsExtensionMember || minfo.IsCSharpStyleExtensionMember) then + add m SemanticClassificationType.ExtensionMethod + else + add m SemanticClassificationType.Method + | (Item.CustomBuilder _ | Item.CustomOperation _), ItemOccurence.Use, _, _, _, m -> add m SemanticClassificationType.ComputationExpression - // types get colored as types when they occur in syntactic types or custom attributes - // type variables get colored as types when they occur in syntactic types custom builders, custom operations get colored as keywords - | Item.Types (_, [OptionalArgumentAttribute]), LegitTypeOccurence, _, _, _, _ -> () - | Item.CtorGroup(_, [MethInfo.FSMeth(_, OptionalArgumentAttribute, _, _)]), LegitTypeOccurence, _, _, _, _ -> () - | Item.Types(_, types), LegitTypeOccurence, _, _, _, m when types |> List.exists (isInterfaceTy g) -> - add m SemanticClassificationType.Interface - | Item.Types(_, types), LegitTypeOccurence, _, _, _, m when types |> List.exists (isStructTy g) -> - add m SemanticClassificationType.ValueType + + // Special case measures for struct types | Item.Types(_, TType_app(tyconRef, TType_measure _ :: _) :: _), LegitTypeOccurence, _, _, _, m when isStructTyconRef tyconRef -> add m SemanticClassificationType.ValueType - | Item.Types(_, types), LegitTypeOccurence, _, _, _, m when types |> List.exists isDisposableTy -> - add m SemanticClassificationType.Disposable - | Item.Types _, LegitTypeOccurence, _, _, _, m -> - add m SemanticClassificationType.ReferenceType + + | Item.Types (_, ty :: _), LegitTypeOccurence, _, _, _, m -> + let reprToClassificationType repr tcref = + match repr with + | TFSharpObjectRepr om -> + match om.fsobjmodel_kind with + | TTyconClass -> SemanticClassificationType.ReferenceType + | TTyconInterface -> SemanticClassificationType.Interface + | TTyconStruct -> SemanticClassificationType.ValueType + | TTyconDelegate _ -> SemanticClassificationType.Delegate + | TTyconEnum _ -> SemanticClassificationType.Enumeration + | TRecdRepr _ + | TUnionRepr _ -> + if isStructTyconRef tcref then + SemanticClassificationType.ValueType + else + SemanticClassificationType.Type + | TILObjectRepr (TILObjectReprData (_, _, td)) -> + if td.IsClass then + SemanticClassificationType.ReferenceType + elif td.IsStruct then + SemanticClassificationType.ValueType + elif td.IsInterface then + SemanticClassificationType.Interface + elif td.IsEnum then + SemanticClassificationType.Enumeration + else + SemanticClassificationType.Delegate + | TAsmRepr _ -> SemanticClassificationType.TypeDef + | TMeasureableRepr _-> SemanticClassificationType.TypeDef +#if !NO_EXTENSIONTYPING + | TProvidedTypeExtensionPoint _-> SemanticClassificationType.TypeDef + | TProvidedNamespaceExtensionPoint _-> SemanticClassificationType.TypeDef +#endif + | TNoRepr -> SemanticClassificationType.ReferenceType + + let ty = stripTyEqns g ty + if isDisposableTy ty then + add m SemanticClassificationType.DisposableType + else + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> + add m (reprToClassificationType tcref.TypeReprInfo tcref) + | ValueNone -> + if isStructTupleTy g ty then + add m SemanticClassificationType.ValueType + elif isRefTupleTy g ty then + add m SemanticClassificationType.ReferenceType + elif isFunction g ty then + add m SemanticClassificationType.Function + elif isTyparTy g ty then + add m SemanticClassificationType.ValueType + else + add m SemanticClassificationType.TypeDef + | (Item.TypeVar _ ), LegitTypeOccurence, _, _, _, m -> add m SemanticClassificationType.TypeArgument - | Item.UnqualifiedType tyconRefs, LegitTypeOccurence, _, _, _, m -> - if tyconRefs |> List.exists (fun tyconRef -> tyconRef.Deref.IsStructOrEnumTycon) then - add m SemanticClassificationType.ValueType - else add m SemanticClassificationType.ReferenceType - | Item.CtorGroup(_, minfos), LegitTypeOccurence, _, _, _, m -> - if minfos |> List.exists (fun minfo -> isStructTy g minfo.ApparentEnclosingType) then - add m SemanticClassificationType.ValueType - else add m SemanticClassificationType.ReferenceType + | Item.ExnCase _, LegitTypeOccurence, _, _, _, m -> - add m SemanticClassificationType.ReferenceType - | Item.ModuleOrNamespaces refs, LegitTypeOccurence, _, _, _, m when refs |> List.exists (fun x -> x.IsModule) -> - add m SemanticClassificationType.Module + add m SemanticClassificationType.Exception + + | Item.ModuleOrNamespaces (modref :: _), LegitTypeOccurence, _, _, _, m -> + if modref.IsNamespace then + add m SemanticClassificationType.NameSpace + else + add m SemanticClassificationType.Module + | (Item.ActivePatternCase _ | Item.UnionCase _ | Item.ActivePatternResult _), _, _, _, _, m -> add m SemanticClassificationType.UnionCase - | _ -> ()) + + | Item.UnionCaseField _, _, _, _, _, m -> + add m SemanticClassificationType.UnionCaseField + + | Item.ILField _, _, _, _, _, m -> + add m SemanticClassificationType.Field + + | Item.Event _, _, _, _, _, m -> + add m SemanticClassificationType.Event + + | (Item.ArgName _ | Item.SetterArg _), _, _, _, _, m -> + add m SemanticClassificationType.NamedArgument + + | Item.SetterArg _, _, _, _, _, m -> + add m SemanticClassificationType.Property + + | Item.UnqualifiedType (tcref :: _), LegitTypeOccurence, _, _, _, m -> + if tcref.IsEnumTycon || tcref.IsILEnumTycon then + add m SemanticClassificationType.Enumeration + elif tcref.IsExceptionDecl then + add m SemanticClassificationType.Exception + elif tcref.IsFSharpDelegateTycon then + add m SemanticClassificationType.Delegate + elif tcref.IsFSharpInterfaceTycon then + add m SemanticClassificationType.Interface + elif tcref.IsFSharpStructOrEnumTycon then + add m SemanticClassificationType.ValueType + elif tcref.IsModule then + add m SemanticClassificationType.Module + elif tcref.IsNamespace then + add m SemanticClassificationType.NameSpace + elif tcref.IsUnionTycon || tcref.IsRecordTycon then + if isStructTyconRef tcref then + add m SemanticClassificationType.ValueType + else + add m SemanticClassificationType.UnionCase + elif tcref.IsILTycon then + let (TILObjectReprData (_, _, tydef)) = tcref.ILTyconInfo + + if tydef.IsInterface then + add m SemanticClassificationType.Interface + elif tydef.IsDelegate then + add m SemanticClassificationType.Delegate + elif tydef.IsEnum then + add m SemanticClassificationType.Enumeration + elif tydef.IsStruct then + add m SemanticClassificationType.ValueType + else + add m SemanticClassificationType.ReferenceType + + | _ -> + ()) results.AddRange(formatSpecifierLocations |> Array.map (fun (m, _) -> struct(m, SemanticClassificationType.Printf))) results.ToArray() ) diff --git a/src/fsharp/service/SemanticClassification.fsi b/src/fsharp/service/SemanticClassification.fsi index ff0e89a29f8..f2447219bd6 100644 --- a/src/fsharp/service/SemanticClassification.fsi +++ b/src/fsharp/service/SemanticClassification.fsi @@ -2,7 +2,6 @@ namespace FSharp.Compiler.SourceCodeServices -open FSharp.Compiler open FSharp.Compiler.AccessibilityLogic open FSharp.Compiler.Import open FSharp.Compiler.NameResolution @@ -16,10 +15,12 @@ type SemanticClassificationType = | ReferenceType | ValueType | UnionCase + | UnionCaseField | Function | Property | MutableVar | Module + | NameSpace | Printf | ComputationExpression | IntrinsicFunction @@ -27,14 +28,30 @@ type SemanticClassificationType = | Interface | TypeArgument | Operator - | Disposable + | DisposableType + | DisposableValue + | Method + | ExtensionMethod + | ConstructorForReferenceType + | ConstructorForValueType + | Literal + | RecordField + | MutableRecordField + | RecordFieldAsFunction + | Exception + | Field + | Event + | Delegate + | NamedArgument + | Value + | LocalValue + | Type + | TypeDef /// Extension methods for the TcResolutions type. [] module internal TcResolutionsExtensions = - val (|CNR|) : cnr: CapturedNameResolution -> (Item * ItemOccurence * DisplayEnv * NameResolutionEnv * AccessorDomain * range) type TcResolutions with - member GetSemanticClassification: g: TcGlobals * amap: ImportMap * formatSpecifierLocations: (range * int) [] * range: range option -> struct(range * SemanticClassificationType) [] \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/Classification/ClassificationDefinitions.fs b/vsintegration/src/FSharp.Editor/Classification/ClassificationDefinitions.fs index 749c3ceed7a..1dea67f4f35 100644 --- a/vsintegration/src/FSharp.Editor/Classification/ClassificationDefinitions.fs +++ b/vsintegration/src/FSharp.Editor/Classification/ClassificationDefinitions.fs @@ -21,36 +21,45 @@ open FSharp.Compiler.SourceCodeServices [] module internal FSharpClassificationTypes = - let [] Function = "FSharp.Function" let [] MutableVar = "FSharp.MutableVar" - let [] Printf = "FSharp.Printf" - let [] ReferenceType = ClassificationTypeNames.ClassName - let [] Module = ClassificationTypeNames.ModuleName - let [] ValueType = ClassificationTypeNames.StructName - let [] Keyword = ClassificationTypeNames.Keyword - let [] Enum = ClassificationTypeNames.EnumName - let [] Property = "FSharp.Property" - let [] Interface = ClassificationTypeNames.InterfaceName - let [] TypeArgument = ClassificationTypeNames.TypeParameterName - let [] Operator = ClassificationTypeNames.Operator let [] Disposable = "FSharp.Disposable" let getClassificationTypeName = function - | SemanticClassificationType.ReferenceType -> ReferenceType - | SemanticClassificationType.Module -> Module - | SemanticClassificationType.ValueType -> ValueType - | SemanticClassificationType.Function -> Function + | SemanticClassificationType.MutableRecordField | SemanticClassificationType.MutableVar -> MutableVar - | SemanticClassificationType.Printf -> Printf + | SemanticClassificationType.DisposableValue + | SemanticClassificationType.DisposableType -> Disposable + | SemanticClassificationType.NameSpace -> ClassificationTypeNames.NamespaceName + | SemanticClassificationType.Exception + | SemanticClassificationType.Module + | SemanticClassificationType.Type + | SemanticClassificationType.TypeDef + | SemanticClassificationType.ConstructorForReferenceType + | SemanticClassificationType.Printf + | SemanticClassificationType.ReferenceType -> ClassificationTypeNames.ClassName + | SemanticClassificationType.ConstructorForValueType + | SemanticClassificationType.ValueType -> ClassificationTypeNames.StructName | SemanticClassificationType.ComputationExpression - | SemanticClassificationType.IntrinsicFunction -> Keyword + | SemanticClassificationType.IntrinsicFunction -> ClassificationTypeNames.Keyword | SemanticClassificationType.UnionCase - | SemanticClassificationType.Enumeration -> Enum - | SemanticClassificationType.Property -> Property - | SemanticClassificationType.Interface -> Interface - | SemanticClassificationType.TypeArgument -> TypeArgument - | SemanticClassificationType.Operator -> Operator - | SemanticClassificationType.Disposable -> Disposable + | SemanticClassificationType.Enumeration -> ClassificationTypeNames.EnumName + | SemanticClassificationType.Field + | SemanticClassificationType.UnionCaseField -> ClassificationTypeNames.FieldName + | SemanticClassificationType.Interface -> ClassificationTypeNames.InterfaceName + | SemanticClassificationType.TypeArgument -> ClassificationTypeNames.TypeParameterName + | SemanticClassificationType.Operator -> ClassificationTypeNames.Operator + | SemanticClassificationType.Function + | SemanticClassificationType.Method -> ClassificationTypeNames.MethodName + | SemanticClassificationType.ExtensionMethod -> ClassificationTypeNames.ExtensionMethodName + | SemanticClassificationType.Literal -> ClassificationTypeNames.ConstantName + | SemanticClassificationType.Property + | SemanticClassificationType.RecordFieldAsFunction + | SemanticClassificationType.RecordField -> ClassificationTypeNames.PropertyName // TODO - maybe pick something that isn't white by default like Property? + | SemanticClassificationType.NamedArgument -> ClassificationTypeNames.LabelName + | SemanticClassificationType.Event -> ClassificationTypeNames.EventName + | SemanticClassificationType.Delegate -> ClassificationTypeNames.DelegateName + | SemanticClassificationType.Value -> ClassificationTypeNames.Identifier + | SemanticClassificationType.LocalValue -> ClassificationTypeNames.LocalName module internal ClassificationDefinitions = @@ -73,13 +82,11 @@ module internal ClassificationDefinitions = let themeService = serviceProvider.GetService(typeof) :?> IVsColorThemeService themeService.CurrentTheme.ThemeId - let colorData = // name, (light, dark) - [ FSharpClassificationTypes.Function, (Colors.Black, Color.FromRgb(220uy, 220uy, 220uy)) - FSharpClassificationTypes.MutableVar, (Color.FromRgb(160uy, 128uy, 0uy), Color.FromRgb(255uy, 210uy, 28uy)) - FSharpClassificationTypes.Printf, (Color.FromRgb(43uy, 145uy, 175uy), Color.FromRgb(78uy, 220uy, 176uy)) - FSharpClassificationTypes.Property, (Colors.Black, Color.FromRgb(220uy, 220uy, 220uy)) - FSharpClassificationTypes.Disposable, (Color.FromRgb(43uy, 145uy, 175uy), Color.FromRgb(78uy, 220uy, 176uy)) ] - + let customColorData = // name, (light, dark) + [ + FSharpClassificationTypes.MutableVar, (Color.FromRgb(160uy, 128uy, 0uy), Color.FromRgb(255uy, 210uy, 28uy)) + FSharpClassificationTypes.Disposable, (Colors.Green, Color.FromRgb(2uy, 183uy, 43uy)) + ] let setColors _ = let fontAndColorStorage = serviceProvider.GetService(typeof) :?> IVsFontAndColorStorage @@ -90,15 +97,16 @@ module internal ClassificationDefinitions = let formatMap = classificationformatMapService.GetClassificationFormatMap(category = "text") try formatMap.BeginBatchUpdate() - for ctype, (light, dark) in colorData do + for ctype, (light, dark) in customColorData do // we don't touch the changes made by the user if fontAndColorStorage.GetItem(ctype, Array.zeroCreate 1) <> VSConstants.S_OK then let ict = classificationTypeRegistry.GetClassificationType(ctype) let oldProps = formatMap.GetTextProperties(ict) - let newProps = match getCurrentThemeId() with - | LightTheme -> oldProps.SetForeground light - | DarkTheme -> oldProps.SetForeground dark - | UnknownTheme -> oldProps + let newProps = + match getCurrentThemeId() with + | LightTheme -> oldProps.SetForeground light + | DarkTheme -> oldProps.SetForeground dark + | UnknownTheme -> oldProps formatMap.SetTextProperties(ict, newProps) fontAndColorStorage.CloseCategory() |> ignore finally formatMap.EndBatchUpdate() @@ -108,7 +116,7 @@ module internal ClassificationDefinitions = interface IDisposable with member __.Dispose() = VSColorTheme.remove_ThemeChanged handler member __.GetColor(ctype) = - let light, dark = colorData |> Map.ofList |> Map.find ctype + let light, dark = customColorData |> Map.ofList |> Map.find ctype match getCurrentThemeId() with | LightTheme -> Nullable light | DarkTheme -> Nullable dark @@ -116,32 +124,13 @@ module internal ClassificationDefinitions = interface ISetThemeColors with member this.SetColors() = setColors() - - [] - let FSharpFunctionClassificationType : ClassificationTypeDefinition = null - [] let FSharpMutableVarClassificationType : ClassificationTypeDefinition = null - [] - let FSharpPrintfClassificationType : ClassificationTypeDefinition = null - - [] - let FSharpPropertyClassificationType : ClassificationTypeDefinition = null [] let FSharpDisposableClassificationType : ClassificationTypeDefinition = null - [)>] - [] - [] - [] - [] - type internal FSharpFunctionTypeFormat() as self = - inherit ClassificationFormatDefinition() - - do self.DisplayName <- SR.FSharpFunctionsOrMethodsClassificationType() - [)>] [] [] @@ -153,27 +142,6 @@ module internal ClassificationDefinitions = do self.DisplayName <- SR.FSharpMutableVarsClassificationType() self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.MutableVar - [)>] - [] - [] - [] - [] - type internal FSharpPrintfTypeFormat [](theme: ThemeColors) as self = - inherit ClassificationFormatDefinition() - - do self.DisplayName <- SR.FSharpPrintfFormatClassificationType() - self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.Printf - - [)>] - [] - [] - [] - [] - type internal FSharpPropertyFormat() as self = - inherit ClassificationFormatDefinition() - - do self.DisplayName <- SR.FSharpPropertiesClassificationType() - [)>] [] [] diff --git a/vsintegration/tests/UnitTests/SemanticColorizationServiceTests.fs b/vsintegration/tests/UnitTests/SemanticColorizationServiceTests.fs index 46c2f265680..e1591ed0cb1 100644 --- a/vsintegration/tests/UnitTests/SemanticColorizationServiceTests.fs +++ b/vsintegration/tests/UnitTests/SemanticColorizationServiceTests.fs @@ -7,6 +7,7 @@ open Microsoft.VisualStudio.FSharp.Editor open FSharp.Compiler.SourceCodeServices open FSharp.Compiler open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.Classification [] type SemanticClassificationServiceTests() = @@ -57,13 +58,13 @@ type SemanticClassificationServiceTests() = let anyData = ranges |> List.exists (fun struct (range, sct) -> Range.rangeContainsPos range markerPos && ((FSharpClassificationTypes.getClassificationTypeName sct) = classificationType)) Assert.False(anyData, "Classification data was found when it wasn't expected.") - [] - [] - [] - [] - [] - [] - [] + [] + [] + [] + [] + [] + [] + [] member __.Measured_Types(marker: string, classificationType: string) = verifyClassificationAtEndOfMarker( """#light (*Light*) From c479cde26069dca516dd29d7061e081e44668468 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Wed, 24 Jun 2020 13:04:53 -0700 Subject: [PATCH 30/60] Update FSComp.txt (#9556) --- src/fsharp/FSComp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 6dcf26f7c22..e8d7455b508 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1512,4 +1512,4 @@ featureFixedIndexSlice3d4d,"fixed-index slice 3d/4d" featureAndBang,"applicative computation expressions" featureNullableOptionalInterop,"nullable optional interop" featureDefaultInterfaceMemberConsumption,"default interface member consumption" -featureWitnessPassing,"witness passing" +featureWitnessPassing,"witness passing for trait constraints in F# quotations" From 5f8a77b005381c703221e8f8b05fc64f52858869 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 25 Jun 2020 02:14:17 +0300 Subject: [PATCH 31/60] Syntax tree: include modifiers to binding ranges (#9541) --- src/fsharp/pars.fsy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 28d9e9df8d9..3a035bcdf0e 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -2702,7 +2702,7 @@ localBinding: let mRhs = expr.Range let optReturnType = $4 let bindingBuilder, mBindLhs = $3 - let localBindingRange = unionRanges (rhs2 parseState 3 5) mRhs + let localBindingRange = unionRanges (rhs2 parseState 1 5) mRhs let localBindingBuilder = (fun attrs vis mLetKwd -> let mWhole = unionRanges mLetKwd mRhs @@ -2711,7 +2711,7 @@ localBinding: localBindingRange, localBindingBuilder } | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS error - { let mWhole = rhs2 parseState 3 5 + { let mWhole = rhs2 parseState 1 5 let mRhs = rhs parseState 5 let optReturnType = $4 let bindingBuilder, mBindLhs = $3 @@ -2726,7 +2726,7 @@ localBinding: | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints recover { if not $5 then reportParseErrorAt (rhs parseState 5) (FSComp.SR.parsUnexpectedEndOfFileDefinition()) let optReturnType = $4 - let mWhole = match optReturnType with None -> rhs parseState 3 | Some _ -> rhs2 parseState 3 4 + let mWhole = rhs2 parseState 1 (match optReturnType with None -> 3 | _ -> 4) let mRhs = mWhole.EndRange // zero-width range at end of last good token let bindingBuilder, mBindLhs = $3 let localBindingBuilder = From 79c97029975210d5ca2d6743d1570ad440f9ecc1 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Thu, 25 Jun 2020 10:23:50 -0700 Subject: [PATCH 32/60] Update xlf (#9567) --- src/fsharp/xlf/FSComp.txt.cs.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.de.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.es.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.fr.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.it.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.ja.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.ko.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.pl.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.ru.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.tr.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 4 ++-- src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index f7ae174868e..a176f81a800 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index e086596e7b4..13a70ff59e1 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 1eb408ff3f1..48bcbb82529 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index 15bc9610834..ed34481d69b 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 41a4e672b8d..28af1801f19 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 1dd7c03f820..7251c15f4b7 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index b20e9912bbb..197d8985f0c 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index c05715de16d..790649874ef 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index 1e0e527e15f..dd5d94d1b92 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 21cef4e9e7e..33533871d5a 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 136b9f3b8f5..17cd35566de 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 0a1d50ac1bb..301dcb082af 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 3da0fb2cca2..39a787c7103 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -138,8 +138,8 @@ - witness passing - witness passing + witness passing for trait constraints in F# quotations + witness passing for trait constraints in F# quotations From 70f3758eee33fe34bc69874ff9d569bb95a9b13c Mon Sep 17 00:00:00 2001 From: Thorsten Reichert Date: Fri, 26 Jun 2020 15:55:51 +0200 Subject: [PATCH 33/60] Moved fsharpqa/Libraries/Core/Operators test cases to NUnit (#9570) --- .../Libraries/Core/Operators/AbsTests.fs | 94 ++++++++++++++ .../Libraries/Core/Operators/CastTests.fs | 19 +++ .../Libraries/Core/Operators/HashTests.fs | 40 ++++++ .../Libraries/Core/Operators/PowTests.fs | 25 ++++ .../Libraries/Core/Operators/RoundTests.fs | 58 +++++++++ .../Libraries/Core/Operators/SignTests.fs | 81 ++++++++++++ .../Libraries/Core/Operators/StringTests.fs | 115 ++++++++++++++++++ tests/fsharp/FSharpSuite.Tests.fsproj | 7 ++ .../Core/Operators/AbsOnIntegers01.fs | 15 --- .../Libraries/Core/Operators/CastOperator.fs | 11 -- .../Core/Operators/E_EqualityAndHash01.fs | 8 -- .../Libraries/Core/Operators/E_sign02.fs | 12 -- .../Operators/EqualityAndUncheckedHash01.fs | 10 -- .../Core/Operators/Pow_Constrains.fs | 16 --- .../Core/Operators/StringOnEnum01.fs | 68 ----------- .../Core/Operators/e_AbsOnIntegers02.fs | 17 --- .../Source/Libraries/Core/Operators/env.lst | 13 -- .../Libraries/Core/Operators/round01.fs | 60 --------- .../Source/Libraries/Core/Operators/sign01.fs | 34 ------ .../Libraries/Core/Operators/string01.fs | 44 ------- 20 files changed, 439 insertions(+), 308 deletions(-) create mode 100644 tests/fsharp/Compiler/Libraries/Core/Operators/AbsTests.fs create mode 100644 tests/fsharp/Compiler/Libraries/Core/Operators/CastTests.fs create mode 100644 tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs create mode 100644 tests/fsharp/Compiler/Libraries/Core/Operators/PowTests.fs create mode 100644 tests/fsharp/Compiler/Libraries/Core/Operators/RoundTests.fs create mode 100644 tests/fsharp/Compiler/Libraries/Core/Operators/SignTests.fs create mode 100644 tests/fsharp/Compiler/Libraries/Core/Operators/StringTests.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/AbsOnIntegers01.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/CastOperator.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/E_EqualityAndHash01.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/E_sign02.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/EqualityAndUncheckedHash01.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/Pow_Constrains.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/StringOnEnum01.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/e_AbsOnIntegers02.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/env.lst delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/round01.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/sign01.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Operators/string01.fs diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/AbsTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/AbsTests.fs new file mode 100644 index 00000000000..806c93b7dba --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/AbsTests.fs @@ -0,0 +1,94 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Compiler.SourceCodeServices +open FSharp.Test.Utilities + +[] +module ``Abs Tests`` = + + [] + let ``Abs of signed integral types``() = + // Regression test for FSHARP1.0:3470 - exception on abs of native integer + + Assert.areEqual (abs -1y) 1y // signed byte + Assert.areEqual (abs -1s) 1s // int16 + Assert.areEqual (abs -1l) 1l // int32 + Assert.areEqual (abs -1n) 1n // nativeint + Assert.areEqual (abs -1L) 1L // int64 + Assert.areEqual (abs -1I) 1I // bigint + + [] + let ``Abs of byte``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1uy |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'byte' does not support the operator 'Abs'" + + [] + let ``Abs of uint16``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1us |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint16' does not support the operator 'Abs'" + + [] + let ``Abs of uint32``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1ul |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint32' does not support the operator 'Abs'" + + CompilerAssert.TypeCheckSingleError + """ +abs -1u |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 8) + "The type 'uint32' does not support the operator 'Abs'" + + [] + let ``Abs of unativeint``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1un |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'unativeint' does not support the operator 'Abs'" + + [] + let ``Abs of uint64``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1uL |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint64' does not support the operator 'Abs'" + + CompilerAssert.TypeCheckSingleError + """ +abs -1UL |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint64' does not support the operator 'Abs'" \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/CastTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/CastTests.fs new file mode 100644 index 00000000000..5f4d34df153 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/CastTests.fs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test.Utilities +open System + +[] +module ``Cast Tests`` = + + [] + let ``Cast precedence over expression forms``() = + // Regression test for FSHARP1.0:1247 + // Precedence of type annotations :> and :?> over preceeding expression forms, e.g. if-then-else etc. + + Assert.IsInstanceOf (2 :> Object) + Assert.IsInstanceOf [(2 :> Object)] + Assert.IsInstanceOf [2 :> Object] \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs new file mode 100644 index 00000000000..8958cd5b8e9 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Compiler.SourceCodeServices +open FSharp.Test.Utilities + +[] +module ``Hash Tests`` = + + [] + let ``Hash of function values``() = + // Regression test for FSHARP1.0:5436 + // You should not be able to hash F# function values + // Note: most positive cases already covered under fsharp\typecheck\sigs + // I'm adding this simple one since I did not see it there. + + CompilerAssert.TypeCheckSingleError + """ +hash id |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 8) + "The type '('a -> 'a)' does not support the 'equality' constraint because it is a function type" + + [] + let ``Unchecked hash of function values``() = + // Regression test for FSHARP1.0:5436 + // You should not be able to hash F# function values + // Note: most positive cases already covered under fsharp\typecheck\sigs + // I'm adding this simple one since I did not see it there. + + // This is ok (unchecked) + CompilerAssert.TypeCheckWithErrors + """ +Unchecked.hash id |> ignore + """ + [||] \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/PowTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/PowTests.fs new file mode 100644 index 00000000000..4bdb77bca28 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/PowTests.fs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Pow Tests`` = + + type T() = + static let mutable m = false + static member Pow (g: T, _: float) = + m <- true + g + static member Check() = m + + [] + let ``Pow of custom type``() = + // Regression test for FSHARP1.0:4487 + // Feature request: loosen Pow operator constraints + + let t = T() + let _ = t ** 3. + + Assert.IsTrue (T.Check()) \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/RoundTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/RoundTests.fs new file mode 100644 index 00000000000..bdb8e321823 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/RoundTests.fs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Round Tests`` = + + [] + let ``Round of integers``() = + for i in [1 .. 10000] do + Assert.areEqual (i |> float |> round) (float i) + Assert.areEqual (i |> float32 |> round) (float32 i) + Assert.areEqual (i |> decimal |> round) (decimal i) + + [] + let ``Round of floats``() = + // Round down + Assert.areEqual (round 1.1) 1.0 + Assert.areEqual (round 1.2) 1.0 + Assert.areEqual (round 1.3) 1.0 + Assert.areEqual (round 1.4) 1.0 + Assert.areEqual (round 1.1f) 1.0f + Assert.areEqual (round 1.2f) 1.0f + Assert.areEqual (round 1.3f) 1.0f + Assert.areEqual (round 1.4f) 1.0f + Assert.areEqual (round 1.1m) 1.0m + Assert.areEqual (round 1.2m) 1.0m + Assert.areEqual (round 1.3m) 1.0m + Assert.areEqual (round 1.4m) 1.0m + + // Round down + Assert.areEqual (round 1.6) 2.0 + Assert.areEqual (round 1.7) 2.0 + Assert.areEqual (round 1.8) 2.0 + Assert.areEqual (round 1.9) 2.0 + Assert.areEqual (round 1.6f) 2.0f + Assert.areEqual (round 1.7f) 2.0f + Assert.areEqual (round 1.8f) 2.0f + Assert.areEqual (round 1.9f) 2.0f + Assert.areEqual (round 1.6m) 2.0m + Assert.areEqual (round 1.7m) 2.0m + Assert.areEqual (round 1.8m) 2.0m + Assert.areEqual (round 1.9m) 2.0m + + // Midpoint rounding. If between two numbers, round to the 'even' one. + Assert.areEqual (round 1.5 ) 2.0 + Assert.areEqual (round 1.5f) 2.0f + Assert.areEqual (round 1.5m) 2.0m + Assert.areEqual (round 2.5 ) 2.0 + Assert.areEqual (round 2.5f) 2.0f + Assert.areEqual (round 2.5m) 2.0m + + // If not midpoint, round to nearest as usual + Assert.areEqual (round 2.500001 ) 3.0 + Assert.areEqual (round 2.500001f) 3.0f + Assert.areEqual (round 2.500001m) 3.0m \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/SignTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/SignTests.fs new file mode 100644 index 00000000000..751e535d531 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/SignTests.fs @@ -0,0 +1,81 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Compiler.SourceCodeServices +open FSharp.Test.Utilities + +[] +module ``Sign Tests`` = + + [] + let ``Sign of signed types``() = + Assert.areEqual (sign 1y) 1 // byte + Assert.areEqual (sign 1s) 1 // int16 + Assert.areEqual (sign 1) 1 // int32 + Assert.areEqual (sign 1L) 1 // int64 + Assert.areEqual (sign 1.0f) 1 // float + Assert.areEqual (sign 1.0) 1 // double + Assert.areEqual (sign 1.0m) 1 // decimal + Assert.areEqual (sign 0y) 0 // byte + Assert.areEqual (sign 0s) 0 // int16 + Assert.areEqual (sign 0) 0 // int32 + Assert.areEqual (sign 0L) 0 // int64 + Assert.areEqual (sign 0.0f) 0 // float + Assert.areEqual (sign 0.0) 0 // double + Assert.areEqual (sign 0.0m) 0 // decimal + Assert.areEqual (sign -1y) -1 // byte + Assert.areEqual (sign -1s) -1 // int16 + Assert.areEqual (sign -1) -1 // int32 + Assert.areEqual (sign -1L) -1 // int64 + Assert.areEqual (sign -1.0f) -1 // float + Assert.areEqual (sign -1.0) -1 // double + Assert.areEqual (sign -1.0m) -1 // decimal + + // #Regression #Libraries #Operators + // Test sign function on unsigned primitives, should get error. + + [] + let ``Sign of byte``() = + CompilerAssert.TypeCheckSingleError + """ +sign 0uy |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'byte' does not support the operator 'get_Sign'" + + [] + let ``Sign of uint16``() = + CompilerAssert.TypeCheckSingleError + """ +sign 0us |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint16' does not support the operator 'get_Sign'" + + [] + let ``Sign of uint32``() = + CompilerAssert.TypeCheckSingleError + """ +sign 0u |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 8) + "The type 'uint32' does not support the operator 'get_Sign'" + + [] + let ``Sign of uint64``() = + CompilerAssert.TypeCheckSingleError + """ +sign 0uL |> ignore + """ + FSharpErrorSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint64' does not support the operator 'get_Sign'" \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/StringTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/StringTests.fs new file mode 100644 index 00000000000..dbb691fb35b --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/StringTests.fs @@ -0,0 +1,115 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open System + +[] +module ``String Tests`` = + + type CalcSum(x : int, y: int) = + let mutable x = x + let mutable y = y + + member __.Sum () = x + y + + interface IFormattable with + member x.ToString (format: string, _ : IFormatProvider) = + match format with + | null | "" + | "g" | "G" -> String.Format("X + Y = {0}", x.Sum()) + | "s" | "S" -> x.Sum().ToString() // Short form + | _ -> invalidArg format "Format is wrong!" + + override x.ToString() = (x :> IFormattable).ToString(null, null) + + [] + let ``String of custom type``() = + let calc = CalcSum(10, 20) + Assert.areEqual (string calc) "X + Y = 30" + + let testDelegate = TestDelegate (fun () -> + printfn "%s" (calc.ToString()) + Console.WriteLine("{0:S}", calc) + Console.Write("{0} {1} {2:D}", 10, 20, calc)) + let e = Assert.Throws testDelegate + Assert.areEqual e.ParamName "D" + + // int32 + type Foo = + | A = 1 + | B = 2 + + [] + let ``String of int32 based enum``() = + let a = Foo.A + let r = a :> System.IFormattable + + Assert.areEqual (string a) (string r) + + // uint32 + type Foo2 = + | A = 3u + | B = 4u + + [] + let ``String of uint32 based enum``() = + let a = Foo2.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // char + type Foo3 = + | A = 'a' + | B = 'b' + + [] + let ``String of char based enum``() = + let a = Foo3.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // int16 + type Foo4 = + | A = 1s + | B = 2s + + [] + let ``String of int16 based enum``() = + let a = Foo4.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // uint16 + type Foo5 = + | A = 1us + | B = 2us + + [] + let ``String of uint16 based enum``() = + let a = Foo5.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // sbyte + type Foo6 = + | A = 1y + | B = 2y + + [] + let ``String of sbyte based enum``() = + let a = Foo6.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // byte + type Foo7 = + | A = 1uy + | B = 2uy + + [] + let ``String of byte based enum``() = + let a = Foo7.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) \ No newline at end of file diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index 374a27b68cb..b06425e88dc 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -68,6 +68,13 @@ + + + + + + + diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/AbsOnIntegers01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/AbsOnIntegers01.fs deleted file mode 100644 index 76687657876..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/AbsOnIntegers01.fs +++ /dev/null @@ -1,15 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:3470 - exception on abs of native integer - -#light - -let res = - abs -1y = 1y // signed byte - && abs -1s = 1s // int16 - && abs -1l = 1l // int32 - && abs -1n = 1n // nativeint - && abs -1L = 1L // int64 - && abs -1I = 1I // bigint - -if not res then exit 1 -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/CastOperator.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/CastOperator.fs deleted file mode 100644 index a79a04119b2..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/CastOperator.fs +++ /dev/null @@ -1,11 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:1247 -// Precedence of type annotations :> and :?> over preceeding expression forms, e.g. if-then-else etc. -// - -open System -let x = 2 :> Object -let y = [(2 :> Object)] -let z = [2 :> Object] - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/E_EqualityAndHash01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/E_EqualityAndHash01.fs deleted file mode 100644 index 46f3d2cd725..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/E_EqualityAndHash01.fs +++ /dev/null @@ -1,8 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:5436 -// You should not be able to hash F# function values) -// Note: most positive cases already covered under fsharp\typecheck\sigs -// I'm adding this simple one since I did not see it there. -//The type '\('a -> 'a\)' does not support the 'equality' constraint because it is a function type - -let q = hash id diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/E_sign02.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/E_sign02.fs deleted file mode 100644 index 7a368182e02..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/E_sign02.fs +++ /dev/null @@ -1,12 +0,0 @@ -// #Regression #Libraries #Operators -// Test sign function on unsigned primitives, should get error. - -//The type 'byte' does not support the operator 'get_Sign'$ -//The type 'uint16' does not support the operator 'get_Sign'$ -//The type 'uint32' does not support the operator 'get_Sign'$ -//The type 'uint64' does not support the operator 'get_Sign'$ - -if sign 0uy <> 0 then exit 1 // byte -if sign 0us <> 0 then exit 1 // int16 -if sign 0u <> 0 then exit 1 // int32 -if sign 0uL <> 0 then exit 1 // int64 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/EqualityAndUncheckedHash01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/EqualityAndUncheckedHash01.fs deleted file mode 100644 index 7ae622955eb..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/EqualityAndUncheckedHash01.fs +++ /dev/null @@ -1,10 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:5436 -// You should not be able to hash F# function values -// Note: most positive cases already covered under fsharp\typecheck\sigs -// I'm adding this simple one since I did not see it there. -// -module TestModule - -// This is ok (unchecked) -let p = Unchecked.hash id diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/Pow_Constrains.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/Pow_Constrains.fs deleted file mode 100644 index f54171f6ccf..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/Pow_Constrains.fs +++ /dev/null @@ -1,16 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:4487 -// Feature request: loosen Pow operator constraints - -type T(x : float, y : float) = - static let mutable m = false - static member Pow (g: T, e: float) = m <- true - g - static member Check() = m - -let t = new T(1.,2.) - -let c = t ** 3. // OK! - -exit <| if T.Check() then 0 else 1 - diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/StringOnEnum01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/StringOnEnum01.fs deleted file mode 100644 index 7fd2ceccddb..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/StringOnEnum01.fs +++ /dev/null @@ -1,68 +0,0 @@ -// #Regression #Libraries #Operators -// Regression for FSHARP1.0:5995 -// Calling "string" on an enum results in the integer value rather than the ToString name (possibly other static optimization issues?) - -module M - -// int32 -type Foo = - | A = 1 - | B = 2 - -let a = Foo.A -let r = a :> System.IFormattable -if (string a) <> (string r) then exit 1 - -// uint32 -type Foo2 = - | A = 3u - | B = 4u - -let a2 = Foo2.A -let r2 = a :> System.IFormattable -if (string a2) <> (string r2) then exit 1 - -// char : see FSHARP1.0:6228 -//type Foo3 = -// | A = 'a' -// | B = 'b' - -//let a3 = Foo3.A -//let r3 = a :> System.IFormattable -//if (string a3) <> (string r3) then exit 1 - -// int16 -type Foo4 = - | A = 1s - | B = 2s - -let a4 = Foo4.A -let r4 = a :> System.IFormattable -if (string a4) <> (string r4) then exit 1 - -// uint16 -type Foo5 = - | A = 1us - | B = 2us - -let a5 = Foo5.A -let r5 = a :> System.IFormattable -if (string a5) <> (string r5) then exit 1 - -// sbyte -type Foo6 = - | A = 1y - | B = 2y - -let a6 = Foo6.A -let r6 = a :> System.IFormattable -if (string a6) <> (string r6) then exit 1 - -// byte -type Foo7 = - | A = 1uy - | B = 2uy - -let a7 = Foo7.A -let r7 = a :> System.IFormattable -if (string a7) <> (string r7) then exit 1 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/e_AbsOnIntegers02.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/e_AbsOnIntegers02.fs deleted file mode 100644 index 60ec1eb5da6..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/e_AbsOnIntegers02.fs +++ /dev/null @@ -1,17 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:3470 - exception on abs of native integer -//The type 'byte' does not support the operator 'Abs'$ -//The type 'uint16' does not support the operator 'Abs'$ -//The type 'uint32' does not support the operator 'Abs'$ -//The type 'uint32' does not support the operator 'Abs'$ -//The type 'unativeint' does not support the operator 'Abs'$ -//The type 'uint64' does not support the operator 'Abs'$ -//The type 'uint64' does not support the operator 'Abs'$ - -abs -1uy // byte -abs -1us // uint16 -abs -1ul // uint32 -abs -1u // uint32 -abs -1un // unativeint -abs -1uL // uint64 -abs -1UL // uint64 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/env.lst b/tests/fsharpqa/Source/Libraries/Core/Operators/env.lst deleted file mode 100644 index 3b893973508..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/env.lst +++ /dev/null @@ -1,13 +0,0 @@ - SOURCE=Pow_Constrains.fs SCFLAGS=--warnaserror # Pow_Constrains.fs - SOURCE=sign01.fs # sign01.fs - SOURCE=E_sign02.fs SCFLAGS=--test:ErrorRanges # E_sign02.fs - SOURCE=round01.fs # round01.fs - SOURCE=string01.fs # string01.fs - SOURCE=AbsOnIntegers01.fs # AbsOnIntegers01.fs - SOURCE=E_AbsOnIntegers02.fs SCFLAGS="--test:ErrorRanges --nowarn:20" # E_AbsOnIntegers02.fs - SOURCE=CastOperator.fs # CastOperator.fs - - SOURCE=EqualityAndUncheckedHash01.fs SCFLAGS=-a # EqualityAndUncheckedHash01.fs - SOURCE=E_EqualityAndHash01.fs SCFLAGS=--test:ErrorRanges # E_EqualityAndHash01.fs - - SOURCE=StringOnEnum01.fs # StringOnEnum01.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/round01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/round01.fs deleted file mode 100644 index a9287100a85..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/round01.fs +++ /dev/null @@ -1,60 +0,0 @@ -// #Libraries #Operators -#light - -// Test the round function - -// Identity -for i in [1 .. 10000] do - if i |> float |> round <> float i then exit 1 - if i |> float32 |> round <> float32 i then exit 1 - if i |> decimal |> round <> decimal i then exit 1 - -// Round down -if round 1.1 <> 1.0 then exit 1 -if round 1.2 <> 1.0 then exit 1 -if round 1.3 <> 1.0 then exit 1 -if round 1.4 <> 1.0 then exit 1 - -if round 1.1f <> 1.0f then exit 1 -if round 1.2f <> 1.0f then exit 1 -if round 1.3f <> 1.0f then exit 1 -if round 1.4f <> 1.0f then exit 1 - -if round 1.1m <> 1.0m then exit 1 -if round 1.2m <> 1.0m then exit 1 -if round 1.3m <> 1.0m then exit 1 -if round 1.4m <> 1.0m then exit 1 - -// Round down -if round 1.6 <> 2.0 then exit 1 -if round 1.7 <> 2.0 then exit 1 -if round 1.8 <> 2.0 then exit 1 -if round 1.9 <> 2.0 then exit 1 - -if round 1.6f <> 2.0f then exit 1 -if round 1.7f <> 2.0f then exit 1 -if round 1.8f <> 2.0f then exit 1 -if round 1.9f <> 2.0f then exit 1 - -if round 1.6m <> 2.0m then exit 1 -if round 1.7m <> 2.0m then exit 1 -if round 1.8m <> 2.0m then exit 1 -if round 1.9m <> 2.0m then exit 1 - -// Midpoint rounding. If between two numbers, round to the 'even' one. - -if round 1.5 <> 2.0 then exit 1 -if round 1.5f <> 2.0f then exit 1 -if round 1.5m <> 2.0m then exit 1 - -if round 2.5 <> 2.0 then exit 1 -if round 2.5f <> 2.0f then exit 1 -if round 2.5m <> 2.0m then exit 1 - -// If not midpoint, round to nearest as usual - -if round 2.500001 <> 3.0 then exit 1 -if round 2.500001f <> 3.0f then exit 1 -if round 2.500001m <> 3.0m then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/sign01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/sign01.fs deleted file mode 100644 index f181ba4ca89..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/sign01.fs +++ /dev/null @@ -1,34 +0,0 @@ -// #Libraries #Operators -#light - -// Test the 'sign' library function - -// Positive sign -if sign 1y <> 1 then exit 1 // byte -if sign 1s <> 1 then exit 1 // int16 -if sign 1 <> 1 then exit 1 // int32 -if sign 1L <> 1 then exit 1 // int64 -if sign 1.0f <> 1 then exit 1 // float -if sign 1.0 <> 1 then exit 1 // double -if sign 1.0m <> 1 then exit 1 // decimal - -// Zero -if sign 0y <> 0 then exit 1 // byte -if sign 0s <> 0 then exit 1 // int16 -if sign 0 <> 0 then exit 1 // int32 -if sign 0L <> 0 then exit 1 // int64 -if sign 0.0f <> 0 then exit 1 // float -if sign 0.0 <> 0 then exit 1 // double -if sign 0.0m <> 0 then exit 1 // decimal - -// Negative sign -if sign -1y <> -1 then exit 1 // byte -if sign -1s <> -1 then exit 1 // int16 -if sign -1 <> -1 then exit 1 // int32 -if sign -1L <> -1 then exit 1 // int64 -if sign -1.0f <> -1 then exit 1 // float -if sign -1.0 <> -1 then exit 1 // double -if sign -1.0m <> -1 then exit 1 // decimal - -// All clear! -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/string01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/string01.fs deleted file mode 100644 index 881cd5c28a2..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/string01.fs +++ /dev/null @@ -1,44 +0,0 @@ -// #Regression #Libraries #Operators -open System - -// Regression test for FSHARP1.0:3977 - Make "string" function work for decimal and user-defined IFormattable types. - -type CalcSum(x : int, y: int) = - let mutable x = x - let mutable y = y - - member this.Sum () = x + y - - interface IFormattable with - member x.ToString (format: string, provider : IFormatProvider) = - match format with - | null | "" - | "g" | "G" -> - String.Format("X + Y = {0}", x.Sum()) - | "s" | "S" -> - // Short form - x.Sum().ToString() - | _ -> - invalidArg format "Format is wrong!" - - override x.ToString() = (x :> IFormattable).ToString(null, null) - -let calc = CalcSum(10, 20) - -// test string function -match string calc with -| "X + Y = 30" -> () -| _ -> exit 1 - -// test with Console.WriteLine -try - printfn "%s" (calc.ToString()) - Console.WriteLine("{0:S}", calc) - Console.Write("{0} {1} {2:D}", 10, 20, calc) -with - | :? ArgumentException as e -> - match e.ParamName with - | "D" -> exit 0 - | _ -> exit 2 - -exit 1 From 7896b6cb23c8180ea6432e0eb922ad3472a8a66d Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Fri, 26 Jun 2020 15:02:20 -0700 Subject: [PATCH 34/60] temp --- ...{MultipleInst07.fs => E_MultipleInst07.fs} | 2 +- .../Inheritance_OverrideInterface.fs | 8 - .../InterfaceTypes/MultipleInst08.fs | 16 + .../InterfaceTypes/env.lst | 25 +- tests/fsharpqa/Source/test.lst | 554 +++++++++--------- 5 files changed, 307 insertions(+), 298 deletions(-) rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{MultipleInst07.fs => E_MultipleInst07.fs} (63%) create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst08.fs diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst07.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs similarity index 63% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst07.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs index d89c7763eef..c4c00dbd1b5 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst07.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs @@ -1,7 +1,7 @@ // #Conformance #ObjectOrientedTypes #InterfacesAndImplementations // Aliased types should correctly unify, even in combination with a measure. -//'C' cannot implement the interface 'IB<_>' with the two instantiations 'IB' and 'IB>' because they may unify. +//This type implements the same interface at different generic instantiations 'IB' and 'IB>'. This is not permitted in this version of F#. type MyInt = int [] type kg diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs index 29ee78f8743..e1d05457214 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs @@ -44,12 +44,4 @@ type C5() = interface IB with member x.X() = 10 -// see https://github.com/fsharp/fslang-design/issues/185#issuecomment-331737819 -// currently fails to compile -// open question whether "by-design" or bug -//type C6<'T>() = -// inherit C5() -// interface IB<'T> with -// member x.X() = 11 - exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst08.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst08.fs new file mode 100644 index 00000000000..3a8fa7a599c --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst08.fs @@ -0,0 +1,16 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +type MyInt = int +[] type kg + +type IB<'a> = + interface + abstract X : unit -> int + end + +type C() = + interface IB> with + member x.X() = 1 + interface IB with + member x.X() = 2 + +exit 1 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst index 34fa7745323..0c8d4e19a0d 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst @@ -4,18 +4,19 @@ SOURCE=ObjImplementsInterfaceGenWithConstraint.fs COMPILE_ONLY=1 # ObjImplementsInterfaceGenWithConstraint.fs - SOURCE=InterfaceMember_NameCollisions.fs SCFLAGS=--test:ErrorRanges # InterfaceMember_NameCollisions.fs - - SOURCE=MultipleInst01.fs SCFLAGS=--test:ErrorRanges --langversion:4.7 # MultipleInst01.fs - SOURCE=MultipleInst02.fs SCFLAGS=--test:ErrorRanges # MultipleInst02.fs - SOURCE=MultipleInst03.fs SCFLAGS=--test:ErrorRanges # MultipleInst03.fs - SOURCE=MultipleInst04.fs SCFLAGS=--test:ErrorRanges --langversion:4.7 # MultipleInst04.fs - SOURCE=MultipleInst05.fs SCFLAGS=--test:ErrorRanges # MultipleInst05.fs - SOURCE=MultipleInst06.fs SCFLAGS=--test:ErrorRanges # MultipleInst06.fs - SOURCE=MultipleInst07.fs SCFLAGS=--test:ErrorRanges --langversion:preview # MultipleInst07.fs - - SOURCE=Inheritance_OverrideInterface.fs # Inheritance_OverrideInterface.fs - SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs + SOURCE=InterfaceMember_NameCollisions.fs SCFLAGS=--test:ErrorRanges # InterfaceMember_NameCollisions.fs + + SOURCE=MultipleInst01.fs SCFLAGS=--test:ErrorRanges # MultipleInst01.fs + SOURCE=MultipleInst02.fs SCFLAGS=--test:ErrorRanges # MultipleInst02.fs + SOURCE=MultipleInst03.fs SCFLAGS=--test:ErrorRanges # MultipleInst03.fs + SOURCE=MultipleInst04.fs SCFLAGS=--test:ErrorRanges # MultipleInst04.fs + SOURCE=MultipleInst05.fs SCFLAGS=--test:ErrorRanges # MultipleInst05.fs + SOURCE=MultipleInst06.fs SCFLAGS="--test:ErrorRanges" # MultipleInst06.fs + SOURCE=E_MultipleInst07.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_MultipleInst07.fs + SOURCE=MultipleInst08.fs SCFLAGS="--test:ErrorRanges --langversion:preview" # MultipleInst08.fs + + SOURCE=Inheritance_OverrideInterface.fs SCFLAGS="--test:ErrorRanges --langversion:preview" # Inheritance_OverrideInterface.fs + SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs SOURCE=E_InterfaceNotFullyImpl01.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl01.fs SOURCE=E_InterfaceNotFullyImpl02.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl02.fs SOURCE=E_InterfaceNotFullyImpl03.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl03.fs diff --git a/tests/fsharpqa/Source/test.lst b/tests/fsharpqa/Source/test.lst index 95afc5893b4..41284ca837d 100644 --- a/tests/fsharpqa/Source/test.lst +++ b/tests/fsharpqa/Source/test.lst @@ -5,281 +5,281 @@ # ReqNOCov -- skip this test/suite if we are doing a code coverage run # ReqENU -- skip this test/suite if we are running on non-ENU (useful to exclude hard-to-localize tests) -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\AsyncExpressionStepping -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\AttributeTargets -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\CCtorDUWithMember -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\CompiledNameAttribute -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\ComputationExpressions -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\DoNotBoxStruct -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\GeneratedIterators -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\InequalityComparison -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\ListExpressionStepping -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\LiteralValue -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\MethodImplAttribute -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Misc -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Mutation -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Operators -Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\QueryExpressionStepping -Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SeqExpressionStepping -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SeqExpressionTailCalls -CodeGen01,NoMT,CodeGen,NoHostedCompiler,SerializableAttribute CodeGen\EmittedIL\SerializableAttribute -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\StaticInit -Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SteppingMatch -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\TailCalls -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\TestFunctions -CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Tuples -CodeGen01,NoMT,CodeGen CodeGen\StringEncoding -CodeGen01,NoMT,CodeGen CodeGen\Structure - - -CompilerOptions01,NoMT CompilerOptions\fsc\checked -CompilerOptions01,NoMT CompilerOptions\fsc\cliversion -CompilerOptions01,NoMT CompilerOptions\fsc\codepage -CompilerOptions01,NoMT CompilerOptions\fsc\crossoptimize -CompilerOptions01,NoMT CompilerOptions\fsc\debug -CompilerOptions01,NoMT CompilerOptions\fsc\dumpAllCommandLineOptions -CompilerOptions01,NoMT CompilerOptions\fsc\flaterrors -CompilerOptions02,NoMT CompilerOptions\fsc\gccerrors -CompilerOptions01,NoMT,help CompilerOptions\fsc\help -CompilerOptions01,NoMT CompilerOptions\fsc\highentropyva -CompilerOptions01,NoMT CompilerOptions\fsc\langversion -CompilerOptions01,NoMT CompilerOptions\fsc\lib -CompilerOptions01,NoMT CompilerOptions\fsc\noframework -CompilerOptions01,NoMT CompilerOptions\fsc\nologo -CompilerOptions01,NoMT CompilerOptions\fsc\optimize -CompilerOptions01,NoMT CompilerOptions\fsc\out -CompilerOptions01,NoMT,pdbs CompilerOptions\fsc\pdb -CompilerOptions01,NoMT CompilerOptions\fsc\platform -CompilerOptions01,NoMT CompilerOptions\fsc\reference -CompilerOptions01,NoMT CompilerOptions\fsc\Removed -CompilerOptions01,NoMT CompilerOptions\fsc\standalone -CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\staticlink -CompilerOptions01,NoMT CompilerOptions\fsc\subsystemversion -CompilerOptions01,NoMT CompilerOptions\fsc\tailcalls -CompilerOptions01,NoMT CompilerOptions\fsc\target -CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\times -CompilerOptions01,NoMT CompilerOptions\fsc\warn -CompilerOptions01,NoMT CompilerOptions\fsc\warnaserror -CompilerOptions01,NoMT CompilerOptions\fsc\warnon -CompilerOptions01,NoMT CompilerOptions\fsc\responsefile -CompilerOptions01,NoMT,help CompilerOptions\fsi\help -CompilerOptions01,NoMT CompilerOptions\fsi\highentropyva -CompilerOptions01,NoMT CompilerOptions\fsi\langversion -CompilerOptions01,NoMT CompilerOptions\fsi\nologo -CompilerOptions01,NoMT CompilerOptions\fsi\subsystemversion -CompilerOptions01,NoMT CompilerOptions\fsi\times -CompilerOptions02,NoMT CompilerOptions\fsi\exename -CompilerOptions01,NoMT,Determinism CompilerOptions\fsc\determinism - -Conformance01 Conformance\BasicGrammarElements\Constants -Conformance01 Conformance\BasicGrammarElements\OperatorNames -Conformance01 Conformance\BasicGrammarElements\PrecedenceAndOperators -Conformance01 Conformance\BasicTypeAndModuleDefinitions\ExceptionDefinitions -Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\Diags -Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\Legacy -Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\New -Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Basic -Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\IComparison -Conformance01 Conformance\BasicTypeAndModuleDefinitions\ModuleDefinitions -Conformance01 Conformance\BasicTypeAndModuleDefinitions\NamespaceDeclGroups -Conformance01 Conformance\BasicTypeAndModuleDefinitions\NullRepresentations -Conformance01 Conformance\BasicTypeAndModuleDefinitions\RecordTypes -Conformance01 Conformance\BasicTypeAndModuleDefinitions\TypeAbbreviations -Conformance01 Conformance\BasicTypeAndModuleDefinitions\UnionTypes -Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\Basic -Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\OnOverridesAndIFaceImpl -Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\OnTypeMembers -Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\PermittedLocations -Conformance01 Conformance\DeclarationElements\CustomAttributes\ArgumentsOfAllTypes -Conformance01 Conformance\DeclarationElements\CustomAttributes\AttributeInheritance - -Conformance02 Conformance\DeclarationElements\CustomAttributes\AttributeUsage -Conformance02 Conformance\DeclarationElements\CustomAttributes\Basic -Conformance02 Conformance\DeclarationElements\CustomAttributes\ImportedAttributes -Conformance02 Conformance\DeclarationElements\Events\basic -Conformance02 Conformance\DeclarationElements\FieldMembers -Conformance02 Conformance\DeclarationElements\ImportDeclarations -Conformance02 Conformance\DeclarationElements\InterfaceSpecificationsAndImplementations -Conformance02 Conformance\DeclarationElements\LetBindings\ActivePatternBindings -Conformance02 Conformance\DeclarationElements\LetBindings\ArityInference -Conformance02 Conformance\DeclarationElements\LetBindings\Basic -Conformance02 Conformance\DeclarationElements\LetBindings\ExplicitTypeParameters -Conformance02 Conformance\DeclarationElements\LetBindings\TypeFunctions -Conformance02 Conformance\DeclarationElements\MemberDefinitions\ImplementingDispatchSlots -Conformance02 Conformance\DeclarationElements\MemberDefinitions\MethodsAndProperties -Conformance02 Conformance\DeclarationElements\MemberDefinitions\NamedArguments -Conformance02 Conformance\DeclarationElements\MemberDefinitions\OptionalArguments -Conformance02 Conformance\DeclarationElements\MemberDefinitions\OptionalDefaultParameterValueArguments -Conformance02 Conformance\DeclarationElements\MemberDefinitions\OverloadingMembers -Conformance02 Conformance\DeclarationElements\ModuleAbbreviations -Conformance02 Conformance\DeclarationElements\ObjectConstructors -Conformance02 Conformance\DeclarationElements\P-invokeDeclarations - -Conformance03 Conformance\Expressions\ApplicationExpressions\Assertion -Conformance03 Conformance\Expressions\ApplicationExpressions\BasicApplication -Conformance03 Conformance\Expressions\ApplicationExpressions\ObjectConstruction -Conformance03 Conformance\Expressions\BindingExpressions\Binding -Conformance03 Conformance\Expressions\ConstantExpressions -Conformance03 Conformance\Expressions\ControlFlowExpressions\Assertion -Conformance03 Conformance\Expressions\ControlFlowExpressions\Conditional -Conformance03 Conformance\Expressions\ControlFlowExpressions\ParenthesizedAndBlock -Conformance03 Conformance\Expressions\ControlFlowExpressions\PatternMatching -Conformance03 Conformance\Expressions\ControlFlowExpressions\SequenceIteration -Conformance03 Conformance\Expressions\ControlFlowExpressions\SequentialExecution -Conformance03 Conformance\Expressions\ControlFlowExpressions\SimpleFor -Conformance03 Conformance\Expressions\ControlFlowExpressions\TryCatch -Conformance03 Conformance\Expressions\ControlFlowExpressions\TryFinally -Conformance03 Conformance\Expressions\ControlFlowExpressions\While -Conformance03 Conformance\Expressions\DataExpressions\AddressOf -Conformance03 Conformance\Expressions\DataExpressions\ComputationExpressions -Conformance03 Conformance\Expressions\DataExpressions\ObjectExpressions -Conformance03 Conformance\Expressions\DataExpressions\QueryExpressions -Conformance03 Conformance\Expressions\DataExpressions\RangeExpressions - -Conformance04 Conformance\Expressions\DataExpressions\SequenceExpressions -Conformance04 Conformance\Expressions\DataExpressions\TupleExpressions -Conformance04 Conformance\Expressions\ElaborationAndElaboratedExpressions -Conformance04 Conformance\Expressions\EvaluationAndValues -Conformance04 Conformance\Expressions\EvaluationOfElaboratedForms -Conformance04 Conformance\Expressions\ExpressionQuotations\Baselines -Conformance04 Conformance\Expressions\ExpressionQuotations\Regressions -Conformance04 Conformance\Expressions\SomeCheckingAndInferenceTerminology -Conformance04 Conformance\Expressions\SyntacticSugar -Conformance04 Conformance\Expressions\SyntacticSugarAndAmbiguities -Conformance04 Conformance\Expressions\Type-relatedExpressions -Conformance04 Conformance\ImplementationFilesAndSignatureFiles\CheckingOfImplementationFiles -Conformance04 Conformance\ImplementationFilesAndSignatureFiles\InitializationSemanticsForImplementationFiles -Conformance04 Conformance\ImplementationFilesAndSignatureFiles\NamespacesFragmentsAndImplementationFiles\basic -Conformance04 Conformance\ImplementationFilesAndSignatureFiles\NamespacesFragmentsAndImplementationFiles\global -Conformance04 Conformance\ImplementationFilesAndSignatureFiles\SignatureFiles -Conformance04 Conformance\InferenceProcedures\ByrefSafetyAnalysis -Conformance04 Conformance\InferenceProcedures\ConstraintSolving -Conformance04 Conformance\InferenceProcedures\DispatchSlotChecking - -Conformance05 Conformance\InferenceProcedures\DispatchSlotInference -Conformance05 Conformance\InferenceProcedures\FunctionApplicationResolution -Conformance05 Conformance\InferenceProcedures\Generalization -Conformance05 Conformance\InferenceProcedures\MethodApplicationResolution -Conformance05 Conformance\InferenceProcedures\NameResolution\AutoOpen -Conformance05 Conformance\InferenceProcedures\NameResolution\Misc -Conformance05 Conformance\InferenceProcedures\NameResolution\RequireQualifiedAccess -Conformance05 Conformance\InferenceProcedures\RecursiveSafetyAnalysis -Conformance05 Conformance\InferenceProcedures\ResolvingApplicationExpressions -Conformance05 Conformance\InferenceProcedures\TypeInference -Conformance05 Conformance\InferenceProcedures\WellFormednessChecking -Conformance05 Conformance\LexicalAnalysis\Comments -Conformance05 Conformance\LexicalAnalysis\ConditionalCompilation -Conformance05 Conformance\LexicalAnalysis\Directives -Conformance05 Conformance\LexicalAnalysis\HiddenTokens -Conformance05 Conformance\LexicalAnalysis\IdentifierReplacements -Conformance05 Conformance\LexicalAnalysis\IdentifiersAndKeywords -Conformance05 Conformance\LexicalAnalysis\LineDirectives -Conformance05 Conformance\LexicalAnalysis\NumericLiterals -Conformance05 Conformance\LexicalAnalysis\Shift\Generics - -Conformance06 Conformance\LexicalAnalysis\StringsAndCharacters -Conformance06 Conformance\LexicalAnalysis\SymbolicKeywords -Conformance06 Conformance\LexicalAnalysis\SymbolicOperators -Conformance06 Conformance\LexicalAnalysis\Whitespace -Conformance06 Conformance\LexicalFiltering\Basic\ByExample -Conformance06 Conformance\LexicalFiltering\Basic\OffsideExceptions -Conformance06 Conformance\LexicalFiltering\HashLight -Conformance06 Conformance\LexicalFiltering\HighPrecedenceApplication -Conformance06 Conformance\LexicalFiltering\LexicalAnalysisOfTypeApplications -Conformance06 Conformance\ObjectOrientedTypeDefinitions\AbstractMembers -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\AsDeclarations -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\AutoProperties -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ExplicitFields -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ExplicitObjectConstructors -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ImplicitObjectConstructors -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\InheritsDeclarations -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\LetDoDeclarations -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\MemberDeclarations -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\Misc -Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\StaticLetDoDeclarations - -Conformance07 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ValueRestriction -Conformance07 Conformance\ObjectOrientedTypeDefinitions\DelegateTypes -Conformance07 Conformance\ObjectOrientedTypeDefinitions\EnumTypes +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\AsyncExpressionStepping +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\AttributeTargets +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\CCtorDUWithMember +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\CompiledNameAttribute +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\ComputationExpressions +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\DoNotBoxStruct +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\GeneratedIterators +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\InequalityComparison +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\ListExpressionStepping +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\LiteralValue +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\MethodImplAttribute +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Misc +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Mutation +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Operators +####Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\QueryExpressionStepping +####Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SeqExpressionStepping +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SeqExpressionTailCalls +####CodeGen01,NoMT,CodeGen,NoHostedCompiler,SerializableAttribute CodeGen\EmittedIL\SerializableAttribute +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\StaticInit +####Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SteppingMatch +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\TailCalls +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\TestFunctions +####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Tuples +####CodeGen01,NoMT,CodeGen CodeGen\StringEncoding +####CodeGen01,NoMT,CodeGen CodeGen\Structure +#### +#### +####CompilerOptions01,NoMT CompilerOptions\fsc\checked +####CompilerOptions01,NoMT CompilerOptions\fsc\cliversion +####CompilerOptions01,NoMT CompilerOptions\fsc\codepage +####CompilerOptions01,NoMT CompilerOptions\fsc\crossoptimize +####CompilerOptions01,NoMT CompilerOptions\fsc\debug +####CompilerOptions01,NoMT CompilerOptions\fsc\dumpAllCommandLineOptions +####CompilerOptions01,NoMT CompilerOptions\fsc\flaterrors +####CompilerOptions02,NoMT CompilerOptions\fsc\gccerrors +####CompilerOptions01,NoMT,help CompilerOptions\fsc\help +####CompilerOptions01,NoMT CompilerOptions\fsc\highentropyva +####CompilerOptions01,NoMT CompilerOptions\fsc\langversion +####CompilerOptions01,NoMT CompilerOptions\fsc\lib +####CompilerOptions01,NoMT CompilerOptions\fsc\noframework +####CompilerOptions01,NoMT CompilerOptions\fsc\nologo +####CompilerOptions01,NoMT CompilerOptions\fsc\optimize +####CompilerOptions01,NoMT CompilerOptions\fsc\out +####CompilerOptions01,NoMT,pdbs CompilerOptions\fsc\pdb +####CompilerOptions01,NoMT CompilerOptions\fsc\platform +####CompilerOptions01,NoMT CompilerOptions\fsc\reference +####CompilerOptions01,NoMT CompilerOptions\fsc\Removed +####CompilerOptions01,NoMT CompilerOptions\fsc\standalone +####CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\staticlink +####CompilerOptions01,NoMT CompilerOptions\fsc\subsystemversion +####CompilerOptions01,NoMT CompilerOptions\fsc\tailcalls +####CompilerOptions01,NoMT CompilerOptions\fsc\target +####CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\times +####CompilerOptions01,NoMT CompilerOptions\fsc\warn +####CompilerOptions01,NoMT CompilerOptions\fsc\warnaserror +####CompilerOptions01,NoMT CompilerOptions\fsc\warnon +####CompilerOptions01,NoMT CompilerOptions\fsc\responsefile +####CompilerOptions01,NoMT,help CompilerOptions\fsi\help +####CompilerOptions01,NoMT CompilerOptions\fsi\highentropyva +####CompilerOptions01,NoMT CompilerOptions\fsi\langversion +####CompilerOptions01,NoMT CompilerOptions\fsi\nologo +####CompilerOptions01,NoMT CompilerOptions\fsi\subsystemversion +####CompilerOptions01,NoMT CompilerOptions\fsi\times +####CompilerOptions02,NoMT CompilerOptions\fsi\exename +####CompilerOptions01,NoMT,Determinism CompilerOptions\fsc\determinism +#### +####Conformance01 Conformance\BasicGrammarElements\Constants +####Conformance01 Conformance\BasicGrammarElements\OperatorNames +####Conformance01 Conformance\BasicGrammarElements\PrecedenceAndOperators +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\ExceptionDefinitions +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\Diags +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\Legacy +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\New +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Basic +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\IComparison +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\ModuleDefinitions +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\NamespaceDeclGroups +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\NullRepresentations +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\RecordTypes +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\TypeAbbreviations +####Conformance01 Conformance\BasicTypeAndModuleDefinitions\UnionTypes +####Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\Basic +####Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\OnOverridesAndIFaceImpl +####Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\OnTypeMembers +####Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\PermittedLocations +####Conformance01 Conformance\DeclarationElements\CustomAttributes\ArgumentsOfAllTypes +####Conformance01 Conformance\DeclarationElements\CustomAttributes\AttributeInheritance +#### +####Conformance02 Conformance\DeclarationElements\CustomAttributes\AttributeUsage +####Conformance02 Conformance\DeclarationElements\CustomAttributes\Basic +####Conformance02 Conformance\DeclarationElements\CustomAttributes\ImportedAttributes +####Conformance02 Conformance\DeclarationElements\Events\basic +####Conformance02 Conformance\DeclarationElements\FieldMembers +####Conformance02 Conformance\DeclarationElements\ImportDeclarations +####Conformance02 Conformance\DeclarationElements\InterfaceSpecificationsAndImplementations +####Conformance02 Conformance\DeclarationElements\LetBindings\ActivePatternBindings +####Conformance02 Conformance\DeclarationElements\LetBindings\ArityInference +####Conformance02 Conformance\DeclarationElements\LetBindings\Basic +####Conformance02 Conformance\DeclarationElements\LetBindings\ExplicitTypeParameters +####Conformance02 Conformance\DeclarationElements\LetBindings\TypeFunctions +####Conformance02 Conformance\DeclarationElements\MemberDefinitions\ImplementingDispatchSlots +####Conformance02 Conformance\DeclarationElements\MemberDefinitions\MethodsAndProperties +####Conformance02 Conformance\DeclarationElements\MemberDefinitions\NamedArguments +####Conformance02 Conformance\DeclarationElements\MemberDefinitions\OptionalArguments +####Conformance02 Conformance\DeclarationElements\MemberDefinitions\OptionalDefaultParameterValueArguments +####Conformance02 Conformance\DeclarationElements\MemberDefinitions\OverloadingMembers +####Conformance02 Conformance\DeclarationElements\ModuleAbbreviations +####Conformance02 Conformance\DeclarationElements\ObjectConstructors +####Conformance02 Conformance\DeclarationElements\P-invokeDeclarations +#### +####Conformance03 Conformance\Expressions\ApplicationExpressions\Assertion +####Conformance03 Conformance\Expressions\ApplicationExpressions\BasicApplication +####Conformance03 Conformance\Expressions\ApplicationExpressions\ObjectConstruction +####Conformance03 Conformance\Expressions\BindingExpressions\Binding +####Conformance03 Conformance\Expressions\ConstantExpressions +####Conformance03 Conformance\Expressions\ControlFlowExpressions\Assertion +####Conformance03 Conformance\Expressions\ControlFlowExpressions\Conditional +####Conformance03 Conformance\Expressions\ControlFlowExpressions\ParenthesizedAndBlock +####Conformance03 Conformance\Expressions\ControlFlowExpressions\PatternMatching +####Conformance03 Conformance\Expressions\ControlFlowExpressions\SequenceIteration +####Conformance03 Conformance\Expressions\ControlFlowExpressions\SequentialExecution +####Conformance03 Conformance\Expressions\ControlFlowExpressions\SimpleFor +####Conformance03 Conformance\Expressions\ControlFlowExpressions\TryCatch +####Conformance03 Conformance\Expressions\ControlFlowExpressions\TryFinally +####Conformance03 Conformance\Expressions\ControlFlowExpressions\While +####Conformance03 Conformance\Expressions\DataExpressions\AddressOf +####Conformance03 Conformance\Expressions\DataExpressions\ComputationExpressions +####Conformance03 Conformance\Expressions\DataExpressions\ObjectExpressions +####Conformance03 Conformance\Expressions\DataExpressions\QueryExpressions +####Conformance03 Conformance\Expressions\DataExpressions\RangeExpressions +#### +####Conformance04 Conformance\Expressions\DataExpressions\SequenceExpressions +####Conformance04 Conformance\Expressions\DataExpressions\TupleExpressions +####Conformance04 Conformance\Expressions\ElaborationAndElaboratedExpressions +####Conformance04 Conformance\Expressions\EvaluationAndValues +####Conformance04 Conformance\Expressions\EvaluationOfElaboratedForms +####Conformance04 Conformance\Expressions\ExpressionQuotations\Baselines +####Conformance04 Conformance\Expressions\ExpressionQuotations\Regressions +####Conformance04 Conformance\Expressions\SomeCheckingAndInferenceTerminology +####Conformance04 Conformance\Expressions\SyntacticSugar +####Conformance04 Conformance\Expressions\SyntacticSugarAndAmbiguities +####Conformance04 Conformance\Expressions\Type-relatedExpressions +####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\CheckingOfImplementationFiles +####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\InitializationSemanticsForImplementationFiles +####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\NamespacesFragmentsAndImplementationFiles\basic +####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\NamespacesFragmentsAndImplementationFiles\global +####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\SignatureFiles +####Conformance04 Conformance\InferenceProcedures\ByrefSafetyAnalysis +####Conformance04 Conformance\InferenceProcedures\ConstraintSolving +####Conformance04 Conformance\InferenceProcedures\DispatchSlotChecking +#### +####Conformance05 Conformance\InferenceProcedures\DispatchSlotInference +####Conformance05 Conformance\InferenceProcedures\FunctionApplicationResolution +####Conformance05 Conformance\InferenceProcedures\Generalization +####Conformance05 Conformance\InferenceProcedures\MethodApplicationResolution +####Conformance05 Conformance\InferenceProcedures\NameResolution\AutoOpen +####Conformance05 Conformance\InferenceProcedures\NameResolution\Misc +####Conformance05 Conformance\InferenceProcedures\NameResolution\RequireQualifiedAccess +####Conformance05 Conformance\InferenceProcedures\RecursiveSafetyAnalysis +####Conformance05 Conformance\InferenceProcedures\ResolvingApplicationExpressions +####Conformance05 Conformance\InferenceProcedures\TypeInference +####Conformance05 Conformance\InferenceProcedures\WellFormednessChecking +####Conformance05 Conformance\LexicalAnalysis\Comments +####Conformance05 Conformance\LexicalAnalysis\ConditionalCompilation +####Conformance05 Conformance\LexicalAnalysis\Directives +####Conformance05 Conformance\LexicalAnalysis\HiddenTokens +####Conformance05 Conformance\LexicalAnalysis\IdentifierReplacements +####Conformance05 Conformance\LexicalAnalysis\IdentifiersAndKeywords +####Conformance05 Conformance\LexicalAnalysis\LineDirectives +####Conformance05 Conformance\LexicalAnalysis\NumericLiterals +####Conformance05 Conformance\LexicalAnalysis\Shift\Generics +#### +####Conformance06 Conformance\LexicalAnalysis\StringsAndCharacters +####Conformance06 Conformance\LexicalAnalysis\SymbolicKeywords +####Conformance06 Conformance\LexicalAnalysis\SymbolicOperators +####Conformance06 Conformance\LexicalAnalysis\Whitespace +####Conformance06 Conformance\LexicalFiltering\Basic\ByExample +####Conformance06 Conformance\LexicalFiltering\Basic\OffsideExceptions +####Conformance06 Conformance\LexicalFiltering\HashLight +####Conformance06 Conformance\LexicalFiltering\HighPrecedenceApplication +####Conformance06 Conformance\LexicalFiltering\LexicalAnalysisOfTypeApplications +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\AbstractMembers +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\AsDeclarations +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\AutoProperties +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ExplicitFields +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ExplicitObjectConstructors +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ImplicitObjectConstructors +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\InheritsDeclarations +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\LetDoDeclarations +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\MemberDeclarations +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\Misc +####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\StaticLetDoDeclarations +#### +####Conformance07 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ValueRestriction +####Conformance07 Conformance\ObjectOrientedTypeDefinitions\DelegateTypes +####Conformance07 Conformance\ObjectOrientedTypeDefinitions\EnumTypes Conformance07 Conformance\ObjectOrientedTypeDefinitions\InterfaceTypes -Conformance07 Conformance\ObjectOrientedTypeDefinitions\StructTypes -Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\basic -Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\intrinsic -Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\optional -Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeKindInference -Conformance07 Conformance\PatternMatching\And -Conformance07 Conformance\PatternMatching\Array -Conformance07 Conformance\PatternMatching\As -Conformance07 Conformance\PatternMatching\ConsList -Conformance07 Conformance\PatternMatching\DynamicTypeTest -Conformance07 Conformance\PatternMatching\Expression -Conformance07 Conformance\PatternMatching\Named -Conformance07 Conformance\PatternMatching\Null -Conformance07 Conformance\PatternMatching\Record -Conformance07 Conformance\PatternMatching\Simple -Conformance07 Conformance\PatternMatching\SimpleConstant - -Conformance08 Conformance\PatternMatching\Tuple -Conformance08 Conformance\PatternMatching\TypeAnnotated -Conformance08 Conformance\PatternMatching\TypeConstraint -Conformance08 Conformance\PatternMatching\Union -Conformance08 Conformance\PatternMatching\Wildcard -Conformance08 Conformance\Signatures\SignatureConformance -Conformance08 Conformance\Signatures\SignatureTypes -Conformance08 Conformance\SpecialAttributesAndTypes\Imported\System.ThreadStatic -Conformance08 Conformance\SpecialAttributesAndTypes\Imported\CallerInfo -Conformance08 Conformance\StructFieldEqualityComparison -Conformance08 Conformance\TypesAndTypeConstraints\CheckingSyntacticTypes -Conformance08 Conformance\TypesAndTypeConstraints\LogicalPropertiesOfTypes -Conformance08 Conformance\TypesAndTypeConstraints\TypeConstraints -Conformance08 Conformance\TypesAndTypeConstraints\TypeParameterDefinitions -Conformance08 Conformance\UnitsOfMeasure\Basic -Conformance08 Conformance\UnitsOfMeasure\Bounds -Conformance08 Conformance\UnitsOfMeasure\Constants -Conformance08 Conformance\UnitsOfMeasure\Diagnostics -Conformance08 Conformance\UnitsOfMeasure\Operators -Conformance08 Conformance\UnitsOfMeasure\Parenthesis -Conformance08 Conformance\UnitsOfMeasure\Parsing -Conformance08 Conformance\UnitsOfMeasure\TypeChecker -Conformance08 Conformance\UnitsOfMeasure\WithOOP -Conformance08 Conformance\Expressions\DataExpressions\NameOf - -Misc01 ClrFx\PseudoCustomAttributes\AssemblyAlgorithmId -Misc01 ClrFx\PseudoCustomAttributes\AssemblyConfiguration -Misc01 ClrFx\PseudoCustomAttributes\AssemblyVersion -Misc01 Diagnostics\async -Misc01,Diagnostics Diagnostics\General -Misc01 Diagnostics\NONTERM -Misc01 Diagnostics\ParsingAtEOF -Misc01 EntryPoint -Misc01 Globalization -Misc01,NoMT Import -Misc01,NoMT ..\..\..\testsprivate\fsharpqa\Source\InteractiveSession\AssemblyLoading -Misc01,NoMT InteractiveSession\Misc -Misc01,NoMT InteractiveSession\Misc\GenericConstraintWoes\issue2411 -Misc01 Libraries\Control -Misc01 Libraries\Core\collections -Misc01 Libraries\Core\ExtraTopLevelOperators -Misc01 Libraries\Core\LanguagePrimitives -Misc01 Libraries\Core\NativeInterop\stackalloc -Misc01 Libraries\Core\Operators -Misc01 Libraries\Core\Reflection -Misc01 Libraries\Core\Unchecked -Misc01 Warnings - -Misc02 Libraries\Portable -Misc02 Misc -Misc02 MultiTargeting -Misc02 OCamlCompat -Misc02,CodeGen Optimizations\AssemblyBoundary -Misc02,CodeGen Optimizations\ForLoop -Misc02,CodeGen Optimizations\GenericComparison -Misc02,CodeGen Optimizations\Inlining -Misc02,NoMT Printing -Misc02 ..\..\..\testsprivate\fsharpqa\Source\RealWorld\UnitsOfMeasure -Misc02 ..\..\..\testsprivate\fsharpqa\Source\RealWorld\Agents -Misc02,NoMT ..\..\..\testsprivate\fsharpqa\Source\Setup -Misc02 Stress -Misc02 XmlDoc\Basic -Misc02 XmlDoc\OCamlDoc -Misc02 XmlDoc\UnitOfMeasure +####Conformance07 Conformance\ObjectOrientedTypeDefinitions\StructTypes +####Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\basic +####Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\intrinsic +####Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\optional +####Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeKindInference +####Conformance07 Conformance\PatternMatching\And +####Conformance07 Conformance\PatternMatching\Array +####Conformance07 Conformance\PatternMatching\As +####Conformance07 Conformance\PatternMatching\ConsList +####Conformance07 Conformance\PatternMatching\DynamicTypeTest +####Conformance07 Conformance\PatternMatching\Expression +####Conformance07 Conformance\PatternMatching\Named +####Conformance07 Conformance\PatternMatching\Null +####Conformance07 Conformance\PatternMatching\Record +####Conformance07 Conformance\PatternMatching\Simple +####Conformance07 Conformance\PatternMatching\SimpleConstant +#### +####Conformance08 Conformance\PatternMatching\Tuple +####Conformance08 Conformance\PatternMatching\TypeAnnotated +####Conformance08 Conformance\PatternMatching\TypeConstraint +####Conformance08 Conformance\PatternMatching\Union +####Conformance08 Conformance\PatternMatching\Wildcard +####Conformance08 Conformance\Signatures\SignatureConformance +####Conformance08 Conformance\Signatures\SignatureTypes +####Conformance08 Conformance\SpecialAttributesAndTypes\Imported\System.ThreadStatic +####Conformance08 Conformance\SpecialAttributesAndTypes\Imported\CallerInfo +####Conformance08 Conformance\StructFieldEqualityComparison +####Conformance08 Conformance\TypesAndTypeConstraints\CheckingSyntacticTypes +####Conformance08 Conformance\TypesAndTypeConstraints\LogicalPropertiesOfTypes +####Conformance08 Conformance\TypesAndTypeConstraints\TypeConstraints +####Conformance08 Conformance\TypesAndTypeConstraints\TypeParameterDefinitions +####Conformance08 Conformance\UnitsOfMeasure\Basic +####Conformance08 Conformance\UnitsOfMeasure\Bounds +####Conformance08 Conformance\UnitsOfMeasure\Constants +####Conformance08 Conformance\UnitsOfMeasure\Diagnostics +####Conformance08 Conformance\UnitsOfMeasure\Operators +####Conformance08 Conformance\UnitsOfMeasure\Parenthesis +####Conformance08 Conformance\UnitsOfMeasure\Parsing +####Conformance08 Conformance\UnitsOfMeasure\TypeChecker +####Conformance08 Conformance\UnitsOfMeasure\WithOOP +####Conformance08 Conformance\Expressions\DataExpressions\NameOf +#### +####Misc01 ClrFx\PseudoCustomAttributes\AssemblyAlgorithmId +####Misc01 ClrFx\PseudoCustomAttributes\AssemblyConfiguration +####Misc01 ClrFx\PseudoCustomAttributes\AssemblyVersion +####Misc01 Diagnostics\async +####Misc01,Diagnostics Diagnostics\General +####Misc01 Diagnostics\NONTERM +####Misc01 Diagnostics\ParsingAtEOF +####Misc01 EntryPoint +####Misc01 Globalization +####Misc01,NoMT Import +####Misc01,NoMT ..\..\..\testsprivate\fsharpqa\Source\InteractiveSession\AssemblyLoading +####Misc01,NoMT InteractiveSession\Misc +####Misc01,NoMT InteractiveSession\Misc\GenericConstraintWoes\issue2411 +####Misc01 Libraries\Control +####Misc01 Libraries\Core\collections +####Misc01 Libraries\Core\ExtraTopLevelOperators +####Misc01 Libraries\Core\LanguagePrimitives +####Misc01 Libraries\Core\NativeInterop\stackalloc +####Misc01 Libraries\Core\Operators +####Misc01 Libraries\Core\Reflection +####Misc01 Libraries\Core\Unchecked +####Misc01 Warnings +#### +####Misc02 Libraries\Portable +####Misc02 Misc +####Misc02 MultiTargeting +####Misc02 OCamlCompat +####Misc02,CodeGen Optimizations\AssemblyBoundary +####Misc02,CodeGen Optimizations\ForLoop +####Misc02,CodeGen Optimizations\GenericComparison +####Misc02,CodeGen Optimizations\Inlining +####Misc02,NoMT Printing +####Misc02 ..\..\..\testsprivate\fsharpqa\Source\RealWorld\UnitsOfMeasure +####Misc02 ..\..\..\testsprivate\fsharpqa\Source\RealWorld\Agents +####Misc02,NoMT ..\..\..\testsprivate\fsharpqa\Source\Setup +####Misc02 Stress +####Misc02 XmlDoc\Basic +####Misc02 XmlDoc\OCamlDoc +####Misc02 XmlDoc\UnitOfMeasure From a166922936f05229845f0fb45d7ff1de13426930 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sat, 27 Jun 2020 15:55:51 +0000 Subject: [PATCH 35/60] Update dependencies from https://github.com/dotnet/arcade build 20200626.2 (#9577) Microsoft.DotNet.Arcade.Sdk From Version 1.0.0-beta.20302.3 -> To Version 1.0.0-beta.20326.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/common/sdl/packages.config | 2 +- eng/common/templates/job/execute-sdl.yml | 2 +- global.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 231cca712e2..44065c7c818 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -3,9 +3,9 @@ - + https://github.com/dotnet/arcade - 9b71be0663493cd0e111b55536a2e1eeb272f54c + ed69753a3ffbdaa08365252c710d57a64d17f859 diff --git a/eng/common/sdl/packages.config b/eng/common/sdl/packages.config index 256ffbfb93a..968b39bef5f 100644 --- a/eng/common/sdl/packages.config +++ b/eng/common/sdl/packages.config @@ -1,4 +1,4 @@ - + diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml index 52e2ff021d7..bf09d2511c6 100644 --- a/eng/common/templates/job/execute-sdl.yml +++ b/eng/common/templates/job/execute-sdl.yml @@ -65,7 +65,7 @@ jobs: continueOnError: ${{ parameters.sdlContinueOnError }} - ${{ if eq(parameters.overrideParameters, '') }}: - powershell: eng/common/sdl/execute-all-sdl-tools.ps1 - -GuardianPackageName Microsoft.Guardian.Cli.0.7.2 + -GuardianPackageName Microsoft.Guardian.Cli.win10-x64.0.20.1 -NugetPackageDirectory $(Build.SourcesDirectory)\.packages -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) ${{ parameters.additionalParameters }} diff --git a/global.json b/global.json index 146979f9b93..7afbdb52d28 100644 --- a/global.json +++ b/global.json @@ -9,7 +9,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.20302.3", + "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.20326.2", "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2" } } From 7b29d44bf7f88d7808c1989c1c607806302dbfa6 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 27 Jun 2020 17:58:28 +0200 Subject: [PATCH 36/60] Improve perf for String.filter up to 3x (#9509) * Improve perf for String.filter 2-2.5x * Cleanup: remove "foo" etc in tests * Add tests for new execution path for LOH in String.filter * Change test string --- src/fsharp/FSharp.Core/string.fs | 28 +++++++++++++++++-- .../StringModule.fs | 15 +++++++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/fsharp/FSharp.Core/string.fs b/src/fsharp/FSharp.Core/string.fs index 7e4b65f1a08..cabbbea51ef 100644 --- a/src/fsharp/FSharp.Core/string.fs +++ b/src/fsharp/FSharp.Core/string.fs @@ -12,6 +12,11 @@ namespace Microsoft.FSharp.Core [] [] module String = + [] + /// LOH threshold is calculated from FSharp.Compiler.AbstractIL.Internal.Library.LOH_SIZE_THRESHOLD_BYTES, + /// and is equal to 80_000 / sizeof + let LOH_CHAR_THRESHOLD = 40_000 + [] let length (str:string) = if isNull str then 0 else str.Length @@ -53,13 +58,30 @@ namespace Microsoft.FSharp.Core [] let filter (predicate: char -> bool) (str:string) = - if String.IsNullOrEmpty str then + let len = length str + + if len = 0 then String.Empty - else - let res = StringBuilder str.Length + + elif len > LOH_CHAR_THRESHOLD then + // By using SB here, which is twice slower than the optimized path, we prevent LOH allocations + // and 'stop the world' collections if the filtering results in smaller strings. + // We also don't pre-allocate SB here, to allow for less mem pressure when filter result is small. + let res = StringBuilder() str |> iter (fun c -> if predicate c then res.Append c |> ignore) res.ToString() + else + // Must do it this way, since array.fs is not yet in scope, but this is safe + let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len + let mutable i = 0 + for c in str do + if predicate c then + target.[i] <- c + i <- i + 1 + + String(target, 0, i) + [] let collect (mapping: char -> string) (str:string) = if String.IsNullOrEmpty str then diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs index a72ab64e236..66a2c1b2006 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs @@ -87,18 +87,25 @@ type StringModule() = [] member this.Filter() = - let e1 = String.filter (fun c -> true) "foo" - Assert.AreEqual("foo", e1) + let e1 = String.filter (fun c -> true) "Taradiddle" + Assert.AreEqual("Taradiddle", e1) let e2 = String.filter (fun c -> true) null Assert.AreEqual("", e2) - let e3 = String.filter (fun c -> c <> 'o') "foo bar" - Assert.AreEqual("f bar", e3) + let e3 = String.filter Char.IsUpper "How Vexingly Quick Daft Zebras Jump!" + Assert.AreEqual("HVQDZJ", e3) let e4 = String.filter (fun c -> c <> 'o') "" Assert.AreEqual("", e4) + let e5 = String.filter (fun c -> c > 'B' ) "ABRACADABRA" + Assert.AreEqual("RCDR", e5) + + // LOH test with 55k string, which is 110k bytes + let e5 = String.filter (fun c -> c > 'B' ) (String.replicate 5_000 "ABRACADABRA") + Assert.AreEqual(String.replicate 5_000 "RCDR", e5) + [] member this.Collect() = let e1 = String.collect (fun c -> "a"+string c) "foo" From 35e2caac7b719df86f278a45f268407181ca797a Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 27 Jun 2020 17:59:18 +0200 Subject: [PATCH 37/60] String map performance improvement (#9470) * Simplify and improve perf of String.length * Improve performance of String.map * Revert "Simplify and improve perf of String.length" * Resolves https://github.com/dotnet/fsharp/pull/9470#discussion_r441293049 * Lingering space * Change `String` to use `new` to clarify use of ctor * Add some better tests for String.map, add side-effect test * Add tests to ensure the mapping function is called a deterministically amount of times * Fix typo * Remove "foo" from String.map tests --- src/fsharp/FSharp.Core/string.fs | 10 ++++-- .../StringModule.fs | 32 ++++++++++++++++--- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/fsharp/FSharp.Core/string.fs b/src/fsharp/FSharp.Core/string.fs index cabbbea51ef..b17c06fd0f2 100644 --- a/src/fsharp/FSharp.Core/string.fs +++ b/src/fsharp/FSharp.Core/string.fs @@ -42,9 +42,13 @@ namespace Microsoft.FSharp.Core if String.IsNullOrEmpty str then String.Empty else - let res = StringBuilder str.Length - str |> iter (fun c -> res.Append(mapping c) |> ignore) - res.ToString() + let result = str.ToCharArray() + let mutable i = 0 + for c in result do + result.[i] <- mapping c + i <- i + 1 + + new String(result) [] let mapi (mapping: int -> char -> char) (str:string) = diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs index 66a2c1b2006..1962e39b2c9 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs @@ -71,11 +71,35 @@ type StringModule() = [] member this.Map() = - let e1 = String.map (fun c -> c) "foo" - Assert.AreEqual("foo", e1) + let e1 = String.map id "xyz" + Assert.AreEqual("xyz", e1) - let e2 = String.map (fun c -> c) null - Assert.AreEqual("", e2) + let e2 = String.map (fun c -> c + char 1) "abcde" + Assert.AreEqual("bcdef", e2) + + let e3 = String.map (fun c -> c) null + Assert.AreEqual("", e3) + + let e4 = String.map (fun c -> c) String.Empty + Assert.AreEqual("", e4) + + let e5 = String.map (fun _ -> 'B') "A" + Assert.AreEqual("B", e5) + + let e6 = String.map (fun _ -> failwith "should not raise") null + Assert.AreEqual("", e6) + + // this tests makes sure mapping function is not called too many times + let mutable x = 0 + let e7 = String.map (fun _ -> if x > 2 then failwith "should not raise" else x <- x + 1; 'x') "abc" + Assert.AreEqual(x, 3) + Assert.AreEqual(e7, "xxx") + + // side-effect and "order of operation" test + let mutable x = 0 + let e8 = String.map (fun c -> x <- x + 1; c + char x) "abcde" + Assert.AreEqual(x, 5) + Assert.AreEqual(e8, "bdfhj") [] member this.MapI() = From de5dc3b8bf6375ef27907ba4a5bb5440360742b1 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 27 Jun 2020 18:03:07 +0200 Subject: [PATCH 38/60] Perf: String.replicate from O(n) to O(log(n)), up to 12x speed improvement (#9512) * Turn String.replicate from O(n) into O(log(n)) * Cleanup String.replicate tests by removing usages of "foo" * String.replicate: add tests for missing cases, and for the new O(log(n)) cut-off points * Improve String.replicate algorithm further * Add tests for String.replicate covering all lines/branches of algo * Fix accidental comment --- src/fsharp/FSharp.Core/string.fs | 35 ++++++++++++++++--- .../StringModule.fs | 35 ++++++++++++++++--- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/fsharp/FSharp.Core/string.fs b/src/fsharp/FSharp.Core/string.fs index b17c06fd0f2..d009615e6aa 100644 --- a/src/fsharp/FSharp.Core/string.fs +++ b/src/fsharp/FSharp.Core/string.fs @@ -107,13 +107,38 @@ namespace Microsoft.FSharp.Core let replicate (count:int) (str:string) = if count < 0 then invalidArgInputMustBeNonNegative "count" count - if String.IsNullOrEmpty str then + let len = length str + if len = 0 || count = 0 then String.Empty + + elif len = 1 then + new String(str.[0], count) + + elif count <= 4 then + match count with + | 1 -> str + | 2 -> String.Concat(str, str) + | 3 -> String.Concat(str, str, str) + | _ -> String.Concat(str, str, str, str) + else - let res = StringBuilder(count * str.Length) - for i = 0 to count - 1 do - res.Append str |> ignore - res.ToString() + // Using the primitive, because array.fs is not yet in scope. It's safe: both len and count are positive. + let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked (len * count) + let source = str.ToCharArray() + + // O(log(n)) performance loop: + // Copy first string, then keep copying what we already copied + // (i.e., doubling it) until we reach or pass the halfway point + Array.Copy(source, 0, target, 0, len) + let mutable i = len + while i * 2 < target.Length do + Array.Copy(target, 0, target, i, i) + i <- i * 2 + + // finally, copy the remain half, or less-then half + Array.Copy(target, 0, target, i, target.Length - i) + new String(target) + [] let forall predicate (str:string) = diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs index 1962e39b2c9..6c1b1360585 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. namespace FSharp.Core.UnitTests.Collections @@ -156,15 +156,42 @@ type StringModule() = [] member this.Replicate() = - let e1 = String.replicate 0 "foo" + let e1 = String.replicate 0 "Snickersnee" Assert.AreEqual("", e1) - let e2 = String.replicate 2 "foo" - Assert.AreEqual("foofoo", e2) + let e2 = String.replicate 2 "Collywobbles, " + Assert.AreEqual("Collywobbles, Collywobbles, ", e2) let e3 = String.replicate 2 null Assert.AreEqual("", e3) + let e4 = String.replicate 300_000 "" + Assert.AreEqual("", e4) + + let e5 = String.replicate 23 "天地玄黃,宇宙洪荒。" + Assert.AreEqual(230 , e5.Length) + Assert.AreEqual("天地玄黃,宇宙洪荒。天地玄黃,宇宙洪荒。", e5.Substring(0, 20)) + + // This tests the cut-off point for the O(log(n)) algorithm with a prime number + let e6 = String.replicate 84673 "!!!" + Assert.AreEqual(84673 * 3, e6.Length) + + // This tests the cut-off point for the O(log(n)) algorithm with a 2^x number + let e7 = String.replicate 1024 "!!!" + Assert.AreEqual(1024 * 3, e7.Length) + + let e8 = String.replicate 1 "What a wonderful world" + Assert.AreEqual("What a wonderful world", e8) + + let e9 = String.replicate 3 "أضعت طريقي! أضعت طريقي" // means: I'm lost + Assert.AreEqual("أضعت طريقي! أضعت طريقيأضعت طريقي! أضعت طريقيأضعت طريقي! أضعت طريقي", e9) + + let e10 = String.replicate 4 "㏖ ㏗ ℵ " + Assert.AreEqual("㏖ ㏗ ℵ ㏖ ㏗ ℵ ㏖ ㏗ ℵ ㏖ ㏗ ℵ ", e10) + + let e11 = String.replicate 5 "5" + Assert.AreEqual("55555", e11) + CheckThrowsArgumentException(fun () -> String.replicate -1 "foo" |> ignore) [] From b74c9de731058d0258f82dac1bddc7688a5fa410 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Sat, 27 Jun 2020 12:13:18 -0700 Subject: [PATCH 39/60] Merge master to release/dev16.7 (#9578) * Update dependencies from https://github.com/dotnet/arcade build 20200626.2 (#9577) Microsoft.DotNet.Arcade.Sdk From Version 1.0.0-beta.20302.3 -> To Version 1.0.0-beta.20326.2 Co-authored-by: dotnet-maestro[bot] * Improve perf for String.filter up to 3x (#9509) * Improve perf for String.filter 2-2.5x * Cleanup: remove "foo" etc in tests * Add tests for new execution path for LOH in String.filter * Change test string * String map performance improvement (#9470) * Simplify and improve perf of String.length * Improve performance of String.map * Revert "Simplify and improve perf of String.length" * Resolves https://github.com/dotnet/fsharp/pull/9470#discussion_r441293049 * Lingering space * Change `String` to use `new` to clarify use of ctor * Add some better tests for String.map, add side-effect test * Add tests to ensure the mapping function is called a deterministically amount of times * Fix typo * Remove "foo" from String.map tests * Perf: String.replicate from O(n) to O(log(n)), up to 12x speed improvement (#9512) * Turn String.replicate from O(n) into O(log(n)) * Cleanup String.replicate tests by removing usages of "foo" * String.replicate: add tests for missing cases, and for the new O(log(n)) cut-off points * Improve String.replicate algorithm further * Add tests for String.replicate covering all lines/branches of algo * Fix accidental comment Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: dotnet-maestro[bot] Co-authored-by: Abel Braaksma --- eng/Version.Details.xml | 4 +- eng/common/sdl/packages.config | 2 +- eng/common/templates/job/execute-sdl.yml | 2 +- global.json | 2 +- src/fsharp/FSharp.Core/string.fs | 73 ++++++++++++++--- .../StringModule.fs | 82 ++++++++++++++++--- 6 files changed, 137 insertions(+), 28 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 231cca712e2..44065c7c818 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -3,9 +3,9 @@ - + https://github.com/dotnet/arcade - 9b71be0663493cd0e111b55536a2e1eeb272f54c + ed69753a3ffbdaa08365252c710d57a64d17f859 diff --git a/eng/common/sdl/packages.config b/eng/common/sdl/packages.config index 256ffbfb93a..968b39bef5f 100644 --- a/eng/common/sdl/packages.config +++ b/eng/common/sdl/packages.config @@ -1,4 +1,4 @@ - + diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml index 52e2ff021d7..bf09d2511c6 100644 --- a/eng/common/templates/job/execute-sdl.yml +++ b/eng/common/templates/job/execute-sdl.yml @@ -65,7 +65,7 @@ jobs: continueOnError: ${{ parameters.sdlContinueOnError }} - ${{ if eq(parameters.overrideParameters, '') }}: - powershell: eng/common/sdl/execute-all-sdl-tools.ps1 - -GuardianPackageName Microsoft.Guardian.Cli.0.7.2 + -GuardianPackageName Microsoft.Guardian.Cli.win10-x64.0.20.1 -NugetPackageDirectory $(Build.SourcesDirectory)\.packages -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) ${{ parameters.additionalParameters }} diff --git a/global.json b/global.json index 146979f9b93..7afbdb52d28 100644 --- a/global.json +++ b/global.json @@ -9,7 +9,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.20302.3", + "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.20326.2", "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2" } } diff --git a/src/fsharp/FSharp.Core/string.fs b/src/fsharp/FSharp.Core/string.fs index 7e4b65f1a08..d009615e6aa 100644 --- a/src/fsharp/FSharp.Core/string.fs +++ b/src/fsharp/FSharp.Core/string.fs @@ -12,6 +12,11 @@ namespace Microsoft.FSharp.Core [] [] module String = + [] + /// LOH threshold is calculated from FSharp.Compiler.AbstractIL.Internal.Library.LOH_SIZE_THRESHOLD_BYTES, + /// and is equal to 80_000 / sizeof + let LOH_CHAR_THRESHOLD = 40_000 + [] let length (str:string) = if isNull str then 0 else str.Length @@ -37,9 +42,13 @@ namespace Microsoft.FSharp.Core if String.IsNullOrEmpty str then String.Empty else - let res = StringBuilder str.Length - str |> iter (fun c -> res.Append(mapping c) |> ignore) - res.ToString() + let result = str.ToCharArray() + let mutable i = 0 + for c in result do + result.[i] <- mapping c + i <- i + 1 + + new String(result) [] let mapi (mapping: int -> char -> char) (str:string) = @@ -53,13 +62,30 @@ namespace Microsoft.FSharp.Core [] let filter (predicate: char -> bool) (str:string) = - if String.IsNullOrEmpty str then + let len = length str + + if len = 0 then String.Empty - else - let res = StringBuilder str.Length + + elif len > LOH_CHAR_THRESHOLD then + // By using SB here, which is twice slower than the optimized path, we prevent LOH allocations + // and 'stop the world' collections if the filtering results in smaller strings. + // We also don't pre-allocate SB here, to allow for less mem pressure when filter result is small. + let res = StringBuilder() str |> iter (fun c -> if predicate c then res.Append c |> ignore) res.ToString() + else + // Must do it this way, since array.fs is not yet in scope, but this is safe + let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len + let mutable i = 0 + for c in str do + if predicate c then + target.[i] <- c + i <- i + 1 + + String(target, 0, i) + [] let collect (mapping: char -> string) (str:string) = if String.IsNullOrEmpty str then @@ -81,13 +107,38 @@ namespace Microsoft.FSharp.Core let replicate (count:int) (str:string) = if count < 0 then invalidArgInputMustBeNonNegative "count" count - if String.IsNullOrEmpty str then + let len = length str + if len = 0 || count = 0 then String.Empty + + elif len = 1 then + new String(str.[0], count) + + elif count <= 4 then + match count with + | 1 -> str + | 2 -> String.Concat(str, str) + | 3 -> String.Concat(str, str, str) + | _ -> String.Concat(str, str, str, str) + else - let res = StringBuilder(count * str.Length) - for i = 0 to count - 1 do - res.Append str |> ignore - res.ToString() + // Using the primitive, because array.fs is not yet in scope. It's safe: both len and count are positive. + let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked (len * count) + let source = str.ToCharArray() + + // O(log(n)) performance loop: + // Copy first string, then keep copying what we already copied + // (i.e., doubling it) until we reach or pass the halfway point + Array.Copy(source, 0, target, 0, len) + let mutable i = len + while i * 2 < target.Length do + Array.Copy(target, 0, target, i, i) + i <- i * 2 + + // finally, copy the remain half, or less-then half + Array.Copy(target, 0, target, i, target.Length - i) + new String(target) + [] let forall predicate (str:string) = diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs index a72ab64e236..6c1b1360585 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. namespace FSharp.Core.UnitTests.Collections @@ -71,11 +71,35 @@ type StringModule() = [] member this.Map() = - let e1 = String.map (fun c -> c) "foo" - Assert.AreEqual("foo", e1) + let e1 = String.map id "xyz" + Assert.AreEqual("xyz", e1) - let e2 = String.map (fun c -> c) null - Assert.AreEqual("", e2) + let e2 = String.map (fun c -> c + char 1) "abcde" + Assert.AreEqual("bcdef", e2) + + let e3 = String.map (fun c -> c) null + Assert.AreEqual("", e3) + + let e4 = String.map (fun c -> c) String.Empty + Assert.AreEqual("", e4) + + let e5 = String.map (fun _ -> 'B') "A" + Assert.AreEqual("B", e5) + + let e6 = String.map (fun _ -> failwith "should not raise") null + Assert.AreEqual("", e6) + + // this tests makes sure mapping function is not called too many times + let mutable x = 0 + let e7 = String.map (fun _ -> if x > 2 then failwith "should not raise" else x <- x + 1; 'x') "abc" + Assert.AreEqual(x, 3) + Assert.AreEqual(e7, "xxx") + + // side-effect and "order of operation" test + let mutable x = 0 + let e8 = String.map (fun c -> x <- x + 1; c + char x) "abcde" + Assert.AreEqual(x, 5) + Assert.AreEqual(e8, "bdfhj") [] member this.MapI() = @@ -87,18 +111,25 @@ type StringModule() = [] member this.Filter() = - let e1 = String.filter (fun c -> true) "foo" - Assert.AreEqual("foo", e1) + let e1 = String.filter (fun c -> true) "Taradiddle" + Assert.AreEqual("Taradiddle", e1) let e2 = String.filter (fun c -> true) null Assert.AreEqual("", e2) - let e3 = String.filter (fun c -> c <> 'o') "foo bar" - Assert.AreEqual("f bar", e3) + let e3 = String.filter Char.IsUpper "How Vexingly Quick Daft Zebras Jump!" + Assert.AreEqual("HVQDZJ", e3) let e4 = String.filter (fun c -> c <> 'o') "" Assert.AreEqual("", e4) + let e5 = String.filter (fun c -> c > 'B' ) "ABRACADABRA" + Assert.AreEqual("RCDR", e5) + + // LOH test with 55k string, which is 110k bytes + let e5 = String.filter (fun c -> c > 'B' ) (String.replicate 5_000 "ABRACADABRA") + Assert.AreEqual(String.replicate 5_000 "RCDR", e5) + [] member this.Collect() = let e1 = String.collect (fun c -> "a"+string c) "foo" @@ -125,15 +156,42 @@ type StringModule() = [] member this.Replicate() = - let e1 = String.replicate 0 "foo" + let e1 = String.replicate 0 "Snickersnee" Assert.AreEqual("", e1) - let e2 = String.replicate 2 "foo" - Assert.AreEqual("foofoo", e2) + let e2 = String.replicate 2 "Collywobbles, " + Assert.AreEqual("Collywobbles, Collywobbles, ", e2) let e3 = String.replicate 2 null Assert.AreEqual("", e3) + let e4 = String.replicate 300_000 "" + Assert.AreEqual("", e4) + + let e5 = String.replicate 23 "天地玄黃,宇宙洪荒。" + Assert.AreEqual(230 , e5.Length) + Assert.AreEqual("天地玄黃,宇宙洪荒。天地玄黃,宇宙洪荒。", e5.Substring(0, 20)) + + // This tests the cut-off point for the O(log(n)) algorithm with a prime number + let e6 = String.replicate 84673 "!!!" + Assert.AreEqual(84673 * 3, e6.Length) + + // This tests the cut-off point for the O(log(n)) algorithm with a 2^x number + let e7 = String.replicate 1024 "!!!" + Assert.AreEqual(1024 * 3, e7.Length) + + let e8 = String.replicate 1 "What a wonderful world" + Assert.AreEqual("What a wonderful world", e8) + + let e9 = String.replicate 3 "أضعت طريقي! أضعت طريقي" // means: I'm lost + Assert.AreEqual("أضعت طريقي! أضعت طريقيأضعت طريقي! أضعت طريقيأضعت طريقي! أضعت طريقي", e9) + + let e10 = String.replicate 4 "㏖ ㏗ ℵ " + Assert.AreEqual("㏖ ㏗ ℵ ㏖ ㏗ ℵ ㏖ ㏗ ℵ ㏖ ㏗ ℵ ", e10) + + let e11 = String.replicate 5 "5" + Assert.AreEqual("55555", e11) + CheckThrowsArgumentException(fun () -> String.replicate -1 "foo" |> ignore) [] From 97778cbfcf738d4a077588b63c438a2c8b2b25fe Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sun, 28 Jun 2020 17:47:31 +0200 Subject: [PATCH 40/60] Re enable tests for operators: OperatorsModule1.fs and OperatorsModule2.fs (#9516) * Re-enabling tests from OperatorsModule1/2.fs (compile errors) * Fix compile errors in OperatorsModule1/2.fs, fix tests. Note tanh test comment. * Fix `tanh` test, ensure stable result on x86 vs x64 runtimes * Stop using exception AssertionException, so that test window shows useful info * Whitespace cleanup and redundant code removal * Cleanup spelling etc * Re-enabling int, int16, int32, int64, nativeint, incr, nullArg etc tests * Special-case floating-point assertion messages for higher precision output * Fix/update/add tests (some still failing) * Separate Checked tests, add & fix others, differentiate framework/bitness for some tests * Add branch for .NET Native (ignore cos test) * Resorting to comparing floats with a delta using Assert.AreNearEqual * Add some more tests --- .../FSharp.Core.UnitTests.fsproj | 19 +- .../FSharp.Core/OperatorsModule1.fs | 802 +++++---------- .../FSharp.Core/OperatorsModule2.fs | 909 +++++++++++------- .../FSharp.Core/OperatorsModuleChecked.fs | 307 ++++++ tests/FSharp.Core.UnitTests/LibraryTestFx.fs | 2 + .../NUnitFrameworkShims.fs | 55 +- 6 files changed, 1197 insertions(+), 897 deletions(-) create mode 100644 tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj index 90b1436e398..0706e76eef5 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj @@ -33,6 +33,13 @@ + + + + + + + @@ -59,10 +66,6 @@ - - - - @@ -87,9 +90,7 @@ - - - + @@ -106,4 +107,8 @@ + + + + diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs index 5aacff670ab..e81ddf29c01 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs @@ -3,360 +3,57 @@ // Various tests for the: // Microsoft.FSharp.Core.Operators module -namespace SystematicUnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests.Operators open System -open SystematicUnitTests.LibraryTestFx +open FSharp.Core.UnitTests.LibraryTestFx open NUnit.Framework -open Microsoft.FSharp.Core.Operators.Checked [] type OperatorsModule1() = [] - member this.Checkedbyte() = - // int type - let intByte = Operators.Checked.byte 100 - Assert.AreEqual(intByte,(byte)100) - - // char type - let charByte = Operators.Checked.byte '0' - Assert.AreEqual(charByte,(byte)48) - - // boundary value - let boundByte = Operators.Checked.byte 255.0 - Assert.AreEqual(boundByte, (byte)255) - - // overflow exception - try - let overflowByte = Operators.Checked.byte 256.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - - - - [] - member this.Checkedchar() = - - // number - let numberChar = Operators.Checked.char 48 - Assert.AreEqual(numberChar,'0') - - // letter - let letterChar = Operators.Checked.char 65 - Assert.AreEqual(letterChar,'A') - - // boundary value - let boundchar = Operators.Checked.char 126 - Assert.AreEqual(boundchar, '~') - - // overflow exception - try - let overflowchar = Operators.Checked.char (System.Int64.MaxValue+(int64)2) - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - [] - member this.CheckedInt() = - - // char - let charInt = Operators.Checked.int '0' - Assert.AreEqual(charInt,48) - - // float - let floatInt = Operators.Checked.int 10.0 - Assert.AreEqual(floatInt,10) - - - // boundary value - let boundInt = Operators.Checked.int 32767.0 - Assert.AreEqual(boundInt, (int)32767) - - // overflow exception - try - let overflowint = Operators.Checked.int 2147483648.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - () - - [] - member this.CheckedInt16() = - - // char - let charInt16 = Operators.Checked.int16 '0' - Assert.AreEqual(charInt16,(int16)48) - - // float - let floatInt16 = Operators.Checked.int16 10.0 - Assert.AreEqual(floatInt16,(int16)10) - - // boundary value - let boundInt16 = Operators.Checked.int16 32767.0 - Assert.AreEqual(boundInt16, (int16)32767) - - // overflow exception - try - let overflowint16 = Operators.Checked.int16 32768.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.CheckedInt32() = - - // char - let charInt32 = Operators.Checked.int32 '0' - Assert.AreEqual(charInt32,(int32)48) - - // float - let floatInt32 = Operators.Checked.int32 10.0 - Assert.AreEqual(floatInt32,(int32)10) - - // boundary value - let boundInt32 = Operators.Checked.int32 2147483647.0 - Assert.AreEqual(boundInt32, (int32)2147483647) - - // overflow exception - try - let overflowint32 = Operators.Checked.int32 2147483648.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - () - - [] - member this.CheckedInt64() = - - // char - let charInt64 = Operators.Checked.int64 '0' - Assert.AreEqual(charInt64,(int64)48) - - // float - let floatInt64 = Operators.Checked.int64 10.0 - Assert.AreEqual(floatInt64,(int64)10) - - // boundary value - let boundInt64 = Operators.Checked.int64 9223372036854775807I - let a = 9223372036854775807L - Assert.AreEqual(boundInt64, 9223372036854775807L) - - // overflow exception - try - let overflowint64 = Operators.Checked.int64 (System.Double.MaxValue+2.0) - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.CheckedNativeint() = - - // char - let charnativeint = Operators.Checked.nativeint '0' - Assert.AreEqual(charnativeint,(nativeint)48) - - // float - let floatnativeint = Operators.Checked.nativeint 10.0 - Assert.AreEqual(floatnativeint,(nativeint)10) - - // boundary value - let boundnativeint = Operators.Checked.nativeint 32767.0 - Assert.AreEqual(boundnativeint, (nativeint)32767) - - // overflow exception - try - let overflownativeint = Operators.Checked.nativeint 2147483648.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkedsbyte() = - - // char - let charsbyte = Operators.Checked.sbyte '0' - Assert.AreEqual(charsbyte,(sbyte)48) - - // float - let floatsbyte = Operators.Checked.sbyte -10.0 - Assert.AreEqual(floatsbyte,(sbyte)(-10)) - - // boundary value - let boundsbyte = Operators.Checked.sbyte -127.0 - Assert.AreEqual(boundsbyte, (sbyte)(-127)) - - // overflow exception - try - let overflowsbyte = Operators.Checked.sbyte -256.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - () - - [] - member this.Checkeduint16() = + member _.KeyValue() = - // char - let charuint16 = Operators.Checked.uint16 '0' - Assert.AreEqual(charuint16,(uint16)48) - - // float - let floatuint16 = Operators.Checked.uint16 10.0 - Assert.AreEqual(floatuint16,(uint16)(10)) - - // boundary value - let bounduint16 = Operators.Checked.uint16 65535.0 - Assert.AreEqual(bounduint16, (uint16)(65535)) - - // overflow exception - try - let overflowuint16 = Operators.Checked.uint16 65536.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkeduint32() = - - // char - let charuint32 = Operators.Checked.uint32 '0' - Assert.AreEqual(charuint32,(uint32)48) - - // float - let floatuint32 = Operators.Checked.uint32 10.0 - Assert.AreEqual(floatuint32,(uint32)(10)) - - // boundary value - let bounduint32 = Operators.Checked.uint32 429496729.0 - Assert.AreEqual(bounduint32, (uint32)(429496729)) - - - // overflow exception - try - let overflowuint32 = Operators.Checked.uint32 uint32.MaxValue+1u - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkeduint64() = - - // char - let charuint64 = Operators.Checked.uint64 '0' - Assert.AreEqual(charuint64,(uint64)48) - - // float - let floatuint64 = Operators.Checked.uint64 10.0 - Assert.AreEqual(floatuint64,(uint64)(10)) - - // boundary value - let bounduint64 = Operators.Checked.uint64 429496729.0 - Assert.AreEqual(bounduint64, (uint64)(429496729)) - - // overflow exception - try - let overflowuint64 = Operators.Checked.uint64 System.UInt64.MaxValue+1UL - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkedunativeint() = - - // char - let charunativeint = Operators.Checked.unativeint '0' - Assert.AreEqual(charunativeint,(unativeint)48) - - // float - let floatunativeint = Operators.Checked.unativeint 10.0 - Assert.AreEqual(floatunativeint,(unativeint)10) - - // boundary value - let boundunativeint = Operators.Checked.unativeint 65353.0 - Assert.AreEqual(boundunativeint, (unativeint)65353) - - // overflow exception - try - let overflowuint64 = Operators.Checked.uint64 System.UInt64.MaxValue+1UL - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.KeyValue() = - - let funcKeyValue x = match x with | Operators.KeyValue(a) -> a // string int let stringint = funcKeyValue ( new System.Collections.Generic.KeyValuePair("string",1)) - Assert.AreEqual(stringint,("string",1)) + Assert.AreEqual(("string",1), stringint) // float char let floatchar = funcKeyValue ( new System.Collections.Generic.KeyValuePair(1.0,'a')) - Assert.AreEqual(floatchar,(1.0,'a')) + Assert.AreEqual((1.0,'a'), floatchar) // null let nullresult = funcKeyValue ( new System.Collections.Generic.KeyValuePair(null,' ')) let (nullstring:string,blankchar:char) = nullresult CheckThrowsNullRefException(fun () -> nullstring.ToString() |> ignore) - - - () - + [] - member this.OptimizedRangesGetArraySlice() = + member _.OptimizedRangesGetArraySlice() = - let param1 = Some(1) let param2 = Some(2) // int let intslice = Operators.OperatorIntrinsics.GetArraySlice [|1;2;3;4;5;6|] param1 param2 - Assert.AreEqual(intslice,[|2;3|]) + Assert.AreEqual([|2;3|], intslice) // string let stringslice = Operators.OperatorIntrinsics.GetArraySlice [|"1";"2";"3"|] param1 param2 - Assert.AreEqual(stringslice,[|"2";"3"|]) + Assert.AreEqual([|"2";"3"|], stringslice) // null let stringslice = Operators.OperatorIntrinsics.GetArraySlice [|null;null;null|] param1 param2 - Assert.AreEqual(stringslice,[|null;null|]) - - () - + Assert.AreEqual([|null;null|], stringslice) + [] - member this.OptimizedRangesGetArraySlice2D() = + member _.OptimizedRangesGetArraySlice2D() = - let param1D1 = Some(0) let param1D2 = Some(1) let param2D1 = Some(0) @@ -366,36 +63,32 @@ type OperatorsModule1() = let intArray2D = Array2D.init 2 3 (fun i j -> i*100+j) let intslice = Operators.OperatorIntrinsics.GetArraySlice2D intArray2D param1D1 param1D2 param2D1 param2D2 - Assert.AreEqual(intslice.[1,1],101) + Assert.AreEqual(101, intslice.[1,1]) // string let stringArray2D = Array2D.init 2 3 (fun i j -> (i*100+j).ToString()) let stringslice = Operators.OperatorIntrinsics.GetArraySlice2D stringArray2D param1D1 param1D2 param2D1 param2D2 - Assert.AreEqual(stringslice.[1,1],(101).ToString()) + Assert.AreEqual((101).ToString(), stringslice.[1,1]) // null let nullArray2D = Array2D.init 2 3 (fun i j -> null) let nullslice = Operators.OperatorIntrinsics.GetArraySlice2D nullArray2D param1D1 param1D2 param2D1 param2D2 - Assert.AreEqual(nullslice.[1,1],null) - - () - + Assert.AreEqual(null, nullslice.[1,1]) + [] - member this.OptimizedRangesGetStringSlice() = + member _.OptimizedRangesGetStringSlice() = let param1 = Some(4) let param2 = Some(6) // string let stringslice = Operators.OperatorIntrinsics.GetStringSlice "abcdefg" param1 param2 - Assert.AreEqual(stringslice,"efg") + Assert.AreEqual("efg", stringslice) // null CheckThrowsNullRefException(fun () -> Operators.OperatorIntrinsics.GetStringSlice null param1 param2 |> ignore) - () - - + [] - member this.OptimizedRangesSetArraySlice() = + member _.OptimizedRangesSetArraySlice() = let param1 = Some(1) let param2 = Some(2) @@ -403,23 +96,22 @@ type OperatorsModule1() = let intArray1 = [|1;2;3|] let intArray2 = [|4;5;6|] Operators.OperatorIntrinsics.SetArraySlice intArray1 param1 param2 intArray2 - Assert.AreEqual(intArray1,[|1;4;5|]) + Assert.AreEqual([|1;4;5|], intArray1) // string let stringArray1 = [|"1";"2";"3"|] let stringArray2 = [|"4";"5";"6"|] Operators.OperatorIntrinsics.SetArraySlice stringArray1 param1 param2 stringArray2 - Assert.AreEqual(stringArray1,[|"1";"4";"5"|]) + Assert.AreEqual([|"1";"4";"5"|], stringArray1) // null let nullArray1 = [|null;null;null|] let nullArray2 = [|null;null;null|] Operators.OperatorIntrinsics.SetArraySlice nullArray1 param1 param2 nullArray2 CheckThrowsNullRefException(fun () -> nullArray1.[0].ToString() |> ignore) - () - + [] - member this.OptimizedRangesSetArraySlice2D() = + member _.OptimizedRangesSetArraySlice2D() = let param1D1 = Some(0) let param1D2 = Some(1) let param2D1 = Some(0) @@ -429,43 +121,40 @@ type OperatorsModule1() = let intArray1 = Array2D.init 2 3 (fun i j -> i*10+j) let intArray2 = Array2D.init 2 3 (fun i j -> i*100+j) Operators.OperatorIntrinsics.SetArraySlice2D intArray1 param1D1 param1D2 param2D1 param2D2 intArray2 - Assert.AreEqual(intArray1.[1,1],101) + Assert.AreEqual(101, intArray1.[1,1]) // string let stringArray2D1 = Array2D.init 2 3 (fun i j -> (i*10+j).ToString()) let stringArray2D2 = Array2D.init 2 3 (fun i j -> (i*100+j).ToString()) Operators.OperatorIntrinsics.SetArraySlice2D stringArray2D1 param1D1 param1D2 param2D1 param2D2 stringArray2D2 - Assert.AreEqual(stringArray2D1.[1,1],(101).ToString()) + Assert.AreEqual((101).ToString(), stringArray2D1.[1,1]) // null let nullArray2D1 = Array2D.init 2 3 (fun i j -> null) let nullArray2D2 = Array2D.init 2 3 (fun i j -> null) Operators.OperatorIntrinsics.SetArraySlice2D nullArray2D1 param1D1 param1D2 param2D1 param2D2 nullArray2D2 CheckThrowsNullRefException(fun () -> nullArray2D1.[0,0].ToString() |> ignore) - () - + [] - member this.OptimizedRangesSetArraySlice3D() = + member _.OptimizedRangesSetArraySlice3D() = let intArray1 = Array3D.init 2 3 4 (fun i j k -> i*10+j) let intArray2 = Array3D.init 2 3 4 (fun i j k -> i*100+j) Operators.OperatorIntrinsics.SetArraySlice3D intArray1 (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) intArray2 - Assert.AreEqual(intArray1.[1,1,1],101) - () + Assert.AreEqual(101, intArray1.[1,1,1]) [] - member this.OptimizedRangesSetArraySlice4D() = + member _.OptimizedRangesSetArraySlice4D() = let intArray1 = Array4D.init 2 3 4 5 (fun i j k l -> i*10+j) let intArray2 = Array4D.init 2 3 4 5 (fun i j k l -> i*100+j) - Operators.OperatorIntrinsics.SetArraySlice4D intArray1 (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) intArray2 - Assert.AreEqual(intArray1.[1,1,1,1],101) - () - + Operators.OperatorIntrinsics.SetArraySlice4D intArray1 (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) intArray2 + Assert.AreEqual(101, intArray1.[1,1,1,1]) + [] - member this.Uncheckeddefaultof () = + member _.Uncheckeddefaultof () = // int let intdefault = Operators.Unchecked.defaultof - Assert.AreEqual(intdefault, 0) + Assert.AreEqual(0, intdefault) // string let stringdefault = Operators.Unchecked.defaultof @@ -473,433 +162,419 @@ type OperatorsModule1() = // null let structdefault = Operators.Unchecked.defaultof - Assert.AreEqual( structdefault.Day,1) - - () - + Assert.AreEqual(1, structdefault.Day) + [] - member this.abs () = + member _.abs () = // int let intabs = Operators.abs (-7) - Assert.AreEqual(intabs, 7) + Assert.AreEqual(7, intabs) - // float + // float let floatabs = Operators.abs (-100.0) - Assert.AreEqual(floatabs, 100.0) + Assert.AreEqual(100.0, floatabs) // decimal let decimalabs = Operators.abs (-1000M) - Assert.AreEqual(decimalabs, 1000M) - - () - + Assert.AreEqual(1000M, decimalabs) + [] - member this.acos () = + member _.acos () = // min value let minacos = Operators.acos (0.0) - Assert.AreEqual(minacos, 1.5707963267948966) + Assert.AreNearEqual(1.5707963267948966, minacos) // normal value let normalacos = Operators.acos (0.3) - Assert.AreEqual(normalacos, 1.2661036727794992) + Assert.AreNearEqual(1.2661036727794992, normalacos) // max value let maxacos = Operators.acos (1.0) - Assert.AreEqual(maxacos, 0.0) - () - + Assert.AreEqual(0.0, maxacos) + [] - member this.asin () = + member _.asin () = // min value let minasin = Operators.asin (0.0) - Assert.AreEqual(minasin, 0) + Assert.AreEqual(0.0, minasin) // normal value let normalasin = Operators.asin (0.5) - Assert.AreEqual(normalasin, 0.52359877559829893) + Assert.AreNearEqual(0.52359877559829893, normalasin) // max value let maxasin = Operators.asin (1.0) - Assert.AreEqual(maxasin, 1.5707963267948966) - () - - - + Assert.AreNearEqual(1.5707963267948966, maxasin) + [] - member this.atan () = + member _.atan () = // min value let minatan = Operators.atan (0.0) - Assert.AreEqual(minatan, 0) + Assert.AreNearEqual(0.0, minatan) // normal value let normalatan = Operators.atan (1.0) - Assert.AreEqual(normalatan, 0.78539816339744828) + Assert.AreNearEqual(0.78539816339744828, normalatan) // biggish value let maxatan = Operators.atan (infinity) - Assert.AreEqual(maxatan, 1.5707963267948966) - () - + Assert.AreNearEqual(1.5707963267948966, maxatan) + [] - member this.atan2 () = + member _.atan2 () = // min value let minatan2 = Operators.atan2 (0.0) (1.0) - Assert.AreEqual(minatan2, 0) + Assert.AreNearEqual(0.0, minatan2) // normal value let normalatan2 = Operators.atan2 (1.0) (1.0) - Assert.AreEqual(normalatan2, 0.78539816339744828) + Assert.AreNearEqual(0.78539816339744828, normalatan2) // biggish value let maxatan2 = Operators.atan2 (1.0) (0.0) - Assert.AreEqual(maxatan2, 1.5707963267948966) - () - + Assert.AreNearEqual(1.5707963267948966, maxatan2) + [] - member this.box () = + member _.box () = // int value let intbox = Operators.box 1 - Assert.AreEqual(intbox, 1) + Assert.AreEqual(1, intbox) // string value let stringlbox = Operators.box "string" - Assert.AreEqual(stringlbox, "string") + Assert.AreEqual("string", stringlbox) // null value let nullbox = Operators.box null CheckThrowsNullRefException(fun () -> nullbox.ToString() |> ignore) - () - + [] - member this.byte() = - // int type + member _.byte() = + // int type let intByte = Operators.byte 100 - Assert.AreEqual(intByte,(byte)100) + Assert.AreEqual(100uy, intByte) - // char type + // char type let charByte = Operators.byte '0' - Assert.AreEqual(charByte,(byte)48) + Assert.AreEqual(48uy, charByte) // boundary value let boundByte = Operators.byte 255.0 - Assert.AreEqual(boundByte, (byte)255) + Assert.AreEqual(255uy, boundByte) - // overflow exception - try - let overflowbyte = Operators.byte (System.Int64.MaxValue*(int64)2) - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") + // Overflow + let result = Operators.byte Int64.MaxValue + Assert.AreEqual(Byte.MaxValue, result) + + // Overflow + let result = Operators.byte Int64.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Double.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Double.MaxValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte (Int64.MaxValue * 8L) + Assert.AreEqual(248uy, result) // bit-complement + + // Overflow + let result = 255uy + 5uy + Assert.AreEqual(4uy, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.byte Decimal.MinValue |> ignore) [] - member this.ceil() = - // min value + member _.ceil() = + // min value let minceil = Operators.ceil 0.1 - Assert.AreEqual(minceil,1.0) + Assert.AreEqual(1.0, minceil) - // normal value + // normal value let normalceil = Operators.ceil 100.0 - Assert.AreEqual(normalceil,100.0) + Assert.AreEqual(100.0, normalceil) // max value let maxceil = Operators.ceil 1.7E+308 - Assert.AreEqual(maxceil, 1.7E+308) + Assert.AreEqual(1.7E+308, maxceil) [] - member this.char() = - // int type + member _.char() = + // int type let intchar = Operators.char 48 - Assert.AreEqual(intchar,'0') + Assert.AreEqual('0', intchar) - // string type + // string type let stringchar = Operators.char " " - Assert.AreEqual(stringchar, ' ') + Assert.AreEqual(' ', stringchar) [] - member this.compare() = - // int type + member _.compare() = + // int type let intcompare = Operators.compare 100 101 - Assert.AreEqual(intcompare,-1) + Assert.AreEqual(-1, intcompare) - // char type + // char type let charcompare = Operators.compare '0' '1' - Assert.AreEqual(charcompare,-1) + Assert.AreEqual(-1, charcompare) // null value let boundcompare = Operators.compare null null - Assert.AreEqual(boundcompare, 0) - - + Assert.AreEqual(0, boundcompare) + [] - member this.cos () = + member _.cos () = // min value let mincos = Operators.cos (0.0) - Assert.AreEqual(mincos, 1) + Assert.AreEqual(1.0, mincos) // normal value let normalcos = Operators.cos (1.0) - Assert.AreEqual(normalcos, 0.54030230586813977) + Assert.AreNearEqual(0.54030230586813977, normalcos) // biggish value let maxcos = Operators.cos (1.57) - Assert.AreEqual(maxcos, 0.00079632671073326335) - () - + Assert.AreNearEqual(0.00079632671073326335, maxcos) + [] - member this.cosh () = - + member _.cosh () = + // min value let mincosh = Operators.cosh (0.0) - Assert.AreEqual(mincosh, 1.0) + Assert.AreEqual(1.0, mincosh) // normal value let normalcosh = Operators.cosh (1.0) - Assert.AreEqual(normalcosh, 1.5430806348152437) + Assert.AreNearEqual(1.5430806348152437, normalcosh) // biggish value let maxcosh = Operators.cosh (1.57) - Assert.AreEqual(maxcosh, 2.5073466880660993) - - - () - - - + Assert.AreNearEqual(2.5073466880660993, maxcosh) + [] - member this.decimal () = + member _.decimal () = // int value let mindecimal = Operators.decimal (1) - Assert.AreEqual(mindecimal, 1) + Assert.AreEqual(1M, mindecimal) // float value let maxdecimal = Operators.decimal (1.0) - Assert.AreEqual(maxdecimal, 1) - () - + Assert.AreEqual(1M, maxdecimal) + [] - member this.decr() = - // zero + member _.decr() = + // zero let zeroref = ref 0 Operators.decr zeroref - Assert.AreEqual(zeroref,(ref -1)) + Assert.AreEqual((ref -1), zeroref) // big number let bigref = ref 32767 Operators.decr bigref - Assert.AreEqual(bigref,(ref 32766)) + Assert.AreEqual((ref 32766), bigref) // normal value let normalref = ref 100 Operators.decr (normalref) - Assert.AreEqual(normalref,(ref 99)) + Assert.AreEqual((ref 99), normalref) [] - member this.defaultArg() = - // zero + member _.defaultArg() = + // zero let zeroOption = Some(0) let intdefaultArg = Operators.defaultArg zeroOption 2 - Assert.AreEqual(intdefaultArg,0) + Assert.AreEqual(0, intdefaultArg) // big number let bigOption = Some(32767) let bigdefaultArg = Operators.defaultArg bigOption 32766 - Assert.AreEqual(bigdefaultArg,32767) + Assert.AreEqual(32767, bigdefaultArg) // normal value let normalOption = Some(100) let normalfaultArg = Operators.defaultArg normalOption 100 - Assert.AreEqual(normalfaultArg, 100) + Assert.AreEqual(100, normalfaultArg) [] - member this.double() = - // int type - let intdouble = Operators.double 100 - Assert.AreEqual(intdouble,100.0) + member _.double() = + // int type + let intdouble = Operators.float 100 + Assert.AreEqual(100.0, intdouble) - // char type - let chardouble = Operators.double '0' - Assert.AreEqual(chardouble,48) - () - + // char type + let chardouble = Operators.float '0' + Assert.AreEqual(48.0, chardouble) + [] - member this.enum() = - // zero + member _.enum() = + // zero let intarg : int32 = 0 let intenum = Operators.enum intarg - Assert.AreEqual(intenum,System.ConsoleColor.Black) + Assert.AreEqual(System.ConsoleColor.Black, intenum) // big number let bigarg : int32 = 15 let charenum = Operators.enum bigarg - Assert.AreEqual(charenum,System.ConsoleColor.White) + Assert.AreEqual(System.ConsoleColor.White, charenum) // normal value let normalarg : int32 = 9 let boundenum = Operators.enum normalarg - Assert.AreEqual(boundenum, System.ConsoleColor.Blue) + Assert.AreEqual(System.ConsoleColor.Blue, boundenum) #if IGNORED [] - member this.exit() = - // zero - try + member _.exit() = + // zero + try let intexit = Operators.exit 1 - () + with | _ -> () - //Assert.AreEqual(intexit,-1) + //Assert.AreEqual(-1, intexit) // big number let charexit = Operators.exit 32767 - //Assert.AreEqual(charexit,-1) + //Assert.AreEqual(-1, charexit) // normal value let boundexit = Operators.exit 100 - Assert.AreEqual(boundexit, 0) + Assert.AreEqual(0, boundexit) #endif [] - member this.exp() = - // zero + member _.exp() = + // zero let zeroexp = Operators.exp 0.0 - Assert.AreEqual(zeroexp,1.0) + Assert.AreEqual(1.0, zeroexp) // big number let bigexp = Operators.exp 32767.0 - Assert.AreEqual(bigexp,infinity) + Assert.AreEqual(infinity, bigexp) // normal value let normalexp = Operators.exp 100.0 - Assert.AreEqual(normalexp, 2.6881171418161356E+43) + Assert.AreEqual(2.6881171418161356E+43, normalexp) [] - member this.failwith() = - try + member _.failwith() = + try let _ = Operators.failwith "failwith" Assert.Fail("Expect fail but not.") - () + with | Failure("failwith") -> () |_ -> Assert.Fail("Throw unexpected exception") - - + [] - member this.float() = - // int type + member _.float() = + // int type let intfloat = Operators.float 100 - Assert.AreEqual(intfloat,(float)100) + Assert.AreEqual((float)100, intfloat) - // char type + // char type let charfloat = Operators.float '0' - Assert.AreEqual(charfloat,(float)48) - - () - - + Assert.AreEqual((float)48, charfloat) + [] - member this.float32() = - // int type + member _.float32() = + // int type let intfloat32 = Operators.float32 100 - Assert.AreEqual(intfloat32,(float32)100) + Assert.AreEqual((float32)100, intfloat32) - // char type + // char type let charfloat32 = Operators.float32 '0' - Assert.AreEqual(charfloat32,(float32)48) - - () - - + Assert.AreEqual((float32)48, charfloat32) + [] - member this.floor() = - // float type - let intfloor = Operators.floor 100.0 - Assert.AreEqual(intfloor,100) + member _.floor() = + // float type + let intfloor = Operators.floor 100.9 + Assert.AreEqual(100.0, intfloor) - // float32 type - let charfloor = Operators.floor ((float32)100.0) - Assert.AreEqual(charfloor,100) + // float32 type + let charfloor = Operators.floor ((float32)100.9) + Assert.AreEqual(100.0f, charfloor) [] - member this.fst() = - // int type + member _.fst() = + // int type let intfst = Operators.fst (100,101) - Assert.AreEqual(intfst,100) + Assert.AreEqual(100, intfst) - // char type + // char type let charfst = Operators.fst ('0','1') - Assert.AreEqual(charfst,'0') + Assert.AreEqual('0', charfst) // null value let boundfst = Operators.fst (null,null) - Assert.AreEqual(boundfst, null) + Assert.AreEqual(null, boundfst) [] - member this.hash() = - // int type + member _.hash() = + // int type (stable between JIT versions) let inthash = Operators.hash 100 - Assert.AreEqual(inthash,100) + Assert.AreEqual(100, inthash) - // char type + // char type (stable between JIT versions) let charhash = Operators.hash '0' - Assert.AreEqual(charhash,3145776) + Assert.AreEqual(3145776, charhash) - // string value - let boundhash = Operators.hash "A" - Assert.AreEqual(boundhash, -842352673) + // string value (test disabled, each JIT and each x86 vs x64 creates a different hash here) + //let boundhash = Operators.hash "A" + //Assert.AreEqual(-842352673, boundhash) [] - member this.id() = - // int type + member _.id() = + // int type let intid = Operators.id 100 - Assert.AreEqual(intid,100) + Assert.AreEqual(100, intid) - // char type + // char type let charid = Operators.id '0' - Assert.AreEqual(charid,'0') + Assert.AreEqual('0', charid) // string value let boundid = Operators.id "A" - Assert.AreEqual(boundid, "A") - - + Assert.AreEqual("A", boundid) + [] - member this.ignore() = - // value type + member _.ignore() = + // value type let result = Operators.ignore 10 - Assert.AreEqual(result,null) + Assert.AreEqual(null, result) // reference type let result = Operators.ignore "A" - Assert.AreEqual(result,null) - - () + Assert.AreEqual(null, result) -#if IGNORED - [] - member this.incr() = - // legit value + [] + member _.incr() = + // legit value let result = ref 10 Operators.incr result - Assert.AreEqual(!result,11) + Assert.AreEqual(11, !result) - // overflow + // Overflow. let result = ref (Operators.Checked.int System.Int32.MaxValue) - CheckThrowsOverflowException(fun() -> Operators.incr result |> ignore) - - () -#endif + Operators.incr result + Assert.AreEqual(System.Int32.MinValue, !result) [] - member this.infinity() = + member _.infinity() = let inf = Operators.infinity let result = inf > System.Double.MaxValue @@ -907,21 +582,18 @@ type OperatorsModule1() = // arithmetic operation let result = infinity + 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity - 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity * 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity / 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity / 3.0 - Assert.AreEqual(result,infinity) - - - () - + Assert.AreEqual(Double.PositiveInfinity, result) + [] - member this.infinityf() = + member _.infinityf() = let inf = Operators.infinityf let result = inf > System.Single.MaxValue @@ -929,16 +601,12 @@ type OperatorsModule1() = // arithmetic operation let result = infinityf + 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf - 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf * 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf / 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf / 3.0f - Assert.AreEqual(result,infinityf) - - () - - \ No newline at end of file + Assert.AreEqual(Single.PositiveInfinity, result) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs index 8ac0ebfd9c6..da874ebe118 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs @@ -3,138 +3,194 @@ // Various tests for the: // Microsoft.FSharp.Core.Operators module -namespace SystematicUnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests.Operators open System -open SystematicUnitTests.LibraryTestFx +open FSharp.Core.UnitTests.LibraryTestFx open NUnit.Framework -open Microsoft.FSharp.Core.Operators.Checked [] type OperatorsModule2() = -#if IGNORED - [] - member this.int() = - // int + [] + member _.int() = + // int let result = Operators.int 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // string let result = Operators.int "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // double let result = Operators.int 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // negative let result = Operators.int -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10, result) // zero let result = Operators.int 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int System.Double.MaxValue |>ignore) + // Overflow + let result = Operators.int Double.MaxValue + Assert.AreEqual(Int32.MinValue, result) - () -#endif + // Overflow + let result = Operators.int Double.MinValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int Int64.MaxValue + Assert.AreEqual(-1, result) + + // Overflow + let result = Operators.int Int64.MinValue + Assert.AreEqual(0, result) + + // Overflow + let result = Int32.MaxValue + 1 + Assert.AreEqual(Int32.MinValue, result) -#if IGNORED - [] - member this.int16() = - // int + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int Decimal.MinValue |> ignore) + + [] + member _.int16() = + // int let result = Operators.int16 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10s, result) // double let result = Operators.int16 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10s, result) // negative let result = Operators.int16 -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10s, result) // zero let result = Operators.int16 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0s, result) // string let result = Operators.int16 "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10s, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int16 System.Double.MaxValue |>ignore) - () -#endif - -#if IGNORED - [] - member this.int32() = - // int + // Overflow + let result = Operators.int16 Double.MaxValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Operators.int16 Double.MinValue + Assert.AreEqual(0s, result) + + let result = Operators.int16 Int64.MaxValue + Assert.AreEqual(-1s, result) + + // Overflow + let result = Operators.int16 Int64.MinValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Int16.MaxValue + 1s + Assert.AreEqual(Int16.MinValue, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int16 Decimal.MinValue |> ignore) + + [] + member _.int32() = + // int let result = Operators.int32 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // double let result = Operators.int32 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // negative let result = Operators.int32 -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10, result) // zero let result = Operators.int32 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // string let result = Operators.int32 "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int32 System.Double.MaxValue |>ignore) - () -#endif - -#if IGNORED - [] - member this.int64() = - // int + // Overflow + let result = Operators.int32 Double.MaxValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Double.MinValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Int64.MaxValue + Assert.AreEqual(-1, result) + + // Overflow + let result = Operators.int32 Int64.MinValue + Assert.AreEqual(0, result) + + // Overflow + let result = Int32.MaxValue + 5 + Assert.AreEqual(Int32.MinValue + 4, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int32 Decimal.MinValue |> ignore) + + [] + member _.int64() = + // int let result = Operators.int64 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10L, result) // double let result = Operators.int64 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10L, result) // negative let result = Operators.int64 -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10L, result) // zero let result = Operators.int64 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0L, result) // string let result = Operators.int64 "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10L, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int64 System.Double.MaxValue |>ignore) - () -#endif + // Overflow. + let result = Operators.int64 Double.MaxValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 Double.MinValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 UInt64.MaxValue + Assert.AreEqual(-1L, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int64 Decimal.MinValue |> ignore) + + [] + member _.invalidArg() = + CheckThrowsArgumentException(fun() -> Operators.invalidArg "A" "B" |>ignore ) -// [] -// member this.invalidArg() = -// CheckThrowsArgumentException(fun() -> Operators.invalidArg "A" "B" |>ignore ) -// -// () [] - member this.lock() = - // lock + member _.lock() = + // lock printfn "test8 started" let syncRoot = System.Object() let k = ref 0 @@ -142,542 +198,753 @@ type OperatorsModule2() = System.Threading.Thread.Sleep(1) !k ) } let arr = Async.RunSynchronously (Async.Parallel(Seq.map comp [1..50])) - Assert.AreEqual((Array.sort compare arr; arr), [|1..50|]) + Assert.AreEqual([|1..50|], Array.sort arr) // without lock let syncRoot = System.Object() let k = ref 0 let comp _ = async { do incr k - do! System.Threading.Thread.AsyncSleep(10) + do! Async.Sleep (10) return !k } let arr = Async.RunSynchronously (Async.Parallel(Seq.map comp [1..100])) - Assert.AreNotEqual ((Array.sort compare arr; arr) , [|1..100|]) - - () + Assert.AreNotEqual ([|1..100|], Array.sort arr) [] - member this.log() = + member _.log() = // double let result = Operators.log 10.0 - Assert.AreEqual(result.ToString(),"2.30258509299405") + Assert.AreEqual(2.3025850929940459, result) // negative let result = Operators.log -10.0 - Assert.AreEqual(result.ToString(),System.Double.NaN.ToString()) + Assert.AreEqual(Double.NaN, result) // zero let result = Operators.log 0.0 - Assert.AreEqual(result,-infinity) - - () + Assert.AreEqual(Double.NegativeInfinity , result) [] - member this.log10() = + member _.log10() = // double let result = Operators.log10 10.0 - Assert.AreEqual(result,1) + Assert.AreEqual(1.0, result) // negative let result = Operators.log10 -10.0 - Assert.AreEqual(result.ToString(),System.Double.NaN.ToString()) + Assert.AreEqual(System.Double.NaN, result) // zero let result = Operators.log10 0.0 - Assert.AreEqual(result,-infinity) - - () + Assert.AreEqual(Double.NegativeInfinity, result) [] - member this.max() = + member _.max() = // value type let result = Operators.max 10 8 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // negative let result = Operators.max -10.0 -8.0 - Assert.AreEqual(result,-8.0) + Assert.AreEqual(-8.0, result) // zero let result = Operators.max 0 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // reference type let result = Operators.max "A" "ABC" - Assert.AreEqual(result,"ABC") - - // overflow - CheckThrowsOverflowException(fun() -> Operators.max 10 System.Int32.MaxValue+1 |>ignore) - - () + Assert.AreEqual("ABC", result) [] - member this.min() = + member _.min() = // value type let result = Operators.min 10 8 - Assert.AreEqual(result,8) + Assert.AreEqual(8, result) // negative let result = Operators.min -10.0 -8.0 - Assert.AreEqual(result,-10.0) + Assert.AreEqual(-10.0, result) // zero let result = Operators.min 0 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // reference type let result = Operators.min "A" "ABC" - Assert.AreEqual(result,"A") - - // overflow - CheckThrowsOverflowException(fun() -> Operators.min 10 System.Int32.MinValue - 1 |>ignore) - - () + Assert.AreEqual("A", result) [] - member this.nan() = + member _.nan() = // value type - let result = Operators.nan - Assert.AreEqual(result.ToString(),System.Double.NaN.ToString()) - - () + let result = Operators.nan + Assert.AreEqual(System.Double.NaN, nan) [] - member this.nanf() = + member _.nanf() = // value type - let result = Operators.nanf - Assert.AreEqual(result,System.Single.NaN) + let result = Operators.nanf + Assert.AreEqual(System.Single.NaN, result) - () - -#if IGNORED - [] - member this.nativeint() = - // int + [] + member _.nativeint() = + // int let result = Operators.nativeint 10 - Assert.AreEqual(result,10n) + Assert.AreEqual(10n, result) // double let result = Operators.nativeint 10.0 - Assert.AreEqual(result,10n) + Assert.AreEqual(10n, result) // int64 let result = Operators.nativeint 10L - Assert.AreEqual(result,10n) + Assert.AreEqual(10n, result) // negative let result = Operators.nativeint -10 - Assert.AreEqual(result,-10n) + Assert.AreEqual(-10n, result) // zero let result = Operators.nativeint 0 - Assert.AreEqual(result,0n) - - // overflow - CheckThrowsOverflowException(fun() -> Operators.nativeint System.Double.MaxValue |>ignore) - - () -#endif + Assert.AreEqual(0n, result) + + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.nativeint Double.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Int64.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + if Info.isX86Runtime then + let result = nativeint Int32.MaxValue + 5n + Assert.AreEqual(-2147483644n, result) + else + let result = nativeint Int64.MaxValue + 5n + Assert.AreEqual(-9223372036854775804n, result) + + + // Overflow (depends on pointer size) + let result = Operators.nativeint System.Double.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot express this as a literal, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual("-9223372036854775808", string result) + + let result = Operators.nativeint System.Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot express this as a literal, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual("-9223372036854775808", string result) [] - member this.not() = + member _.not() = let result = Operators.not true Assert.IsFalse(result) let result = Operators.not false - Assert.IsTrue(result) - - () + Assert.IsTrue(result) -// [] -// member this.nullArg() = -// CheckThrowsArgumentNullException(fun() -> Operators.nullArg "A" |> ignore) -// -// () + [] + member _.nullArg() = + CheckThrowsArgumentNullException(fun() -> Operators.nullArg "A" |> ignore) + [] - member this.pown() = - // int + member _.pown() = + // int let result = Operators.pown 10 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) // double let result = Operators.pown 10.0 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100.0, result) // int64 let result = Operators.pown 10L 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100L, result) // decimal let result = Operators.pown 10M 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100M, result) // negative let result = Operators.pown -10 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) // zero let result = Operators.pown 0 2 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // overflow let result = Operators.pown System.Double.MaxValue System.Int32.MaxValue - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) CheckThrowsOverflowException(fun() -> Operators.pown System.Int32.MaxValue System.Int32.MaxValue |>ignore) - () - [] - member this.raise() = + member _.raise() = CheckThrowsArgumentException(fun()-> Operators.raise <| new ArgumentException("Invalid Argument ") |> ignore) - - () [] - member this.ref() = + member _.ref() = // value type - let result = Operators.ref 0 - let funInt (x:int) = - result := !result + x - () - Array.iter funInt [|1..10|] + let result = Operators.ref 0 + let funInt (x:int) = + result := !result + x + () + Array.iter funInt [|1..10|] Assert.AreEqual(!result,55) // reference type let result = Operators.ref "" let funStr (x : string) = - result := (!result) + x + result := (!result) + x () Array.iter funStr [|"A";"B";"C";"D"|] Assert.AreEqual(!result,"ABCD") - () - [] - member this.reraise() = - // double + member _.reraise() = + // nothing to reraise should not trigger exception try () with | _ -> Operators.reraise() - () - [] - member this.round() = + member _.round() = // double let result = Operators.round 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10.0, result) + + // double + let result = Operators.round 0.6640367702678489 + Assert.AreEqual(1.0, result) + + // double + let result = Operators.round 0.6640367702678489e4 + Assert.AreEqual(6640.0, result) + + // double, show half-to-even + let result = Operators.round 0.6640500000e4 + Assert.AreEqual(6640.0, result) + + // double, show half-to-even + let result = Operators.round 0.6639500000e4 + Assert.AreEqual(6640.0, result) + + // double, show half-to-even + let result = Operators.round 0.6641500000e4 + Assert.AreEqual(6642.0, result) + + // double, show rounding up if anything follows '5' + let result = Operators.round 0.66405000001e4 + Assert.AreEqual(6641.0, result) // decimal let result = Operators.round 10M - Assert.AreEqual(result,10) + Assert.AreEqual(10M, result) + + // decimal, show half-to-even + let result = Operators.round 1233.5M + Assert.AreEqual(1234M, result) + + // decimal, show half-to-even + let result = Operators.round 1234.5M + Assert.AreEqual(1234M, result) + + // decimal, show half-to-even + let result = Operators.round 1235.5M + Assert.AreEqual(1236M, result) + + // decimal, show rounding up if anything follows '5' + let result = Operators.round 1234.500000000001M + Assert.AreEqual(1235M, result) + + // decimal, round up + let result = Operators.round 1234.6M + Assert.AreEqual(1235M, result) - () - [] - member this.sbyte() = - // int + member _.sbyte() = + // int let result = Operators.sbyte 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10y, result) // double let result = Operators.sbyte 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10y, result) // negative let result = Operators.sbyte -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10y, result) // zero let result = Operators.sbyte 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Int64.MaxValue + Assert.AreEqual(-1y, result) + + // Overflow + let result = Operators.sbyte Int64.MinValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Double.MinValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Double.MaxValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte (Int64.MaxValue * 8L) + Assert.AreEqual(-8y, result) // bit-complement + + // Overflow + let result = 127y + 1y + Assert.AreEqual(-128y, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.sbyte Decimal.MinValue |> ignore) - () - [] - member this.sign() = - // int + member _.sign() = + // int let result = Operators.sign 10 - Assert.AreEqual(result,1) + Assert.AreEqual(1, result) + // negative int + let result = Operators.sign -10 + Assert.AreEqual(-1, result) + + // zero int + let result = Operators.sign 0 + Assert.AreEqual(0, result) + // double let result = Operators.sign 10.0 - Assert.AreEqual(result,1) + Assert.AreEqual(1, result) - // negative - let result = Operators.sign -10 - Assert.AreEqual(result,-1) + // double max + let result = Operators.sign Double.MaxValue + Assert.AreEqual(1, result) - // zero - let result = Operators.sign 0 - Assert.AreEqual(result,0) + // double min + let result = Operators.sign Double.MinValue + Assert.AreEqual(-1, result) + + // double epsilon positive + let result = Operators.sign Double.Epsilon + Assert.AreEqual(1, result) + + // double epsilon negative + let result = Operators.sign (-Double.Epsilon) + Assert.AreEqual(-1, result) + + // double inf + let result = Operators.sign Double.PositiveInfinity + Assert.AreEqual(1, result) + + // double -inf + let result = Operators.sign Double.NegativeInfinity + Assert.AreEqual(-1, result) + + // float32 + let result = Operators.sign 10.0f + Assert.AreEqual(1, result) + + // float32 max + let result = Operators.sign Single.MaxValue + Assert.AreEqual(1, result) + + // float32 min + let result = Operators.sign Single.MinValue + Assert.AreEqual(-1, result) + + // float32 epsilon positive + let result = Operators.sign Single.Epsilon + Assert.AreEqual(1, result) + + // float32 epsilon negative + let result = Operators.sign (-Single.Epsilon) + Assert.AreEqual(-1, result) + + // float32 inf + let result = Operators.sign Single.PositiveInfinity + Assert.AreEqual(1, result) + + // float32 -inf + let result = Operators.sign Single.NegativeInfinity + Assert.AreEqual(-1, result) + + // double nan + CheckThrowsArithmeticException(fun () -> Operators.sign Double.NaN |> ignore) + + // float32 nan + CheckThrowsArithmeticException(fun () -> Operators.sign Single.NaN |> ignore) - () - [] - member this.sin() = + member _.sin() = let result = Operators.sin 0.5 - Assert.AreEqual(result.ToString(),"0.479425538604203") + Assert.AreNearEqual(0.479425538604203, result) + + let result = Operators.sin Double.NaN + Assert.AreEqual(Double.NaN, result) + + let result = Operators.sin Double.PositiveInfinity + Assert.AreEqual(Double.NaN, result) + + let result = Operators.sin Double.NegativeInfinity + Assert.AreEqual(Double.NaN, result) - () - [] - member this.single() = - // int - let result = Operators.single 10 - Assert.AreEqual(result,10) + member _.single() = + // int + let result = Operators.float32 10 + Assert.AreEqual(10f, result) // double - let result = Operators.single 10.0 - Assert.AreEqual(result,10) + let result = Operators.float32 10.0 + Assert.AreEqual(10f, result) // string - let result = Operators.single "10" - Assert.AreEqual(result,10) - - () - + let result = Operators.float32 "10" + Assert.AreEqual(10f, result) + [] - member this.sinh() = + member _.sinh() = let result = Operators.sinh 1.0 - Assert.AreEqual(result.ToString(),"1.1752011936438") + Assert.AreNearEqual(1.1752011936438014, result) - () - + let result = Operators.sinh 0.0 + Assert.AreNearEqual(0.0, result) + + let result = Operators.sinh Double.PositiveInfinity + Assert.AreNearEqual(Double.PositiveInfinity, result) + + let result = Operators.sinh Double.NegativeInfinity + Assert.AreNearEqual(Double.NegativeInfinity, result) + + let result = Operators.sinh Double.NaN + Assert.AreNearEqual(Double.NaN, result) + [] - member this.sizeof() = - // value type + member _.sizeof() = + // value type let result = Operators.sizeof - Assert.AreEqual(result,4) + Assert.AreEqual(4, result) - // System.Int64 + // System.Int64 let result = Operators.sizeof - Assert.AreEqual(result,8) + Assert.AreEqual(8, result) - // reference type + // reference type should have the same size as the IntPtr let result = Operators.sizeof - Assert.AreEqual(result,4) + Assert.AreEqual(IntPtr.Size, result) - // null + // null should have the same size as the IntPtr let result = Operators.sizeof - Assert.AreEqual(result,4) + Assert.AreEqual(IntPtr.Size, result) - () - [] - member this.snd() = - // value type + member _.snd() = + // value type let result = Operators.snd ("ABC",100) - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) - // reference type + // reference type let result = Operators.snd (100,"ABC") - Assert.AreEqual(result,"ABC") + Assert.AreEqual("ABC", result) - // null + // null let result = Operators.snd (100,null) - Assert.AreEqual(result,null) + Assert.AreEqual(null, result) - () - [] - member this.sqrt() = - // double + member _.sqrt() = + // double let result = Operators.sqrt 100.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10.0, result) + + let result = Operators.sqrt -2.0 + Assert.AreEqual(Double.NaN, result) - () - [] - member this.stderr() = - let result = Operators.stderr - Assert.AreEqual(result.WriteLine("go"),null) + member _.stderr() = + let result = Operators.stderr + Assert.AreEqual(null, result.WriteLine("go")) - () - [] - member this.stdin() = - let result = Operators.stdin - Assert.AreEqual(result.Dispose(),null) + member _.stdin() = + let result = Operators.stdin + Assert.AreEqual(null, result.Dispose()) - () - [] - member this.stdout() = - let result = Operators.stdout - Assert.AreEqual(result.WriteLine("go"),null) + member _.stdout() = + let result = Operators.stdout + Assert.AreEqual(null, result.WriteLine("go")) - () - [] - member this.string() = + member _.string() = // value type let result = Operators.string 100 - Assert.AreEqual(result,"100") + Assert.AreEqual("100", result) // reference type let result = Operators.string "ABC" - Assert.AreEqual(result,"ABC") + Assert.AreEqual("ABC", result) - // unit - CheckThrowsNullRefException(fun () -> Operators.string null |>ignore) - - () - [] - member this.tan() = + member _.tan() = // double let result = Operators.tan 1.0 - Assert.AreEqual(result.ToString(),"1.5574077246549") + Assert.AreNearEqual(1.5574077246549023, result) - () - [] - member this.tanh() = - // double + member _.tanh() = + // The x86 runtime uses 64 bit precision, whereas the x64 runtime uses SSE instructions with 80 bit precision + // details can be found here: https://github.com/dotnet/fsharp/issues/9522 let result = Operators.tanh 0.8 - Assert.AreEqual(result,0.664036770267849) + Assert.AreNearEqual(0.66403677026784902, result) + + let result = Operators.tanh 19.06154 + Assert.AreNearEqual(1.0, result) // can be 0.99999999999999989 + + let result = tanh 0.0 + Assert.AreEqual(0.0, result) + + let result = tanh infinity + Assert.AreEqual(1.0, result) + + let result = tanh -infinity + Assert.AreEqual(-1.0, result) - () - [] - member this.truncate() = + member _.truncate() = // double let result = Operators.truncate 10.101 - Assert.AreEqual(result,10) + Assert.AreEqual(10.0, result) // decimal let result = Operators.truncate 10.101M - Assert.AreEqual(result,10M) + Assert.AreEqual(10M, result) // zero let result = Operators.truncate 0.101 - Assert.AreEqual(result,0) + Assert.AreEqual(0.0, result) - () - [] - member this.typedefof() = + member _.typedefof() = // value type let result = Operators.typedefof - Assert.AreEqual(result.FullName,"System.Int32") + Assert.AreEqual("System.Int32", result.FullName) // reference type let result = Operators.typedefof - Assert.AreEqual(result.FullName,"System.String") + Assert.AreEqual("System.String", result.FullName) // unit let result = Operators.typedefof - Assert.AreEqual(result.FullName,"Microsoft.FSharp.Core.Unit") + Assert.AreEqual("Microsoft.FSharp.Core.Unit", result.FullName) - () - [] - member this.typeof() = + member _.typeof() = // value type let result = Operators.typeof - Assert.AreEqual(result.FullName,"System.Int32") + Assert.AreEqual("System.Int32", result.FullName) // reference type let result = Operators.typeof - Assert.AreEqual(result.FullName,"System.String") + Assert.AreEqual("System.String", result.FullName) // unit let result = Operators.typeof - Assert.AreEqual(result.FullName,"Microsoft.FSharp.Core.Unit") + Assert.AreEqual("Microsoft.FSharp.Core.Unit", result.FullName) - () - [] - member this.uint16() = - // int + member _.uint16() = + // int let result = Operators.uint16 100 - Assert.AreEqual(result,100us) + Assert.AreEqual(100us, result) // double let result = Operators.uint16 (100.0:double) - Assert.AreEqual(result,100us) + Assert.AreEqual(100us, result) // decimal let result = Operators.uint16 100M - Assert.AreEqual(result,100us) + Assert.AreEqual(100us, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint16 Decimal.MinValue |> ignore) - () - [] - member this.uint32() = + member _.uint32() = // int let result = Operators.uint32 100 - Assert.AreEqual(result,100ul) + Assert.AreEqual(100u, result) // double let result = Operators.uint32 (100.0:double) - Assert.AreEqual(result,100ul) + Assert.AreEqual(100u, result) // decimal let result = Operators.uint32 100M - Assert.AreEqual(result,100ul) + Assert.AreEqual(100u, result) - () - + // Overflow + let result = Operators.uint32 Double.MaxValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Double.MinValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Int64.MaxValue + Assert.AreEqual(UInt32.MaxValue, result) + + // Overflow + let result = Operators.uint32 Int64.MinValue + Assert.AreEqual(0u, result) + + // Overflow + let result = UInt32.MaxValue + 5u + Assert.AreEqual(4u, result) + + // both 'u' and 'ul' are valid numeric suffixes for UInt32 + let result = 42u + 42ul + Assert.AreEqual(84u, result) + Assert.AreEqual(84ul, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint32 Decimal.MinValue |> ignore) + [] - member this.uint64() = + member _.uint64() = // int let result = Operators.uint64 100 - Assert.AreEqual(result,100UL) + Assert.AreEqual(100UL, result) // double - let result = Operators.uint64 (100.0:double) - Assert.AreEqual(result,100UL) + let result = Operators.uint64 100.0 + Assert.AreEqual(100UL, result) // decimal let result = Operators.uint64 100M - Assert.AreEqual(result,100UL) - - () - + Assert.AreEqual(100UL, result) + + // Overflow + let result = Operators.uint64 Double.MaxValue + Assert.AreEqual(0UL, result) + + // Overflow + let result = Operators.uint64 Double.MinValue + Assert.AreEqual(9223372036854775808UL, result) // surprising, but true, 2^63 + 1 + + // Overflow + let result = Operators.uint64 Int64.MinValue + Assert.AreEqual(9223372036854775808UL, result) + + // Overflow + let result = Operators.uint64 SByte.MinValue + Assert.AreEqual(UInt64.MaxValue - 127UL, result) + + // Overflow + let result = UInt64.MaxValue + 5UL + Assert.AreEqual(4UL, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint64 Decimal.MinValue |> ignore) + [] - member this.unativeint() = + member _.unativeint() = // int let result = Operators.unativeint 100 - Assert.AreEqual(result,100un) + let x: unativeint = 12un + Assert.AreEqual(100un, result) // double - let result = Operators.unativeint (100.0:double) - Assert.AreEqual(result,100un) - - () - + let result = Operators.unativeint 100.0 + Assert.AreEqual(100un, result) + + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.unativeint Double.MaxValue + Assert.AreEqual(0un, result) + + // Overflow (depends on pointer size) + let result = Operators.unativeint Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) // surprising, but true, 2^63 + 1 + + // Overflow (depends on pointer size) + let result = Operators.unativeint Int64.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) + + // Overflow (depends on pointer size) + let result = 0un - 1un + if Info.isX86Runtime then + Assert.AreEqual(4294967295un, result) + else + Assert.AreEqual(18446744073709551615un, result) + [] - member this.unbox() = + member _.unbox() = // value type let oint = box 100 let result = Operators.unbox oint - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) // reference type let ostr = box "ABC" let result = Operators.unbox ostr - Assert.AreEqual(result,"ABC") + Assert.AreEqual("ABC", result) - // null + // null let onull = box null let result = Operators.unbox onull - Assert.AreEqual(result,null) - - () - + Assert.AreEqual(null, result) + + // None == null + let onone = box None + let result = Operators.unbox onone + Assert.AreEqual(None, result) + Assert.AreEqual(null, result) + [] - member this.using() = + member _.using() = let sr = new System.IO.StringReader("ABCD") Assert.AreEqual(sr.ReadToEnd(),"ABCD") - let result = Operators.using sr (fun x -> x.ToString()) + let _ = Operators.using sr (fun x -> x.ToString()) CheckThrowsObjectDisposedException(fun () -> sr.ReadToEnd() |> ignore) - - () \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs new file mode 100644 index 00000000000..12e33a6b69a --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs @@ -0,0 +1,307 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Various tests for the Checked module + +namespace FSharp.Core.UnitTests.Operators + +open System +open FSharp.Core.UnitTests.LibraryTestFx +open NUnit.Framework +open Microsoft.FSharp.Core.Operators.Checked + +[] +type OperatorsModuleChecked() = + + [] + member _.Checkedbyte() = + // int type + let intByte = Operators.Checked.byte 100 + Assert.AreEqual(100uy, intByte) + + // char type + let charByte = Operators.Checked.byte '0' + Assert.AreEqual(48uy, charByte) + + // boundary value + let boundByte = Operators.Checked.byte 255.0 + Assert.AreEqual(255uy, boundByte) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> 255uy + 1uy |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> 0uy - 1uy |> ignore) + + [] + member _.Checkedchar() = + + // number + let numberChar = Operators.Checked.char 48 + Assert.AreEqual('0', numberChar) + + // letter + let letterChar = Operators.Checked.char 65 + Assert.AreEqual('A', letterChar) + + // boundary value + let boundchar = Operators.Checked.char 126 + Assert.AreEqual('~', boundchar) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.char (int64 Char.MaxValue + 1L) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> '\uFFFF' + '\u0001' |> ignore) + + + [] + member _.CheckedInt() = + + // char + let charInt = Operators.Checked.int '0' + Assert.AreEqual(48, charInt) + + // float + let floatInt = Operators.Checked.int 10.0 + Assert.AreEqual(10, floatInt) + + // boundary value + let boundInt = Operators.Checked.int 32767.0 + Assert.AreEqual(32767, boundInt) + + // overflow exception + CheckThrowsOverflowException(fun() -> Operators.Checked.int 2147483648.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MinValue - 1 |> ignore) + + [] + member _.CheckedInt16() = + + // char + let charInt16 = Operators.Checked.int16 '0' + Assert.AreEqual(48s, charInt16) + + // float + let floatInt16 = Operators.Checked.int16 10.0 + Assert.AreEqual(10s, floatInt16) + + // boundary value + let boundInt16 = Operators.Checked.int16 32767.0 + Assert.AreEqual(32767s, boundInt16) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.int16 32768.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int16.MaxValue + 1s |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int16.MinValue - 1s |> ignore) + + [] + member _.CheckedInt32() = + + // char + let charInt32 = Operators.Checked.int32 '0' + Assert.AreEqual(48, charInt32) + + // float + let floatInt32 = Operators.Checked.int32 10.0 + Assert.AreEqual(10, floatInt32) + + // boundary value + let boundInt32 = Operators.Checked.int32 2147483647.0 + Assert.AreEqual(2147483647, boundInt32) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.int32 2147483648.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MinValue - 1 |> ignore) + + [] + member _.CheckedInt64() = + + // char + let charInt64 = Operators.Checked.int64 '0' + Assert.AreEqual(48L, charInt64) + + // float + let floatInt64 = Operators.Checked.int64 10.0 + Assert.AreEqual(10L, floatInt64) + + // boundary value + let boundInt64 = Operators.Checked.int64 9223372036854775807I + let _ = 9223372036854775807L + Assert.AreEqual(9223372036854775807L, boundInt64) + + // boundary value + let boundInt64 = Operators.Checked.int64 -9223372036854775808I + let _ = -9223372036854775808L + Assert.AreEqual(-9223372036854775808L, boundInt64) + + // overflow exception + CheckThrowsOverflowException(fun() -> Operators.Checked.int64 (float Int64.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int64.MaxValue + 1L |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int64.MinValue - 1L |> ignore) + + [] + member _.CheckedNativeint() = + + // char + let charnativeint = Operators.Checked.nativeint '0' + Assert.AreEqual(48n, charnativeint) + + // float + let floatnativeint = Operators.Checked.nativeint 10.0 + Assert.AreEqual(10n, floatnativeint) + + // boundary value + let boundnativeint = Operators.Checked.nativeint 32767.0 + Assert.AreEqual(32767n, boundnativeint) + + // overflow exception (depends on pointer size) + CheckThrowsOverflowException(fun() -> + if Info.isX86Runtime then + Operators.Checked.nativeint 2147483648.0 |> ignore + else + Operators.Checked.nativeint 9223372036854775808.0 |> ignore) + + + [] + member _.Checkedsbyte() = + + // char + let charsbyte = Operators.Checked.sbyte '0' + Assert.AreEqual(48y, charsbyte) + + // float + let floatsbyte = Operators.Checked.sbyte -10.0 + Assert.AreEqual(-10y, floatsbyte) + + // boundary value + let boundsbyte = Operators.Checked.sbyte -127.0 + Assert.AreEqual(-127y, boundsbyte) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte -256 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> SByte.MaxValue + 1y |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> SByte.MinValue - 1y |> ignore) + + [] + member _.Checkeduint16() = + + // char + let charuint16 = Operators.Checked.uint16 '0' + Assert.AreEqual(48us, charuint16) + + // float + let floatuint16 = Operators.Checked.uint16 10.0 + Assert.AreEqual(10us, floatuint16) + + // boundary value + let bounduint16 = Operators.Checked.uint16 65535.0 + Assert.AreEqual(65535us, bounduint16) + + CheckThrowsOverflowException(fun() -> Operators.Checked.uint16 65536.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt16.MaxValue + 1us |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt16.MinValue - 1us |> ignore) + + [] + member _.Checkeduint32() = + + // char + let charuint32 = Operators.Checked.uint32 '0' + Assert.AreEqual(48u, charuint32) + + // float + let floatuint32 = Operators.Checked.uint32 10.0 + Assert.AreEqual(10u, floatuint32) + + // boundary value + let bounduint32 = Operators.Checked.uint32 429496729.0 + Assert.AreEqual(429496729u, bounduint32) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32(float UInt32.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt32.MaxValue + 1u |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt32.MinValue - 1u |> ignore) + + [] + member _.Checkeduint64() = + + // char + let charuint64 = Operators.Checked.uint64 '0' + Assert.AreEqual(48UL, charuint64) + + // float + let floatuint64 = Operators.Checked.uint64 10.0 + Assert.AreEqual(10UL, floatuint64) + + // boundary value + let bounduint64 = Operators.Checked.uint64 429496729.0 + Assert.AreEqual(429496729UL, bounduint64) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 (float System.UInt64.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt64.MaxValue + 1UL |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt64.MinValue - 1UL |> ignore) + + [] + member _.Checkedunativeint() = + + // char + let charunativeint = Operators.Checked.unativeint '0' + Assert.AreEqual(48un, charunativeint) + + // float + let floatunativeint = Operators.Checked.unativeint 10.0 + Assert.AreEqual(10un, floatunativeint) + + // boundary value (dependent on pointer size) + if Info.isX86Runtime then + let boundunativeint = Operators.Checked.unativeint 4294967295.0 + Assert.AreEqual(4294967295un, boundunativeint) + else + let boundnativeint = Operators.Checked.unativeint 1.84467440737095505E+19 // 64 bit max value cannot be expressed exactly as double + Assert.AreEqual(18446744073709549568un, boundnativeint) + + // overflow exception (depends on pointer size) + CheckThrowsOverflowException(fun () -> + if Info.isX86Runtime then + Operators.Checked.unativeint (float UInt32.MaxValue + 1.0) |> ignore + else + Operators.Checked.unativeint (float UInt64.MaxValue + 1.0) |> ignore + ) + + diff --git a/tests/FSharp.Core.UnitTests/LibraryTestFx.fs b/tests/FSharp.Core.UnitTests/LibraryTestFx.fs index f17daba432e..48c12638010 100644 --- a/tests/FSharp.Core.UnitTests/LibraryTestFx.fs +++ b/tests/FSharp.Core.UnitTests/LibraryTestFx.fs @@ -37,6 +37,7 @@ let private CheckThrowsExn2<'a when 'a :> exn> s (f : unit -> unit) = // attribute to flag these exception's usage as a bug. let CheckThrowsNullRefException f = CheckThrowsExn f let CheckThrowsIndexOutRangException f = CheckThrowsExn f +let CheckThrowsObjectDisposedException f = CheckThrowsExn f // Legit exceptions let CheckThrowsNotSupportedException f = CheckThrowsExn f @@ -49,6 +50,7 @@ let CheckThrowsDivideByZeroException f = CheckThrowsExn let CheckThrowsOverflowException f = CheckThrowsExn f let CheckThrowsInvalidOperationExn f = CheckThrowsExn f let CheckThrowsFormatException f = CheckThrowsExn f +let CheckThrowsArithmeticException f = CheckThrowsExn f // Verifies two sequences are equal (same length, equiv elements) let VerifySeqsEqual (seq1 : seq<'T>) (seq2 : seq<'T>) = diff --git a/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs b/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs index 8b0eec34fed..b91a8bc88e8 100644 --- a/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs +++ b/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs @@ -5,6 +5,8 @@ namespace NUnit.Framework open System open System.Collections.Generic open System.Linq +open System.Runtime.InteropServices + #if XUNIT open Xunit @@ -39,7 +41,27 @@ type IgnoreAttribute (_comment:string) = // Alias NUnit and XUnit Assert as LocalAssert type TestFrameworkAssert = Assert -exception AssertionException of string +module Info = + /// Use this to distinguish cases where output is deterministically different between x86 runtime or x64 runtime, + /// for instance w.r.t. floating point arithmetic. For more info, see https://github.com/dotnet/roslyn/issues/7333 + let isX86Runtime = sizeof = 4 + + /// Use this to distinguish cases where output is deterministically different between x86 runtime or x64 runtime, + /// for instance w.r.t. floating point arithmetic. For more info, see https://github.com/dotnet/roslyn/issues/7333 + let isX64Runtime = sizeof = 8 + + let framework = RuntimeInformation.FrameworkDescription + + /// Whether a test is run inside a .NET Core Runtime + let isNetCore = framework.StartsWith(".NET Core") + + /// Whether a test is run using a .NET Framework Runtime + let isNetFramework = framework.StartsWith(".NET Framework") + + /// Whether a test is run after being compiled to .NET Native + let isNetNative = framework.StartsWith(".NET Native") + + module private Impl = open FsCheck.Arb @@ -86,10 +108,28 @@ module private Impl = | _ -> Object.Equals(expected, actual) + /// Special treatment of float and float32 to get a somewhat meaningful error message + /// (otherwise, the missing precision leads to different values that are close together looking the same) + let floatStr (flt1: obj) (flt2: obj) = + match flt1, flt2 with + | :? float as flt1, (:? float as flt2) -> + flt1.ToString("R"), flt2.ToString("R") + + | :? float32 as flt1, (:? float32 as flt2) -> + flt1.ToString("R"), flt2.ToString("R") + + | _ -> flt1.ToString(), flt2.ToString() + + type Assert = + static member AreEqual(expected : obj, actual : obj, message : string) = + if not (Impl.equals expected actual) then - let message = sprintf "%s: Expected %A but got %A" message expected actual + let message = + let (exp, act) = Impl.floatStr expected actual + sprintf "%s: Expected %s but got %s" message exp act + AssertionException message |> raise static member AreNotEqual(expected : obj, actual : obj, message : string) = @@ -99,6 +139,17 @@ type Assert = static member AreEqual(expected : obj, actual : obj) = Assert.AreEqual(expected, actual, "Assertion") + /// Use this to compare floats within a delta of 1e-15, useful for discrepancies + /// between 80-bit (dotnet, RyuJIT) and 64-bit (x86, Legacy JIT) floating point calculations + static member AreNearEqual(expected: float, actual: float) = + let delta = 1.0e-15 + let message = + let ((e, a)) = Impl.floatStr expected actual + sprintf "Are near equal: expected %s, but got %s (with delta: %f)" e a delta + + global.NUnit.Framework.Assert.AreEqual(expected, actual, 1.0, message) + Assert.AreEqual(Math.Round(expected, 15), Math.Round(actual, 15), message) + static member AreNotEqual(expected : obj, actual : obj) = Assert.AreNotEqual(expected, actual, "Assertion") static member IsNull(o : obj) = Assert.AreEqual(null, o) From 34df7e432355d7dfd76e9e5539847ba04142a752 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Sun, 28 Jun 2020 16:48:39 -0700 Subject: [PATCH 41/60] Complification, the recent simplification did not flow measures / erasure striping. --- src/fsharp/PostInferenceChecks.fs | 13 +++++----- src/fsharp/TypeRelations.fs | 42 +++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 7a005a3bc0f..8e5fc72c1af 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -699,14 +699,13 @@ type TTypeEquality = let compareTypesWithRegardToTypeVariablesAndMeasures g amap m typ1 typ2 = - if (typeEquiv g typ1 typ2) then ExactlyEqual else - - let typ1 = typ1 |> stripTyEqnsWrtErasure EraseAll g |> stripMeasuresFromTType g - let typ2 = typ2 |> stripTyEqnsWrtErasure EraseAll g |> stripMeasuresFromTType g - if (typeEquiv g typ1 typ2 || TypesFeasiblyEquiv 0 g amap m typ1 typ2) then - FeasiblyEqual + if (typeEquiv g typ1 typ2) then + ExactlyEqual else - NotEqual + if (typeEquiv g typ1 typ2 || TypesFeasiblyEquivStripMeasures g amap m typ1 typ2) then + FeasiblyEqual + else + NotEqual let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list) isObjectExpression m = let keyf ty = assert isAppTy cenv.g ty; (tcrefOfAppTy cenv.g ty).Stamp diff --git a/src/fsharp/TypeRelations.fs b/src/fsharp/TypeRelations.fs index efd82d277dd..22d6cb56aeb 100755 --- a/src/fsharp/TypeRelations.fs +++ b/src/fsharp/TypeRelations.fs @@ -47,30 +47,45 @@ let rec TypeDefinitelySubsumesTypeNoCoercion ndeep g amap m ty1 ty2 = type CanCoerce = CanCoerce | NoCoerce /// The feasible equivalence relation. Part of the language spec. -let rec TypesFeasiblyEquiv ndeep g amap m ty1 ty2 = +let rec TypesFeasiblyEquivalent stripMeasures ndeep g amap m ty1 ty2 = if ndeep > 100 then error(InternalError("recursive class hierarchy (detected in TypeFeasiblySubsumesType), ty1 = " + (DebugPrint.showType ty1), m)); - let ty1 = stripTyEqns g ty1 - let ty2 = stripTyEqns g ty2 - match ty1, ty2 with + let stripAll ty = + if stripMeasures then + ty |> stripTyEqnsWrtErasure EraseAll g |> stripMeasuresFromTType g + else + ty |> stripTyEqns g + + let ty1str = stripAll ty1 + let ty2str = stripAll ty2 + + let _found, _tc_eq = + match ty1str, ty2str with + | TType_app (tc1, _l1), TType_app (tc2, _l2) -> + let tc1_local = tc1 + let tc2_local = tc2 + true, tyconRefEq g tc1_local tc2_local + | _ -> false, false + + match ty1str, ty2str with | TType_var _, _ | _, TType_var _ -> true - | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> - List.lengthsEqAndForall2 (TypesFeasiblyEquiv ndeep g amap m) l1 l2 + | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> + List.lengthsEqAndForall2 (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) l1 l2 | TType_anon (anonInfo1, l1),TType_anon (anonInfo2, l2) -> (evalTupInfoIsStruct anonInfo1.TupInfo = evalTupInfoIsStruct anonInfo2.TupInfo) && (match anonInfo1.Assembly, anonInfo2.Assembly with ccu1, ccu2 -> ccuEq ccu1 ccu2) && (anonInfo1.SortedNames = anonInfo2.SortedNames) && - List.lengthsEqAndForall2 (TypesFeasiblyEquiv ndeep g amap m) l1 l2 + List.lengthsEqAndForall2 (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) l1 l2 | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> evalTupInfoIsStruct tupInfo1 = evalTupInfoIsStruct tupInfo2 && - List.lengthsEqAndForall2 (TypesFeasiblyEquiv ndeep g amap m) l1 l2 + List.lengthsEqAndForall2 (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) l1 l2 | TType_fun (d1, r1), TType_fun (d2, r2) -> - (TypesFeasiblyEquiv ndeep g amap m) d1 d2 && (TypesFeasiblyEquiv ndeep g amap m) r1 r2 + (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) d1 d2 && (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) r1 r2 | TType_measure _, TType_measure _ -> true @@ -78,8 +93,15 @@ let rec TypesFeasiblyEquiv ndeep g amap m ty1 ty2 = | _ -> false -/// The feasible coercion relation. Part of the language spec. +/// The feasible equivalence relation. Part of the language spec. +let rec TypesFeasiblyEquiv ndeep g amap m ty1 ty2 = + TypesFeasiblyEquivalent false ndeep g amap m ty1 ty2 +/// The feasible equivalence relation after stripping Measures. +let TypesFeasiblyEquivStripMeasures g amap m ty1 ty2 = + TypesFeasiblyEquivalent true 0 g amap m ty1 ty2 + +/// The feasible coercion relation. Part of the language spec. let rec TypeFeasiblySubsumesType ndeep g amap m ty1 canCoerce ty2 = if ndeep > 100 then error(InternalError("recursive class hierarchy (detected in TypeFeasiblySubsumesType), ty1 = " + (DebugPrint.showType ty1), m)) let ty1 = stripTyEqns g ty1 From 2cd49dcaff95f8cade512d525cd70789a2b4588e Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Sun, 28 Jun 2020 18:23:34 -0700 Subject: [PATCH 42/60] Re enable tests for operators: OperatorsModule1.fs and OperatorsModule2.fs (#9516) (#9587) * Re-enabling tests from OperatorsModule1/2.fs (compile errors) * Fix compile errors in OperatorsModule1/2.fs, fix tests. Note tanh test comment. * Fix `tanh` test, ensure stable result on x86 vs x64 runtimes * Stop using exception AssertionException, so that test window shows useful info * Whitespace cleanup and redundant code removal * Cleanup spelling etc * Re-enabling int, int16, int32, int64, nativeint, incr, nullArg etc tests * Special-case floating-point assertion messages for higher precision output * Fix/update/add tests (some still failing) * Separate Checked tests, add & fix others, differentiate framework/bitness for some tests * Add branch for .NET Native (ignore cos test) * Resorting to comparing floats with a delta using Assert.AreNearEqual * Add some more tests Co-authored-by: Abel Braaksma --- .../FSharp.Core.UnitTests.fsproj | 19 +- .../FSharp.Core/OperatorsModule1.fs | 802 +++++---------- .../FSharp.Core/OperatorsModule2.fs | 909 +++++++++++------- .../FSharp.Core/OperatorsModuleChecked.fs | 307 ++++++ tests/FSharp.Core.UnitTests/LibraryTestFx.fs | 2 + .../NUnitFrameworkShims.fs | 55 +- 6 files changed, 1197 insertions(+), 897 deletions(-) create mode 100644 tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj index 90b1436e398..0706e76eef5 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj @@ -33,6 +33,13 @@ + + + + + + + @@ -59,10 +66,6 @@ - - - - @@ -87,9 +90,7 @@ - - - + @@ -106,4 +107,8 @@ + + + + diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs index 5aacff670ab..e81ddf29c01 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs @@ -3,360 +3,57 @@ // Various tests for the: // Microsoft.FSharp.Core.Operators module -namespace SystematicUnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests.Operators open System -open SystematicUnitTests.LibraryTestFx +open FSharp.Core.UnitTests.LibraryTestFx open NUnit.Framework -open Microsoft.FSharp.Core.Operators.Checked [] type OperatorsModule1() = [] - member this.Checkedbyte() = - // int type - let intByte = Operators.Checked.byte 100 - Assert.AreEqual(intByte,(byte)100) - - // char type - let charByte = Operators.Checked.byte '0' - Assert.AreEqual(charByte,(byte)48) - - // boundary value - let boundByte = Operators.Checked.byte 255.0 - Assert.AreEqual(boundByte, (byte)255) - - // overflow exception - try - let overflowByte = Operators.Checked.byte 256.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - - - - [] - member this.Checkedchar() = - - // number - let numberChar = Operators.Checked.char 48 - Assert.AreEqual(numberChar,'0') - - // letter - let letterChar = Operators.Checked.char 65 - Assert.AreEqual(letterChar,'A') - - // boundary value - let boundchar = Operators.Checked.char 126 - Assert.AreEqual(boundchar, '~') - - // overflow exception - try - let overflowchar = Operators.Checked.char (System.Int64.MaxValue+(int64)2) - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - [] - member this.CheckedInt() = - - // char - let charInt = Operators.Checked.int '0' - Assert.AreEqual(charInt,48) - - // float - let floatInt = Operators.Checked.int 10.0 - Assert.AreEqual(floatInt,10) - - - // boundary value - let boundInt = Operators.Checked.int 32767.0 - Assert.AreEqual(boundInt, (int)32767) - - // overflow exception - try - let overflowint = Operators.Checked.int 2147483648.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - () - - [] - member this.CheckedInt16() = - - // char - let charInt16 = Operators.Checked.int16 '0' - Assert.AreEqual(charInt16,(int16)48) - - // float - let floatInt16 = Operators.Checked.int16 10.0 - Assert.AreEqual(floatInt16,(int16)10) - - // boundary value - let boundInt16 = Operators.Checked.int16 32767.0 - Assert.AreEqual(boundInt16, (int16)32767) - - // overflow exception - try - let overflowint16 = Operators.Checked.int16 32768.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.CheckedInt32() = - - // char - let charInt32 = Operators.Checked.int32 '0' - Assert.AreEqual(charInt32,(int32)48) - - // float - let floatInt32 = Operators.Checked.int32 10.0 - Assert.AreEqual(floatInt32,(int32)10) - - // boundary value - let boundInt32 = Operators.Checked.int32 2147483647.0 - Assert.AreEqual(boundInt32, (int32)2147483647) - - // overflow exception - try - let overflowint32 = Operators.Checked.int32 2147483648.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - () - - [] - member this.CheckedInt64() = - - // char - let charInt64 = Operators.Checked.int64 '0' - Assert.AreEqual(charInt64,(int64)48) - - // float - let floatInt64 = Operators.Checked.int64 10.0 - Assert.AreEqual(floatInt64,(int64)10) - - // boundary value - let boundInt64 = Operators.Checked.int64 9223372036854775807I - let a = 9223372036854775807L - Assert.AreEqual(boundInt64, 9223372036854775807L) - - // overflow exception - try - let overflowint64 = Operators.Checked.int64 (System.Double.MaxValue+2.0) - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.CheckedNativeint() = - - // char - let charnativeint = Operators.Checked.nativeint '0' - Assert.AreEqual(charnativeint,(nativeint)48) - - // float - let floatnativeint = Operators.Checked.nativeint 10.0 - Assert.AreEqual(floatnativeint,(nativeint)10) - - // boundary value - let boundnativeint = Operators.Checked.nativeint 32767.0 - Assert.AreEqual(boundnativeint, (nativeint)32767) - - // overflow exception - try - let overflownativeint = Operators.Checked.nativeint 2147483648.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkedsbyte() = - - // char - let charsbyte = Operators.Checked.sbyte '0' - Assert.AreEqual(charsbyte,(sbyte)48) - - // float - let floatsbyte = Operators.Checked.sbyte -10.0 - Assert.AreEqual(floatsbyte,(sbyte)(-10)) - - // boundary value - let boundsbyte = Operators.Checked.sbyte -127.0 - Assert.AreEqual(boundsbyte, (sbyte)(-127)) - - // overflow exception - try - let overflowsbyte = Operators.Checked.sbyte -256.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - () - - [] - member this.Checkeduint16() = + member _.KeyValue() = - // char - let charuint16 = Operators.Checked.uint16 '0' - Assert.AreEqual(charuint16,(uint16)48) - - // float - let floatuint16 = Operators.Checked.uint16 10.0 - Assert.AreEqual(floatuint16,(uint16)(10)) - - // boundary value - let bounduint16 = Operators.Checked.uint16 65535.0 - Assert.AreEqual(bounduint16, (uint16)(65535)) - - // overflow exception - try - let overflowuint16 = Operators.Checked.uint16 65536.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkeduint32() = - - // char - let charuint32 = Operators.Checked.uint32 '0' - Assert.AreEqual(charuint32,(uint32)48) - - // float - let floatuint32 = Operators.Checked.uint32 10.0 - Assert.AreEqual(floatuint32,(uint32)(10)) - - // boundary value - let bounduint32 = Operators.Checked.uint32 429496729.0 - Assert.AreEqual(bounduint32, (uint32)(429496729)) - - - // overflow exception - try - let overflowuint32 = Operators.Checked.uint32 uint32.MaxValue+1u - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkeduint64() = - - // char - let charuint64 = Operators.Checked.uint64 '0' - Assert.AreEqual(charuint64,(uint64)48) - - // float - let floatuint64 = Operators.Checked.uint64 10.0 - Assert.AreEqual(floatuint64,(uint64)(10)) - - // boundary value - let bounduint64 = Operators.Checked.uint64 429496729.0 - Assert.AreEqual(bounduint64, (uint64)(429496729)) - - // overflow exception - try - let overflowuint64 = Operators.Checked.uint64 System.UInt64.MaxValue+1UL - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkedunativeint() = - - // char - let charunativeint = Operators.Checked.unativeint '0' - Assert.AreEqual(charunativeint,(unativeint)48) - - // float - let floatunativeint = Operators.Checked.unativeint 10.0 - Assert.AreEqual(floatunativeint,(unativeint)10) - - // boundary value - let boundunativeint = Operators.Checked.unativeint 65353.0 - Assert.AreEqual(boundunativeint, (unativeint)65353) - - // overflow exception - try - let overflowuint64 = Operators.Checked.uint64 System.UInt64.MaxValue+1UL - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.KeyValue() = - - let funcKeyValue x = match x with | Operators.KeyValue(a) -> a // string int let stringint = funcKeyValue ( new System.Collections.Generic.KeyValuePair("string",1)) - Assert.AreEqual(stringint,("string",1)) + Assert.AreEqual(("string",1), stringint) // float char let floatchar = funcKeyValue ( new System.Collections.Generic.KeyValuePair(1.0,'a')) - Assert.AreEqual(floatchar,(1.0,'a')) + Assert.AreEqual((1.0,'a'), floatchar) // null let nullresult = funcKeyValue ( new System.Collections.Generic.KeyValuePair(null,' ')) let (nullstring:string,blankchar:char) = nullresult CheckThrowsNullRefException(fun () -> nullstring.ToString() |> ignore) - - - () - + [] - member this.OptimizedRangesGetArraySlice() = + member _.OptimizedRangesGetArraySlice() = - let param1 = Some(1) let param2 = Some(2) // int let intslice = Operators.OperatorIntrinsics.GetArraySlice [|1;2;3;4;5;6|] param1 param2 - Assert.AreEqual(intslice,[|2;3|]) + Assert.AreEqual([|2;3|], intslice) // string let stringslice = Operators.OperatorIntrinsics.GetArraySlice [|"1";"2";"3"|] param1 param2 - Assert.AreEqual(stringslice,[|"2";"3"|]) + Assert.AreEqual([|"2";"3"|], stringslice) // null let stringslice = Operators.OperatorIntrinsics.GetArraySlice [|null;null;null|] param1 param2 - Assert.AreEqual(stringslice,[|null;null|]) - - () - + Assert.AreEqual([|null;null|], stringslice) + [] - member this.OptimizedRangesGetArraySlice2D() = + member _.OptimizedRangesGetArraySlice2D() = - let param1D1 = Some(0) let param1D2 = Some(1) let param2D1 = Some(0) @@ -366,36 +63,32 @@ type OperatorsModule1() = let intArray2D = Array2D.init 2 3 (fun i j -> i*100+j) let intslice = Operators.OperatorIntrinsics.GetArraySlice2D intArray2D param1D1 param1D2 param2D1 param2D2 - Assert.AreEqual(intslice.[1,1],101) + Assert.AreEqual(101, intslice.[1,1]) // string let stringArray2D = Array2D.init 2 3 (fun i j -> (i*100+j).ToString()) let stringslice = Operators.OperatorIntrinsics.GetArraySlice2D stringArray2D param1D1 param1D2 param2D1 param2D2 - Assert.AreEqual(stringslice.[1,1],(101).ToString()) + Assert.AreEqual((101).ToString(), stringslice.[1,1]) // null let nullArray2D = Array2D.init 2 3 (fun i j -> null) let nullslice = Operators.OperatorIntrinsics.GetArraySlice2D nullArray2D param1D1 param1D2 param2D1 param2D2 - Assert.AreEqual(nullslice.[1,1],null) - - () - + Assert.AreEqual(null, nullslice.[1,1]) + [] - member this.OptimizedRangesGetStringSlice() = + member _.OptimizedRangesGetStringSlice() = let param1 = Some(4) let param2 = Some(6) // string let stringslice = Operators.OperatorIntrinsics.GetStringSlice "abcdefg" param1 param2 - Assert.AreEqual(stringslice,"efg") + Assert.AreEqual("efg", stringslice) // null CheckThrowsNullRefException(fun () -> Operators.OperatorIntrinsics.GetStringSlice null param1 param2 |> ignore) - () - - + [] - member this.OptimizedRangesSetArraySlice() = + member _.OptimizedRangesSetArraySlice() = let param1 = Some(1) let param2 = Some(2) @@ -403,23 +96,22 @@ type OperatorsModule1() = let intArray1 = [|1;2;3|] let intArray2 = [|4;5;6|] Operators.OperatorIntrinsics.SetArraySlice intArray1 param1 param2 intArray2 - Assert.AreEqual(intArray1,[|1;4;5|]) + Assert.AreEqual([|1;4;5|], intArray1) // string let stringArray1 = [|"1";"2";"3"|] let stringArray2 = [|"4";"5";"6"|] Operators.OperatorIntrinsics.SetArraySlice stringArray1 param1 param2 stringArray2 - Assert.AreEqual(stringArray1,[|"1";"4";"5"|]) + Assert.AreEqual([|"1";"4";"5"|], stringArray1) // null let nullArray1 = [|null;null;null|] let nullArray2 = [|null;null;null|] Operators.OperatorIntrinsics.SetArraySlice nullArray1 param1 param2 nullArray2 CheckThrowsNullRefException(fun () -> nullArray1.[0].ToString() |> ignore) - () - + [] - member this.OptimizedRangesSetArraySlice2D() = + member _.OptimizedRangesSetArraySlice2D() = let param1D1 = Some(0) let param1D2 = Some(1) let param2D1 = Some(0) @@ -429,43 +121,40 @@ type OperatorsModule1() = let intArray1 = Array2D.init 2 3 (fun i j -> i*10+j) let intArray2 = Array2D.init 2 3 (fun i j -> i*100+j) Operators.OperatorIntrinsics.SetArraySlice2D intArray1 param1D1 param1D2 param2D1 param2D2 intArray2 - Assert.AreEqual(intArray1.[1,1],101) + Assert.AreEqual(101, intArray1.[1,1]) // string let stringArray2D1 = Array2D.init 2 3 (fun i j -> (i*10+j).ToString()) let stringArray2D2 = Array2D.init 2 3 (fun i j -> (i*100+j).ToString()) Operators.OperatorIntrinsics.SetArraySlice2D stringArray2D1 param1D1 param1D2 param2D1 param2D2 stringArray2D2 - Assert.AreEqual(stringArray2D1.[1,1],(101).ToString()) + Assert.AreEqual((101).ToString(), stringArray2D1.[1,1]) // null let nullArray2D1 = Array2D.init 2 3 (fun i j -> null) let nullArray2D2 = Array2D.init 2 3 (fun i j -> null) Operators.OperatorIntrinsics.SetArraySlice2D nullArray2D1 param1D1 param1D2 param2D1 param2D2 nullArray2D2 CheckThrowsNullRefException(fun () -> nullArray2D1.[0,0].ToString() |> ignore) - () - + [] - member this.OptimizedRangesSetArraySlice3D() = + member _.OptimizedRangesSetArraySlice3D() = let intArray1 = Array3D.init 2 3 4 (fun i j k -> i*10+j) let intArray2 = Array3D.init 2 3 4 (fun i j k -> i*100+j) Operators.OperatorIntrinsics.SetArraySlice3D intArray1 (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) intArray2 - Assert.AreEqual(intArray1.[1,1,1],101) - () + Assert.AreEqual(101, intArray1.[1,1,1]) [] - member this.OptimizedRangesSetArraySlice4D() = + member _.OptimizedRangesSetArraySlice4D() = let intArray1 = Array4D.init 2 3 4 5 (fun i j k l -> i*10+j) let intArray2 = Array4D.init 2 3 4 5 (fun i j k l -> i*100+j) - Operators.OperatorIntrinsics.SetArraySlice4D intArray1 (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) intArray2 - Assert.AreEqual(intArray1.[1,1,1,1],101) - () - + Operators.OperatorIntrinsics.SetArraySlice4D intArray1 (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) intArray2 + Assert.AreEqual(101, intArray1.[1,1,1,1]) + [] - member this.Uncheckeddefaultof () = + member _.Uncheckeddefaultof () = // int let intdefault = Operators.Unchecked.defaultof - Assert.AreEqual(intdefault, 0) + Assert.AreEqual(0, intdefault) // string let stringdefault = Operators.Unchecked.defaultof @@ -473,433 +162,419 @@ type OperatorsModule1() = // null let structdefault = Operators.Unchecked.defaultof - Assert.AreEqual( structdefault.Day,1) - - () - + Assert.AreEqual(1, structdefault.Day) + [] - member this.abs () = + member _.abs () = // int let intabs = Operators.abs (-7) - Assert.AreEqual(intabs, 7) + Assert.AreEqual(7, intabs) - // float + // float let floatabs = Operators.abs (-100.0) - Assert.AreEqual(floatabs, 100.0) + Assert.AreEqual(100.0, floatabs) // decimal let decimalabs = Operators.abs (-1000M) - Assert.AreEqual(decimalabs, 1000M) - - () - + Assert.AreEqual(1000M, decimalabs) + [] - member this.acos () = + member _.acos () = // min value let minacos = Operators.acos (0.0) - Assert.AreEqual(minacos, 1.5707963267948966) + Assert.AreNearEqual(1.5707963267948966, minacos) // normal value let normalacos = Operators.acos (0.3) - Assert.AreEqual(normalacos, 1.2661036727794992) + Assert.AreNearEqual(1.2661036727794992, normalacos) // max value let maxacos = Operators.acos (1.0) - Assert.AreEqual(maxacos, 0.0) - () - + Assert.AreEqual(0.0, maxacos) + [] - member this.asin () = + member _.asin () = // min value let minasin = Operators.asin (0.0) - Assert.AreEqual(minasin, 0) + Assert.AreEqual(0.0, minasin) // normal value let normalasin = Operators.asin (0.5) - Assert.AreEqual(normalasin, 0.52359877559829893) + Assert.AreNearEqual(0.52359877559829893, normalasin) // max value let maxasin = Operators.asin (1.0) - Assert.AreEqual(maxasin, 1.5707963267948966) - () - - - + Assert.AreNearEqual(1.5707963267948966, maxasin) + [] - member this.atan () = + member _.atan () = // min value let minatan = Operators.atan (0.0) - Assert.AreEqual(minatan, 0) + Assert.AreNearEqual(0.0, minatan) // normal value let normalatan = Operators.atan (1.0) - Assert.AreEqual(normalatan, 0.78539816339744828) + Assert.AreNearEqual(0.78539816339744828, normalatan) // biggish value let maxatan = Operators.atan (infinity) - Assert.AreEqual(maxatan, 1.5707963267948966) - () - + Assert.AreNearEqual(1.5707963267948966, maxatan) + [] - member this.atan2 () = + member _.atan2 () = // min value let minatan2 = Operators.atan2 (0.0) (1.0) - Assert.AreEqual(minatan2, 0) + Assert.AreNearEqual(0.0, minatan2) // normal value let normalatan2 = Operators.atan2 (1.0) (1.0) - Assert.AreEqual(normalatan2, 0.78539816339744828) + Assert.AreNearEqual(0.78539816339744828, normalatan2) // biggish value let maxatan2 = Operators.atan2 (1.0) (0.0) - Assert.AreEqual(maxatan2, 1.5707963267948966) - () - + Assert.AreNearEqual(1.5707963267948966, maxatan2) + [] - member this.box () = + member _.box () = // int value let intbox = Operators.box 1 - Assert.AreEqual(intbox, 1) + Assert.AreEqual(1, intbox) // string value let stringlbox = Operators.box "string" - Assert.AreEqual(stringlbox, "string") + Assert.AreEqual("string", stringlbox) // null value let nullbox = Operators.box null CheckThrowsNullRefException(fun () -> nullbox.ToString() |> ignore) - () - + [] - member this.byte() = - // int type + member _.byte() = + // int type let intByte = Operators.byte 100 - Assert.AreEqual(intByte,(byte)100) + Assert.AreEqual(100uy, intByte) - // char type + // char type let charByte = Operators.byte '0' - Assert.AreEqual(charByte,(byte)48) + Assert.AreEqual(48uy, charByte) // boundary value let boundByte = Operators.byte 255.0 - Assert.AreEqual(boundByte, (byte)255) + Assert.AreEqual(255uy, boundByte) - // overflow exception - try - let overflowbyte = Operators.byte (System.Int64.MaxValue*(int64)2) - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") + // Overflow + let result = Operators.byte Int64.MaxValue + Assert.AreEqual(Byte.MaxValue, result) + + // Overflow + let result = Operators.byte Int64.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Double.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Double.MaxValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte (Int64.MaxValue * 8L) + Assert.AreEqual(248uy, result) // bit-complement + + // Overflow + let result = 255uy + 5uy + Assert.AreEqual(4uy, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.byte Decimal.MinValue |> ignore) [] - member this.ceil() = - // min value + member _.ceil() = + // min value let minceil = Operators.ceil 0.1 - Assert.AreEqual(minceil,1.0) + Assert.AreEqual(1.0, minceil) - // normal value + // normal value let normalceil = Operators.ceil 100.0 - Assert.AreEqual(normalceil,100.0) + Assert.AreEqual(100.0, normalceil) // max value let maxceil = Operators.ceil 1.7E+308 - Assert.AreEqual(maxceil, 1.7E+308) + Assert.AreEqual(1.7E+308, maxceil) [] - member this.char() = - // int type + member _.char() = + // int type let intchar = Operators.char 48 - Assert.AreEqual(intchar,'0') + Assert.AreEqual('0', intchar) - // string type + // string type let stringchar = Operators.char " " - Assert.AreEqual(stringchar, ' ') + Assert.AreEqual(' ', stringchar) [] - member this.compare() = - // int type + member _.compare() = + // int type let intcompare = Operators.compare 100 101 - Assert.AreEqual(intcompare,-1) + Assert.AreEqual(-1, intcompare) - // char type + // char type let charcompare = Operators.compare '0' '1' - Assert.AreEqual(charcompare,-1) + Assert.AreEqual(-1, charcompare) // null value let boundcompare = Operators.compare null null - Assert.AreEqual(boundcompare, 0) - - + Assert.AreEqual(0, boundcompare) + [] - member this.cos () = + member _.cos () = // min value let mincos = Operators.cos (0.0) - Assert.AreEqual(mincos, 1) + Assert.AreEqual(1.0, mincos) // normal value let normalcos = Operators.cos (1.0) - Assert.AreEqual(normalcos, 0.54030230586813977) + Assert.AreNearEqual(0.54030230586813977, normalcos) // biggish value let maxcos = Operators.cos (1.57) - Assert.AreEqual(maxcos, 0.00079632671073326335) - () - + Assert.AreNearEqual(0.00079632671073326335, maxcos) + [] - member this.cosh () = - + member _.cosh () = + // min value let mincosh = Operators.cosh (0.0) - Assert.AreEqual(mincosh, 1.0) + Assert.AreEqual(1.0, mincosh) // normal value let normalcosh = Operators.cosh (1.0) - Assert.AreEqual(normalcosh, 1.5430806348152437) + Assert.AreNearEqual(1.5430806348152437, normalcosh) // biggish value let maxcosh = Operators.cosh (1.57) - Assert.AreEqual(maxcosh, 2.5073466880660993) - - - () - - - + Assert.AreNearEqual(2.5073466880660993, maxcosh) + [] - member this.decimal () = + member _.decimal () = // int value let mindecimal = Operators.decimal (1) - Assert.AreEqual(mindecimal, 1) + Assert.AreEqual(1M, mindecimal) // float value let maxdecimal = Operators.decimal (1.0) - Assert.AreEqual(maxdecimal, 1) - () - + Assert.AreEqual(1M, maxdecimal) + [] - member this.decr() = - // zero + member _.decr() = + // zero let zeroref = ref 0 Operators.decr zeroref - Assert.AreEqual(zeroref,(ref -1)) + Assert.AreEqual((ref -1), zeroref) // big number let bigref = ref 32767 Operators.decr bigref - Assert.AreEqual(bigref,(ref 32766)) + Assert.AreEqual((ref 32766), bigref) // normal value let normalref = ref 100 Operators.decr (normalref) - Assert.AreEqual(normalref,(ref 99)) + Assert.AreEqual((ref 99), normalref) [] - member this.defaultArg() = - // zero + member _.defaultArg() = + // zero let zeroOption = Some(0) let intdefaultArg = Operators.defaultArg zeroOption 2 - Assert.AreEqual(intdefaultArg,0) + Assert.AreEqual(0, intdefaultArg) // big number let bigOption = Some(32767) let bigdefaultArg = Operators.defaultArg bigOption 32766 - Assert.AreEqual(bigdefaultArg,32767) + Assert.AreEqual(32767, bigdefaultArg) // normal value let normalOption = Some(100) let normalfaultArg = Operators.defaultArg normalOption 100 - Assert.AreEqual(normalfaultArg, 100) + Assert.AreEqual(100, normalfaultArg) [] - member this.double() = - // int type - let intdouble = Operators.double 100 - Assert.AreEqual(intdouble,100.0) + member _.double() = + // int type + let intdouble = Operators.float 100 + Assert.AreEqual(100.0, intdouble) - // char type - let chardouble = Operators.double '0' - Assert.AreEqual(chardouble,48) - () - + // char type + let chardouble = Operators.float '0' + Assert.AreEqual(48.0, chardouble) + [] - member this.enum() = - // zero + member _.enum() = + // zero let intarg : int32 = 0 let intenum = Operators.enum intarg - Assert.AreEqual(intenum,System.ConsoleColor.Black) + Assert.AreEqual(System.ConsoleColor.Black, intenum) // big number let bigarg : int32 = 15 let charenum = Operators.enum bigarg - Assert.AreEqual(charenum,System.ConsoleColor.White) + Assert.AreEqual(System.ConsoleColor.White, charenum) // normal value let normalarg : int32 = 9 let boundenum = Operators.enum normalarg - Assert.AreEqual(boundenum, System.ConsoleColor.Blue) + Assert.AreEqual(System.ConsoleColor.Blue, boundenum) #if IGNORED [] - member this.exit() = - // zero - try + member _.exit() = + // zero + try let intexit = Operators.exit 1 - () + with | _ -> () - //Assert.AreEqual(intexit,-1) + //Assert.AreEqual(-1, intexit) // big number let charexit = Operators.exit 32767 - //Assert.AreEqual(charexit,-1) + //Assert.AreEqual(-1, charexit) // normal value let boundexit = Operators.exit 100 - Assert.AreEqual(boundexit, 0) + Assert.AreEqual(0, boundexit) #endif [] - member this.exp() = - // zero + member _.exp() = + // zero let zeroexp = Operators.exp 0.0 - Assert.AreEqual(zeroexp,1.0) + Assert.AreEqual(1.0, zeroexp) // big number let bigexp = Operators.exp 32767.0 - Assert.AreEqual(bigexp,infinity) + Assert.AreEqual(infinity, bigexp) // normal value let normalexp = Operators.exp 100.0 - Assert.AreEqual(normalexp, 2.6881171418161356E+43) + Assert.AreEqual(2.6881171418161356E+43, normalexp) [] - member this.failwith() = - try + member _.failwith() = + try let _ = Operators.failwith "failwith" Assert.Fail("Expect fail but not.") - () + with | Failure("failwith") -> () |_ -> Assert.Fail("Throw unexpected exception") - - + [] - member this.float() = - // int type + member _.float() = + // int type let intfloat = Operators.float 100 - Assert.AreEqual(intfloat,(float)100) + Assert.AreEqual((float)100, intfloat) - // char type + // char type let charfloat = Operators.float '0' - Assert.AreEqual(charfloat,(float)48) - - () - - + Assert.AreEqual((float)48, charfloat) + [] - member this.float32() = - // int type + member _.float32() = + // int type let intfloat32 = Operators.float32 100 - Assert.AreEqual(intfloat32,(float32)100) + Assert.AreEqual((float32)100, intfloat32) - // char type + // char type let charfloat32 = Operators.float32 '0' - Assert.AreEqual(charfloat32,(float32)48) - - () - - + Assert.AreEqual((float32)48, charfloat32) + [] - member this.floor() = - // float type - let intfloor = Operators.floor 100.0 - Assert.AreEqual(intfloor,100) + member _.floor() = + // float type + let intfloor = Operators.floor 100.9 + Assert.AreEqual(100.0, intfloor) - // float32 type - let charfloor = Operators.floor ((float32)100.0) - Assert.AreEqual(charfloor,100) + // float32 type + let charfloor = Operators.floor ((float32)100.9) + Assert.AreEqual(100.0f, charfloor) [] - member this.fst() = - // int type + member _.fst() = + // int type let intfst = Operators.fst (100,101) - Assert.AreEqual(intfst,100) + Assert.AreEqual(100, intfst) - // char type + // char type let charfst = Operators.fst ('0','1') - Assert.AreEqual(charfst,'0') + Assert.AreEqual('0', charfst) // null value let boundfst = Operators.fst (null,null) - Assert.AreEqual(boundfst, null) + Assert.AreEqual(null, boundfst) [] - member this.hash() = - // int type + member _.hash() = + // int type (stable between JIT versions) let inthash = Operators.hash 100 - Assert.AreEqual(inthash,100) + Assert.AreEqual(100, inthash) - // char type + // char type (stable between JIT versions) let charhash = Operators.hash '0' - Assert.AreEqual(charhash,3145776) + Assert.AreEqual(3145776, charhash) - // string value - let boundhash = Operators.hash "A" - Assert.AreEqual(boundhash, -842352673) + // string value (test disabled, each JIT and each x86 vs x64 creates a different hash here) + //let boundhash = Operators.hash "A" + //Assert.AreEqual(-842352673, boundhash) [] - member this.id() = - // int type + member _.id() = + // int type let intid = Operators.id 100 - Assert.AreEqual(intid,100) + Assert.AreEqual(100, intid) - // char type + // char type let charid = Operators.id '0' - Assert.AreEqual(charid,'0') + Assert.AreEqual('0', charid) // string value let boundid = Operators.id "A" - Assert.AreEqual(boundid, "A") - - + Assert.AreEqual("A", boundid) + [] - member this.ignore() = - // value type + member _.ignore() = + // value type let result = Operators.ignore 10 - Assert.AreEqual(result,null) + Assert.AreEqual(null, result) // reference type let result = Operators.ignore "A" - Assert.AreEqual(result,null) - - () + Assert.AreEqual(null, result) -#if IGNORED - [] - member this.incr() = - // legit value + [] + member _.incr() = + // legit value let result = ref 10 Operators.incr result - Assert.AreEqual(!result,11) + Assert.AreEqual(11, !result) - // overflow + // Overflow. let result = ref (Operators.Checked.int System.Int32.MaxValue) - CheckThrowsOverflowException(fun() -> Operators.incr result |> ignore) - - () -#endif + Operators.incr result + Assert.AreEqual(System.Int32.MinValue, !result) [] - member this.infinity() = + member _.infinity() = let inf = Operators.infinity let result = inf > System.Double.MaxValue @@ -907,21 +582,18 @@ type OperatorsModule1() = // arithmetic operation let result = infinity + 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity - 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity * 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity / 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity / 3.0 - Assert.AreEqual(result,infinity) - - - () - + Assert.AreEqual(Double.PositiveInfinity, result) + [] - member this.infinityf() = + member _.infinityf() = let inf = Operators.infinityf let result = inf > System.Single.MaxValue @@ -929,16 +601,12 @@ type OperatorsModule1() = // arithmetic operation let result = infinityf + 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf - 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf * 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf / 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf / 3.0f - Assert.AreEqual(result,infinityf) - - () - - \ No newline at end of file + Assert.AreEqual(Single.PositiveInfinity, result) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs index 8ac0ebfd9c6..da874ebe118 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs @@ -3,138 +3,194 @@ // Various tests for the: // Microsoft.FSharp.Core.Operators module -namespace SystematicUnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests.Operators open System -open SystematicUnitTests.LibraryTestFx +open FSharp.Core.UnitTests.LibraryTestFx open NUnit.Framework -open Microsoft.FSharp.Core.Operators.Checked [] type OperatorsModule2() = -#if IGNORED - [] - member this.int() = - // int + [] + member _.int() = + // int let result = Operators.int 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // string let result = Operators.int "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // double let result = Operators.int 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // negative let result = Operators.int -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10, result) // zero let result = Operators.int 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int System.Double.MaxValue |>ignore) + // Overflow + let result = Operators.int Double.MaxValue + Assert.AreEqual(Int32.MinValue, result) - () -#endif + // Overflow + let result = Operators.int Double.MinValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int Int64.MaxValue + Assert.AreEqual(-1, result) + + // Overflow + let result = Operators.int Int64.MinValue + Assert.AreEqual(0, result) + + // Overflow + let result = Int32.MaxValue + 1 + Assert.AreEqual(Int32.MinValue, result) -#if IGNORED - [] - member this.int16() = - // int + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int Decimal.MinValue |> ignore) + + [] + member _.int16() = + // int let result = Operators.int16 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10s, result) // double let result = Operators.int16 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10s, result) // negative let result = Operators.int16 -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10s, result) // zero let result = Operators.int16 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0s, result) // string let result = Operators.int16 "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10s, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int16 System.Double.MaxValue |>ignore) - () -#endif - -#if IGNORED - [] - member this.int32() = - // int + // Overflow + let result = Operators.int16 Double.MaxValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Operators.int16 Double.MinValue + Assert.AreEqual(0s, result) + + let result = Operators.int16 Int64.MaxValue + Assert.AreEqual(-1s, result) + + // Overflow + let result = Operators.int16 Int64.MinValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Int16.MaxValue + 1s + Assert.AreEqual(Int16.MinValue, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int16 Decimal.MinValue |> ignore) + + [] + member _.int32() = + // int let result = Operators.int32 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // double let result = Operators.int32 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // negative let result = Operators.int32 -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10, result) // zero let result = Operators.int32 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // string let result = Operators.int32 "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int32 System.Double.MaxValue |>ignore) - () -#endif - -#if IGNORED - [] - member this.int64() = - // int + // Overflow + let result = Operators.int32 Double.MaxValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Double.MinValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Int64.MaxValue + Assert.AreEqual(-1, result) + + // Overflow + let result = Operators.int32 Int64.MinValue + Assert.AreEqual(0, result) + + // Overflow + let result = Int32.MaxValue + 5 + Assert.AreEqual(Int32.MinValue + 4, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int32 Decimal.MinValue |> ignore) + + [] + member _.int64() = + // int let result = Operators.int64 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10L, result) // double let result = Operators.int64 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10L, result) // negative let result = Operators.int64 -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10L, result) // zero let result = Operators.int64 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0L, result) // string let result = Operators.int64 "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10L, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int64 System.Double.MaxValue |>ignore) - () -#endif + // Overflow. + let result = Operators.int64 Double.MaxValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 Double.MinValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 UInt64.MaxValue + Assert.AreEqual(-1L, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int64 Decimal.MinValue |> ignore) + + [] + member _.invalidArg() = + CheckThrowsArgumentException(fun() -> Operators.invalidArg "A" "B" |>ignore ) -// [] -// member this.invalidArg() = -// CheckThrowsArgumentException(fun() -> Operators.invalidArg "A" "B" |>ignore ) -// -// () [] - member this.lock() = - // lock + member _.lock() = + // lock printfn "test8 started" let syncRoot = System.Object() let k = ref 0 @@ -142,542 +198,753 @@ type OperatorsModule2() = System.Threading.Thread.Sleep(1) !k ) } let arr = Async.RunSynchronously (Async.Parallel(Seq.map comp [1..50])) - Assert.AreEqual((Array.sort compare arr; arr), [|1..50|]) + Assert.AreEqual([|1..50|], Array.sort arr) // without lock let syncRoot = System.Object() let k = ref 0 let comp _ = async { do incr k - do! System.Threading.Thread.AsyncSleep(10) + do! Async.Sleep (10) return !k } let arr = Async.RunSynchronously (Async.Parallel(Seq.map comp [1..100])) - Assert.AreNotEqual ((Array.sort compare arr; arr) , [|1..100|]) - - () + Assert.AreNotEqual ([|1..100|], Array.sort arr) [] - member this.log() = + member _.log() = // double let result = Operators.log 10.0 - Assert.AreEqual(result.ToString(),"2.30258509299405") + Assert.AreEqual(2.3025850929940459, result) // negative let result = Operators.log -10.0 - Assert.AreEqual(result.ToString(),System.Double.NaN.ToString()) + Assert.AreEqual(Double.NaN, result) // zero let result = Operators.log 0.0 - Assert.AreEqual(result,-infinity) - - () + Assert.AreEqual(Double.NegativeInfinity , result) [] - member this.log10() = + member _.log10() = // double let result = Operators.log10 10.0 - Assert.AreEqual(result,1) + Assert.AreEqual(1.0, result) // negative let result = Operators.log10 -10.0 - Assert.AreEqual(result.ToString(),System.Double.NaN.ToString()) + Assert.AreEqual(System.Double.NaN, result) // zero let result = Operators.log10 0.0 - Assert.AreEqual(result,-infinity) - - () + Assert.AreEqual(Double.NegativeInfinity, result) [] - member this.max() = + member _.max() = // value type let result = Operators.max 10 8 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // negative let result = Operators.max -10.0 -8.0 - Assert.AreEqual(result,-8.0) + Assert.AreEqual(-8.0, result) // zero let result = Operators.max 0 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // reference type let result = Operators.max "A" "ABC" - Assert.AreEqual(result,"ABC") - - // overflow - CheckThrowsOverflowException(fun() -> Operators.max 10 System.Int32.MaxValue+1 |>ignore) - - () + Assert.AreEqual("ABC", result) [] - member this.min() = + member _.min() = // value type let result = Operators.min 10 8 - Assert.AreEqual(result,8) + Assert.AreEqual(8, result) // negative let result = Operators.min -10.0 -8.0 - Assert.AreEqual(result,-10.0) + Assert.AreEqual(-10.0, result) // zero let result = Operators.min 0 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // reference type let result = Operators.min "A" "ABC" - Assert.AreEqual(result,"A") - - // overflow - CheckThrowsOverflowException(fun() -> Operators.min 10 System.Int32.MinValue - 1 |>ignore) - - () + Assert.AreEqual("A", result) [] - member this.nan() = + member _.nan() = // value type - let result = Operators.nan - Assert.AreEqual(result.ToString(),System.Double.NaN.ToString()) - - () + let result = Operators.nan + Assert.AreEqual(System.Double.NaN, nan) [] - member this.nanf() = + member _.nanf() = // value type - let result = Operators.nanf - Assert.AreEqual(result,System.Single.NaN) + let result = Operators.nanf + Assert.AreEqual(System.Single.NaN, result) - () - -#if IGNORED - [] - member this.nativeint() = - // int + [] + member _.nativeint() = + // int let result = Operators.nativeint 10 - Assert.AreEqual(result,10n) + Assert.AreEqual(10n, result) // double let result = Operators.nativeint 10.0 - Assert.AreEqual(result,10n) + Assert.AreEqual(10n, result) // int64 let result = Operators.nativeint 10L - Assert.AreEqual(result,10n) + Assert.AreEqual(10n, result) // negative let result = Operators.nativeint -10 - Assert.AreEqual(result,-10n) + Assert.AreEqual(-10n, result) // zero let result = Operators.nativeint 0 - Assert.AreEqual(result,0n) - - // overflow - CheckThrowsOverflowException(fun() -> Operators.nativeint System.Double.MaxValue |>ignore) - - () -#endif + Assert.AreEqual(0n, result) + + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.nativeint Double.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Int64.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + if Info.isX86Runtime then + let result = nativeint Int32.MaxValue + 5n + Assert.AreEqual(-2147483644n, result) + else + let result = nativeint Int64.MaxValue + 5n + Assert.AreEqual(-9223372036854775804n, result) + + + // Overflow (depends on pointer size) + let result = Operators.nativeint System.Double.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot express this as a literal, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual("-9223372036854775808", string result) + + let result = Operators.nativeint System.Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot express this as a literal, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual("-9223372036854775808", string result) [] - member this.not() = + member _.not() = let result = Operators.not true Assert.IsFalse(result) let result = Operators.not false - Assert.IsTrue(result) - - () + Assert.IsTrue(result) -// [] -// member this.nullArg() = -// CheckThrowsArgumentNullException(fun() -> Operators.nullArg "A" |> ignore) -// -// () + [] + member _.nullArg() = + CheckThrowsArgumentNullException(fun() -> Operators.nullArg "A" |> ignore) + [] - member this.pown() = - // int + member _.pown() = + // int let result = Operators.pown 10 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) // double let result = Operators.pown 10.0 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100.0, result) // int64 let result = Operators.pown 10L 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100L, result) // decimal let result = Operators.pown 10M 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100M, result) // negative let result = Operators.pown -10 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) // zero let result = Operators.pown 0 2 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // overflow let result = Operators.pown System.Double.MaxValue System.Int32.MaxValue - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) CheckThrowsOverflowException(fun() -> Operators.pown System.Int32.MaxValue System.Int32.MaxValue |>ignore) - () - [] - member this.raise() = + member _.raise() = CheckThrowsArgumentException(fun()-> Operators.raise <| new ArgumentException("Invalid Argument ") |> ignore) - - () [] - member this.ref() = + member _.ref() = // value type - let result = Operators.ref 0 - let funInt (x:int) = - result := !result + x - () - Array.iter funInt [|1..10|] + let result = Operators.ref 0 + let funInt (x:int) = + result := !result + x + () + Array.iter funInt [|1..10|] Assert.AreEqual(!result,55) // reference type let result = Operators.ref "" let funStr (x : string) = - result := (!result) + x + result := (!result) + x () Array.iter funStr [|"A";"B";"C";"D"|] Assert.AreEqual(!result,"ABCD") - () - [] - member this.reraise() = - // double + member _.reraise() = + // nothing to reraise should not trigger exception try () with | _ -> Operators.reraise() - () - [] - member this.round() = + member _.round() = // double let result = Operators.round 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10.0, result) + + // double + let result = Operators.round 0.6640367702678489 + Assert.AreEqual(1.0, result) + + // double + let result = Operators.round 0.6640367702678489e4 + Assert.AreEqual(6640.0, result) + + // double, show half-to-even + let result = Operators.round 0.6640500000e4 + Assert.AreEqual(6640.0, result) + + // double, show half-to-even + let result = Operators.round 0.6639500000e4 + Assert.AreEqual(6640.0, result) + + // double, show half-to-even + let result = Operators.round 0.6641500000e4 + Assert.AreEqual(6642.0, result) + + // double, show rounding up if anything follows '5' + let result = Operators.round 0.66405000001e4 + Assert.AreEqual(6641.0, result) // decimal let result = Operators.round 10M - Assert.AreEqual(result,10) + Assert.AreEqual(10M, result) + + // decimal, show half-to-even + let result = Operators.round 1233.5M + Assert.AreEqual(1234M, result) + + // decimal, show half-to-even + let result = Operators.round 1234.5M + Assert.AreEqual(1234M, result) + + // decimal, show half-to-even + let result = Operators.round 1235.5M + Assert.AreEqual(1236M, result) + + // decimal, show rounding up if anything follows '5' + let result = Operators.round 1234.500000000001M + Assert.AreEqual(1235M, result) + + // decimal, round up + let result = Operators.round 1234.6M + Assert.AreEqual(1235M, result) - () - [] - member this.sbyte() = - // int + member _.sbyte() = + // int let result = Operators.sbyte 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10y, result) // double let result = Operators.sbyte 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10y, result) // negative let result = Operators.sbyte -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10y, result) // zero let result = Operators.sbyte 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Int64.MaxValue + Assert.AreEqual(-1y, result) + + // Overflow + let result = Operators.sbyte Int64.MinValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Double.MinValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Double.MaxValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte (Int64.MaxValue * 8L) + Assert.AreEqual(-8y, result) // bit-complement + + // Overflow + let result = 127y + 1y + Assert.AreEqual(-128y, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.sbyte Decimal.MinValue |> ignore) - () - [] - member this.sign() = - // int + member _.sign() = + // int let result = Operators.sign 10 - Assert.AreEqual(result,1) + Assert.AreEqual(1, result) + // negative int + let result = Operators.sign -10 + Assert.AreEqual(-1, result) + + // zero int + let result = Operators.sign 0 + Assert.AreEqual(0, result) + // double let result = Operators.sign 10.0 - Assert.AreEqual(result,1) + Assert.AreEqual(1, result) - // negative - let result = Operators.sign -10 - Assert.AreEqual(result,-1) + // double max + let result = Operators.sign Double.MaxValue + Assert.AreEqual(1, result) - // zero - let result = Operators.sign 0 - Assert.AreEqual(result,0) + // double min + let result = Operators.sign Double.MinValue + Assert.AreEqual(-1, result) + + // double epsilon positive + let result = Operators.sign Double.Epsilon + Assert.AreEqual(1, result) + + // double epsilon negative + let result = Operators.sign (-Double.Epsilon) + Assert.AreEqual(-1, result) + + // double inf + let result = Operators.sign Double.PositiveInfinity + Assert.AreEqual(1, result) + + // double -inf + let result = Operators.sign Double.NegativeInfinity + Assert.AreEqual(-1, result) + + // float32 + let result = Operators.sign 10.0f + Assert.AreEqual(1, result) + + // float32 max + let result = Operators.sign Single.MaxValue + Assert.AreEqual(1, result) + + // float32 min + let result = Operators.sign Single.MinValue + Assert.AreEqual(-1, result) + + // float32 epsilon positive + let result = Operators.sign Single.Epsilon + Assert.AreEqual(1, result) + + // float32 epsilon negative + let result = Operators.sign (-Single.Epsilon) + Assert.AreEqual(-1, result) + + // float32 inf + let result = Operators.sign Single.PositiveInfinity + Assert.AreEqual(1, result) + + // float32 -inf + let result = Operators.sign Single.NegativeInfinity + Assert.AreEqual(-1, result) + + // double nan + CheckThrowsArithmeticException(fun () -> Operators.sign Double.NaN |> ignore) + + // float32 nan + CheckThrowsArithmeticException(fun () -> Operators.sign Single.NaN |> ignore) - () - [] - member this.sin() = + member _.sin() = let result = Operators.sin 0.5 - Assert.AreEqual(result.ToString(),"0.479425538604203") + Assert.AreNearEqual(0.479425538604203, result) + + let result = Operators.sin Double.NaN + Assert.AreEqual(Double.NaN, result) + + let result = Operators.sin Double.PositiveInfinity + Assert.AreEqual(Double.NaN, result) + + let result = Operators.sin Double.NegativeInfinity + Assert.AreEqual(Double.NaN, result) - () - [] - member this.single() = - // int - let result = Operators.single 10 - Assert.AreEqual(result,10) + member _.single() = + // int + let result = Operators.float32 10 + Assert.AreEqual(10f, result) // double - let result = Operators.single 10.0 - Assert.AreEqual(result,10) + let result = Operators.float32 10.0 + Assert.AreEqual(10f, result) // string - let result = Operators.single "10" - Assert.AreEqual(result,10) - - () - + let result = Operators.float32 "10" + Assert.AreEqual(10f, result) + [] - member this.sinh() = + member _.sinh() = let result = Operators.sinh 1.0 - Assert.AreEqual(result.ToString(),"1.1752011936438") + Assert.AreNearEqual(1.1752011936438014, result) - () - + let result = Operators.sinh 0.0 + Assert.AreNearEqual(0.0, result) + + let result = Operators.sinh Double.PositiveInfinity + Assert.AreNearEqual(Double.PositiveInfinity, result) + + let result = Operators.sinh Double.NegativeInfinity + Assert.AreNearEqual(Double.NegativeInfinity, result) + + let result = Operators.sinh Double.NaN + Assert.AreNearEqual(Double.NaN, result) + [] - member this.sizeof() = - // value type + member _.sizeof() = + // value type let result = Operators.sizeof - Assert.AreEqual(result,4) + Assert.AreEqual(4, result) - // System.Int64 + // System.Int64 let result = Operators.sizeof - Assert.AreEqual(result,8) + Assert.AreEqual(8, result) - // reference type + // reference type should have the same size as the IntPtr let result = Operators.sizeof - Assert.AreEqual(result,4) + Assert.AreEqual(IntPtr.Size, result) - // null + // null should have the same size as the IntPtr let result = Operators.sizeof - Assert.AreEqual(result,4) + Assert.AreEqual(IntPtr.Size, result) - () - [] - member this.snd() = - // value type + member _.snd() = + // value type let result = Operators.snd ("ABC",100) - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) - // reference type + // reference type let result = Operators.snd (100,"ABC") - Assert.AreEqual(result,"ABC") + Assert.AreEqual("ABC", result) - // null + // null let result = Operators.snd (100,null) - Assert.AreEqual(result,null) + Assert.AreEqual(null, result) - () - [] - member this.sqrt() = - // double + member _.sqrt() = + // double let result = Operators.sqrt 100.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10.0, result) + + let result = Operators.sqrt -2.0 + Assert.AreEqual(Double.NaN, result) - () - [] - member this.stderr() = - let result = Operators.stderr - Assert.AreEqual(result.WriteLine("go"),null) + member _.stderr() = + let result = Operators.stderr + Assert.AreEqual(null, result.WriteLine("go")) - () - [] - member this.stdin() = - let result = Operators.stdin - Assert.AreEqual(result.Dispose(),null) + member _.stdin() = + let result = Operators.stdin + Assert.AreEqual(null, result.Dispose()) - () - [] - member this.stdout() = - let result = Operators.stdout - Assert.AreEqual(result.WriteLine("go"),null) + member _.stdout() = + let result = Operators.stdout + Assert.AreEqual(null, result.WriteLine("go")) - () - [] - member this.string() = + member _.string() = // value type let result = Operators.string 100 - Assert.AreEqual(result,"100") + Assert.AreEqual("100", result) // reference type let result = Operators.string "ABC" - Assert.AreEqual(result,"ABC") + Assert.AreEqual("ABC", result) - // unit - CheckThrowsNullRefException(fun () -> Operators.string null |>ignore) - - () - [] - member this.tan() = + member _.tan() = // double let result = Operators.tan 1.0 - Assert.AreEqual(result.ToString(),"1.5574077246549") + Assert.AreNearEqual(1.5574077246549023, result) - () - [] - member this.tanh() = - // double + member _.tanh() = + // The x86 runtime uses 64 bit precision, whereas the x64 runtime uses SSE instructions with 80 bit precision + // details can be found here: https://github.com/dotnet/fsharp/issues/9522 let result = Operators.tanh 0.8 - Assert.AreEqual(result,0.664036770267849) + Assert.AreNearEqual(0.66403677026784902, result) + + let result = Operators.tanh 19.06154 + Assert.AreNearEqual(1.0, result) // can be 0.99999999999999989 + + let result = tanh 0.0 + Assert.AreEqual(0.0, result) + + let result = tanh infinity + Assert.AreEqual(1.0, result) + + let result = tanh -infinity + Assert.AreEqual(-1.0, result) - () - [] - member this.truncate() = + member _.truncate() = // double let result = Operators.truncate 10.101 - Assert.AreEqual(result,10) + Assert.AreEqual(10.0, result) // decimal let result = Operators.truncate 10.101M - Assert.AreEqual(result,10M) + Assert.AreEqual(10M, result) // zero let result = Operators.truncate 0.101 - Assert.AreEqual(result,0) + Assert.AreEqual(0.0, result) - () - [] - member this.typedefof() = + member _.typedefof() = // value type let result = Operators.typedefof - Assert.AreEqual(result.FullName,"System.Int32") + Assert.AreEqual("System.Int32", result.FullName) // reference type let result = Operators.typedefof - Assert.AreEqual(result.FullName,"System.String") + Assert.AreEqual("System.String", result.FullName) // unit let result = Operators.typedefof - Assert.AreEqual(result.FullName,"Microsoft.FSharp.Core.Unit") + Assert.AreEqual("Microsoft.FSharp.Core.Unit", result.FullName) - () - [] - member this.typeof() = + member _.typeof() = // value type let result = Operators.typeof - Assert.AreEqual(result.FullName,"System.Int32") + Assert.AreEqual("System.Int32", result.FullName) // reference type let result = Operators.typeof - Assert.AreEqual(result.FullName,"System.String") + Assert.AreEqual("System.String", result.FullName) // unit let result = Operators.typeof - Assert.AreEqual(result.FullName,"Microsoft.FSharp.Core.Unit") + Assert.AreEqual("Microsoft.FSharp.Core.Unit", result.FullName) - () - [] - member this.uint16() = - // int + member _.uint16() = + // int let result = Operators.uint16 100 - Assert.AreEqual(result,100us) + Assert.AreEqual(100us, result) // double let result = Operators.uint16 (100.0:double) - Assert.AreEqual(result,100us) + Assert.AreEqual(100us, result) // decimal let result = Operators.uint16 100M - Assert.AreEqual(result,100us) + Assert.AreEqual(100us, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint16 Decimal.MinValue |> ignore) - () - [] - member this.uint32() = + member _.uint32() = // int let result = Operators.uint32 100 - Assert.AreEqual(result,100ul) + Assert.AreEqual(100u, result) // double let result = Operators.uint32 (100.0:double) - Assert.AreEqual(result,100ul) + Assert.AreEqual(100u, result) // decimal let result = Operators.uint32 100M - Assert.AreEqual(result,100ul) + Assert.AreEqual(100u, result) - () - + // Overflow + let result = Operators.uint32 Double.MaxValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Double.MinValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Int64.MaxValue + Assert.AreEqual(UInt32.MaxValue, result) + + // Overflow + let result = Operators.uint32 Int64.MinValue + Assert.AreEqual(0u, result) + + // Overflow + let result = UInt32.MaxValue + 5u + Assert.AreEqual(4u, result) + + // both 'u' and 'ul' are valid numeric suffixes for UInt32 + let result = 42u + 42ul + Assert.AreEqual(84u, result) + Assert.AreEqual(84ul, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint32 Decimal.MinValue |> ignore) + [] - member this.uint64() = + member _.uint64() = // int let result = Operators.uint64 100 - Assert.AreEqual(result,100UL) + Assert.AreEqual(100UL, result) // double - let result = Operators.uint64 (100.0:double) - Assert.AreEqual(result,100UL) + let result = Operators.uint64 100.0 + Assert.AreEqual(100UL, result) // decimal let result = Operators.uint64 100M - Assert.AreEqual(result,100UL) - - () - + Assert.AreEqual(100UL, result) + + // Overflow + let result = Operators.uint64 Double.MaxValue + Assert.AreEqual(0UL, result) + + // Overflow + let result = Operators.uint64 Double.MinValue + Assert.AreEqual(9223372036854775808UL, result) // surprising, but true, 2^63 + 1 + + // Overflow + let result = Operators.uint64 Int64.MinValue + Assert.AreEqual(9223372036854775808UL, result) + + // Overflow + let result = Operators.uint64 SByte.MinValue + Assert.AreEqual(UInt64.MaxValue - 127UL, result) + + // Overflow + let result = UInt64.MaxValue + 5UL + Assert.AreEqual(4UL, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint64 Decimal.MinValue |> ignore) + [] - member this.unativeint() = + member _.unativeint() = // int let result = Operators.unativeint 100 - Assert.AreEqual(result,100un) + let x: unativeint = 12un + Assert.AreEqual(100un, result) // double - let result = Operators.unativeint (100.0:double) - Assert.AreEqual(result,100un) - - () - + let result = Operators.unativeint 100.0 + Assert.AreEqual(100un, result) + + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.unativeint Double.MaxValue + Assert.AreEqual(0un, result) + + // Overflow (depends on pointer size) + let result = Operators.unativeint Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) // surprising, but true, 2^63 + 1 + + // Overflow (depends on pointer size) + let result = Operators.unativeint Int64.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) + + // Overflow (depends on pointer size) + let result = 0un - 1un + if Info.isX86Runtime then + Assert.AreEqual(4294967295un, result) + else + Assert.AreEqual(18446744073709551615un, result) + [] - member this.unbox() = + member _.unbox() = // value type let oint = box 100 let result = Operators.unbox oint - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) // reference type let ostr = box "ABC" let result = Operators.unbox ostr - Assert.AreEqual(result,"ABC") + Assert.AreEqual("ABC", result) - // null + // null let onull = box null let result = Operators.unbox onull - Assert.AreEqual(result,null) - - () - + Assert.AreEqual(null, result) + + // None == null + let onone = box None + let result = Operators.unbox onone + Assert.AreEqual(None, result) + Assert.AreEqual(null, result) + [] - member this.using() = + member _.using() = let sr = new System.IO.StringReader("ABCD") Assert.AreEqual(sr.ReadToEnd(),"ABCD") - let result = Operators.using sr (fun x -> x.ToString()) + let _ = Operators.using sr (fun x -> x.ToString()) CheckThrowsObjectDisposedException(fun () -> sr.ReadToEnd() |> ignore) - - () \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs new file mode 100644 index 00000000000..12e33a6b69a --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs @@ -0,0 +1,307 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Various tests for the Checked module + +namespace FSharp.Core.UnitTests.Operators + +open System +open FSharp.Core.UnitTests.LibraryTestFx +open NUnit.Framework +open Microsoft.FSharp.Core.Operators.Checked + +[] +type OperatorsModuleChecked() = + + [] + member _.Checkedbyte() = + // int type + let intByte = Operators.Checked.byte 100 + Assert.AreEqual(100uy, intByte) + + // char type + let charByte = Operators.Checked.byte '0' + Assert.AreEqual(48uy, charByte) + + // boundary value + let boundByte = Operators.Checked.byte 255.0 + Assert.AreEqual(255uy, boundByte) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> 255uy + 1uy |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> 0uy - 1uy |> ignore) + + [] + member _.Checkedchar() = + + // number + let numberChar = Operators.Checked.char 48 + Assert.AreEqual('0', numberChar) + + // letter + let letterChar = Operators.Checked.char 65 + Assert.AreEqual('A', letterChar) + + // boundary value + let boundchar = Operators.Checked.char 126 + Assert.AreEqual('~', boundchar) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.char (int64 Char.MaxValue + 1L) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> '\uFFFF' + '\u0001' |> ignore) + + + [] + member _.CheckedInt() = + + // char + let charInt = Operators.Checked.int '0' + Assert.AreEqual(48, charInt) + + // float + let floatInt = Operators.Checked.int 10.0 + Assert.AreEqual(10, floatInt) + + // boundary value + let boundInt = Operators.Checked.int 32767.0 + Assert.AreEqual(32767, boundInt) + + // overflow exception + CheckThrowsOverflowException(fun() -> Operators.Checked.int 2147483648.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MinValue - 1 |> ignore) + + [] + member _.CheckedInt16() = + + // char + let charInt16 = Operators.Checked.int16 '0' + Assert.AreEqual(48s, charInt16) + + // float + let floatInt16 = Operators.Checked.int16 10.0 + Assert.AreEqual(10s, floatInt16) + + // boundary value + let boundInt16 = Operators.Checked.int16 32767.0 + Assert.AreEqual(32767s, boundInt16) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.int16 32768.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int16.MaxValue + 1s |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int16.MinValue - 1s |> ignore) + + [] + member _.CheckedInt32() = + + // char + let charInt32 = Operators.Checked.int32 '0' + Assert.AreEqual(48, charInt32) + + // float + let floatInt32 = Operators.Checked.int32 10.0 + Assert.AreEqual(10, floatInt32) + + // boundary value + let boundInt32 = Operators.Checked.int32 2147483647.0 + Assert.AreEqual(2147483647, boundInt32) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.int32 2147483648.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MinValue - 1 |> ignore) + + [] + member _.CheckedInt64() = + + // char + let charInt64 = Operators.Checked.int64 '0' + Assert.AreEqual(48L, charInt64) + + // float + let floatInt64 = Operators.Checked.int64 10.0 + Assert.AreEqual(10L, floatInt64) + + // boundary value + let boundInt64 = Operators.Checked.int64 9223372036854775807I + let _ = 9223372036854775807L + Assert.AreEqual(9223372036854775807L, boundInt64) + + // boundary value + let boundInt64 = Operators.Checked.int64 -9223372036854775808I + let _ = -9223372036854775808L + Assert.AreEqual(-9223372036854775808L, boundInt64) + + // overflow exception + CheckThrowsOverflowException(fun() -> Operators.Checked.int64 (float Int64.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int64.MaxValue + 1L |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int64.MinValue - 1L |> ignore) + + [] + member _.CheckedNativeint() = + + // char + let charnativeint = Operators.Checked.nativeint '0' + Assert.AreEqual(48n, charnativeint) + + // float + let floatnativeint = Operators.Checked.nativeint 10.0 + Assert.AreEqual(10n, floatnativeint) + + // boundary value + let boundnativeint = Operators.Checked.nativeint 32767.0 + Assert.AreEqual(32767n, boundnativeint) + + // overflow exception (depends on pointer size) + CheckThrowsOverflowException(fun() -> + if Info.isX86Runtime then + Operators.Checked.nativeint 2147483648.0 |> ignore + else + Operators.Checked.nativeint 9223372036854775808.0 |> ignore) + + + [] + member _.Checkedsbyte() = + + // char + let charsbyte = Operators.Checked.sbyte '0' + Assert.AreEqual(48y, charsbyte) + + // float + let floatsbyte = Operators.Checked.sbyte -10.0 + Assert.AreEqual(-10y, floatsbyte) + + // boundary value + let boundsbyte = Operators.Checked.sbyte -127.0 + Assert.AreEqual(-127y, boundsbyte) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte -256 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> SByte.MaxValue + 1y |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> SByte.MinValue - 1y |> ignore) + + [] + member _.Checkeduint16() = + + // char + let charuint16 = Operators.Checked.uint16 '0' + Assert.AreEqual(48us, charuint16) + + // float + let floatuint16 = Operators.Checked.uint16 10.0 + Assert.AreEqual(10us, floatuint16) + + // boundary value + let bounduint16 = Operators.Checked.uint16 65535.0 + Assert.AreEqual(65535us, bounduint16) + + CheckThrowsOverflowException(fun() -> Operators.Checked.uint16 65536.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt16.MaxValue + 1us |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt16.MinValue - 1us |> ignore) + + [] + member _.Checkeduint32() = + + // char + let charuint32 = Operators.Checked.uint32 '0' + Assert.AreEqual(48u, charuint32) + + // float + let floatuint32 = Operators.Checked.uint32 10.0 + Assert.AreEqual(10u, floatuint32) + + // boundary value + let bounduint32 = Operators.Checked.uint32 429496729.0 + Assert.AreEqual(429496729u, bounduint32) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32(float UInt32.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt32.MaxValue + 1u |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt32.MinValue - 1u |> ignore) + + [] + member _.Checkeduint64() = + + // char + let charuint64 = Operators.Checked.uint64 '0' + Assert.AreEqual(48UL, charuint64) + + // float + let floatuint64 = Operators.Checked.uint64 10.0 + Assert.AreEqual(10UL, floatuint64) + + // boundary value + let bounduint64 = Operators.Checked.uint64 429496729.0 + Assert.AreEqual(429496729UL, bounduint64) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 (float System.UInt64.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt64.MaxValue + 1UL |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt64.MinValue - 1UL |> ignore) + + [] + member _.Checkedunativeint() = + + // char + let charunativeint = Operators.Checked.unativeint '0' + Assert.AreEqual(48un, charunativeint) + + // float + let floatunativeint = Operators.Checked.unativeint 10.0 + Assert.AreEqual(10un, floatunativeint) + + // boundary value (dependent on pointer size) + if Info.isX86Runtime then + let boundunativeint = Operators.Checked.unativeint 4294967295.0 + Assert.AreEqual(4294967295un, boundunativeint) + else + let boundnativeint = Operators.Checked.unativeint 1.84467440737095505E+19 // 64 bit max value cannot be expressed exactly as double + Assert.AreEqual(18446744073709549568un, boundnativeint) + + // overflow exception (depends on pointer size) + CheckThrowsOverflowException(fun () -> + if Info.isX86Runtime then + Operators.Checked.unativeint (float UInt32.MaxValue + 1.0) |> ignore + else + Operators.Checked.unativeint (float UInt64.MaxValue + 1.0) |> ignore + ) + + diff --git a/tests/FSharp.Core.UnitTests/LibraryTestFx.fs b/tests/FSharp.Core.UnitTests/LibraryTestFx.fs index f17daba432e..48c12638010 100644 --- a/tests/FSharp.Core.UnitTests/LibraryTestFx.fs +++ b/tests/FSharp.Core.UnitTests/LibraryTestFx.fs @@ -37,6 +37,7 @@ let private CheckThrowsExn2<'a when 'a :> exn> s (f : unit -> unit) = // attribute to flag these exception's usage as a bug. let CheckThrowsNullRefException f = CheckThrowsExn f let CheckThrowsIndexOutRangException f = CheckThrowsExn f +let CheckThrowsObjectDisposedException f = CheckThrowsExn f // Legit exceptions let CheckThrowsNotSupportedException f = CheckThrowsExn f @@ -49,6 +50,7 @@ let CheckThrowsDivideByZeroException f = CheckThrowsExn let CheckThrowsOverflowException f = CheckThrowsExn f let CheckThrowsInvalidOperationExn f = CheckThrowsExn f let CheckThrowsFormatException f = CheckThrowsExn f +let CheckThrowsArithmeticException f = CheckThrowsExn f // Verifies two sequences are equal (same length, equiv elements) let VerifySeqsEqual (seq1 : seq<'T>) (seq2 : seq<'T>) = diff --git a/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs b/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs index 8b0eec34fed..b91a8bc88e8 100644 --- a/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs +++ b/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs @@ -5,6 +5,8 @@ namespace NUnit.Framework open System open System.Collections.Generic open System.Linq +open System.Runtime.InteropServices + #if XUNIT open Xunit @@ -39,7 +41,27 @@ type IgnoreAttribute (_comment:string) = // Alias NUnit and XUnit Assert as LocalAssert type TestFrameworkAssert = Assert -exception AssertionException of string +module Info = + /// Use this to distinguish cases where output is deterministically different between x86 runtime or x64 runtime, + /// for instance w.r.t. floating point arithmetic. For more info, see https://github.com/dotnet/roslyn/issues/7333 + let isX86Runtime = sizeof = 4 + + /// Use this to distinguish cases where output is deterministically different between x86 runtime or x64 runtime, + /// for instance w.r.t. floating point arithmetic. For more info, see https://github.com/dotnet/roslyn/issues/7333 + let isX64Runtime = sizeof = 8 + + let framework = RuntimeInformation.FrameworkDescription + + /// Whether a test is run inside a .NET Core Runtime + let isNetCore = framework.StartsWith(".NET Core") + + /// Whether a test is run using a .NET Framework Runtime + let isNetFramework = framework.StartsWith(".NET Framework") + + /// Whether a test is run after being compiled to .NET Native + let isNetNative = framework.StartsWith(".NET Native") + + module private Impl = open FsCheck.Arb @@ -86,10 +108,28 @@ module private Impl = | _ -> Object.Equals(expected, actual) + /// Special treatment of float and float32 to get a somewhat meaningful error message + /// (otherwise, the missing precision leads to different values that are close together looking the same) + let floatStr (flt1: obj) (flt2: obj) = + match flt1, flt2 with + | :? float as flt1, (:? float as flt2) -> + flt1.ToString("R"), flt2.ToString("R") + + | :? float32 as flt1, (:? float32 as flt2) -> + flt1.ToString("R"), flt2.ToString("R") + + | _ -> flt1.ToString(), flt2.ToString() + + type Assert = + static member AreEqual(expected : obj, actual : obj, message : string) = + if not (Impl.equals expected actual) then - let message = sprintf "%s: Expected %A but got %A" message expected actual + let message = + let (exp, act) = Impl.floatStr expected actual + sprintf "%s: Expected %s but got %s" message exp act + AssertionException message |> raise static member AreNotEqual(expected : obj, actual : obj, message : string) = @@ -99,6 +139,17 @@ type Assert = static member AreEqual(expected : obj, actual : obj) = Assert.AreEqual(expected, actual, "Assertion") + /// Use this to compare floats within a delta of 1e-15, useful for discrepancies + /// between 80-bit (dotnet, RyuJIT) and 64-bit (x86, Legacy JIT) floating point calculations + static member AreNearEqual(expected: float, actual: float) = + let delta = 1.0e-15 + let message = + let ((e, a)) = Impl.floatStr expected actual + sprintf "Are near equal: expected %s, but got %s (with delta: %f)" e a delta + + global.NUnit.Framework.Assert.AreEqual(expected, actual, 1.0, message) + Assert.AreEqual(Math.Round(expected, 15), Math.Round(actual, 15), message) + static member AreNotEqual(expected : obj, actual : obj) = Assert.AreNotEqual(expected, actual, "Assertion") static member IsNull(o : obj) = Assert.AreEqual(null, o) From 0b5f732ad6d7139daab81187dbdee1f1791c0add Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Sun, 28 Jun 2020 21:05:40 -0700 Subject: [PATCH 43/60] more testing --- src/fsharp/ErrorLogger.fs | 19 +- .../E_ImplementGenIFaceTwice01_4.7.fs | 27 + ...1.fs => E_ImplementGenIFaceTwice01_5.0.fs} | 2 +- ...2.fs => E_ImplementGenIFaceTwice02_4.7.fs} | 2 +- .../InterfaceTypes/E_MultipleInst07.fs | 2 +- ...{MultipleInst08.fs => E_MultipleInst08.fs} | 6 +- .../ImplementGenIFaceTwice02_5.0.fs | 11 + .../InterfaceTypes/env.lst | 10 +- tests/fsharpqa/Source/test.lst | 554 +++++++++--------- 9 files changed, 343 insertions(+), 290 deletions(-) create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{E_ImplementGenIFaceTwice01.fs => E_ImplementGenIFaceTwice01_5.0.fs} (72%) rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{E_ImplementGenIFaceTwice02.fs => E_ImplementGenIFaceTwice02_4.7.fs} (69%) rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{MultipleInst08.fs => E_MultipleInst08.fs} (55%) create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ImplementGenIFaceTwice02_5.0.fs diff --git a/src/fsharp/ErrorLogger.fs b/src/fsharp/ErrorLogger.fs index 3e345ea4abf..feebf981866 100755 --- a/src/fsharp/ErrorLogger.fs +++ b/src/fsharp/ErrorLogger.fs @@ -677,15 +677,24 @@ type public FSharpErrorSeverityOptions = // let dummyMethodFOrBug6417A() = () // let dummyMethodFOrBug6417B() = () -let private tryLanguageFeatureErrorAux (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) error = - if not (langVersion.SupportsFeature langFeature) then +let private tryLanguageFeatureErrorAux (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) = + if not (langVersion.SupportsFeature langFeature) then let featureStr = langVersion.GetFeatureString langFeature let currentVersionStr = langVersion.SpecifiedVersionString let suggestedVersionStr = langVersion.GetFeatureVersionString langFeature - error (Error(FSComp.SR.chkFeatureNotLanguageSupported(featureStr, currentVersionStr, suggestedVersionStr), m)) + Some (Error(FSComp.SR.chkFeatureNotLanguageSupported(featureStr, currentVersionStr, suggestedVersionStr), m)) + else + None let internal tryLanguageFeatureError langVersion langFeature m = - tryLanguageFeatureErrorAux langVersion langFeature m error + match tryLanguageFeatureErrorAux langVersion langFeature m with + | Some e -> error (e) + | None -> () let internal tryLanguageFeatureErrorRecover langVersion langFeature m = - tryLanguageFeatureErrorAux langVersion langFeature m errorR \ No newline at end of file + match tryLanguageFeatureErrorAux langVersion langFeature m with + | Some e -> errorR e + | None -> () + +let internal tryLanguageFeatureErrorOption langVersion langFeature m = + tryLanguageFeatureErrorAux langVersion langFeature m \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs new file mode 100644 index 00000000000..0a861b8cddb --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs @@ -0,0 +1,27 @@ +// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations + + +// Verify error when trying to implement the same generic interface twice. +// Regression for FSB 3574, PE Verification failure when implementing multiple generic interfaces (one generic, one specifc) +//This type implements the same interface at different generic instantiations 'IA' and 'IA<'b>'. This is not permitted in this version of F#. + +type IA<'b> = + interface + abstract Foo : int -> int + end +type IB<'b> = + interface + inherit IA<'b> + inherit IA + end + +type A() = + class + interface IB with + member obj.Foo (x : int) = x + end + end + +let x = A() + +exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_5.0.fs similarity index 72% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_5.0.fs index 10927e41457..638eda79518 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_5.0.fs @@ -3,7 +3,7 @@ // Verify error when trying to implement the same generic interface twice. // Regression for FSB 3574, PE Verification failure when implementing multiple generic interfaces (one generic, one specifc) -//This type implements the same interface at different generic instantiations 'IA' and 'IA<'b>'\. This is not permitted in this version of F# +//'IB<'b>' cannot implement the interface 'IA<_>' with the two instantiations 'IA' and 'IA<'b>' because they may unify. type IA<'b> = interface diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs similarity index 69% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs index 560cb715586..b8cf023508a 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations // Verify error when trying to implement the same generic // interface twice -//This type implements the same interface at different generic instantiations 'IFoo' and 'IFoo'\. This is not permitted in this version of F# +//This type implements the same interface at different generic instantiations 'IFoo' and 'IFoo'. This is not permitted in this version of F#. type IFoo<'a> = interface diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs index c4c00dbd1b5..965ccfe6055 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs @@ -17,4 +17,4 @@ type C() = interface IB with member x.X() = 2 -exit 1 \ No newline at end of file +exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst08.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst08.fs similarity index 55% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst08.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst08.fs index 3a8fa7a599c..73d0be3c7aa 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst08.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst08.fs @@ -1,4 +1,8 @@ // #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// int does not unify with in. + +//'C' cannot implement the interface 'IB<_>' with the two instantiations 'IB' and 'IB>' because they may unify. + type MyInt = int [] type kg @@ -13,4 +17,4 @@ type C() = interface IB with member x.X() = 2 -exit 1 \ No newline at end of file +exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ImplementGenIFaceTwice02_5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ImplementGenIFaceTwice02_5.0.fs new file mode 100644 index 00000000000..86acf7b2926 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ImplementGenIFaceTwice02_5.0.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +type IFoo<'a> = + interface + abstract DoStuff : unit -> string + end + +type Bar() = + interface IFoo with + member this.DoStuff() = "IFoo" + interface IFoo with + member this.DoStuff() = "IFoo" diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst index 0c8d4e19a0d..00ebd538279 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst @@ -12,8 +12,8 @@ SOURCE=MultipleInst04.fs SCFLAGS=--test:ErrorRanges # MultipleInst04.fs SOURCE=MultipleInst05.fs SCFLAGS=--test:ErrorRanges # MultipleInst05.fs SOURCE=MultipleInst06.fs SCFLAGS="--test:ErrorRanges" # MultipleInst06.fs - SOURCE=E_MultipleInst07.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_MultipleInst07.fs - SOURCE=MultipleInst08.fs SCFLAGS="--test:ErrorRanges --langversion:preview" # MultipleInst08.fs + SOURCE=E_MultipleInst07.fs SCFLAGS="--test:ErrorRanges --langversion:4.7 --nowarn:221" # E_MultipleInst07.fs + SOURCE=E_MultipleInst08.fs SCFLAGS="--test:ErrorRanges --langversion:preview --nowarn:221" # E_MultipleInst08.fs SOURCE=Inheritance_OverrideInterface.fs SCFLAGS="--test:ErrorRanges --langversion:preview" # Inheritance_OverrideInterface.fs SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs @@ -38,8 +38,10 @@ NoMT SOURCE=ConsumeMultipleInterfaceFromCS.fs PRECMD="\$CSC_PIPE /t:library Mul NoMT SOURCE=E_ConsumeMultipleInterfaceFromCS.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges" # E_ConsumeMultipleInterfaceFromCS.fs NoMT SOURCE=E_ClassConsumeMultipleInterfaceFromCS.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges" # E_ClassConsumeMultipleInterfaceFromCS.fs - SOURCE="E_ImplementGenIFaceTwice01.fs" # E_ImplementGenIFaceTwice01.fs - SOURCE="E_ImplementGenIFaceTwice02.fs" # E_ImplementGenIFaceTwice02.fs + SOURCE="E_ImplementGenIFaceTwice01_4.7.fs" SCFLAGS="--test:ErrorRanges --langversion:4.7 --nowarn:221" # E_ImplementGenIFaceTwice01_4.7.fs + SOURCE="E_ImplementGenIFaceTwice01_5.0.fs" SCFLAGS="--test:ErrorRanges --langversion:preview --nowarn:221" # E_ImplementGenIFaceTwice01_5.0.fs + SOURCE="E_ImplementGenIFaceTwice02_4.7.fs" SCFLAGS="--test:ErrorRanges --langversion:4.7 --nowarn:221" # E_ImplementGenIFaceTwice02_4.7.fs + SOURCE="ImplementGenIFaceTwice02_5.0.fs" SCFLAGS="--test:ErrorRanges --langversion:preview --nowarn:221" # ImplementGenIFaceTwice02_5.0.fs SOURCE=EmptyInterface01.fs # EmptyInterface01.fs SOURCE=InheritDotNetInterface.fs # InheritDotNetInterface.fs diff --git a/tests/fsharpqa/Source/test.lst b/tests/fsharpqa/Source/test.lst index 41284ca837d..95afc5893b4 100644 --- a/tests/fsharpqa/Source/test.lst +++ b/tests/fsharpqa/Source/test.lst @@ -5,281 +5,281 @@ # ReqNOCov -- skip this test/suite if we are doing a code coverage run # ReqENU -- skip this test/suite if we are running on non-ENU (useful to exclude hard-to-localize tests) -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\AsyncExpressionStepping -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\AttributeTargets -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\CCtorDUWithMember -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\CompiledNameAttribute -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\ComputationExpressions -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\DoNotBoxStruct -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\GeneratedIterators -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\InequalityComparison -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\ListExpressionStepping -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\LiteralValue -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\MethodImplAttribute -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Misc -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Mutation -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Operators -####Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\QueryExpressionStepping -####Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SeqExpressionStepping -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SeqExpressionTailCalls -####CodeGen01,NoMT,CodeGen,NoHostedCompiler,SerializableAttribute CodeGen\EmittedIL\SerializableAttribute -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\StaticInit -####Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SteppingMatch -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\TailCalls -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\TestFunctions -####CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Tuples -####CodeGen01,NoMT,CodeGen CodeGen\StringEncoding -####CodeGen01,NoMT,CodeGen CodeGen\Structure -#### -#### -####CompilerOptions01,NoMT CompilerOptions\fsc\checked -####CompilerOptions01,NoMT CompilerOptions\fsc\cliversion -####CompilerOptions01,NoMT CompilerOptions\fsc\codepage -####CompilerOptions01,NoMT CompilerOptions\fsc\crossoptimize -####CompilerOptions01,NoMT CompilerOptions\fsc\debug -####CompilerOptions01,NoMT CompilerOptions\fsc\dumpAllCommandLineOptions -####CompilerOptions01,NoMT CompilerOptions\fsc\flaterrors -####CompilerOptions02,NoMT CompilerOptions\fsc\gccerrors -####CompilerOptions01,NoMT,help CompilerOptions\fsc\help -####CompilerOptions01,NoMT CompilerOptions\fsc\highentropyva -####CompilerOptions01,NoMT CompilerOptions\fsc\langversion -####CompilerOptions01,NoMT CompilerOptions\fsc\lib -####CompilerOptions01,NoMT CompilerOptions\fsc\noframework -####CompilerOptions01,NoMT CompilerOptions\fsc\nologo -####CompilerOptions01,NoMT CompilerOptions\fsc\optimize -####CompilerOptions01,NoMT CompilerOptions\fsc\out -####CompilerOptions01,NoMT,pdbs CompilerOptions\fsc\pdb -####CompilerOptions01,NoMT CompilerOptions\fsc\platform -####CompilerOptions01,NoMT CompilerOptions\fsc\reference -####CompilerOptions01,NoMT CompilerOptions\fsc\Removed -####CompilerOptions01,NoMT CompilerOptions\fsc\standalone -####CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\staticlink -####CompilerOptions01,NoMT CompilerOptions\fsc\subsystemversion -####CompilerOptions01,NoMT CompilerOptions\fsc\tailcalls -####CompilerOptions01,NoMT CompilerOptions\fsc\target -####CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\times -####CompilerOptions01,NoMT CompilerOptions\fsc\warn -####CompilerOptions01,NoMT CompilerOptions\fsc\warnaserror -####CompilerOptions01,NoMT CompilerOptions\fsc\warnon -####CompilerOptions01,NoMT CompilerOptions\fsc\responsefile -####CompilerOptions01,NoMT,help CompilerOptions\fsi\help -####CompilerOptions01,NoMT CompilerOptions\fsi\highentropyva -####CompilerOptions01,NoMT CompilerOptions\fsi\langversion -####CompilerOptions01,NoMT CompilerOptions\fsi\nologo -####CompilerOptions01,NoMT CompilerOptions\fsi\subsystemversion -####CompilerOptions01,NoMT CompilerOptions\fsi\times -####CompilerOptions02,NoMT CompilerOptions\fsi\exename -####CompilerOptions01,NoMT,Determinism CompilerOptions\fsc\determinism -#### -####Conformance01 Conformance\BasicGrammarElements\Constants -####Conformance01 Conformance\BasicGrammarElements\OperatorNames -####Conformance01 Conformance\BasicGrammarElements\PrecedenceAndOperators -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\ExceptionDefinitions -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\Diags -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\Legacy -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\New -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Basic -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\IComparison -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\ModuleDefinitions -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\NamespaceDeclGroups -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\NullRepresentations -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\RecordTypes -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\TypeAbbreviations -####Conformance01 Conformance\BasicTypeAndModuleDefinitions\UnionTypes -####Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\Basic -####Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\OnOverridesAndIFaceImpl -####Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\OnTypeMembers -####Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\PermittedLocations -####Conformance01 Conformance\DeclarationElements\CustomAttributes\ArgumentsOfAllTypes -####Conformance01 Conformance\DeclarationElements\CustomAttributes\AttributeInheritance -#### -####Conformance02 Conformance\DeclarationElements\CustomAttributes\AttributeUsage -####Conformance02 Conformance\DeclarationElements\CustomAttributes\Basic -####Conformance02 Conformance\DeclarationElements\CustomAttributes\ImportedAttributes -####Conformance02 Conformance\DeclarationElements\Events\basic -####Conformance02 Conformance\DeclarationElements\FieldMembers -####Conformance02 Conformance\DeclarationElements\ImportDeclarations -####Conformance02 Conformance\DeclarationElements\InterfaceSpecificationsAndImplementations -####Conformance02 Conformance\DeclarationElements\LetBindings\ActivePatternBindings -####Conformance02 Conformance\DeclarationElements\LetBindings\ArityInference -####Conformance02 Conformance\DeclarationElements\LetBindings\Basic -####Conformance02 Conformance\DeclarationElements\LetBindings\ExplicitTypeParameters -####Conformance02 Conformance\DeclarationElements\LetBindings\TypeFunctions -####Conformance02 Conformance\DeclarationElements\MemberDefinitions\ImplementingDispatchSlots -####Conformance02 Conformance\DeclarationElements\MemberDefinitions\MethodsAndProperties -####Conformance02 Conformance\DeclarationElements\MemberDefinitions\NamedArguments -####Conformance02 Conformance\DeclarationElements\MemberDefinitions\OptionalArguments -####Conformance02 Conformance\DeclarationElements\MemberDefinitions\OptionalDefaultParameterValueArguments -####Conformance02 Conformance\DeclarationElements\MemberDefinitions\OverloadingMembers -####Conformance02 Conformance\DeclarationElements\ModuleAbbreviations -####Conformance02 Conformance\DeclarationElements\ObjectConstructors -####Conformance02 Conformance\DeclarationElements\P-invokeDeclarations -#### -####Conformance03 Conformance\Expressions\ApplicationExpressions\Assertion -####Conformance03 Conformance\Expressions\ApplicationExpressions\BasicApplication -####Conformance03 Conformance\Expressions\ApplicationExpressions\ObjectConstruction -####Conformance03 Conformance\Expressions\BindingExpressions\Binding -####Conformance03 Conformance\Expressions\ConstantExpressions -####Conformance03 Conformance\Expressions\ControlFlowExpressions\Assertion -####Conformance03 Conformance\Expressions\ControlFlowExpressions\Conditional -####Conformance03 Conformance\Expressions\ControlFlowExpressions\ParenthesizedAndBlock -####Conformance03 Conformance\Expressions\ControlFlowExpressions\PatternMatching -####Conformance03 Conformance\Expressions\ControlFlowExpressions\SequenceIteration -####Conformance03 Conformance\Expressions\ControlFlowExpressions\SequentialExecution -####Conformance03 Conformance\Expressions\ControlFlowExpressions\SimpleFor -####Conformance03 Conformance\Expressions\ControlFlowExpressions\TryCatch -####Conformance03 Conformance\Expressions\ControlFlowExpressions\TryFinally -####Conformance03 Conformance\Expressions\ControlFlowExpressions\While -####Conformance03 Conformance\Expressions\DataExpressions\AddressOf -####Conformance03 Conformance\Expressions\DataExpressions\ComputationExpressions -####Conformance03 Conformance\Expressions\DataExpressions\ObjectExpressions -####Conformance03 Conformance\Expressions\DataExpressions\QueryExpressions -####Conformance03 Conformance\Expressions\DataExpressions\RangeExpressions -#### -####Conformance04 Conformance\Expressions\DataExpressions\SequenceExpressions -####Conformance04 Conformance\Expressions\DataExpressions\TupleExpressions -####Conformance04 Conformance\Expressions\ElaborationAndElaboratedExpressions -####Conformance04 Conformance\Expressions\EvaluationAndValues -####Conformance04 Conformance\Expressions\EvaluationOfElaboratedForms -####Conformance04 Conformance\Expressions\ExpressionQuotations\Baselines -####Conformance04 Conformance\Expressions\ExpressionQuotations\Regressions -####Conformance04 Conformance\Expressions\SomeCheckingAndInferenceTerminology -####Conformance04 Conformance\Expressions\SyntacticSugar -####Conformance04 Conformance\Expressions\SyntacticSugarAndAmbiguities -####Conformance04 Conformance\Expressions\Type-relatedExpressions -####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\CheckingOfImplementationFiles -####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\InitializationSemanticsForImplementationFiles -####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\NamespacesFragmentsAndImplementationFiles\basic -####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\NamespacesFragmentsAndImplementationFiles\global -####Conformance04 Conformance\ImplementationFilesAndSignatureFiles\SignatureFiles -####Conformance04 Conformance\InferenceProcedures\ByrefSafetyAnalysis -####Conformance04 Conformance\InferenceProcedures\ConstraintSolving -####Conformance04 Conformance\InferenceProcedures\DispatchSlotChecking -#### -####Conformance05 Conformance\InferenceProcedures\DispatchSlotInference -####Conformance05 Conformance\InferenceProcedures\FunctionApplicationResolution -####Conformance05 Conformance\InferenceProcedures\Generalization -####Conformance05 Conformance\InferenceProcedures\MethodApplicationResolution -####Conformance05 Conformance\InferenceProcedures\NameResolution\AutoOpen -####Conformance05 Conformance\InferenceProcedures\NameResolution\Misc -####Conformance05 Conformance\InferenceProcedures\NameResolution\RequireQualifiedAccess -####Conformance05 Conformance\InferenceProcedures\RecursiveSafetyAnalysis -####Conformance05 Conformance\InferenceProcedures\ResolvingApplicationExpressions -####Conformance05 Conformance\InferenceProcedures\TypeInference -####Conformance05 Conformance\InferenceProcedures\WellFormednessChecking -####Conformance05 Conformance\LexicalAnalysis\Comments -####Conformance05 Conformance\LexicalAnalysis\ConditionalCompilation -####Conformance05 Conformance\LexicalAnalysis\Directives -####Conformance05 Conformance\LexicalAnalysis\HiddenTokens -####Conformance05 Conformance\LexicalAnalysis\IdentifierReplacements -####Conformance05 Conformance\LexicalAnalysis\IdentifiersAndKeywords -####Conformance05 Conformance\LexicalAnalysis\LineDirectives -####Conformance05 Conformance\LexicalAnalysis\NumericLiterals -####Conformance05 Conformance\LexicalAnalysis\Shift\Generics -#### -####Conformance06 Conformance\LexicalAnalysis\StringsAndCharacters -####Conformance06 Conformance\LexicalAnalysis\SymbolicKeywords -####Conformance06 Conformance\LexicalAnalysis\SymbolicOperators -####Conformance06 Conformance\LexicalAnalysis\Whitespace -####Conformance06 Conformance\LexicalFiltering\Basic\ByExample -####Conformance06 Conformance\LexicalFiltering\Basic\OffsideExceptions -####Conformance06 Conformance\LexicalFiltering\HashLight -####Conformance06 Conformance\LexicalFiltering\HighPrecedenceApplication -####Conformance06 Conformance\LexicalFiltering\LexicalAnalysisOfTypeApplications -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\AbstractMembers -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\AsDeclarations -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\AutoProperties -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ExplicitFields -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ExplicitObjectConstructors -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ImplicitObjectConstructors -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\InheritsDeclarations -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\LetDoDeclarations -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\MemberDeclarations -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\Misc -####Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\StaticLetDoDeclarations -#### -####Conformance07 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ValueRestriction -####Conformance07 Conformance\ObjectOrientedTypeDefinitions\DelegateTypes -####Conformance07 Conformance\ObjectOrientedTypeDefinitions\EnumTypes +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\AsyncExpressionStepping +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\AttributeTargets +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\CCtorDUWithMember +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\CompiledNameAttribute +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\ComputationExpressions +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\DoNotBoxStruct +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\GeneratedIterators +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\InequalityComparison +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\ListExpressionStepping +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\LiteralValue +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\MethodImplAttribute +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Misc +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Mutation +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Operators +Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\QueryExpressionStepping +Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SeqExpressionStepping +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SeqExpressionTailCalls +CodeGen01,NoMT,CodeGen,NoHostedCompiler,SerializableAttribute CodeGen\EmittedIL\SerializableAttribute +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\StaticInit +Retry,CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\SteppingMatch +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\TailCalls +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\TestFunctions +CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Tuples +CodeGen01,NoMT,CodeGen CodeGen\StringEncoding +CodeGen01,NoMT,CodeGen CodeGen\Structure + + +CompilerOptions01,NoMT CompilerOptions\fsc\checked +CompilerOptions01,NoMT CompilerOptions\fsc\cliversion +CompilerOptions01,NoMT CompilerOptions\fsc\codepage +CompilerOptions01,NoMT CompilerOptions\fsc\crossoptimize +CompilerOptions01,NoMT CompilerOptions\fsc\debug +CompilerOptions01,NoMT CompilerOptions\fsc\dumpAllCommandLineOptions +CompilerOptions01,NoMT CompilerOptions\fsc\flaterrors +CompilerOptions02,NoMT CompilerOptions\fsc\gccerrors +CompilerOptions01,NoMT,help CompilerOptions\fsc\help +CompilerOptions01,NoMT CompilerOptions\fsc\highentropyva +CompilerOptions01,NoMT CompilerOptions\fsc\langversion +CompilerOptions01,NoMT CompilerOptions\fsc\lib +CompilerOptions01,NoMT CompilerOptions\fsc\noframework +CompilerOptions01,NoMT CompilerOptions\fsc\nologo +CompilerOptions01,NoMT CompilerOptions\fsc\optimize +CompilerOptions01,NoMT CompilerOptions\fsc\out +CompilerOptions01,NoMT,pdbs CompilerOptions\fsc\pdb +CompilerOptions01,NoMT CompilerOptions\fsc\platform +CompilerOptions01,NoMT CompilerOptions\fsc\reference +CompilerOptions01,NoMT CompilerOptions\fsc\Removed +CompilerOptions01,NoMT CompilerOptions\fsc\standalone +CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\staticlink +CompilerOptions01,NoMT CompilerOptions\fsc\subsystemversion +CompilerOptions01,NoMT CompilerOptions\fsc\tailcalls +CompilerOptions01,NoMT CompilerOptions\fsc\target +CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\times +CompilerOptions01,NoMT CompilerOptions\fsc\warn +CompilerOptions01,NoMT CompilerOptions\fsc\warnaserror +CompilerOptions01,NoMT CompilerOptions\fsc\warnon +CompilerOptions01,NoMT CompilerOptions\fsc\responsefile +CompilerOptions01,NoMT,help CompilerOptions\fsi\help +CompilerOptions01,NoMT CompilerOptions\fsi\highentropyva +CompilerOptions01,NoMT CompilerOptions\fsi\langversion +CompilerOptions01,NoMT CompilerOptions\fsi\nologo +CompilerOptions01,NoMT CompilerOptions\fsi\subsystemversion +CompilerOptions01,NoMT CompilerOptions\fsi\times +CompilerOptions02,NoMT CompilerOptions\fsi\exename +CompilerOptions01,NoMT,Determinism CompilerOptions\fsc\determinism + +Conformance01 Conformance\BasicGrammarElements\Constants +Conformance01 Conformance\BasicGrammarElements\OperatorNames +Conformance01 Conformance\BasicGrammarElements\PrecedenceAndOperators +Conformance01 Conformance\BasicTypeAndModuleDefinitions\ExceptionDefinitions +Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\Diags +Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\Legacy +Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Attributes\New +Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\Basic +Conformance01 Conformance\BasicTypeAndModuleDefinitions\GeneratedEqualityHashingComparison\IComparison +Conformance01 Conformance\BasicTypeAndModuleDefinitions\ModuleDefinitions +Conformance01 Conformance\BasicTypeAndModuleDefinitions\NamespaceDeclGroups +Conformance01 Conformance\BasicTypeAndModuleDefinitions\NullRepresentations +Conformance01 Conformance\BasicTypeAndModuleDefinitions\RecordTypes +Conformance01 Conformance\BasicTypeAndModuleDefinitions\TypeAbbreviations +Conformance01 Conformance\BasicTypeAndModuleDefinitions\UnionTypes +Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\Basic +Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\OnOverridesAndIFaceImpl +Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\OnTypeMembers +Conformance01 Conformance\DeclarationElements\AccessibilityAnnotations\PermittedLocations +Conformance01 Conformance\DeclarationElements\CustomAttributes\ArgumentsOfAllTypes +Conformance01 Conformance\DeclarationElements\CustomAttributes\AttributeInheritance + +Conformance02 Conformance\DeclarationElements\CustomAttributes\AttributeUsage +Conformance02 Conformance\DeclarationElements\CustomAttributes\Basic +Conformance02 Conformance\DeclarationElements\CustomAttributes\ImportedAttributes +Conformance02 Conformance\DeclarationElements\Events\basic +Conformance02 Conformance\DeclarationElements\FieldMembers +Conformance02 Conformance\DeclarationElements\ImportDeclarations +Conformance02 Conformance\DeclarationElements\InterfaceSpecificationsAndImplementations +Conformance02 Conformance\DeclarationElements\LetBindings\ActivePatternBindings +Conformance02 Conformance\DeclarationElements\LetBindings\ArityInference +Conformance02 Conformance\DeclarationElements\LetBindings\Basic +Conformance02 Conformance\DeclarationElements\LetBindings\ExplicitTypeParameters +Conformance02 Conformance\DeclarationElements\LetBindings\TypeFunctions +Conformance02 Conformance\DeclarationElements\MemberDefinitions\ImplementingDispatchSlots +Conformance02 Conformance\DeclarationElements\MemberDefinitions\MethodsAndProperties +Conformance02 Conformance\DeclarationElements\MemberDefinitions\NamedArguments +Conformance02 Conformance\DeclarationElements\MemberDefinitions\OptionalArguments +Conformance02 Conformance\DeclarationElements\MemberDefinitions\OptionalDefaultParameterValueArguments +Conformance02 Conformance\DeclarationElements\MemberDefinitions\OverloadingMembers +Conformance02 Conformance\DeclarationElements\ModuleAbbreviations +Conformance02 Conformance\DeclarationElements\ObjectConstructors +Conformance02 Conformance\DeclarationElements\P-invokeDeclarations + +Conformance03 Conformance\Expressions\ApplicationExpressions\Assertion +Conformance03 Conformance\Expressions\ApplicationExpressions\BasicApplication +Conformance03 Conformance\Expressions\ApplicationExpressions\ObjectConstruction +Conformance03 Conformance\Expressions\BindingExpressions\Binding +Conformance03 Conformance\Expressions\ConstantExpressions +Conformance03 Conformance\Expressions\ControlFlowExpressions\Assertion +Conformance03 Conformance\Expressions\ControlFlowExpressions\Conditional +Conformance03 Conformance\Expressions\ControlFlowExpressions\ParenthesizedAndBlock +Conformance03 Conformance\Expressions\ControlFlowExpressions\PatternMatching +Conformance03 Conformance\Expressions\ControlFlowExpressions\SequenceIteration +Conformance03 Conformance\Expressions\ControlFlowExpressions\SequentialExecution +Conformance03 Conformance\Expressions\ControlFlowExpressions\SimpleFor +Conformance03 Conformance\Expressions\ControlFlowExpressions\TryCatch +Conformance03 Conformance\Expressions\ControlFlowExpressions\TryFinally +Conformance03 Conformance\Expressions\ControlFlowExpressions\While +Conformance03 Conformance\Expressions\DataExpressions\AddressOf +Conformance03 Conformance\Expressions\DataExpressions\ComputationExpressions +Conformance03 Conformance\Expressions\DataExpressions\ObjectExpressions +Conformance03 Conformance\Expressions\DataExpressions\QueryExpressions +Conformance03 Conformance\Expressions\DataExpressions\RangeExpressions + +Conformance04 Conformance\Expressions\DataExpressions\SequenceExpressions +Conformance04 Conformance\Expressions\DataExpressions\TupleExpressions +Conformance04 Conformance\Expressions\ElaborationAndElaboratedExpressions +Conformance04 Conformance\Expressions\EvaluationAndValues +Conformance04 Conformance\Expressions\EvaluationOfElaboratedForms +Conformance04 Conformance\Expressions\ExpressionQuotations\Baselines +Conformance04 Conformance\Expressions\ExpressionQuotations\Regressions +Conformance04 Conformance\Expressions\SomeCheckingAndInferenceTerminology +Conformance04 Conformance\Expressions\SyntacticSugar +Conformance04 Conformance\Expressions\SyntacticSugarAndAmbiguities +Conformance04 Conformance\Expressions\Type-relatedExpressions +Conformance04 Conformance\ImplementationFilesAndSignatureFiles\CheckingOfImplementationFiles +Conformance04 Conformance\ImplementationFilesAndSignatureFiles\InitializationSemanticsForImplementationFiles +Conformance04 Conformance\ImplementationFilesAndSignatureFiles\NamespacesFragmentsAndImplementationFiles\basic +Conformance04 Conformance\ImplementationFilesAndSignatureFiles\NamespacesFragmentsAndImplementationFiles\global +Conformance04 Conformance\ImplementationFilesAndSignatureFiles\SignatureFiles +Conformance04 Conformance\InferenceProcedures\ByrefSafetyAnalysis +Conformance04 Conformance\InferenceProcedures\ConstraintSolving +Conformance04 Conformance\InferenceProcedures\DispatchSlotChecking + +Conformance05 Conformance\InferenceProcedures\DispatchSlotInference +Conformance05 Conformance\InferenceProcedures\FunctionApplicationResolution +Conformance05 Conformance\InferenceProcedures\Generalization +Conformance05 Conformance\InferenceProcedures\MethodApplicationResolution +Conformance05 Conformance\InferenceProcedures\NameResolution\AutoOpen +Conformance05 Conformance\InferenceProcedures\NameResolution\Misc +Conformance05 Conformance\InferenceProcedures\NameResolution\RequireQualifiedAccess +Conformance05 Conformance\InferenceProcedures\RecursiveSafetyAnalysis +Conformance05 Conformance\InferenceProcedures\ResolvingApplicationExpressions +Conformance05 Conformance\InferenceProcedures\TypeInference +Conformance05 Conformance\InferenceProcedures\WellFormednessChecking +Conformance05 Conformance\LexicalAnalysis\Comments +Conformance05 Conformance\LexicalAnalysis\ConditionalCompilation +Conformance05 Conformance\LexicalAnalysis\Directives +Conformance05 Conformance\LexicalAnalysis\HiddenTokens +Conformance05 Conformance\LexicalAnalysis\IdentifierReplacements +Conformance05 Conformance\LexicalAnalysis\IdentifiersAndKeywords +Conformance05 Conformance\LexicalAnalysis\LineDirectives +Conformance05 Conformance\LexicalAnalysis\NumericLiterals +Conformance05 Conformance\LexicalAnalysis\Shift\Generics + +Conformance06 Conformance\LexicalAnalysis\StringsAndCharacters +Conformance06 Conformance\LexicalAnalysis\SymbolicKeywords +Conformance06 Conformance\LexicalAnalysis\SymbolicOperators +Conformance06 Conformance\LexicalAnalysis\Whitespace +Conformance06 Conformance\LexicalFiltering\Basic\ByExample +Conformance06 Conformance\LexicalFiltering\Basic\OffsideExceptions +Conformance06 Conformance\LexicalFiltering\HashLight +Conformance06 Conformance\LexicalFiltering\HighPrecedenceApplication +Conformance06 Conformance\LexicalFiltering\LexicalAnalysisOfTypeApplications +Conformance06 Conformance\ObjectOrientedTypeDefinitions\AbstractMembers +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\AsDeclarations +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\AutoProperties +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ExplicitFields +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ExplicitObjectConstructors +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ImplicitObjectConstructors +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\InheritsDeclarations +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\LetDoDeclarations +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\MemberDeclarations +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\Misc +Conformance06 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\StaticLetDoDeclarations + +Conformance07 Conformance\ObjectOrientedTypeDefinitions\ClassTypes\ValueRestriction +Conformance07 Conformance\ObjectOrientedTypeDefinitions\DelegateTypes +Conformance07 Conformance\ObjectOrientedTypeDefinitions\EnumTypes Conformance07 Conformance\ObjectOrientedTypeDefinitions\InterfaceTypes -####Conformance07 Conformance\ObjectOrientedTypeDefinitions\StructTypes -####Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\basic -####Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\intrinsic -####Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\optional -####Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeKindInference -####Conformance07 Conformance\PatternMatching\And -####Conformance07 Conformance\PatternMatching\Array -####Conformance07 Conformance\PatternMatching\As -####Conformance07 Conformance\PatternMatching\ConsList -####Conformance07 Conformance\PatternMatching\DynamicTypeTest -####Conformance07 Conformance\PatternMatching\Expression -####Conformance07 Conformance\PatternMatching\Named -####Conformance07 Conformance\PatternMatching\Null -####Conformance07 Conformance\PatternMatching\Record -####Conformance07 Conformance\PatternMatching\Simple -####Conformance07 Conformance\PatternMatching\SimpleConstant -#### -####Conformance08 Conformance\PatternMatching\Tuple -####Conformance08 Conformance\PatternMatching\TypeAnnotated -####Conformance08 Conformance\PatternMatching\TypeConstraint -####Conformance08 Conformance\PatternMatching\Union -####Conformance08 Conformance\PatternMatching\Wildcard -####Conformance08 Conformance\Signatures\SignatureConformance -####Conformance08 Conformance\Signatures\SignatureTypes -####Conformance08 Conformance\SpecialAttributesAndTypes\Imported\System.ThreadStatic -####Conformance08 Conformance\SpecialAttributesAndTypes\Imported\CallerInfo -####Conformance08 Conformance\StructFieldEqualityComparison -####Conformance08 Conformance\TypesAndTypeConstraints\CheckingSyntacticTypes -####Conformance08 Conformance\TypesAndTypeConstraints\LogicalPropertiesOfTypes -####Conformance08 Conformance\TypesAndTypeConstraints\TypeConstraints -####Conformance08 Conformance\TypesAndTypeConstraints\TypeParameterDefinitions -####Conformance08 Conformance\UnitsOfMeasure\Basic -####Conformance08 Conformance\UnitsOfMeasure\Bounds -####Conformance08 Conformance\UnitsOfMeasure\Constants -####Conformance08 Conformance\UnitsOfMeasure\Diagnostics -####Conformance08 Conformance\UnitsOfMeasure\Operators -####Conformance08 Conformance\UnitsOfMeasure\Parenthesis -####Conformance08 Conformance\UnitsOfMeasure\Parsing -####Conformance08 Conformance\UnitsOfMeasure\TypeChecker -####Conformance08 Conformance\UnitsOfMeasure\WithOOP -####Conformance08 Conformance\Expressions\DataExpressions\NameOf -#### -####Misc01 ClrFx\PseudoCustomAttributes\AssemblyAlgorithmId -####Misc01 ClrFx\PseudoCustomAttributes\AssemblyConfiguration -####Misc01 ClrFx\PseudoCustomAttributes\AssemblyVersion -####Misc01 Diagnostics\async -####Misc01,Diagnostics Diagnostics\General -####Misc01 Diagnostics\NONTERM -####Misc01 Diagnostics\ParsingAtEOF -####Misc01 EntryPoint -####Misc01 Globalization -####Misc01,NoMT Import -####Misc01,NoMT ..\..\..\testsprivate\fsharpqa\Source\InteractiveSession\AssemblyLoading -####Misc01,NoMT InteractiveSession\Misc -####Misc01,NoMT InteractiveSession\Misc\GenericConstraintWoes\issue2411 -####Misc01 Libraries\Control -####Misc01 Libraries\Core\collections -####Misc01 Libraries\Core\ExtraTopLevelOperators -####Misc01 Libraries\Core\LanguagePrimitives -####Misc01 Libraries\Core\NativeInterop\stackalloc -####Misc01 Libraries\Core\Operators -####Misc01 Libraries\Core\Reflection -####Misc01 Libraries\Core\Unchecked -####Misc01 Warnings -#### -####Misc02 Libraries\Portable -####Misc02 Misc -####Misc02 MultiTargeting -####Misc02 OCamlCompat -####Misc02,CodeGen Optimizations\AssemblyBoundary -####Misc02,CodeGen Optimizations\ForLoop -####Misc02,CodeGen Optimizations\GenericComparison -####Misc02,CodeGen Optimizations\Inlining -####Misc02,NoMT Printing -####Misc02 ..\..\..\testsprivate\fsharpqa\Source\RealWorld\UnitsOfMeasure -####Misc02 ..\..\..\testsprivate\fsharpqa\Source\RealWorld\Agents -####Misc02,NoMT ..\..\..\testsprivate\fsharpqa\Source\Setup -####Misc02 Stress -####Misc02 XmlDoc\Basic -####Misc02 XmlDoc\OCamlDoc -####Misc02 XmlDoc\UnitOfMeasure +Conformance07 Conformance\ObjectOrientedTypeDefinitions\StructTypes +Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\basic +Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\intrinsic +Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeExtensions\optional +Conformance07 Conformance\ObjectOrientedTypeDefinitions\TypeKindInference +Conformance07 Conformance\PatternMatching\And +Conformance07 Conformance\PatternMatching\Array +Conformance07 Conformance\PatternMatching\As +Conformance07 Conformance\PatternMatching\ConsList +Conformance07 Conformance\PatternMatching\DynamicTypeTest +Conformance07 Conformance\PatternMatching\Expression +Conformance07 Conformance\PatternMatching\Named +Conformance07 Conformance\PatternMatching\Null +Conformance07 Conformance\PatternMatching\Record +Conformance07 Conformance\PatternMatching\Simple +Conformance07 Conformance\PatternMatching\SimpleConstant + +Conformance08 Conformance\PatternMatching\Tuple +Conformance08 Conformance\PatternMatching\TypeAnnotated +Conformance08 Conformance\PatternMatching\TypeConstraint +Conformance08 Conformance\PatternMatching\Union +Conformance08 Conformance\PatternMatching\Wildcard +Conformance08 Conformance\Signatures\SignatureConformance +Conformance08 Conformance\Signatures\SignatureTypes +Conformance08 Conformance\SpecialAttributesAndTypes\Imported\System.ThreadStatic +Conformance08 Conformance\SpecialAttributesAndTypes\Imported\CallerInfo +Conformance08 Conformance\StructFieldEqualityComparison +Conformance08 Conformance\TypesAndTypeConstraints\CheckingSyntacticTypes +Conformance08 Conformance\TypesAndTypeConstraints\LogicalPropertiesOfTypes +Conformance08 Conformance\TypesAndTypeConstraints\TypeConstraints +Conformance08 Conformance\TypesAndTypeConstraints\TypeParameterDefinitions +Conformance08 Conformance\UnitsOfMeasure\Basic +Conformance08 Conformance\UnitsOfMeasure\Bounds +Conformance08 Conformance\UnitsOfMeasure\Constants +Conformance08 Conformance\UnitsOfMeasure\Diagnostics +Conformance08 Conformance\UnitsOfMeasure\Operators +Conformance08 Conformance\UnitsOfMeasure\Parenthesis +Conformance08 Conformance\UnitsOfMeasure\Parsing +Conformance08 Conformance\UnitsOfMeasure\TypeChecker +Conformance08 Conformance\UnitsOfMeasure\WithOOP +Conformance08 Conformance\Expressions\DataExpressions\NameOf + +Misc01 ClrFx\PseudoCustomAttributes\AssemblyAlgorithmId +Misc01 ClrFx\PseudoCustomAttributes\AssemblyConfiguration +Misc01 ClrFx\PseudoCustomAttributes\AssemblyVersion +Misc01 Diagnostics\async +Misc01,Diagnostics Diagnostics\General +Misc01 Diagnostics\NONTERM +Misc01 Diagnostics\ParsingAtEOF +Misc01 EntryPoint +Misc01 Globalization +Misc01,NoMT Import +Misc01,NoMT ..\..\..\testsprivate\fsharpqa\Source\InteractiveSession\AssemblyLoading +Misc01,NoMT InteractiveSession\Misc +Misc01,NoMT InteractiveSession\Misc\GenericConstraintWoes\issue2411 +Misc01 Libraries\Control +Misc01 Libraries\Core\collections +Misc01 Libraries\Core\ExtraTopLevelOperators +Misc01 Libraries\Core\LanguagePrimitives +Misc01 Libraries\Core\NativeInterop\stackalloc +Misc01 Libraries\Core\Operators +Misc01 Libraries\Core\Reflection +Misc01 Libraries\Core\Unchecked +Misc01 Warnings + +Misc02 Libraries\Portable +Misc02 Misc +Misc02 MultiTargeting +Misc02 OCamlCompat +Misc02,CodeGen Optimizations\AssemblyBoundary +Misc02,CodeGen Optimizations\ForLoop +Misc02,CodeGen Optimizations\GenericComparison +Misc02,CodeGen Optimizations\Inlining +Misc02,NoMT Printing +Misc02 ..\..\..\testsprivate\fsharpqa\Source\RealWorld\UnitsOfMeasure +Misc02 ..\..\..\testsprivate\fsharpqa\Source\RealWorld\Agents +Misc02,NoMT ..\..\..\testsprivate\fsharpqa\Source\Setup +Misc02 Stress +Misc02 XmlDoc\Basic +Misc02 XmlDoc\OCamlDoc +Misc02 XmlDoc\UnitOfMeasure From b2f3aa1d887b2be5c1575528b4a4f6418f3ab096 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Sun, 28 Jun 2020 21:36:29 -0700 Subject: [PATCH 44/60] Re enable tests for operators: OperatorsModule1.fs and OperatorsModule2.fs (#9516) (#9590) * Re-enabling tests from OperatorsModule1/2.fs (compile errors) * Fix compile errors in OperatorsModule1/2.fs, fix tests. Note tanh test comment. * Fix `tanh` test, ensure stable result on x86 vs x64 runtimes * Stop using exception AssertionException, so that test window shows useful info * Whitespace cleanup and redundant code removal * Cleanup spelling etc * Re-enabling int, int16, int32, int64, nativeint, incr, nullArg etc tests * Special-case floating-point assertion messages for higher precision output * Fix/update/add tests (some still failing) * Separate Checked tests, add & fix others, differentiate framework/bitness for some tests * Add branch for .NET Native (ignore cos test) * Resorting to comparing floats with a delta using Assert.AreNearEqual * Add some more tests Co-authored-by: Abel Braaksma From 4bfe004ea73be426ca6203abf779e94e3cb0b421 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Mon, 29 Jun 2020 02:46:50 -0700 Subject: [PATCH 45/60] more tests --- src/fsharp/PostInferenceChecks.fs | 113 +++++++++++------- ...fs => E_ObjExprWithSameInterface01.4.7.fs} | 2 +- .../E_ObjExprWithSameInterface01.5.0.fs | 20 ++++ .../DataExpressions/ObjectExpressions/env.lst | 3 +- ...ClassConsumeMultipleInterfaceFromCS.5.0.fs | 20 ++++ ... => ConsumeMultipleInterfaceFromCS.5.0.fs} | 0 ...lassConsumeMultipleInterfaceFromCS.4.7.fs} | 9 +- .../E_ConsumeMultipleInterfaceFromCS.4.7.fs | 67 +++++++++++ ...> E_ConsumeMultipleInterfaceFromCS.5.0.fs} | 0 .../E_ImplementGenIFaceTwice01_4.7.fs | 10 +- .../E_ImplementGenIFaceTwice02_4.7.fs | 7 +- .../InterfaceTypes/E_MultipleInst01.4.7.fs | 13 ++ ...tipleInst04.fs => E_MultipleInst04.4.7.fs} | 2 +- ...tipleInst07.fs => E_MultipleInst07.4.7.fs} | 2 +- ...tipleInst08.fs => E_MultipleInst07.5.0.fs} | 0 .../InterfaceTypes/MultipleInst01.5.0.fs | 10 ++ .../InterfaceTypes/MultipleInst01.fs | 13 -- .../InterfaceTypes/MultipleInst04.5.0.fs | 15 +++ .../InterfaceTypes/env.lst | 62 +++++----- tests/fsharpqa/Source/test.lst | 1 - 20 files changed, 266 insertions(+), 103 deletions(-) rename tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/{E_ObjExprWithSameInterface01.fs => E_ObjExprWithSameInterface01.4.7.fs} (68%) create mode 100644 tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.5.0.fs create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ClassConsumeMultipleInterfaceFromCS.5.0.fs rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{ConsumeMultipleInterfaceFromCS.fs => ConsumeMultipleInterfaceFromCS.5.0.fs} (100%) rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{E_ClassConsumeMultipleInterfaceFromCS.fs => E_ClassConsumeMultipleInterfaceFromCS.4.7.fs} (60%) create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.4.7.fs rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{E_ConsumeMultipleInterfaceFromCS.fs => E_ConsumeMultipleInterfaceFromCS.5.0.fs} (100%) create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst01.4.7.fs rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{MultipleInst04.fs => E_MultipleInst04.4.7.fs} (64%) rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{E_MultipleInst07.fs => E_MultipleInst07.4.7.fs} (63%) rename tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/{E_MultipleInst08.fs => E_MultipleInst07.5.0.fs} (100%) create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.5.0.fs delete mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs create mode 100644 tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.5.0.fs diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 8e5fc72c1af..f3dc323b6b3 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -707,49 +707,80 @@ let compareTypesWithRegardToTypeVariablesAndMeasures g amap m typ1 typ2 = else NotEqual +//let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list) isObjectExpression m = +// let keyf ty = assert isAppTy cenv.g ty; (tcrefOfAppTy cenv.g ty).Stamp +// if not(cenv.g.langVersion.SupportsFeature LanguageFeature.InterfacesWithMultipleGenericInstantiation) then +// let table = interfaces |> MultiMap.initBy keyf +// let firstInterfaceWithMultipleGenericInstantiations = +// interfaces |> List.tryPick (fun typ1 -> +// table |> MultiMap.find (keyf typ1) |> List.tryPick (fun typ2 -> +// if // same nominal type +// tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && +// // different instantiations +// not (typeEquivAux EraseNone cenv.g typ1 typ2) +// then Some (typ1, typ2) +// else None)) +// match firstInterfaceWithMultipleGenericInstantiations with +// | None -> () +// | Some (typ1, typ2) -> +// let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 +// let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 +// errorR(Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations(typ1Str, typ2Str), m)) +// else +// let groups = interfaces |> List.groupBy keyf +// let errors = seq { +// for (_, items) in groups do +// for i1 in 0 .. items.Length - 1 do +// for i2 in i1 + 1 .. items.Length - 1 do +// let typ1 = items.[i1] +// let typ2 = items.[i2] +// match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g cenv.amap m typ1 typ2 with +// | ExactlyEqual -> () // exact duplicates are checked in another place +// | FeasiblyEqual -> +// let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 +// let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 +// if isObjectExpression then +// yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariableObjectExpression(tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) +// else +// let typStr = NicePrint.minimalStringOfType cenv.denv typ +// yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) +// | NotEqual -> () +// } +// match Seq.tryHead errors with +// | None -> () +// | Some e -> errorR(e) + let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list) isObjectExpression m = let keyf ty = assert isAppTy cenv.g ty; (tcrefOfAppTy cenv.g ty).Stamp - if not(cenv.g.langVersion.SupportsFeature LanguageFeature.InterfacesWithMultipleGenericInstantiation) then - let table = interfaces |> MultiMap.initBy keyf - let firstInterfaceWithMultipleGenericInstantiations = - interfaces |> List.tryPick (fun typ1 -> - table |> MultiMap.find (keyf typ1) |> List.tryPick (fun typ2 -> - if // same nominal type - tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && - // different instantiations - not (typeEquivAux EraseNone cenv.g typ1 typ2) - then Some (typ1, typ2) - else None)) - match firstInterfaceWithMultipleGenericInstantiations with - | None -> () - | Some (typ1, typ2) -> - let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 - let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 - errorR(Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations(typ1Str, typ2Str), m)) - else - let groups = interfaces |> List.groupBy keyf - let errors = seq { - for (_, items) in groups do - for i1 in 0 .. items.Length - 1 do - for i2 in i1 + 1 .. items.Length - 1 do - let typ1 = items.[i1] - let typ2 = items.[i2] - let tcRef1 = tcrefOfAppTy cenv.g typ1 - match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g cenv.amap m typ1 typ2 with - | ExactlyEqual -> () // exact duplicates are checked in another place - | FeasiblyEqual -> - let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 - let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 - if isObjectExpression then - yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariableObjectExpression(tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) - else - let typStr = NicePrint.minimalStringOfType cenv.denv typ - yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) - | NotEqual -> () - } - match Seq.tryHead errors with - | None -> () - | Some e -> errorR(e) + let groups = interfaces |> List.groupBy keyf + let errors = seq { + for (_, items) in groups do + for i1 in 0 .. items.Length - 1 do + for i2 in i1 + 1 .. items.Length - 1 do + let typ1 = items.[i1] + let typ2 = items.[i2] + let tcRef1 = tcrefOfAppTy cenv.g typ1 + match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g cenv.amap m typ1 typ2 with + | ExactlyEqual -> () + | FeasiblyEqual -> + match tryLanguageFeatureErrorOption cenv.g.langVersion LanguageFeature.InterfacesWithMultipleGenericInstantiation m with + | None -> () + | Some e -> yield e + let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 + let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 + if isObjectExpression then + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariableObjectExpression(tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + else + let typStr = NicePrint.minimalStringOfType cenv.denv typ + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + | NotEqual -> + match tryLanguageFeatureErrorOption cenv.g.langVersion LanguageFeature.InterfacesWithMultipleGenericInstantiation m with + | None -> () + | Some e -> yield e + } + match Seq.tryHead errors with + | None -> () + | Some e -> errorR(e) /// Check an expression, where the expression is in a position where byrefs can be generated let rec CheckExprNoByrefs cenv env expr = diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.4.7.fs similarity index 68% rename from tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs rename to tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.4.7.fs index 45f0de9b487..f579046fc7f 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.4.7.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DataExpressions #ObjectConstructors // This was Dev10:854519 and Dev11:5525. The fix was to make this a compile error to avoid a runtime exception. -//This type implements the same interface at different generic instantiations 'IQueue<'T>' and 'IQueue'\. This is not permitted in this version of F#\.$ +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. type IQueue<'a> = abstract Addd: 'a -> IQueue<'a> diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.5.0.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.5.0.fs new file mode 100644 index 00000000000..8a47580aaf8 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.5.0.fs @@ -0,0 +1,20 @@ +// #Regression #Conformance #DataExpressions #ObjectConstructors +// This was Dev10:854519 and Dev11:5525. The fix was to make this a compile error to avoid a runtime exception. +//You cannot implement the interface 'IQueue<_>' with the two instantiations 'IQueue<'T>' and 'IQueue' because they may unify. + +type IQueue<'a> = + abstract Addd: 'a -> IQueue<'a> + +type IQueueEx<'a> = + inherit IQueue<'a> + abstract Add: 'a -> IQueueEx<'a> + +let makeQueueEx2() = + {new IQueueEx<'T> with + member q.Add(x) = q + interface IQueue with + member q.Addd(x) = q } + +makeQueueEx2() |> ignore + +exit 1 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst index 5b5ecc0f1bf..282455a255b 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst @@ -17,5 +17,6 @@ SOURCE=ObjExprWithOverride01.fs # ObjExprWithOverride01.fs SOURCE=E_ObjExprWithOverride01.fs SCFLAGS="-r:Helper.dll --test:ErrorRanges" PRECMD="\$CSC_PIPE /t:library Helper.cs" # E_ObjExprWithOverride01.fs SOURCE=InterfaceObjectExpression01.fs # InterfaceObjectExpression01.fs - SOURCE=E_ObjExprWithSameInterface01.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_ObjExprWithSameInterface01.fs + SOURCE=E_ObjExprWithSameInterface01.4.7.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_ObjExprWithSameInterface01.4.7.fs + SOURCE=E_ObjExprWithSameInterface01.5.0.fs SCFLAGS="--test:ErrorRanges --langversion:preview" # E_ObjExprWithSameInterface01.5.0.fs SOURCE=MultipleInterfacesInObjExpr.fs # MultipleInterfacesInObjExpr.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ClassConsumeMultipleInterfaceFromCS.5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ClassConsumeMultipleInterfaceFromCS.5.0.fs new file mode 100644 index 00000000000..ec6bc99e266 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ClassConsumeMultipleInterfaceFromCS.5.0.fs @@ -0,0 +1,20 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT +#light + +let mutable res = true + +type D() = + inherit T() + interface I_003 with + member xxx.Home(i) = i + +if (D() :> I_003).Home(5) <> 5 then + System.Console.WriteLine("D.Home failed") + res <- false + + +if (res = true) then + exit 0 + +exit 1 + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ConsumeMultipleInterfaceFromCS.5.0.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ConsumeMultipleInterfaceFromCS.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ConsumeMultipleInterfaceFromCS.5.0.fs diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.4.7.fs similarity index 60% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.4.7.fs index ed87e24dbda..244042abc53 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.4.7.fs @@ -1,6 +1,6 @@ // #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT -// This type implements the same interface at different generic instantiations 'I_002\' and 'I_002\'\. This is not permitted in this version of F#\. -#light +// Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. +#light let mutable res = true @@ -11,13 +11,12 @@ type D() = member xxx.Home(i) = i if (D() :> I_003).Home(5) <> 5 then - System.Console.WriteLine("D.Home failed") + System.Console.WriteLine("D.Home failed") res <- false if (res = true) then exit 0 - - + exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.4.7.fs new file mode 100644 index 00000000000..8be65e7fcc2 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.4.7.fs @@ -0,0 +1,67 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT +// Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. +// Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. +// Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. +#light + +let mutable res = true +let t = new T() +if (t.Me("F#") <> 2) then + System.Console.WriteLine("t.Me(string) failed") + res <- false + +if (t.Me('a') <> 1) then + System.Console.WriteLine("t.Me(char) failed") + res <- false + +if (t.Home(0) <> 0) then + System.Console.WriteLine("t.Home failed") + res <- false + +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression implementing a C# interface type +if ( {new I_003 with + member xxx.Home(i) = i + member xxx.Me(c:char) = 0 + member xxx.Me(s:string) = 0 + }.Home ( + {new I_002 with + member x.Me (s) = s + }.Me(0) ) <> 0 ) then + System.Console.WriteLine("I_003.Home failed") + res <- false + +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type +if (({new T() with + member x.ToString() = "a" + interface I_003 with + member xxx.Home(i) = i + member xxx.Me(c:char) = 0 + member xxx.Me(s:string) = 0 + } :> I_003).Home ( + {new I_002 with + member x.Me (s) = s + }.Me(0) ) <> 0 ) then + System.Console.WriteLine("T.Home obj expr failed") + res <- false + +// Check we can create an object of a C# type implementing multiple instantiations of an interface +if T().Home(4) <> 0 then + System.Console.WriteLine("T.Home failed") + res <- false + + +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type +type D() = + inherit T() + interface I_003 with + member xxx.Home(i) = i + +if (D() :> I_003).Home(5) <> 5 then + System.Console.WriteLine("D.Home failed") + res <- false + + +if (res = true) then + exit 0 +exit 1 + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.5.0.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.5.0.fs diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs index 0a861b8cddb..1a9cf23b6c8 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs @@ -1,11 +1,9 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations - - // Verify error when trying to implement the same generic interface twice. // Regression for FSB 3574, PE Verification failure when implementing multiple generic interfaces (one generic, one specifc) -//This type implements the same interface at different generic instantiations 'IA' and 'IA<'b>'. This is not permitted in this version of F#. +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. -type IA<'b> = +type IA<'b> = interface abstract Foo : int -> int end @@ -14,14 +12,14 @@ type IB<'b> = inherit IA<'b> inherit IA end - + type A() = class interface IB with member obj.Foo (x : int) = x end end - + let x = A() exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs index b8cf023508a..adbbffd0eac 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs @@ -1,7 +1,6 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// Verify error when trying to implement the same generic -// interface twice -//This type implements the same interface at different generic instantiations 'IFoo' and 'IFoo'. This is not permitted in this version of F#. +// Verify error when trying to implement the same generic interface twice +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. type IFoo<'a> = interface @@ -19,4 +18,4 @@ let t = new Bar() (t :> IFoo).DoStuff() (t :> IFoo).DoStuff() -exit 1 +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst01.4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst01.4.7.fs new file mode 100644 index 00000000000..3c8530813b8 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst01.4.7.fs @@ -0,0 +1,13 @@ +// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// Regression test for FSHARP1.0:5540 +// Prior to F# 5.0 it was forbidden to implement an interface at multiple instantiations +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. + +type IA<'a> = + interface + //abstract X : unit -> 'a + end + +type C() = + interface IA + interface IA diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst04.4.7.fs similarity index 64% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst04.4.7.fs index f1a2bc33753..b559e895698 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst04.4.7.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations // Regression test for FSHARP1.0:5540 // It is forbidden to implement an interface at multiple instantiations -//This type implements the same interface at different generic instantiations 'IA' and 'IA'\. This is not permitted in this version of F#\.$ +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. type IA<'a, 'b> = diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.4.7.fs similarity index 63% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.4.7.fs index 965ccfe6055..316919a0297 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.4.7.fs @@ -1,7 +1,7 @@ // #Conformance #ObjectOrientedTypes #InterfacesAndImplementations // Aliased types should correctly unify, even in combination with a measure. -//This type implements the same interface at different generic instantiations 'IB' and 'IB>'. This is not permitted in this version of F#. +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater. type MyInt = int [] type kg diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst08.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.5.0.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst08.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.5.0.fs diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.5.0.fs new file mode 100644 index 00000000000..762f164bd9f --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.5.0.fs @@ -0,0 +1,10 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations + +type IA<'a> = + interface + //abstract X : unit -> 'a + end + +type C() = + interface IA + interface IA diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs deleted file mode 100644 index 057d2da039d..00000000000 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs +++ /dev/null @@ -1,13 +0,0 @@ -// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// Regression test for FSHARP1.0:5540 -// It is forbidden to implement an interface at multiple instantiations -//This type implements the same interface at different generic instantiations 'IA' and 'IA'\. This is not permitted in this version of F#\.$ - -type IA<'a> = - interface - //abstract X : unit -> 'a - end - -type C() = - interface IA - interface IA diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.5.0.fs new file mode 100644 index 00000000000..85769553a57 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.5.0.fs @@ -0,0 +1,15 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations + +type IA<'a, 'b> = + interface + abstract X : 'a -> 'b + end + +type C<'a>() = + interface IA with + member m.X(x) = 'a' + + interface IA with + member m.X(c) = 10 + + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst index 00ebd538279..8b359f887c1 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst @@ -1,42 +1,46 @@ - SOURCE=E_InheritInterface.fs SCFLAGS=--test:ErrorRanges # E_InheritInterface.fs + SOURCE=E_InheritInterface.fs SCFLAGS=--test:ErrorRanges # E_InheritInterface.fs - SOURCE=TwoInstantiationOfTheSameInterface.fs COMPILE_ONLY=1 PRECMD="\$CSC_PIPE /t:library TwoInstantiationOfTheSameInterfaceDLL.cs" SCFLAGS=-r:TwoInstantiationOfTheSameInterfaceDLL.dll # TwoInstantiationOfTheSameInterface.fs + SOURCE=TwoInstantiationOfTheSameInterface.fs COMPILE_ONLY=1 PRECMD="\$CSC_PIPE /t:library TwoInstantiationOfTheSameInterfaceDLL.cs" SCFLAGS=-r:TwoInstantiationOfTheSameInterfaceDLL.dll # TwoInstantiationOfTheSameInterface.fs - SOURCE=ObjImplementsInterfaceGenWithConstraint.fs COMPILE_ONLY=1 # ObjImplementsInterfaceGenWithConstraint.fs + SOURCE=ObjImplementsInterfaceGenWithConstraint.fs COMPILE_ONLY=1 # ObjImplementsInterfaceGenWithConstraint.fs - SOURCE=InterfaceMember_NameCollisions.fs SCFLAGS=--test:ErrorRanges # InterfaceMember_NameCollisions.fs + SOURCE=InterfaceMember_NameCollisions.fs SCFLAGS=--test:ErrorRanges # InterfaceMember_NameCollisions.fs - SOURCE=MultipleInst01.fs SCFLAGS=--test:ErrorRanges # MultipleInst01.fs + SOURCE=E_MultipleInst01.4.7.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_MultipleInst01.4.7.fs + SOURCE=MultipleInst01.5.0.fs SCFLAGS="--test:ErrorRanges --langversion:preview" # MultipleInst01.5.0.fs SOURCE=MultipleInst02.fs SCFLAGS=--test:ErrorRanges # MultipleInst02.fs SOURCE=MultipleInst03.fs SCFLAGS=--test:ErrorRanges # MultipleInst03.fs - SOURCE=MultipleInst04.fs SCFLAGS=--test:ErrorRanges # MultipleInst04.fs + SOURCE=E_MultipleInst04.4.7.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_MultipleInst04.4.7.fs + SOURCE=MultipleInst04.5.0.fs SCFLAGS=--test:ErrorRanges --langversion:preview" # MultipleInst04.5.0.fs SOURCE=MultipleInst05.fs SCFLAGS=--test:ErrorRanges # MultipleInst05.fs SOURCE=MultipleInst06.fs SCFLAGS="--test:ErrorRanges" # MultipleInst06.fs - SOURCE=E_MultipleInst07.fs SCFLAGS="--test:ErrorRanges --langversion:4.7 --nowarn:221" # E_MultipleInst07.fs - SOURCE=E_MultipleInst08.fs SCFLAGS="--test:ErrorRanges --langversion:preview --nowarn:221" # E_MultipleInst08.fs + SOURCE=E_MultipleInst07.4.7.fs SCFLAGS="--test:ErrorRanges --langversion:4.7 --nowarn:221" # E_MultipleInst07.4.7.fs + SOURCE=E_MultipleInst07.5.0.fs SCFLAGS="--test:ErrorRanges --langversion:preview --nowarn:221" # E_MultipleInst07.5.0.fs SOURCE=Inheritance_OverrideInterface.fs SCFLAGS="--test:ErrorRanges --langversion:preview" # Inheritance_OverrideInterface.fs - SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs - SOURCE=E_InterfaceNotFullyImpl01.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl01.fs - SOURCE=E_InterfaceNotFullyImpl02.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl02.fs - SOURCE=E_InterfaceNotFullyImpl03.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl03.fs - - SOURCE=InheritedInterface.fs # InheritedInterface - SOURCE=ObjImplementsInterface.fs # ObjImplementsInterface.fs - SOURCE=interface001.fs # interface001.fs - SOURCE=interface002.fs # interface002.fs - SOURCE=interface001e.fs SCFLAGS="--test:ErrorRanges" # interface001e.fs - SOURCE=interface002e.fs # interface002e.fs - SOURCE=interface003.fs # interface003.fs - - SOURCE=ConsumeFromCS.fs POSTCMD="\$CSC_PIPE -r:ConsumeFromCS.dll CallFSharpInterface.cs && CallFSharpInterface.exe" SCFLAGS=-a # ConsumeFromCS.fs -NoMT SOURCE=CallCSharpInterface.fs PRECMD="\$CSC_PIPE /t:library ConsumeFromFS.cs" SCFLAGS="-r:ConsumeFromFS.dll" # CallCSharpInterface.fs - - SOURCE=E_MultipleInterfaceInheritance.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_MultipleInterfaceInheritance.fs - -NoMT SOURCE=ConsumeMultipleInterfaceFromCS.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll" # ConsumeMultipleInterfaceFromCS.fs -NoMT SOURCE=E_ConsumeMultipleInterfaceFromCS.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges" # E_ConsumeMultipleInterfaceFromCS.fs -NoMT SOURCE=E_ClassConsumeMultipleInterfaceFromCS.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges" # E_ClassConsumeMultipleInterfaceFromCS.fs + SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs + SOURCE=E_InterfaceNotFullyImpl01.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl01.fs + SOURCE=E_InterfaceNotFullyImpl02.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl02.fs + SOURCE=E_InterfaceNotFullyImpl03.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl03.fs + + SOURCE=InheritedInterface.fs # InheritedInterface + SOURCE=ObjImplementsInterface.fs # ObjImplementsInterface.fs + SOURCE=interface001.fs # interface001.fs + SOURCE=interface002.fs # interface002.fs + SOURCE=interface001e.fs SCFLAGS="--test:ErrorRanges" # interface001e.fs + SOURCE=interface002e.fs # interface002e.fs + SOURCE=interface003.fs # interface003.fs + + SOURCE=ConsumeFromCS.fs POSTCMD="\$CSC_PIPE -r:ConsumeFromCS.dll CallFSharpInterface.cs && CallFSharpInterface.exe" SCFLAGS=-a # ConsumeFromCS.fs +NoMT SOURCE=CallCSharpInterface.fs PRECMD="\$CSC_PIPE /t:library ConsumeFromFS.cs" SCFLAGS="-r:ConsumeFromFS.dll" # CallCSharpInterface.fs + + SOURCE=E_MultipleInterfaceInheritance.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_MultipleInterfaceInheritance.fs + +NoMT SOURCE=E_ConsumeMultipleInterfaceFromCS.4.7.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges --langversion:4.7" # E_ConsumeMultipleInterfaceFromCS.4.7.fs +NoMT SOURCE=ConsumeMultipleInterfaceFromCS.5.0.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --langversion:preview" # ConsumeMultipleInterfaceFromCS.5.0.fs + +NoMT SOURCE=E_ClassConsumeMultipleInterfaceFromCS.4.7.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges --langversion:4.7" # E_ClassConsumeMultipleInterfaceFromCS.4.7.fs +NoMT SOURCE=ClassConsumeMultipleInterfaceFromCS.5.0.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges --langversion:preview" # ClassConsumeMultipleInterfaceFromCS.5.0.fs SOURCE="E_ImplementGenIFaceTwice01_4.7.fs" SCFLAGS="--test:ErrorRanges --langversion:4.7 --nowarn:221" # E_ImplementGenIFaceTwice01_4.7.fs SOURCE="E_ImplementGenIFaceTwice01_5.0.fs" SCFLAGS="--test:ErrorRanges --langversion:preview --nowarn:221" # E_ImplementGenIFaceTwice01_5.0.fs diff --git a/tests/fsharpqa/Source/test.lst b/tests/fsharpqa/Source/test.lst index 95afc5893b4..c507f9585b1 100644 --- a/tests/fsharpqa/Source/test.lst +++ b/tests/fsharpqa/Source/test.lst @@ -31,7 +31,6 @@ CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Tuples CodeGen01,NoMT,CodeGen CodeGen\StringEncoding CodeGen01,NoMT,CodeGen CodeGen\Structure - CompilerOptions01,NoMT CompilerOptions\fsc\checked CompilerOptions01,NoMT CompilerOptions\fsc\cliversion CompilerOptions01,NoMT CompilerOptions\fsc\codepage From b4e71475ae0012d6df6fcc14fea505bcfe90ade2 Mon Sep 17 00:00:00 2001 From: Thorsten Reichert Date: Mon, 29 Jun 2020 20:18:23 +0200 Subject: [PATCH 46/60] Moved fsharpqa/Libraries/Core/Unchecked test cases to NUnit (#9576) --- .../Core/Unchecked/DefaultOfTests.fs | 63 +++++++++++++++++++ tests/fsharp/FSharpSuite.Tests.fsproj | 1 + .../Libraries/Core/Unchecked/DefaultOf01.fs | 51 --------------- .../Libraries/Core/Unchecked/DefaultOf02.fs | 17 ----- .../Source/Libraries/Core/Unchecked/env.lst | 2 - 5 files changed, 64 insertions(+), 70 deletions(-) create mode 100644 tests/fsharp/Compiler/Libraries/Core/Unchecked/DefaultOfTests.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf01.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf02.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Unchecked/env.lst diff --git a/tests/fsharp/Compiler/Libraries/Core/Unchecked/DefaultOfTests.fs b/tests/fsharp/Compiler/Libraries/Core/Unchecked/DefaultOfTests.fs new file mode 100644 index 00000000000..7c732e479ad --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Unchecked/DefaultOfTests.fs @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``DefaultOf Tests`` = + + type DUType = + | A + | B of int + | C of DUType * DUType + + type RecordType = { A : int; B : string; C : DUType } + + type ClassType = string + + type InterfaceType = + abstract DoStuff : unit -> unit + + type EnumType = + | A = 1 + | B = 2 + | C = 4 + + type StructType = struct + val m_ivalue : int + val m_svalue : string + member this.IValue = this.m_ivalue + member this.SValue = this.m_svalue + end + + [] + let `` Unchecked defaultof reference types``() = + Assert.areEqual Unchecked.defaultof null + Assert.areEqual (box Unchecked.defaultof) null + Assert.areEqual (box Unchecked.defaultof) null + Assert.areEqual (box Unchecked.defaultof) null + + [] + let ``Unchecked defaultof stack types``() = + Assert.areEqual Unchecked.defaultof 0 + Assert.areEqual Unchecked.defaultof 0.0 + Assert.areEqual Unchecked.defaultof (enum 0) + Assert.areEqual Unchecked.defaultof.IValue 0 + Assert.areEqual Unchecked.defaultof.SValue null + + type R = { x : int; y : string } + type U = | A of int | B of string + type S = struct val mutable x : int end + type C() = class end + + [] + let ``Unchecked defaultof and equality``() = + // FSharp1.0:5417 - Unchecked.defaultof<_> on records/unions can cause structural equality check to throw + // Check that Unchecked.defaultof<_> works correctly on various types, mostly structs/unions/records + + Assert.areEqual Unchecked.defaultof Unchecked.defaultof + Assert.areEqual Unchecked.defaultof Unchecked.defaultof + Assert.areEqual Unchecked.defaultof Unchecked.defaultof + Assert.areEqual Unchecked.defaultof Unchecked.defaultof + Assert.areEqual Unchecked.defaultof Unchecked.defaultof \ No newline at end of file diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index b06425e88dc..3153783ff71 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -75,6 +75,7 @@ + diff --git a/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf01.fs b/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf01.fs deleted file mode 100644 index 196448fc4bf..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf01.fs +++ /dev/null @@ -1,51 +0,0 @@ -// #Regression #Libraries #Unchecked -#light - -// 1760, Implement Unchecked.defaultof<_> (delete LanguagePrimitives.DefaultValueUnchecked) - -// Test the 'defaultof<_>' function - -// Reference types --------------------------- -type DUType = - | A - | B of int - | C of DUType * DUType - -type RecordType = { A : int; B : string; C : DUType } - -type ClassType = string - -type InterfaceType = - abstract DoStuff : unit -> unit - -// Stack types ------------------------------- -type EnumType = - | A = 1 - | B = 2 - | C = 4 - -type StructType = struct - val m_ivalue : int - val m_svalue : string - member this.IValue = this.m_ivalue - member this.SValue = this.m_svalue -end - -// Test reference types -if Unchecked.defaultof <> null then exit 1 -// This behaivor for DU, Records, and Interfaces is bey design (need to box to get null) -if box(Unchecked.defaultof) <> null then exit 1 -if box(Unchecked.defaultof) <> null then exit 1 -if box(Unchecked.defaultof) <> null then exit 1 - -let p = Unchecked.defaultof - -// Test stack types -if Unchecked.defaultof <> 0 then exit 1 -if Unchecked.defaultof <> 0.0 then exit 1 -if Unchecked.defaultof <> enum 0 then exit 1 - -if (Unchecked.defaultof).IValue <> 0 then exit 1 -if (Unchecked.defaultof).SValue <> null then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf02.fs b/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf02.fs deleted file mode 100644 index 00414dd8cc8..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf02.fs +++ /dev/null @@ -1,17 +0,0 @@ -// #Regression #Libraries #Unchecked -#light - -// FSharp1.0:5417 - Unchecked.defaultof<_> on records/unions can cause structural equality check to throw -// Check that Unchecked.defaultof<_> works correctly on various types, mostly structs/unions/records - -type R = { x : int; y : string } -type U = | A of int | B of string -type S = struct val mutable x : int end -type C() = class end - -let shouldBeTrue = - Unchecked.defaultof = Unchecked.defaultof // Records as null - && Unchecked.defaultof = Unchecked.defaultof // Unions as null - && Unchecked.defaultof = Unchecked.defaultof // Structs as null - && Unchecked.defaultof = Unchecked.defaultof // Classes as null - && Unchecked.defaultof = Unchecked.defaultof diff --git a/tests/fsharpqa/Source/Libraries/Core/Unchecked/env.lst b/tests/fsharpqa/Source/Libraries/Core/Unchecked/env.lst deleted file mode 100644 index b5cefff3c2e..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Unchecked/env.lst +++ /dev/null @@ -1,2 +0,0 @@ - SOURCE=DefaultOf01.fs # DefaultOf01 - SOURCE=DefaultOf02.fs # DefaultOf02 \ No newline at end of file From bd8721ff3d246070c82899a6b1793473ca6acb54 Mon Sep 17 00:00:00 2001 From: Thorsten Reichert Date: Fri, 3 Jul 2020 12:05:22 +0200 Subject: [PATCH 47/60] Moved fsharpqa/Libraries/Core/Reflectiontest cases to NUnit (#9611) * Migrated PreComputedTupleConstructor01.fs test case * Migrated PreComputedTupleConstructor02.fs test case * Migrated DU.fs and Record.fs test cases --- .../PreComputedTupleConstructorTests.fs | 28 +++++++++++++++++++ .../Libraries/Core/Reflection/SprintfTests.fs | 28 +++++++++++++++++++ tests/fsharp/FSharpSuite.Tests.fsproj | 2 ++ .../Source/Libraries/Core/Reflection/DU.fs | 10 ------- .../PreComputeTupleConstructor01.fs | 12 -------- .../PreComputeTupleConstructor02.fs | 12 -------- .../Libraries/Core/Reflection/Record.fs | 10 ------- .../Source/Libraries/Core/Reflection/env.lst | 4 --- 8 files changed, 58 insertions(+), 48 deletions(-) create mode 100644 tests/fsharp/Compiler/Libraries/Core/Reflection/PreComputedTupleConstructorTests.fs create mode 100644 tests/fsharp/Compiler/Libraries/Core/Reflection/SprintfTests.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Reflection/DU.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor01.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor02.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Reflection/Record.fs delete mode 100644 tests/fsharpqa/Source/Libraries/Core/Reflection/env.lst diff --git a/tests/fsharp/Compiler/Libraries/Core/Reflection/PreComputedTupleConstructorTests.fs b/tests/fsharp/Compiler/Libraries/Core/Reflection/PreComputedTupleConstructorTests.fs new file mode 100644 index 00000000000..cd24ea20106 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Reflection/PreComputedTupleConstructorTests.fs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``PreComputedTupleConstructor Tests`` = + + [] + let ``PreComputedTupleConstructor of int and string``() = + // Regression test for FSHARP1.0:5113 + // MT DCR: Reflection.FSharpValue.PreComputeTupleConstructor fails when executed for NetFx 2.0 by a Dev10 compiler + + let testDelegate = TestDelegate (fun () -> + Reflection.FSharpValue.PreComputeTupleConstructor(typeof) [| box 12; box "text" |] |> ignore) + + Assert.DoesNotThrow testDelegate |> ignore + + [] + let ``PreComputedTupleConstructor with wrong order of arguments``() = + // Regression test for FSHARP1.0:5113 + // MT DCR: Reflection.FSharpValue.PreComputeTupleConstructor fails when executed for NetFx 2.0 by a Dev10 compiler + + let testDelegate = TestDelegate (fun () -> + Reflection.FSharpValue.PreComputeTupleConstructor(typeof) [| box "text"; box 12; |] |> ignore) + + Assert.Throws testDelegate |> ignore \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Reflection/SprintfTests.fs b/tests/fsharp/Compiler/Libraries/Core/Reflection/SprintfTests.fs new file mode 100644 index 00000000000..67ea1baa1bb --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Reflection/SprintfTests.fs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Sprintf Tests`` = + + type MyR = {c:int;b:int;a:int} + + [] + let ``Sprintf %A of record type``() = + // Regression test for FSHARP1.0:5113 + + let s1 = sprintf "%A" {a=1;b=2;c=3} + let s2 = sprintf "%A" {c=3;b=2;a=1} + + Assert.areEqual s1 s2 + + type MyT = MyC of int * string * bool + + [] + let ``Sprintf %A of discriminated union type``() = + // Regression test for FSHARP1.0:5113 + + let DU = MyC (1,"2",true) + Assert.areEqual "MyC (1, \"2\", true)" (sprintf "%A" DU) \ No newline at end of file diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index 3153783ff71..a9d05e1fb76 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -75,6 +75,8 @@ + + diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/DU.fs b/tests/fsharpqa/Source/Libraries/Core/Reflection/DU.fs deleted file mode 100644 index 74f709d760e..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/DU.fs +++ /dev/null @@ -1,10 +0,0 @@ -// #Regression #Libraries #Reflection -// Regression test for FSHARP1.0:5113 - -type MyT = MyC of int * string * bool - -let DU = MyC (1,"2",true) - -printfn "%A" DU - -(if (sprintf "%A" DU) = "MyC (1, \"2\", true)" then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor01.fs b/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor01.fs deleted file mode 100644 index 0b179241cec..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor01.fs +++ /dev/null @@ -1,12 +0,0 @@ -// #Regression #Libraries #Reflection -// Regression test for FSHARP1.0:5113 -// MT DCR: Reflection.FSharpValue.PreComputeTupleConstructor fails when executed for NetFx 2.0 by a Dev10 compiler - -let test1 = try - Reflection.FSharpValue.PreComputeTupleConstructor(typeof) [| box 12; box "text" |] |> ignore - true - with - | _ -> false - - -(if test1 then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor02.fs b/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor02.fs deleted file mode 100644 index 50b1d7bad63..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor02.fs +++ /dev/null @@ -1,12 +0,0 @@ -// #Regression #Libraries #Reflection -// Regression test for FSHARP1.0:5113 -// MT DCR: Reflection.FSharpValue.PreComputeTupleConstructor fails when executed for NetFx 2.0 by a Dev10 compiler - -let test1 = try - Reflection.FSharpValue.PreComputeTupleConstructor(typeof) [| box "text"; box 12; |] |> ignore - false - with - | _ -> true // yes, we expect the call above to throw since the types are swapped! - - -(if test1 then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/Record.fs b/tests/fsharpqa/Source/Libraries/Core/Reflection/Record.fs deleted file mode 100644 index 8c780033a77..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/Record.fs +++ /dev/null @@ -1,10 +0,0 @@ -// #Regression #Libraries #Reflection -// Regression test for FSHARP1.0:5113 - -type MyR = {c:int;b:int;a:int} - -let s1 = sprintf "%A" {a=1;b=2;c=3} -let s2 = sprintf "%A" {c=3;b=2;a=1} - -(if s1 = s2 then 0 else 1) |> exit - diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/env.lst b/tests/fsharpqa/Source/Libraries/Core/Reflection/env.lst deleted file mode 100644 index bf3361d68e3..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/env.lst +++ /dev/null @@ -1,4 +0,0 @@ - SOURCE=DU.fs # DU.fs - SOURCE=PreComputeTupleConstructor01.fs # PreComputeTupleConstructor01.fs - SOURCE=PreComputeTupleConstructor02.fs # PreComputeTupleConstructor02.fs - SOURCE=Record.fs # Record.fs From da84a19e4f4655f811dd63624db3c3f918e9489e Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Fri, 3 Jul 2020 06:45:21 -0700 Subject: [PATCH 48/60] Allow notebook to discover location of shared framework (#9596) --- .../FSharp.DependencyManager.Utilities.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs index d6aad41fe5d..e16dacc71f6 100644 --- a/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs +++ b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs @@ -126,12 +126,12 @@ module internal Utilities = | value when not (String.IsNullOrEmpty(value)) -> Some value // Value set externally | _ -> - // Probe for netsdk install + // Probe for netsdk install, dotnet. and dotnet.exe is a constant offset from the location of System.Int32 let dotnetLocation = let dotnetApp = let platform = Environment.OSVersion.Platform if platform = PlatformID.Unix then "dotnet" else "dotnet.exe" - let assemblyLocation = typeof.GetTypeInfo().Assembly.Location + let assemblyLocation = typeof.GetTypeInfo().Assembly.Location Path.Combine(assemblyLocation, "../../..", dotnetApp) if File.Exists(dotnetLocation) then From 62fb769d5fb671997eeec8172ff59e7db632c0af Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Fri, 3 Jul 2020 15:55:42 -0700 Subject: [PATCH 49/60] Fix tests --- tests/fsharp/Compiler/Language/InterfaceTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fsharp/Compiler/Language/InterfaceTests.fs b/tests/fsharp/Compiler/Language/InterfaceTests.fs index e18d1a9fa48..7f5136e3e8b 100644 --- a/tests/fsharp/Compiler/Language/InterfaceTests.fs +++ b/tests/fsharp/Compiler/Language/InterfaceTests.fs @@ -203,7 +203,7 @@ assertion (fun (x:float) -> x * 3.0) (fun v -> |] ``Many Instantiations of the same interface`` [| - (FSharpErrorSeverity.Error, 443, (24, 6, 24, 20), "This type implements the same interface at different generic instantiations 'IInterface<(float -> float)>' and 'IInterface<(int -> int)>'. This is not permitted in this version of F#.") + (FSharpErrorSeverity.Error, 3350, (24, 6, 24, 20), "Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 'preview' or greater.") |] [] From b2e8dc2acea42271979df76ea112228ae39afe50 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Mon, 6 Jul 2020 08:12:02 -0700 Subject: [PATCH 50/60] feedback --- src/fsharp/TypeRelations.fs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/fsharp/TypeRelations.fs b/src/fsharp/TypeRelations.fs index 22d6cb56aeb..1ef4ada8178 100755 --- a/src/fsharp/TypeRelations.fs +++ b/src/fsharp/TypeRelations.fs @@ -59,14 +59,6 @@ let rec TypesFeasiblyEquivalent stripMeasures ndeep g amap m ty1 ty2 = let ty1str = stripAll ty1 let ty2str = stripAll ty2 - let _found, _tc_eq = - match ty1str, ty2str with - | TType_app (tc1, _l1), TType_app (tc2, _l2) -> - let tc1_local = tc1 - let tc2_local = tc2 - true, tyconRefEq g tc1_local tc2_local - | _ -> false, false - match ty1str, ty2str with | TType_var _, _ | _, TType_var _ -> true From 539ea968b70f30006c831433a51c9452689c4246 Mon Sep 17 00:00:00 2001 From: Thorsten Reichert Date: Mon, 6 Jul 2020 17:26:26 +0200 Subject: [PATCH 51/60] Moved fsharpqa/Conformance/BasicGrammarElements/Constants test cases to NUnit (#9626) * Migrated DecimalLiterals01.fs test case * Migrated DecimalConstants02.fs test case * Migrated E_BasicConstantsBigNum01.fs test case * Migrated E_BasicConstantsBigNum40.fs test case * Removed unlisted test case * Migrated E_UnderscoreLiterals.fs test case * Migrated FullSetOfEscapeCharacters.fs test case * Migrated NegativeNumbers01.fs, NegativeNumbers02.fs, NegativeNumbers03.fs test cases --- .../InvalidNumericLiteralTests.fs | 78 +++++++++++++++++-- .../BasicGrammarElements/CharConstants.fs | 21 +++++ .../BasicGrammarElements/DecimalConstants.fs | 54 +++++++++++++ .../BasicGrammarElements/IntegerConstants.fs | 44 +++++++++++ tests/fsharp/FSharpSuite.Tests.fsproj | 3 + .../Constants/DecimalLiterals01.fs | 26 ------- .../Constants/DecimalLiterals02.fs | 11 --- .../Constants/E_BasicConstantsBigNum01.fsx | 7 -- .../Constants/E_BasicConstantsBigNum40.fsx | 11 --- .../Constants/E_DecimalLiterals02.fs | 9 --- .../Constants/E_UnderscoreLiterals.fs | 30 ------- .../Constants/FullSetOfEscapeCharacters.fs | 21 ----- .../Constants/NegativeNumbers01.fs | 14 ---- .../Constants/NegativeNumbers02.fs | 15 ---- .../Constants/NegativeNumbers03.fs | 13 ---- .../BasicGrammarElements/Constants/env.lst | 15 ---- 16 files changed, 195 insertions(+), 177 deletions(-) create mode 100644 tests/fsharp/Compiler/Conformance/BasicGrammarElements/CharConstants.fs create mode 100644 tests/fsharp/Compiler/Conformance/BasicGrammarElements/DecimalConstants.fs create mode 100644 tests/fsharp/Compiler/Conformance/BasicGrammarElements/IntegerConstants.fs delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals01.fs delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals02.fs delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum01.fsx delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum40.fsx delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_DecimalLiterals02.fs delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_UnderscoreLiterals.fs delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/FullSetOfEscapeCharacters.fs delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers01.fs delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers02.fs delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers03.fs delete mode 100644 tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/env.lst diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs index a20dd899762..720f18a06da 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs @@ -5,16 +5,84 @@ namespace FSharp.Compiler.ErrorMessages.ComponentTests open Xunit open FSharp.Test.Utilities open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.AbstractIL.Internal module ``Numeric Literals`` = + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + let ``Invalid Numeric Literals`` literal = + CompilerAssert.TypeCheckSingleError + ("let x = " + literal) + FSharpErrorSeverity.Error + 1156 + (1, 9, 1, 9 + (String.length literal)) + "This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger)." + [] - let ``1up is invalid Numeric Literal``() = + let ``3_(dot)1415F is invalid numeric literal``() = + CompilerAssert.TypeCheckWithErrors + """ +let x = 3_.1415F + """ + [| + FSharpErrorSeverity.Error, 1156, (2, 9, 2, 11), "This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger)."; + FSharpErrorSeverity.Error, 599, (2, 11, 2, 12),"Missing qualification after '.'" + |] + + [] + let ``_52 is invalid numeric literal``() = CompilerAssert.TypeCheckSingleError """ -let foo = 1up // int +let x = _52 """ FSharpErrorSeverity.Error - 1156 - (2, 11, 2, 14) - "This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger)." + 39 + (2, 9, 2, 12) + "The value or constructor '_52' is not defined." + + + [] + let ``1N is invalid numeric literal``() = + CompilerAssert.TypeCheckSingleError + """ +let x = 1N + """ + FSharpErrorSeverity.Error + 0784 + (2, 9, 2, 11) + "This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope" + + [] + let ``1N is invalid numeric literal in FSI``() = + if Utils.runningOnMono then () + else + CompilerAssert.RunScriptWithOptions [| "--langversion:preview"; "--test:ErrorRanges" |] + """ +let x = 1N + """ + [ + "This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope"; + "Operation could not be completed due to earlier error" + ] + + [] + [] + [] + let ``Valid Numeric Literals`` literal = + // Regressiont test for FSharp1.0: 2543 - Decimal literals do not support exponents + + CompilerAssert.Pass ("let x = " + literal) \ No newline at end of file diff --git a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/CharConstants.fs b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/CharConstants.fs new file mode 100644 index 00000000000..0ff4375ce51 --- /dev/null +++ b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/CharConstants.fs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Char Constants`` = + + [] // alert + [] // backspace + [] // horizontal tab + [] // new line + [] // vertical tab + [] // form feed + [] // return + [] // double quote + [] // single quote + [] // backslash + let ``Escape characters`` character value = + Assert.areEqual character (char value) \ No newline at end of file diff --git a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/DecimalConstants.fs b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/DecimalConstants.fs new file mode 100644 index 00000000000..4fd012f7a03 --- /dev/null +++ b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/DecimalConstants.fs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Decimal Constants`` = + + [] + let ``Product of decimal constants``() = + let oneOfOneMiDec = 1.0E-6M + let oneMiDec = 1.0E+6M + + Assert.areEqual 1.0M (oneOfOneMiDec * oneMiDec) + + [] + let ``Sum of decimal constants``() = + let x = + 1.0E0M + + 2.0E1M + + 3.0E2M + + 4.0E3M + + 5.0E4M + + 6.0E5M + + 7.0E6M + + 8.0E7M + + 9.0E8M + + 1.0E-1M + + 2.0E-2M + + 3.0E-3M + + 4.0E-4M + + 5.0E-5M + + 6.0E-6M + + 7.0E-7M + + 8.0E-8M + + 9.0E-9M + + Assert.areEqual 987654321.123456789M x + + [] + let ``Sum of decimal literals with leading zero in exponential``() = + let x = 1.0E00M + 2.0E01M + 3.E02M + 1.E-01M + 2.0E-02M + + Assert.areEqual 321.12M x + + [] + let ``Non-representable small values are rounded to zero``() = + // This test involves rounding of decimals. The F# design is to follow the BCL. + // This means that the behavior is not deterministic, e.g. Mono and NetFx4 round; NetFx2 gives an error + // This is a positive test on Dev10, at least until + // FSHARP1.0:4523 gets resolved. + + Assert.areEqual 0.0M 1.0E-50M \ No newline at end of file diff --git a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/IntegerConstants.fs b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/IntegerConstants.fs new file mode 100644 index 00000000000..a5be0ccde11 --- /dev/null +++ b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/IntegerConstants.fs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Integer Constants`` = + + [] + let ``Operations with negative one``() = + // Verify the ability to specify negative numbers + // (And not get confused wrt subtraction.) + + let x = -1 + + Assert.areEqual -2 (x + x) + Assert.areEqual 0 (x - x) + Assert.areEqual 1 (x * x) + Assert.areEqual 1 (x / x) + + [] + let ``Operations with negative integers``() = + // Verify the ability to specify negative numbers + // (And not get confused wrt subtraction.) + + let fiveMinusSix = 5 - 6 + let fiveMinusSeven = 5-7 + let negativeSeven = -7 + + Assert.areEqual -1 fiveMinusSix + Assert.areEqual -2 fiveMinusSeven + Assert.areEqual (-1 * 7) negativeSeven + + [] + let ``Functions with negative integers``() = + // Verify the ability to specify negative numbers + // (And not get confused wrt subtraction.) + + let ident x = x + let add x y = x + y + + Assert.areEqual -10 (ident -10) + Assert.areEqual -10 (add -5 -5) \ No newline at end of file diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index a9d05e1fb76..f8d78ae0d17 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -33,6 +33,9 @@ + + + diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals01.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals01.fs deleted file mode 100644 index f78853a422b..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals01.fs +++ /dev/null @@ -1,26 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants -#light - -// Regressiont test for FSharp1.0: 2543 - Decimal literals do not support exponents - -let oneOfOneMiDec = 1.0E-6M -let oneMiDec = 1.0E+6M - -let one = oneOfOneMiDec * oneMiDec - -if one <> 1.0M then exit 1 - -let result = 1.0E0M + 2.0E1M + 3.0E2M + 4.0E3M + 5.0E4M + 6.0E5M + 7.0E6M + 8.0E7M + 9.0E8M + - 1.0E-1M + 2.0E-2M + 3.0E-3M + 4.0E-4M + 5.0E-5M + 6.0E-6M + 7.0E-7M + 8.0E-8M + 9.0E-9M - -if result <> 987654321.123456789M then exit 1 - -// Test boundary case -let xMax = 1.0E28M -let XMin = 1.0E-28M - -// Test with leading zeros in exponential and -let y = 1.0E00M + 2.0E01M + 3.E02M + 1.E-01M + 2.0E-02M -if y <> 321.12M then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals02.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals02.fs deleted file mode 100644 index ff61e0a1b47..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals02.fs +++ /dev/null @@ -1,11 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants #NoMono -// This is a positive test on Dev10, at least until -// FSHARP1.0:4523 gets resolved. -// - -let ok = 1.0E-50M // parses ok on Dev10 - -if ok <> 0.0M then - exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum01.fsx b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum01.fsx deleted file mode 100644 index acc2c91301a..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum01.fsx +++ /dev/null @@ -1,7 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants -// Verify the ability to specify basic constants - continued - - -//This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope - -let bignumConst = 1N diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum40.fsx b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum40.fsx deleted file mode 100644 index 8060826cfbd..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum40.fsx +++ /dev/null @@ -1,11 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants #NoMono #ReqNOMT - -// Verify the ability to specify basic constants - continued - - -// error FS0191: This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope -//This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope - -let bignumConst = 1N - -exit 1 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_DecimalLiterals02.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_DecimalLiterals02.fs deleted file mode 100644 index 18849f241c0..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_DecimalLiterals02.fs +++ /dev/null @@ -1,9 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants #NoMono -#light - -// Negative Regressiont test for FSharp1.0: 2543 - Decimal literals do not support exponents -//This number is outside the allowable range for decimal literals - -let invalidDec = 1.0E-50M - -exit 1 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_UnderscoreLiterals.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_UnderscoreLiterals.fs deleted file mode 100644 index 7f7e1745b8c..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_UnderscoreLiterals.fs +++ /dev/null @@ -1,30 +0,0 @@ -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include - -let pi1 = 3_.1415F -let pi2 = 3._1415F -let socialSecurityNumber1 = 999_99_9999_L -let x1 = _52 -let x2 = 52_ -let x3 = 0_x52 -let x4 = 0x_52 -let x5 = 0x52_ -let x6 = 052_ -let x7 = 0_o52 -let x8 = 0o_52 -let x9 = 0o52_ -let x10 = 2.1_e2F -let x11 = 2.1e_2F -let x12 = 1.0_F \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/FullSetOfEscapeCharacters.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/FullSetOfEscapeCharacters.fs deleted file mode 100644 index e3015854a5e..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/FullSetOfEscapeCharacters.fs +++ /dev/null @@ -1,21 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants -#light - -// Regression test for FSharp1.0: 2956 - F# should have parity with C# wrt escape characters - -let isEscape = - true - && ('\a' = char 7 ) // alert - && ('\b' = char 8 ) // backspace - && ('\t' = char 9 ) // horizontal tab - && ('\n' = char 10) // new line - && ('\v' = char 11) // vertical tab - && ('\f' = char 12) // form feed - && ('\r' = char 13) // return - && ('\"' = char 34) // double quote - && ('\'' = char 39) // single quote - && ('\\' = char 92) // backslash - -if not isEscape then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers01.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers01.fs deleted file mode 100644 index 1291c1377b5..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers01.fs +++ /dev/null @@ -1,14 +0,0 @@ -// #Conformance #BasicGrammarElements #Constants -#light - -// Verify the ability to specify negative numbers -// (And not get confused wrt subtraction.) - -let x = -1 - -if x + x <> -2 then exit 1 -if x - x <> 0 then exit 1 -if x * x <> 1 then exit 1 -if x / x <> 1 then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers02.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers02.fs deleted file mode 100644 index c9b43056971..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers02.fs +++ /dev/null @@ -1,15 +0,0 @@ -// #Conformance #BasicGrammarElements #Constants -#light - -// Verify the ability to specify negative numbers -// (And not get confused wrt subtraction.) - -let fiveMinusSix = 5 - 6 -let fiveMinusSeven = 5-7 -let negativeSeven = -7 - -if fiveMinusSix <> -1 then exit 1 -if fiveMinusSeven <> -2 then exit 1 -if negativeSeven <> -1 * 7 then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers03.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers03.fs deleted file mode 100644 index 751d026a469..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers03.fs +++ /dev/null @@ -1,13 +0,0 @@ -// #Conformance #BasicGrammarElements #Constants -#light - -// Verify the ability to specify negative numbers -// (And not get confused wrt subtraction.) - -let ident x = x -let add x y = x + y - -if ident -10 <> -10 then exit 1 -if add -5 -5 <> -10 then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/env.lst b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/env.lst deleted file mode 100644 index 97183b49781..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/env.lst +++ /dev/null @@ -1,15 +0,0 @@ -NOMONO,NoMT SOURCE=E_BasicConstantsBigNum40.fsx SCFLAGS="--test:ErrorRanges" # E_BasicConstantsBigNum40.fsx - - - SOURCE=NegativeNumbers01.fs # NegativeNumbers01.fs - SOURCE=NegativeNumbers02.fs # NegativeNumbers02.fs - SOURCE=NegativeNumbers03.fs # NegativeNumbers03.fs - - SOURCE=DecimalLiterals01.fs # DecimalLiterals01.fs - -# DecimalLiteral02.fs involves rounding of decimals. The F# design is to follow the BCL. -# This means that the behavior is not deterministic, e.g. Mono and NetFx4 round; NetFx2 gives an error - SOURCE=DecimalLiterals02.fs # DecimalLiterals02.fs - - SOURCE=FullSetOfEscapeCharacters.fs # FullSetOfEscapeCharacters.fs - SOURCE=E_UnderscoreLiterals.fs SCFLAGS="--test:ErrorRanges" # E_UnderscoreLiterals.fs \ No newline at end of file From 5a5f8bd4be7962b917500c6c9626dedf913c327a Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Mon, 6 Jul 2020 18:06:08 +0200 Subject: [PATCH 52/60] Cleanup, remove fsproj lines that are now redundant (#9628) --- tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj index 0706e76eef5..55883519178 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj @@ -107,8 +107,4 @@ - - - - From f71e5b6c7863b591f838bf9e4e48bad77a4a9174 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 6 Jul 2020 10:48:37 -0700 Subject: [PATCH 53/60] Update LanguageFeatures.fs reset language version back to 4.7 for master branch --- src/fsharp/LanguageFeatures.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/LanguageFeatures.fs b/src/fsharp/LanguageFeatures.fs index 4a21cb6b1c5..ad0d8c0185b 100644 --- a/src/fsharp/LanguageFeatures.fs +++ b/src/fsharp/LanguageFeatures.fs @@ -42,7 +42,7 @@ type LanguageVersion (specifiedVersionAsString) = static let languageVersion47 = 4.7m static let languageVersion50 = 5.0m static let previewVersion = 9999m // Language version when preview specified - static let defaultVersion = languageVersion50 // Language version when default specified + static let defaultVersion = languageVersion47 // Language version when default specified static let latestVersion = defaultVersion // Language version when latest specified static let latestMajorVersion = languageVersion47 // Language version when latestmajor specified From e57d036a1450cf9de4ae2acfc55ac3cb215751d9 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 6 Jul 2020 10:48:54 -0700 Subject: [PATCH 54/60] Update LanguageFeatures.fs reset language version back to 4.7 for master branch From 687fa0a1b636575116657f0e8af49ccf30b8bd7f Mon Sep 17 00:00:00 2001 From: Don Syme Date: Mon, 6 Jul 2020 18:53:11 +0100 Subject: [PATCH 55/60] alternative fix for 9565 (#9629) * fix 9565 * add comment --- src/fsharp/MethodCalls.fs | 11 ++++++++++- tests/fsharp/tests.fs | 15 +++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index df06f0064ab..61ce01d1af0 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -1173,6 +1173,15 @@ let AdjustCallerArgForOptional tcFieldInit eCallerMemberName (infoReader: InfoRe if isOptCallerArg then errorR(Error(FSComp.SR.tcFormalArgumentIsNotOptional(), m)) assignedArg + // For non-nullable, non-optional arguments no conversion is needed. + // We return precisely the assignedArg. This also covers the case where there + // can be a lingering permitted type mismatch between caller argument and called argument, + // specifically caller can by `byref` and called `outref`. No coercion is inserted in the + // expression tree in this case. + | NotOptional when not (isNullableTy g calledArgTy) -> + if isOptCallerArg then errorR(Error(FSComp.SR.tcFormalArgumentIsNotOptional(), m)) + assignedArg + | _ -> let callerArgExpr2 = @@ -1183,7 +1192,7 @@ let AdjustCallerArgForOptional tcFieldInit eCallerMemberName (infoReader: InfoRe if isNullableTy g calledArgTy then MakeNullableExprIfNeeded infoReader calledArgTy callerArgTy callerArgExpr m else - callerArgExpr + failwith "unreachable" // see case above | CallerSide dfltVal -> let calledArgTy = calledArg.CalledArgumentType diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 1a2be765dc5..4958c84cbe4 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -254,9 +254,20 @@ module CoreTests = begin use testOkFile = fileguard cfg "test.ok" - fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"] + fsc cfg "%s -o:test.exe -g --langversion:4.7" cfg.fsc_flags ["test.fsx"] - singleNegTest cfg "test" + singleVersionedNegTest cfg "4.7" "test" + exec cfg ("." ++ "test.exe") "" + + testOkFile.CheckExists() + end + + begin + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test.exe -g --langversion:5.0" cfg.fsc_flags ["test.fsx"] + + singleVersionedNegTest cfg "5.0" "test" exec cfg ("." ++ "test.exe") "" From 31a9ba74bbb188c14c724a8fb0c47f7ea3e9dfe0 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 6 Jul 2020 11:26:28 -0700 Subject: [PATCH 56/60] Warn on invalided FSI directives. (#9601) * cleanup fsi a bit * Update baselines --- src/fsharp/FSComp.txt | 1 + src/fsharp/fsi/FSIstrings.txt | 1 - src/fsharp/fsi/fsi.fs | 68 +++++++++---------- src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.ja.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hans.xlf | 5 -- src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hant.xlf | 5 -- src/fsharp/xlf/FSComp.txt.cs.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.de.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.es.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.fr.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.it.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.ja.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.ko.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.pl.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.ru.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.tr.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 5 ++ src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 5 ++ tests/fsharp/core/printing/test.fsx | 2 +- .../printing/z.output.test.1000.stderr.bsl | 6 ++ .../printing/z.output.test.1000.stdout.bsl | 1 - .../printing/z.output.test.200.stderr.bsl | 6 ++ .../printing/z.output.test.200.stdout.bsl | 1 - .../printing/z.output.test.default.stderr.bsl | 6 ++ .../printing/z.output.test.default.stdout.bsl | 1 - .../printing/z.output.test.off.stderr.bsl | 6 ++ .../printing/z.output.test.off.stdout.bsl | 1 - .../printing/z.output.test.quiet.stderr.bsl | 6 ++ 39 files changed, 131 insertions(+), 105 deletions(-) diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index e8d7455b508..dece87e5ee8 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1513,3 +1513,4 @@ featureAndBang,"applicative computation expressions" featureNullableOptionalInterop,"nullable optional interop" featureDefaultInterfaceMemberConsumption,"default interface member consumption" featureWitnessPassing,"witness passing for trait constraints in F# quotations" +3353,fsiInvalidDirective,"Invalid directive '#%s %s'" diff --git a/src/fsharp/fsi/FSIstrings.txt b/src/fsharp/fsi/FSIstrings.txt index c151f7b30e2..a32a2cfd3f0 100644 --- a/src/fsharp/fsi/FSIstrings.txt +++ b/src/fsharp/fsi/FSIstrings.txt @@ -21,7 +21,6 @@ fsiBanner3,"For help type #help;;" fsiConsoleProblem,"A problem occurred starting the F# Interactive process. This may be due to a known problem with background process console support for Unicode-enabled applications on some Windows systems. Try selecting Tools->Options->F# Interactive for Visual Studio and enter '--fsi-server-no-unicode'." 2301,fsiInvalidAssembly,"'%s' is not a valid assembly name" 2302,fsiDirectoryDoesNotExist,"Directory '%s' doesn't exist" -fsiInvalidDirective,"Invalid directive '#%s %s'" fsiLineTooLong,"Warning: line too long, ignoring some characters\n" fsiTimeInfoMainString,"Real: %s, CPU: %s, GC %s" fsiTimeInfoGCGenerationLabelSomeShorthandForTheWordGeneration,"gen" diff --git a/src/fsharp/fsi/fsi.fs b/src/fsharp/fsi/fsi.fs index ddb338a3087..8bbf592c3f5 100644 --- a/src/fsharp/fsi/fsi.fs +++ b/src/fsharp/fsi/fsi.fs @@ -2053,7 +2053,7 @@ type internal FsiInteractionProcessor f istate with e -> stopProcessingRecovery e range0 - istate,CompletedWithReportedError e + istate, CompletedWithReportedError e let isFeatureSupported featureId = tcConfigB.langVersion.SupportsFeature featureId @@ -2099,11 +2099,11 @@ type internal FsiInteractionProcessor let ExecInteraction (ctok, tcConfig:TcConfig, istate, action:ParsedFsiInteraction, errorLogger: ErrorLogger) = istate |> InteractiveCatch errorLogger (fun istate -> match action with - | IDefns ([ ],_) -> + | IDefns ([], _) -> let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) istate,Completed None - | IDefns ([ SynModuleDecl.DoExpr(_,expr,_)],_) -> + | IDefns ([SynModuleDecl.DoExpr(_, expr, _)], _) -> let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) fsiDynamicCompiler.EvalParsedExpression(ctok, errorLogger, istate, expr) @@ -2111,7 +2111,7 @@ type internal FsiInteractionProcessor let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) fsiDynamicCompiler.EvalParsedDefinitions (ctok, errorLogger, istate, true, false, defs) - | IHash (ParsedHashDirective("load",sourceFiles,m),_) -> + | IHash (ParsedHashDirective("load", sourceFiles, m), _) -> let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) fsiDynamicCompiler.EvalSourceFiles (ctok, istate, m, sourceFiles, lexResourceManager, errorLogger),Completed None @@ -2161,69 +2161,69 @@ type internal FsiInteractionProcessor fsiConsoleOutput.uprintnfnn "%s" format) istate,Completed None - | IHash (ParsedHashDirective("I",[path],m),_) -> - tcConfigB.AddIncludePath (m,path, tcConfig.implicitIncludeDir) + | IHash (ParsedHashDirective("I", [path], m), _) -> + tcConfigB.AddIncludePath (m, path, tcConfig.implicitIncludeDir) fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiDidAHashI(tcConfig.MakePathAbsolute path)) - istate,Completed None + istate, Completed None - | IHash (ParsedHashDirective("cd",[path],m),_) -> + | IHash (ParsedHashDirective("cd", [path], m), _) -> ChangeDirectory path m - istate,Completed None + istate, Completed None - | IHash (ParsedHashDirective("silentCd",[path],m),_) -> + | IHash (ParsedHashDirective("silentCd", [path], m), _) -> ChangeDirectory path m fsiConsolePrompt.SkipNext() (* "silent" directive *) - istate,Completed None + istate, Completed None - | IHash (ParsedHashDirective("dbgbreak",[],_),_) -> - {istate with debugBreak = true},Completed None + | IHash (ParsedHashDirective("dbgbreak", [], _), _) -> + {istate with debugBreak = true}, Completed None - | IHash (ParsedHashDirective("time",[],_),_) -> + | IHash (ParsedHashDirective("time", [], _), _) -> if istate.timing then fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOff()) else fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOn()) - {istate with timing = not istate.timing},Completed None + {istate with timing = not istate.timing}, Completed None - | IHash (ParsedHashDirective("time",[("on" | "off") as v],_),_) -> + | IHash (ParsedHashDirective("time", [("on" | "off") as v], _), _) -> if v <> "on" then fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOff()) else fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOn()) - {istate with timing = (v = "on")},Completed None + {istate with timing = (v = "on")}, Completed None - | IHash (ParsedHashDirective("nowarn",numbers,m),_) -> - List.iter (fun (d:string) -> tcConfigB.TurnWarningOff(m,d)) numbers - istate,Completed None + | IHash (ParsedHashDirective("nowarn", numbers, m), _) -> + List.iter (fun (d:string) -> tcConfigB.TurnWarningOff(m, d)) numbers + istate, Completed None - | IHash (ParsedHashDirective("terms",[],_),_) -> + | IHash (ParsedHashDirective("terms", [], _), _) -> tcConfigB.showTerms <- not tcConfig.showTerms - istate,Completed None + istate, Completed None - | IHash (ParsedHashDirective("types",[],_),_) -> + | IHash (ParsedHashDirective("types", [], _), _) -> fsiOptions.ShowTypes <- not fsiOptions.ShowTypes - istate,Completed None + istate, Completed None #if DEBUG - | IHash (ParsedHashDirective("ilcode",[],_m),_) -> + | IHash (ParsedHashDirective("ilcode", [], _m), _) -> fsiOptions.ShowILCode <- not fsiOptions.ShowILCode; - istate,Completed None + istate, Completed None - | IHash (ParsedHashDirective("info",[],_m),_) -> + | IHash (ParsedHashDirective("info", [], _m), _) -> PrintOptionInfo tcConfigB - istate,Completed None + istate, Completed None #endif - | IHash (ParsedHashDirective(("q" | "quit"),[],_),_) -> + | IHash (ParsedHashDirective(("q" | "quit"), [], _), _) -> fsiInterruptController.Exit() - | IHash (ParsedHashDirective("help",[],_),_) -> + | IHash (ParsedHashDirective("help", [], _), _) -> fsiOptions.ShowHelp() - istate,Completed None + istate, Completed None - | IHash (ParsedHashDirective(c,arg,_),_) -> - fsiConsoleOutput.uprintfn "%s" (FSIstrings.SR.fsiInvalidDirective(c, String.concat " " arg)) // REVIEW: uprintnfnn - like other directives above - istate,Completed None (* REVIEW: cont = CompletedWithReportedError *) + | IHash (ParsedHashDirective(c, arg, m), _) -> + warning(Error((FSComp.SR.fsiInvalidDirective(c, String.concat " " arg)), m)) + istate, Completed None ) /// Execute a single parsed interaction which may contain multiple items to be executed diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf index 2d4481919d4..3fb6c4c42ca 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf @@ -122,11 +122,6 @@ Adresář {0} neexistuje. - - Invalid directive '#{0} {1}' - Neplatná direktiva #{0} {1} - - Warning: line too long, ignoring some characters\n Upozornění: řádek je příliš dlouhý, některé znaky se ignorují.\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf index 80ec70245dc..3a439ace8e5 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf @@ -122,11 +122,6 @@ Das Verzeichnis "{0}" ist nicht vorhanden. - - Invalid directive '#{0} {1}' - Ungültige Direktive "#{0} {1}" - - Warning: line too long, ignoring some characters\n Warnung: Die Zeile ist zu lang, einige Zeichen werden ignoriert.\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf index d5ec3bf213c..ce48111e7ad 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf @@ -122,11 +122,6 @@ El directorio '{0}' no existe. - - Invalid directive '#{0} {1}' - Directiva '#{0} {1}' no válida. - - Warning: line too long, ignoring some characters\n Advertencia: línea demasiado larga, omitiendo algunos caracteres.\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf index 963d52c6504..205b4ee29db 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf @@ -122,11 +122,6 @@ Le répertoire '{0}' n'existe pas - - Invalid directive '#{0} {1}' - Directive non valide '#{0} {1}' - - Warning: line too long, ignoring some characters\n Avertissement : ligne trop longue, certains caractères sont ignorés\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf index aa030eb6b34..a80011624b8 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf @@ -122,11 +122,6 @@ La directory '{0}' non esiste - - Invalid directive '#{0} {1}' - Direttiva '#{0} {1}' non valida - - Warning: line too long, ignoring some characters\n Avviso: riga troppo lunga; alcuni caratteri verranno ignorati\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.ja.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.ja.xlf index ad4b06f0fd0..1d2d4ef1a03 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.ja.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.ja.xlf @@ -122,11 +122,6 @@ ディレクトリ "{0}" は存在しません - - Invalid directive '#{0} {1}' - 無効なディレクティブ '#{0} {1}' - - Warning: line too long, ignoring some characters\n 警告: 行が長すぎます。一部の文字は無視されます\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf index 53f9f276082..c6f84506f14 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf @@ -122,11 +122,6 @@ '{0}' 디렉터리가 없습니다. - - Invalid directive '#{0} {1}' - 잘못된 지시문 '#{0} {1}' - - Warning: line too long, ignoring some characters\n 경고: 줄이 너무 길어 일부 문자가 무시됩니다.\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf index 3666ea478ed..4cb9444fb65 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf @@ -122,11 +122,6 @@ Katalog „{0}” nie istnieje - - Invalid directive '#{0} {1}' - Nieprawidłowa dyrektywa „#{0} {1}” - - Warning: line too long, ignoring some characters\n Ostrzeżenie: wiersz jest zbyt długi, niektóre znaki zostaną zignorowane\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf index 9adafa2f096..e5000c692a9 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf @@ -122,11 +122,6 @@ O diretório '{0}' não existe - - Invalid directive '#{0} {1}' - Diretriz inválida '#{0} {1}' - - Warning: line too long, ignoring some characters\n Aviso: linha muito longa, ignore alguns caracteres\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf index 9cbfe6ff50f..a43adbec0df 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf @@ -122,11 +122,6 @@ Каталог "{0}" не существует - - Invalid directive '#{0} {1}' - Недопустимая директива "#{0} {1}" - - Warning: line too long, ignoring some characters\n Предупреждение: слишком длинная строка, некоторые знаки игнорируются\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf index 65042521c76..d409fb44ffd 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf @@ -122,11 +122,6 @@ '{0}' dizini yok - - Invalid directive '#{0} {1}' - Geçersiz yönerge '#{0} {1}' - - Warning: line too long, ignoring some characters\n Uyarı: satır çok uzun, bazı karakterler yok sayılıyor\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hans.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hans.xlf index a97b57363e8..4ad4e4161e9 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hans.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hans.xlf @@ -122,11 +122,6 @@ 目录“{0}”不存在 - - Invalid directive '#{0} {1}' - 无效的指令“#{0} {1}” - - Warning: line too long, ignoring some characters\n 警告: 由于行太长,将忽略某些字符\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hant.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hant.xlf index 936f04dd787..458e547a00d 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hant.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hant.xlf @@ -122,11 +122,6 @@ 目錄 '{0}' 不存在 - - Invalid directive '#{0} {1}' - 無效的指示詞 '#{0} {1}' - - Warning: line too long, ignoring some characters\n 警告: 行太長,將忽略某些字元\n diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index a176f81a800..93b25fc149c 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -152,6 +152,11 @@ Vytváření průřezů od konce vyžaduje jazykovou verzi 5.0, použijte /langversion:preview. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. Stream nezačíná zdrojem s hodnotou null a není ve formátu .RES. diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index 13a70ff59e1..21d4e0495fc 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -152,6 +152,11 @@ Für das vom Ende ausgehende Slicing ist Sprachversion 5.0 erforderlich. Verwenden Sie /langversion:preview. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. Der Stream beginnt nicht mit einer NULL-Ressource und ist nicht im RES-Format. diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 48bcbb82529..d569c0710aa 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -152,6 +152,11 @@ La segmentación desde el final requiere la versión de lenguaje 5.0, use /langversion:preview. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. El flujo no comienza con un recurso nulo ni está en formato ".RES". diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index ed34481d69b..abb9324ac2f 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -152,6 +152,11 @@ L'extraction à partir de la fin nécessite la version 5.0 du langage. Utilisez /langversion:preview. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. Le flux ne commence pas par une ressource null et n'est pas au format '.RES'. diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 28af1801f19..63466b58627 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -152,6 +152,11 @@ Con il sezionamento dalla fine è richiesta la versione 5.0 del linguaggio. Usare /langversion:preview. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. Il flusso non inizia con una risorsa Null e non è in formato '.RES'. diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 7251c15f4b7..edae43da49d 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -152,6 +152,11 @@ 言語バージョン 5.0 が必要な最後からのスライスで、/langversion:preview を使用してください。 + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. ストリームは null リソースでは始まらず、'RES' 形式でもありません。 diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index 197d8985f0c..b2d2fdd5c24 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -152,6 +152,11 @@ 언어 버전 5.0이 필요한 끝 조각화에서는 /langversion:preview를 사용하세요. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. 스트림은 null 리소스로 시작되지 않으며 '.RES' 형식이 아닙니다. diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index 790649874ef..2f0990cee6b 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -152,6 +152,11 @@ Wycinanie od końca wymaga języka w wersji 5.0, użyj parametru /langversion:preview. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. Strumień nie zaczyna się od zasobu o wartości null i nie jest w formacie „.RES”. diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index dd5d94d1b92..22edbadb5d0 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -152,6 +152,11 @@ A opção 'Divisão começando no final' requer a versão de idioma 5.0. Use /langversion:preview. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. Stream não começa com um recurso nulo e não está no formato '.RES'. diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 33533871d5a..484bd79d7eb 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -152,6 +152,11 @@ Для конечного среза, для которого требуется версия языка 5.0, используйте параметр /langversion:preview. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. Поток не начинается с нулевого ресурса и не соответствует формату ".RES". diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 17cd35566de..e4ec2c2c68c 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -152,6 +152,11 @@ Sondan dilimleme, 5.0 dil sürümünü gerektirir, /langversion:preview kullanın. + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. Akış null kaynakla başlamıyor ve '.RES' biçiminde değil. diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 301dcb082af..93cef3ca98c 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -152,6 +152,11 @@ 需要语言版本 5.0 才能从末尾切片,请使用 /langversion:preview。 + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. 流应以空资源开头并且应采用 .RES 格式。 diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 39a787c7103..5f209869ff1 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -152,6 +152,11 @@ 從結尾處切割需要語言版本 5.0,請使用 /langversion:preview。 + + Invalid directive '#{0} {1}' + Invalid directive '#{0} {1}' + + Stream does not begin with a null resource and is not in '.RES' format. 資料流未以 null 資源開頭,並且未使用 '.RES' 格式。 diff --git a/tests/fsharp/core/printing/test.fsx b/tests/fsharp/core/printing/test.fsx index 60b36a00ea2..63dd02878e5 100644 --- a/tests/fsharp/core/printing/test.fsx +++ b/tests/fsharp/core/printing/test.fsx @@ -217,7 +217,7 @@ module RepeatedModule = begin let repeatedByteLiteral = [| 12uy; 13uy; 14uy |] e (* no eval in between, since time can vary and look like a regression *) #time;; (* time off *) "Check #unknown command";; -#blaaaaaa;; // blaaaaaa is not a known command +#blaaaaaa // blaaaaaa is not a known command;; "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)";; #I "/";; diff --git a/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl b/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl index 386c625eeff..32534466417 100644 --- a/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl @@ -1,4 +1,10 @@ + #blaaaaaa // blaaaaaa is not a known command;; + ^ + +stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' + + type Regression4319_T0 = static member (+-+-+) = "0 arguments";; -----------------------------------------^^^^^ diff --git a/tests/fsharp/core/printing/z.output.test.1000.stdout.bsl b/tests/fsharp/core/printing/z.output.test.1000.stdout.bsl index 03b6e6467d4..bbbe0f4d1fc 100644 --- a/tests/fsharp/core/printing/z.output.test.1000.stdout.bsl +++ b/tests/fsharp/core/printing/z.output.test.1000.stdout.bsl @@ -1130,7 +1130,6 @@ end > val it : string = "Check #unknown command" -> Invalid directive '#blaaaaaa ' > val it : string = "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" diff --git a/tests/fsharp/core/printing/z.output.test.200.stderr.bsl b/tests/fsharp/core/printing/z.output.test.200.stderr.bsl index 386c625eeff..32534466417 100644 --- a/tests/fsharp/core/printing/z.output.test.200.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.200.stderr.bsl @@ -1,4 +1,10 @@ + #blaaaaaa // blaaaaaa is not a known command;; + ^ + +stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' + + type Regression4319_T0 = static member (+-+-+) = "0 arguments";; -----------------------------------------^^^^^ diff --git a/tests/fsharp/core/printing/z.output.test.200.stdout.bsl b/tests/fsharp/core/printing/z.output.test.200.stdout.bsl index 681b7a7aafd..002ecebf271 100644 --- a/tests/fsharp/core/printing/z.output.test.200.stdout.bsl +++ b/tests/fsharp/core/printing/z.output.test.200.stdout.bsl @@ -450,7 +450,6 @@ end > val it : string = "Check #unknown command" -> Invalid directive '#blaaaaaa ' > val it : string = "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" diff --git a/tests/fsharp/core/printing/z.output.test.default.stderr.bsl b/tests/fsharp/core/printing/z.output.test.default.stderr.bsl index 386c625eeff..32534466417 100644 --- a/tests/fsharp/core/printing/z.output.test.default.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.default.stderr.bsl @@ -1,4 +1,10 @@ + #blaaaaaa // blaaaaaa is not a known command;; + ^ + +stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' + + type Regression4319_T0 = static member (+-+-+) = "0 arguments";; -----------------------------------------^^^^^ diff --git a/tests/fsharp/core/printing/z.output.test.default.stdout.bsl b/tests/fsharp/core/printing/z.output.test.default.stdout.bsl index b9872ed5e3a..9d5d95917bc 100644 --- a/tests/fsharp/core/printing/z.output.test.default.stdout.bsl +++ b/tests/fsharp/core/printing/z.output.test.default.stdout.bsl @@ -4089,7 +4089,6 @@ end > val it : string = "Check #unknown command" -> Invalid directive '#blaaaaaa ' > val it : string = "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" diff --git a/tests/fsharp/core/printing/z.output.test.off.stderr.bsl b/tests/fsharp/core/printing/z.output.test.off.stderr.bsl index 386c625eeff..32534466417 100644 --- a/tests/fsharp/core/printing/z.output.test.off.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.off.stderr.bsl @@ -1,4 +1,10 @@ + #blaaaaaa // blaaaaaa is not a known command;; + ^ + +stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' + + type Regression4319_T0 = static member (+-+-+) = "0 arguments";; -----------------------------------------^^^^^ diff --git a/tests/fsharp/core/printing/z.output.test.off.stdout.bsl b/tests/fsharp/core/printing/z.output.test.off.stdout.bsl index 9c90f3e2fac..5dc10d6bfe0 100644 --- a/tests/fsharp/core/printing/z.output.test.off.stdout.bsl +++ b/tests/fsharp/core/printing/z.output.test.off.stdout.bsl @@ -277,7 +277,6 @@ end > val it : string = "Check #unknown command" -> Invalid directive '#blaaaaaa ' > val it : string = "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" diff --git a/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl b/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl index 386c625eeff..32534466417 100644 --- a/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl @@ -1,4 +1,10 @@ + #blaaaaaa // blaaaaaa is not a known command;; + ^ + +stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' + + type Regression4319_T0 = static member (+-+-+) = "0 arguments";; -----------------------------------------^^^^^ From fcba42e4e063edd7d6a0c5601b135e77ffaa9aa5 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Mon, 6 Jul 2020 11:53:10 -0700 Subject: [PATCH 57/60] revert baselines --- .../fsc/langversion/langversionhelp.437.1033.bsl | 4 ++-- .../fsi/langversion/langversionhelp.437.1033.bsl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl index b7f6805220b..35fc56a3abe 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl @@ -4,5 +4,5 @@ default latest latestmajor 4.6 -4.7 -5.0 (Default) \ No newline at end of file +4.7 (Default) +5.0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl index b7f6805220b..35fc56a3abe 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl @@ -4,5 +4,5 @@ default latest latestmajor 4.6 -4.7 -5.0 (Default) \ No newline at end of file +4.7 (Default) +5.0 \ No newline at end of file From 3e6cf8b875b5f4ed2963180b8b59e8634b392197 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Tue, 7 Jul 2020 17:39:42 +0200 Subject: [PATCH 58/60] Add launchSettings.json to ignore list (#9638) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b43741116dc..21686006d7d 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ scripts/*.patch /src/fsharp/FSharp.LanguageService.Compiler/pplex.fs /src/fsharp/FSharp.LanguageService.Compiler/pppars.fs /src/fsharp/FSharp.LanguageService.Compiler/pppars.fsi +/src/fsharp/*/Properties/launchSettings.json /vsintegration/src/unittests/Unittests.fsi /tests/*FSharp_Failures.env /tests/*FSharp_Failures.lst From a8d3280b4551db2562946c8e28966e423885d754 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Tue, 7 Jul 2020 11:19:14 -0700 Subject: [PATCH 59/60] clarify some comments --- src/fsharp/LexFilter.fs | 2 +- vsintegration/src/FSharp.LanguageService.Base/Source.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsharp/LexFilter.fs b/src/fsharp/LexFilter.fs index b270910224b..c7ed3939175 100644 --- a/src/fsharp/LexFilter.fs +++ b/src/fsharp/LexFilter.fs @@ -1242,7 +1242,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // a TYPE or MODULE. So the lexfilter helps out by looking ahead for these tokens and (1) closing expression contexts and (2) inserting extra 'coming soon' tokens // that the expression rules in the FsYacc parser can 'shift' to make progress parsing the incomplete expressions, without using the 'recover' action. let insertComingSoonTokens(keywordName, comingSoon, isHere) = - // compiling the source for FSharp.Core.dll uses crazy syntax like + // compiling the source for FSharp.Core.dll uses unconventional syntax like // (# "unbox.any !0" type ('T) x : 'T #) // where the type keyword is used inside an expression, so we must exempt FSharp.Core from some extra failed-parse-diagnostics-recovery-processing of the 'type' keyword let mutable effectsToDo = [] diff --git a/vsintegration/src/FSharp.LanguageService.Base/Source.cs b/vsintegration/src/FSharp.LanguageService.Base/Source.cs index f46dc2f7eab..5053c4d21f3 100644 --- a/vsintegration/src/FSharp.LanguageService.Base/Source.cs +++ b/vsintegration/src/FSharp.LanguageService.Base/Source.cs @@ -2426,7 +2426,7 @@ public void Refresh(MethodTipMiscellany_DEPRECATED methodTipMiscellany) } if (this.currentParameter == -1) { - // a bit of a kludge; if they just backspaced over the last comma and there's no close parenthesis, the caret is just to the right of all the param + // a bit messy; if they just backspaced over the last comma and there's no close parenthesis, the caret is just to the right of all the param // ranges, but we don't want to dismiss the tip. so look just left of the caret and see if that would be inside the final param if (methodTipMiscellany == MethodTipMiscellany_DEPRECATED.JustPressedBackspace && ranges[ranges.Length - 1].GetSpan(wpfTextView.TextSnapshot).Contains(wpfTextView.Caret.Position.BufferPosition.Subtract(1))) From 8077622fdf8f395b17d1246d308700178dbeb78c Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Tue, 7 Jul 2020 13:19:12 -0700 Subject: [PATCH 60/60] make xliff tasks happy again (#9641) --- src/fsharp/xlf/FSComp.txt.cs.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.de.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.es.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.fr.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.it.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.ja.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.ko.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.pl.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.ru.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.tr.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 15 +++++++++++++++ src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 15 +++++++++++++++ 13 files changed, 195 insertions(+) diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 93b25fc149c..85af396cf5c 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. Typ {0} nedefinuje pole, konstruktor ani člen {1}. diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index 21d4e0495fc..ba71a1e94f4 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. Der Typ "{0}" definiert nicht das Feld, den Konstruktor oder den Member "{1}". diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index d569c0710aa..6a8d27fdd3d 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. El tipo "{0}" no define el campo, constructor o miembro "{1}". diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index abb9324ac2f..cc158d8cf4e 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. Le type '{0}' ne définit pas le champ, le constructeur ou le membre '{1}'. diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 63466b58627..28a352f71a5 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. Il tipo '{0}' non definisce il campo, il costruttore o il membro '{1}'. diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index edae43da49d..53d07ef597a 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. 型 '{0}' は、フィールド、コンストラクター、またはメンバー '{1}' を定義していません。 diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index b2d2fdd5c24..cd857ba2135 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. '{0}' 형식은 '{1}' 필드, 생성자 또는 멤버를 정의하지 않습니다. diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index 2f0990cee6b..8b9d38f36a1 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. Typ „{0}” nie definiuje pola, konstruktora lub składowej „{1}”. diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index 22edbadb5d0..4dd0ec18ee8 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. O tipo '{0}' não define o campo, o construtor ou o membro '{1}'. diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 484bd79d7eb..56b8c542b09 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. Тип "{0}" не определяет поле, конструктор или член "{1}". diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index e4ec2c2c68c..dc434b9351f 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. '{0}' türü; alanı, oluşturucuyu veya '{1}' üyesini tanımlamıyor. diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 93cef3ca98c..3dddbf576b1 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. 类型“{0}”未定义字段、构造函数或成员“{1}”。 diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 5f209869ff1..cff0c650647 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -102,6 +102,11 @@ implicit yield + + interfaces with multiple generic instantiation + interfaces with multiple generic instantiation + + nameof nameof @@ -242,6 +247,16 @@ Interface member '{0}' does not have a most specific implementation. + + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify. + + + + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify. + + The type '{0}' does not define the field, constructor or member '{1}'. 類型 '{0}' 未定義欄位、建構函式或成員 '{1}'。