diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam.fs new file mode 100644 index 00000000000..117cee69147 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam.fs @@ -0,0 +1,14 @@ +open Prelude + +module ByRefParam = + type C() = + static member M(x: byref) = x <- 5 + let mutable res = 9 + let v = C.M(&res) + check "cwvereweoiwekl4" res 5 + + let minfo = typeof.GetMethod("M") + check "cwnoreeker1" (minfo.GetParameters().[0].IsIn) false + check "cwnoreeker2" (minfo.GetParameters().[0].IsOut) false + check "cwnoreeker3" (minfo.ReturnParameter.IsIn) false + check "cwnoreeker4" (minfo.ReturnParameter.IsOut) false \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_ExplicitInAttribute.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_ExplicitInAttribute.fs new file mode 100644 index 00000000000..8923fe74272 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_ExplicitInAttribute.fs @@ -0,0 +1,16 @@ +open Prelude + +module ByRefParam_ExplicitInAttribute = + type C() = + static member M([] x: byref) = x <- 5 + let mutable res = 9 + let v = C.M(&res) + check "cwvereweoiwekl4" res 5 + + let minfo = typeof.GetMethod("M") + check "cwnoreeker9" (minfo.GetParameters().[0].IsIn) true + check "cwnoreekerq" (minfo.GetParameters().[0].IsOut) false + check "cwnoreeker6c" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 + check "cwnoreekers2" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 + check "cwnoreekerw" (minfo.ReturnParameter.IsIn) false + check "cwnoreekere" (minfo.ReturnParameter.IsOut) false \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_ExplicitOutAttribute.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_ExplicitOutAttribute.fs new file mode 100644 index 00000000000..1606d19a781 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_ExplicitOutAttribute.fs @@ -0,0 +1,16 @@ +open Prelude + +module ByRefParam_ExplicitOutAttribute = + type C() = + static member M([] x: byref) = x <- 5 + let mutable res = 9 + let v = C.M(&res) + check "cwvereweoiwekl4" res 5 + + let minfo = typeof.GetMethod("M") + check "cwnoreeker5" (minfo.GetParameters().[0].IsIn) false + check "cwnoreeker6a" (minfo.GetParameters().[0].IsOut) true + check "cwnoreeker6b" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 + check "cwnoreekers1" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 + check "cwnoreeker7" (minfo.ReturnParameter.IsIn) false + check "cwnoreeker8" (minfo.ReturnParameter.IsOut) false \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_OverloadedTest_ExplicitOutAttribute.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_OverloadedTest_ExplicitOutAttribute.fs new file mode 100644 index 00000000000..a52bd3bb71d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_OverloadedTest_ExplicitOutAttribute.fs @@ -0,0 +1,11 @@ +open Prelude + +module ByRefParam_OverloadedTest_ExplicitOutAttribute = + type C() = + static member M(a: int, [] x: byref) = x <- 7 + static member M(a: string, [] x: byref) = x <- 8 + let mutable res = 9 + C.M("a", &res) + check "cweweoiwek2cbe9" res 8 + C.M(3, &res) + check "cweweoiwek28498" res 7 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefReturn.fs new file mode 100644 index 00000000000..ac41aba2cc9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefReturn.fs @@ -0,0 +1,13 @@ +open Prelude + +module ByRefReturn = + type C() = + static member M(x: byref) = x <- x + 1; &x + let mutable res = 9 + let v = C.M(&res) + check "cwvereweoiwvw4" v 10 + + let minfo = typeof.GetMethod("M") + check "cwnoreeker6d" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 + check "cwnoreekerr" (minfo.ReturnParameter.IsIn) false + check "cwnoreekert" (minfo.ReturnParameter.IsOut) false \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestArrayParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestArrayParam.fs new file mode 100644 index 00000000000..848a9c7732c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestArrayParam.fs @@ -0,0 +1,13 @@ +open Prelude + +module TestArrayParam = + + let f (x:int[]) = &x.[0] + + let test() = + let r = [| 1 |] + let addr = &f r + addr <- addr + 1 + check2 "cepojcwem14" 2 r.[0] + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestBaseCall.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestBaseCall.fs new file mode 100644 index 00000000000..acd8797df8d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestBaseCall.fs @@ -0,0 +1,14 @@ +open Prelude + +module TestBaseCall = + type Incrementor(z) = + abstract member Increment : int byref * int byref -> unit + default this.Increment(i : int byref,j : int byref) = + i <- i + z + + type Decrementor(z) = + inherit Incrementor(z) + override this.Increment(i, j) = + base.Increment(&i, &j) + + i <- i - z \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestClassParamMutableField.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestClassParamMutableField.fs new file mode 100644 index 00000000000..3374a948d90 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestClassParamMutableField.fs @@ -0,0 +1,15 @@ +open Prelude + +module TestClassParamMutableField = + + type C() = [] val mutable z : int + + let f (x:C) = &x.z + + let test() = + let c = C() + let addr = &f c + addr <- addr + 1 + check2 "cepojcwem13b" 1 c.z + + test() diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestConditionalReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestConditionalReturn.fs new file mode 100644 index 00000000000..7918219ab6b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestConditionalReturn.fs @@ -0,0 +1,26 @@ +open Prelude + +module TestConditionalReturn = + let mutable x = 1 + let mutable y = 1 + + let f inp = if inp = 3 then &x else &y + + let test() = + let addr = &f 3 + addr <- addr + 1 + check2 "cepojcwem6" 2 x + check2 "cepojcwem7" 1 y + let addr = &f 4 + addr <- addr + 1 + check2 "cepojcwem8" 2 x + check2 "cepojcwem9" 2 y + + let test2() = + let res = f 3 + let res2 = res + 1 + check2 "cepojcwem8b" 3 res2 + check2 "cepojcwem9b" 2 res + + test() + test2() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestDelegateMethod.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestDelegateMethod.fs new file mode 100644 index 00000000000..cdb5cb21633 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestDelegateMethod.fs @@ -0,0 +1,18 @@ +open Prelude + +module TestDelegateMethod = + let mutable x = 1 + + type D = delegate of unit -> byref + + let d() = D(fun () -> &x) + + let f (d:D) = &d.Invoke() + + let test() = + let addr = &f (d()) + check2 "cepojcwem18a" 1 x + addr <- addr + 1 + check2 "cepojcwem18b" 2 x + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestDelegateMethod2.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestDelegateMethod2.fs new file mode 100644 index 00000000000..38445e80dde --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestDelegateMethod2.fs @@ -0,0 +1,18 @@ +open Prelude + +module TestDelegateMethod2 = + let mutable x = 1 + + type D = delegate of byref -> byref + + let d() = D(fun xb -> &xb) + + let f (d:D) = &d.Invoke(&x) + + let test() = + let addr = &f (d()) + check2 "cepojcwem18a2" 1 x + addr <- addr + 1 + check2 "cepojcwem18b3" 2 x + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestImmediateReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestImmediateReturn.fs new file mode 100644 index 00000000000..281c2e70ffd --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestImmediateReturn.fs @@ -0,0 +1,20 @@ +open Prelude + +module TestImmediateReturn = + let mutable x = 1 + + let f () = &x + + let test() = + let addr : byref = &f() + addr <- addr + 1 + check2 "cepojcwem1" 2 x + + + let test2() = + let v = f() + let res = v + 1 + check2 "cepojcwem1b" 3 res + + test() + test2() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestInterfaceMethod.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestInterfaceMethod.fs new file mode 100644 index 00000000000..7eef5444b04 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestInterfaceMethod.fs @@ -0,0 +1,26 @@ +open Prelude + +module TestInterfaceMethod = + let mutable x = 1 + + type I = + abstract M : unit -> byref + + type C() = + interface I with + member this.M() = &x + + let ObjExpr() = + { new I with + member this.M() = &x } + + let f (i:I) = &i.M() + + let test() = + let addr = &f (C()) + addr <- addr + 1 + let addr = &f (ObjExpr()) + addr <- addr + 1 + check2 "cepojcwem16" 3 x + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestInterfaceProperty.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestInterfaceProperty.fs new file mode 100644 index 00000000000..fd36f7ae985 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestInterfaceProperty.fs @@ -0,0 +1,26 @@ +open Prelude + +module TestInterfaceProperty = + let mutable x = 1 + + type I = + abstract P : byref + + type C() = + interface I with + member this.P = &x + + let ObjExpr() = + { new I with + member this.P = &x } + + let f (i:I) = &i.P + + let test() = + let addr = &f (C()) + addr <- addr + 1 + let addr = &f (ObjExpr()) + addr <- addr + 1 + check2 "cepojcwem17" 3 x + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestMatchReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestMatchReturn.fs new file mode 100644 index 00000000000..742bba96e41 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestMatchReturn.fs @@ -0,0 +1,26 @@ +open Prelude + +module TestMatchReturn = + let mutable x = 1 + let mutable y = 1 + + let f inp = match inp with 3 -> &x | _ -> &y + + let test() = + let addr = &f 3 + addr <- addr + 1 + check2 "cepojcwem2" 2 x + check2 "cepojcwem3" 1 y + let addr = &f 4 + addr <- addr + 1 + check2 "cepojcwem4" 2 x + check2 "cepojcwem5" 2 y + + let test2() = + let res = f 3 + let res2 = res + 1 + check2 "cepojcwem2b" 3 res2 + check2 "cepojcwem3b" 2 res + + test() + test2() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestOneArgument.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestOneArgument.fs new file mode 100644 index 00000000000..c2ae2a8b203 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestOneArgument.fs @@ -0,0 +1,13 @@ +open Prelude + +module TestOneArgument = + + let f (x:byref) = &x + + let test() = + let mutable r1 = 1 + let addr = &f &r1 + addr <- addr + 1 + check2 "cepojcwem10" 2 r1 + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestRecordParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestRecordParam.fs new file mode 100644 index 00000000000..ff27acbf6d3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestRecordParam.fs @@ -0,0 +1,14 @@ +open Prelude + +module TestRecordParam = + + type R = { mutable z : int } + let f (x:R) = &x.z + + let test() = + let r = { z = 1 } + let addr = &f r + addr <- addr + 1 + check2 "cepojcwem12" 2 r.z + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestRecordParam2.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestRecordParam2.fs new file mode 100644 index 00000000000..8b5404d3309 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestRecordParam2.fs @@ -0,0 +1,14 @@ +open Prelude + +module TestRecordParam2 = + + type R = { mutable z : int } + let f (x:byref) = &x.z + + let test() = + let mutable r = { z = 1 } + let addr = &f &r + addr <- addr + 1 + check2 "cepojcwem13a" 2 r.z + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestStructParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestStructParam.fs new file mode 100644 index 00000000000..cb5cd1f08e7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestStructParam.fs @@ -0,0 +1,16 @@ +open Prelude + +module TestStructParam = + + [] + type R = { mutable z : int } + + let f (x:byref) = &x.z + + let test() = + let mutable r = { z = 1 } + let addr = &f &r + addr <- addr + 1 + check2 "cepojcwem15" 2 r.z + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTryFinallyReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTryFinallyReturn.fs new file mode 100644 index 00000000000..35c237dc5c8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTryFinallyReturn.fs @@ -0,0 +1,26 @@ +open Prelude + +module TestTryFinallyReturn = + let mutable x = 1 + let mutable y = 1 + + let f inp = try &x with _ -> &y + + let test() = + let addr = &f 3 + addr <- addr + 1 + check2 "cepojcwem6b" 2 x + check2 "cepojcwem7b" 1 y + let addr = &f 4 + addr <- addr + 1 + check2 "cepojcwem8b" 3 x + check2 "cepojcwem9b" 1 y + + let test2() = + let res = f 3 + let res2 = res + 1 + check2 "cepojcwem2tf" 4 res2 + check2 "cepojcwem3qw" 3 res + + test() + test2() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTryWithReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTryWithReturn.fs new file mode 100644 index 00000000000..31f4b6fe0bc --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTryWithReturn.fs @@ -0,0 +1,26 @@ +open Prelude + +module TestTryWithReturn = + let mutable x = 1 + let mutable y = 1 + + let f inp = try &x with _ -> &y + + let test() = + let addr = &f 3 + addr <- addr + 1 + check2 "cepojcwem6b" 2 x + check2 "cepojcwem7b" 1 y + let addr = &f 4 + addr <- addr + 1 + check2 "cepojcwem8b" 3 x + check2 "cepojcwem9b" 1 y + + let test2() = + let res = f 3 + let res2 = res + 1 + check2 "cepojcwem2ff" 4 res2 + check2 "cepojcwem3gg" 3 res + + test() + test2() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTwoArguments.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTwoArguments.fs new file mode 100644 index 00000000000..84c1472e4f3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTwoArguments.fs @@ -0,0 +1,14 @@ +open Prelude + +module TestTwoArguments = + + let f (x:byref, y:byref) = &x + + let test() = + let mutable r1 = 1 + let mutable r2 = 0 + let addr = &f (&r1, &r2) + addr <- addr + 1 + check2 "cepojcwem11" 2 r1 + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/BaseCallByref.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/BaseCallByref.fs new file mode 100644 index 00000000000..315f4af7108 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/BaseCallByref.fs @@ -0,0 +1,14 @@ +open Prelude + +module BaseCallByref = + type Incrementor(z) = + abstract member Increment : int byref * int byref -> unit + default this.Increment(i : int byref,j : int byref) = + i <- i + z + + type Decrementor(z) = + inherit Incrementor(z) + override this.Increment(i, j) = + base.Increment(&i, &j) + + i <- i - z \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/Bug820.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/Bug820.fs new file mode 100644 index 00000000000..9683efb8f6e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/Bug820.fs @@ -0,0 +1,7 @@ +open Prelude + +module Bug820 = + + let inline f (x, r:byref<_>) = r <- x + let mutable x = Unchecked.defaultof<_> + f (0, &x) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/Bug820b.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/Bug820b.fs new file mode 100644 index 00000000000..3abbbca2e04 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/Bug820b.fs @@ -0,0 +1,8 @@ +open Prelude + +module Bug820b = + + type Bug820x() = + let f (x, r:byref<_>) = r <- x + let mutable x = Unchecked.defaultof<_> + member __.P = f (0, &x) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/ByRefExtensionMethods1.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/ByRefExtensionMethods1.fs new file mode 100644 index 00000000000..d79a94cb74e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/ByRefExtensionMethods1.fs @@ -0,0 +1,18 @@ +open Prelude + +module ByRefExtensionMethods1 = + + open System + open System.Runtime.CompilerServices + + [] + type Ext = + + [] + static member ExtDateTime2(dt: inref, x:int) = dt.AddDays(double x) + + module UseExt = + let now = DateTime.Now + let dt2 = now.ExtDateTime2(3) + check "£f3mllkm2" dt2 (now.AddDays(3.0)) + \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/ByRefExtensionMethodsOverloading.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/ByRefExtensionMethodsOverloading.fs new file mode 100644 index 00000000000..12db461f322 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/ByRefExtensionMethodsOverloading.fs @@ -0,0 +1,18 @@ +open Prelude + +module ByRefExtensionMethodsOverloading = + + open System + open System.Runtime.CompilerServices + + [] + type Ext = + [] + static member ExtDateTime(dt: DateTime, x:int) = dt.AddDays(double x) + + [] + static member ExtDateTime(dt: inref, x:int) = dt.AddDays(2.0 * double x) + + module UseExt = + let dt = DateTime.Now.ExtDateTime(3) + let dt2 = DateTime.Now.ExtDateTime(3) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/GenericTestNameRecursive.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/GenericTestNameRecursive.fs new file mode 100644 index 00000000000..9cdf1b27a65 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/GenericTestNameRecursive.fs @@ -0,0 +1,16 @@ +open Prelude + +type GenericTestNameRecursive() = + + let rec testValue unused id (data: byref) : unit = + if id = 10 then data <- 3uy else testValue unused (id + 1) &data + + static do GenericTestNameRecursive().Test() + + member __.Test() = + let mutable x = 0uy + testValue "unused" 0 &x + check "vruoer3rv" x 3uy + let mutable z = 0uy + testValue 6L 0 &z + check "vruoer3rvwqf" z 3uy \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/MatrixOfTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/MatrixOfTests.fs new file mode 100644 index 00000000000..5d1f006f809 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/MatrixOfTests.fs @@ -0,0 +1,154 @@ +open Prelude + +[] +type S = + [] + val mutable X : int + +module MatrixOfTests = + + module ReturnAddressOfByRef = + let f1 (x: byref) = &x + + module ReturnAddressOfInRef = + let f1 (x: inref) = &x + + module ReturnAddressOfOutRef = + let f1 (x: outref) = &x + + //----- + + module ReadByRef = + let f1 (x: byref) = x + + module ReadInRef = + let f1 (x: inref) = x + + module ReadOutRef = + let f1 (x: outref) = x + + //----- + + module ReadByRefStructInner = + let f1 (x: byref) = x.X + + module ReadInRefStructInner = + let f1 (x: inref) = x.X + + module ReadOutRefStructInner = + let f1 (x: outref) = x.X + + //----- + module WriteToByRef = + let f1 (x: byref) = x <- 1 + + module WriteToOutRef = + let f1 (x: outref) = x <- 1 + + //----- + module WriteToByRefStructInner = + let f1 (x: byref) = x.X <- 1 + + module WriteToOutRefStructInner = + let f1 (x: outref) = x.X <- 1 + + //----- + module OutRefToByRef = + let f1 (x: byref<'T>) = 1 + let f2 (x: outref<'T>) = f1 &x + + module ByRefToByRef = + let f1 (x: byref<'T>) = 1 + let f2 (x: byref<'T>) = f1 &x + + module ByRefToOutRef = + let f1 (x: outref<'T>) = 1 + let f2 (x: byref<'T>) = f1 &x + + module OutRefToOutRef = + let f1 (x: outref<'T>) = 1 + let f2 (x: outref<'T>) = f1 &x + + module ByRefToInRef = + let f1 (x: inref<'T>) = 1 + let f2 (x: byref<'T>) = f1 &x + + module InRefToInRef = + let f1 (x: inref<'T>) = 1 + let f2 (x: inref<'T>) = f1 &x + + module OutRefToInRef = + let f1 (x: inref<'T>) = 1 + let f2 (x: outref<'T>) = f1 &x // allowed, because &outref are treated as byref, see RFC + + //--------------- + module OutRefToByRefClassMethod = + type C() = + static member f1 (x: byref<'T>) = 1 + let f2 (x: outref<'T>) = C.f1 &x + + module ByRefToByRefClassMethod = + type C() = + static member f1 (x: byref<'T>) = 1 + let f2 (x: byref<'T>) = C.f1 &x + + module ByRefToOutRefClassMethod = + type C() = + static member f1 (x: outref<'T>) = 1 + let f2 (x: byref<'T>) = C.f1 &x + + module OutRefToOutRefClassMethod = + type C() = + static member f1 (x: outref<'T>) = 1 + let f2 (x: outref<'T>) = C.f1 &x + + module ByRefToInRefClassMethod = + type C() = + static member f1 (x: inref<'T>) = 1 + let f2 (x: byref<'T>) = C.f1 &x + + module InRefToInRefClassMethod = + type C() = + static member f1 (x: inref<'T>) = 1 + let f2 (x: inref<'T>) = C.f1 &x + + module OutRefToInRefClassMethod = + type C() = + static member f1 (x: inref<'T>) = 1 + let f2 (x: outref<'T>) = C.f1 &x + + //--------------- + module OutRefToByRefClassMethod2 = + type C() = + static member f1 (x: byref<'T>) = 1 + let f2 (x: outref<'T>) = C.f1(&x) + + module ByRefToByRefClassMethod2 = + type C() = + static member f1 (x: byref<'T>) = 1 + let f2 (x: byref<'T>) = C.f1(&x) + + module ByRefToOutRefClassMethod2 = + type C() = + static member f1 (x: outref<'T>) = 1 + let f2 (x: byref<'T>) = C.f1(&x) + + module OutRefToOutRefClassMethod2 = + type C() = + static member f1 (x: outref<'T>) = 1 + let f2 (x: outref<'T>) = C.f1(&x) + + module ByRefToInRefClassMethod2 = + type C() = + static member f1 (x: inref<'T>) = 1 + let f2 (x: byref<'T>) = C.f1(&x) + + module InRefToInRefClassMethod2 = + type C() = + static member f1 (x: inref<'T>) = 1 + let f2 (x: inref<'T>) = C.f1(&x) + + module OutRefToInRefClassMethod2 = + type C() = + static member f1 (x: inref<'T>) = 1 + let f2 (x: outref<'T>) = C.f1(&x) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/MutateInRef3.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/MutateInRef3.fs new file mode 100644 index 00000000000..26eeef6e5f5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/MutateInRef3.fs @@ -0,0 +1,20 @@ +open Prelude + +module MutateInRef3 = + [] + type TestMut(x: int ref) = + + member this.X = x.contents + member this.XAddr = &x.contents + + let testIn (m: inref) = + // If the struct API indirectly reveals a byref return of a field in a reference type then + // there is nothing stopping it being written to. + m.XAddr <- 1 + + let test() = + let m = TestMut(ref 0) + testIn (&m) + check "vleoij" m.X 1 + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/NonGenericTestNameRecursiveInClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/NonGenericTestNameRecursiveInClass.fs new file mode 100644 index 00000000000..8c9a913b7ec --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/NonGenericTestNameRecursiveInClass.fs @@ -0,0 +1,16 @@ +open Prelude + +type NonGenericTestNameRecursiveInClass() = + + let rec testValue id (data: byref) : unit = + if id = 10 then + data <- 3uy + else + testValue (id + 1) &data + + static do NonGenericTestNameRecursiveInClass().Test() + + member __.Test() = + let mutable x = 0uy + testValue 0 &x + check "vruoer3rvvremtys" x 3uy \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/NonGenericTestNameRecursiveInClassSubsume.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/NonGenericTestNameRecursiveInClassSubsume.fs new file mode 100644 index 00000000000..0b075d00ced --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/NonGenericTestNameRecursiveInClassSubsume.fs @@ -0,0 +1,16 @@ +open Prelude + +type NonGenericTestNameRecursiveInClassSubsume() = + + let rec testValue id (data: byref) (y:System.IComparable) : unit = + if id = 10 then + data <- 3uy + else + testValue (id + 1) &data y + + static do NonGenericTestNameRecursiveInClassSubsume().Test() + + member __.Test() = + let mutable x = 0uy + testValue 0 &x Unchecked.defaultof + check "vruoer3rvvremtys" x 3uy \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/StaticGenericTestNameRecursiveInClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/StaticGenericTestNameRecursiveInClass.fs new file mode 100644 index 00000000000..63a71e7192e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/StaticGenericTestNameRecursiveInClass.fs @@ -0,0 +1,16 @@ +open Prelude + +type StaticGenericTestNameRecursiveInClass() = + + static let rec testValue unused id (data: byref) : unit = + if id = 10 then data <- 3uy else testValue unused (id + 1) &data + + static do StaticGenericTestNameRecursiveInClass.Test() + + static member Test() = + let mutable x = 0uy + testValue "unused" 0 &x + check "vruoer3rv" x 3uy + let mutable z = 0uy + testValue 6L 0 &z + check "vruoer3rvwqfgw" z 3uy \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/StaticNonGenericTestNameRecursiveInClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/StaticNonGenericTestNameRecursiveInClass.fs new file mode 100644 index 00000000000..27495aee9cf --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/StaticNonGenericTestNameRecursiveInClass.fs @@ -0,0 +1,13 @@ +open Prelude + +type StaticNonGenericTestNameRecursiveInClass() = + + static let rec testValue id (data: byref) : unit = + if id = 10 then data <- 3uy else testValue (id + 1) &data + + static do StaticNonGenericTestNameRecursiveInClass.Test() + + static member Test() = + let mutable x = 0uy + testValue 0 &x + check "vruoer3rvvrebae" x 3uy \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestArrayParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestArrayParam.fs new file mode 100644 index 00000000000..959e18d5084 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestArrayParam.fs @@ -0,0 +1,14 @@ +open Prelude + +module TestArrayParam = + + type C() = + static member M (x:int[]) = &x.[0] + + let test() = + let r = [| 1 |] + let addr = &C.M r + addr <- addr + 1 + check2 "mepojcwem14" 2 r.[0] + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestAssignToReturnByref.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestAssignToReturnByref.fs new file mode 100644 index 00000000000..5cfba19159f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestAssignToReturnByref.fs @@ -0,0 +1,24 @@ +open Prelude + +module TestAssignToReturnByref = + type C() = + static let mutable v = System.DateTime.Now + static member M() = &v + static member P = &v + member __.InstanceM() = &v + member __.InstanceP with get() = &v + static member Value = v + + let F1() = + let today = System.DateTime.Now.Date + C.M() <- today + check "cwecjc" C.Value today + C.P <- C.M().AddDays(1.0) + check "cwecjc1" C.Value (today.AddDays(1.0)) + let c = C() + c.InstanceM() <- today.AddDays(2.0) + check "cwecjc2" C.Value (today.AddDays(2.0)) + c.InstanceP <- today.AddDays(3.0) + check "cwecjc1" C.Value (today.AddDays(3.0)) + + F1() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestAssignToReturnByref2.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestAssignToReturnByref2.fs new file mode 100644 index 00000000000..27b9b76f283 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestAssignToReturnByref2.fs @@ -0,0 +1,12 @@ +open Prelude + +module TestAssignToReturnByref2 = + let mutable v = System.DateTime.Now + let M() = &v + + let F1() = + let today = System.DateTime.Now.Date + M() <- today + check "cwecjc" v today + + F1() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestBaseCall.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestBaseCall.fs new file mode 100644 index 00000000000..acd8797df8d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestBaseCall.fs @@ -0,0 +1,14 @@ +open Prelude + +module TestBaseCall = + type Incrementor(z) = + abstract member Increment : int byref * int byref -> unit + default this.Increment(i : int byref,j : int byref) = + i <- i + z + + type Decrementor(z) = + inherit Incrementor(z) + override this.Increment(i, j) = + base.Increment(&i, &j) + + i <- i - z \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestClassParamMutableField.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestClassParamMutableField.fs new file mode 100644 index 00000000000..efc89a89c8f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestClassParamMutableField.fs @@ -0,0 +1,16 @@ +open Prelude + +module TestClassParamMutableField = + + type C() = [] val mutable z : int + + type C2() = + static member M (x:C) = &x.z + + let test() = + let c = C() + let addr = &C2.M c + addr <- addr + 1 + check2 "mepojcwem13b" 1 c.z + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestConditionalReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestConditionalReturn.fs new file mode 100644 index 00000000000..3a9737c8f8b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestConditionalReturn.fs @@ -0,0 +1,27 @@ +open Prelude + +module TestConditionalReturn = + let mutable x = 1 + let mutable y = 1 + + type C() = + static member M inp = if inp = 3 then &x else &y + + let test() = + let addr = &C.M 3 + addr <- addr + 1 + check2 "mepojcwem6" 2 x + check2 "mepojcwem7" 1 y + let addr = &C.M 4 + addr <- addr + 1 + check2 "mepojcwem8" 2 x + check2 "mepojcwem9" 2 y + + let test2() = + let res = &C.M 3 + let res2 = res + 1 + check2 "mepojcwem8b" 3 res2 + check2 "mepojcwem9b" 2 res + + test() + test2() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestDelegateMethod.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestDelegateMethod.fs new file mode 100644 index 00000000000..20e1056c54d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestDelegateMethod.fs @@ -0,0 +1,15 @@ +open Prelude + +module TestDelegateMethod = + let mutable x = 1 + + type D = delegate of unit -> byref + + let test() = + let d = D(fun () -> &x) + let addr = &d.Invoke() + check2 "mepojcwem18a" 1 x + addr <- addr + 1 + check2 "mepojcwem18b" 2 x + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestDelegateMethod2.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestDelegateMethod2.fs new file mode 100644 index 00000000000..550cfd20f8f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestDelegateMethod2.fs @@ -0,0 +1,16 @@ +open Prelude + +module TestDelegateMethod2 = + let mutable x = 1 + + type D = delegate of byref -> byref + + let d = D(fun xb -> &xb) + + let test() = + let addr = &d.Invoke(&x) + check2 "mepojcwem18a2" 1 x + addr <- addr + 1 + check2 "mepojcwem18b3" 2 x + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestImmediateReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestImmediateReturn.fs new file mode 100644 index 00000000000..1b3f1c29c03 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestImmediateReturn.fs @@ -0,0 +1,21 @@ +open Prelude + +module TestImmediateReturn = + let mutable x = 1 + + type C() = + static member M () = &x + + let test() = + let addr : byref = &C.M() + addr <- addr + 1 + check2 "mepojcwem1" 2 x + + + let test2() = + let v = &C.M() + let res = v + 1 + check2 "mepojcwem1b" 3 res + + test() + test2() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInRefMutation.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInRefMutation.fs new file mode 100644 index 00000000000..ac592fd1036 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInRefMutation.fs @@ -0,0 +1,21 @@ +open Prelude + +module TestInRefMutation = + [] + type TestMut = + + val mutable x : int + + member this.AnAction() = + this.x <- 1 + + let testAction (m: inref) = + m.AnAction() + check "vleoij" m.x 0 + + let test() = + let x = TestMut() + //testIn (&x) + testAction (&x) + x + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInterfaceMethod.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInterfaceMethod.fs new file mode 100644 index 00000000000..39c94a1dec9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInterfaceMethod.fs @@ -0,0 +1,24 @@ +open Prelude + +module TestInterfaceMethod = + let mutable x = 1 + + type I = + abstract M : unit -> byref + + type C() = + interface I with + member this.M() = &x + + let ObjExpr() = + { new I with + member this.M() = &x } + + let test() = + let addr = &(C() :> I).M() + addr <- addr + 1 + let addr = &(ObjExpr()).M() + addr <- addr + 1 + check2 "mepojcwem16" 3 x + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInterfaceProperty.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInterfaceProperty.fs new file mode 100644 index 00000000000..a0035f526fc --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInterfaceProperty.fs @@ -0,0 +1,24 @@ +open Prelude + +module TestInterfaceProperty = + let mutable x = 1 + + type I = + abstract P : byref + + type C() = + interface I with + member this.P = &x + + let ObjExpr() = + { new I with + member this.P = &x } + + let test() = + let addr = &(C() :> I).P + addr <- addr + 1 + let addr = &(ObjExpr()).P + addr <- addr + 1 + check2 "mepojcwem17" 3 x + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestMatchReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestMatchReturn.fs new file mode 100644 index 00000000000..ef29ad77b18 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestMatchReturn.fs @@ -0,0 +1,27 @@ +open Prelude + +module TestMatchReturn = + let mutable x = 1 + let mutable y = 1 + + type C() = + static member M inp = match inp with 3 -> &x | _ -> &y + + let test() = + let addr = &C.M 3 + addr <- addr + 1 + check2 "mepojcwem2" 2 x + check2 "mepojcwem3" 1 y + let addr = &C.M 4 + addr <- addr + 1 + check2 "mepojcwem4" 2 x + check2 "mepojcwem5" 2 y + + let test2() = + let res = &C.M 3 + let res2 = res + 1 + check2 "mepojcwem2b" 3 res2 + check2 "mepojcwem3b" 2 res + + test() + test2() diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleGeneric.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleGeneric.fs new file mode 100644 index 00000000000..c5826ae846c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleGeneric.fs @@ -0,0 +1,15 @@ +open Prelude + +// check recursive functions +module TestNameModuleGeneric = + + let rec testValue (unused: 'T) id (data: byref) : unit = + if id = 10 then + data <- 3uy + else + testValue unused (id + 1) &data + let Test() = + let mutable x = 0uy + testValue "unused" 0 &x + check "vruoer" x 3uy + Test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleNonGeneric.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleNonGeneric.fs new file mode 100644 index 00000000000..005435649b2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleNonGeneric.fs @@ -0,0 +1,15 @@ +open Prelude + +module TestNameModuleNonGeneric = + + let rec testValue id (data: byref) : unit = + if id = 10 then + data <- 3uy + else + testValue (id + 1) &data + + let Test() = + let mutable x = 0uy + testValue 0 &x + check "vruoer3r" x 3uy + Test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleNonGenericSubsume.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleNonGenericSubsume.fs new file mode 100644 index 00000000000..b5af70ab710 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleNonGenericSubsume.fs @@ -0,0 +1,16 @@ +open Prelude + +module TestNameModuleNonGenericSubsume = + + let rec testValue id (data: byref) (y: System.IComparable) : unit = + if id = 10 then + data <- 3uy + else + testValue (id + 1) &data y + + let Test() = + let mutable x = 0uy + testValue 0 &x Unchecked.defaultof + check "vruoer3r" x 3uy + + Test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgument.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgument.fs new file mode 100644 index 00000000000..db6992196e7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgument.fs @@ -0,0 +1,14 @@ +open Prelude + +module TestOneArgument = + + type C() = + static member M (x:byref) = &x + + let test() = + let mutable r1 = 1 + let addr = &C.M (&r1) + addr <- addr + 1 + check2 "mepojcwem10" 2 r1 + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgumentInRefReturned.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgumentInRefReturned.fs new file mode 100644 index 00000000000..ec4f12ed4d7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgumentInRefReturned.fs @@ -0,0 +1,15 @@ +open Prelude + +module TestOneArgumentInRefReturned = + + type C() = + static member M (x:inref) = &x + + let test() = + let mutable r1 = 1 + let addr = &C.M (&r1) + let x = addr + 1 + check2 "mepojcwem10" 1 r1 + check2 "mepojcwem10vr" 2 x + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgumentOutRef.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgumentOutRef.fs new file mode 100644 index 00000000000..12f4ee80502 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgumentOutRef.fs @@ -0,0 +1,14 @@ +open Prelude + +module TestOneArgumentOutRef = + + type C() = + static member M (x:outref) = &x + + let test() = + let mutable r1 = 1 + let addr = &C.M (&r1) + addr <- addr + 1 + check2 "mepojcwem10" 2 r1 + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestReadOnlyAddressOfStaticField.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestReadOnlyAddressOfStaticField.fs new file mode 100644 index 00000000000..237f20f7673 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestReadOnlyAddressOfStaticField.fs @@ -0,0 +1,12 @@ +open Prelude + +module TestReadOnlyAddressOfStaticField = + type C() = + static let x = 1 + static member F() = &x + + let test() = + let addr = &C.F() + check2 "mepojcwem18a2dw" 1 addr + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestRecordParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestRecordParam.fs new file mode 100644 index 00000000000..92b0c0a17a8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestRecordParam.fs @@ -0,0 +1,15 @@ +open Prelude + +module TestRecordParam = + + type R = { mutable z : int } + type C() = + static member M (x:R) = &x.z + + let test() = + let r = { z = 1 } + let addr = &C.M r + addr <- addr + 1 + check2 "mepojcwem12" 2 r.z + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestRecordParam2.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestRecordParam2.fs new file mode 100644 index 00000000000..3a0ee11ed96 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestRecordParam2.fs @@ -0,0 +1,15 @@ +open Prelude + +module TestRecordParam2 = + + type R = { mutable z : int } + type C() = + static member M (x:byref) = &x.z + + let test() = + let mutable r = { z = 1 } + let addr = &C.M(&r) + addr <- addr + 1 + check2 "mepojcwem13a" 2 r.z + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestStructParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestStructParam.fs new file mode 100644 index 00000000000..984470b78a3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestStructParam.fs @@ -0,0 +1,17 @@ +open Prelude + +module TestStructParam = + + [] + type R = { mutable z : int } + + type C() = + static member M (x:byref) = &x.z + + let test() = + let mutable r = { z = 1 } + let addr = &C.M(&r) + addr <- addr + 1 + check2 "mepojcwem15" 2 r.z + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestStructRecord.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestStructRecord.fs new file mode 100644 index 00000000000..8666dbd4945 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestStructRecord.fs @@ -0,0 +1,9 @@ +open Prelude + +module TestStructRecord = + [] + type AnItem = + { Link: string } + + let link item = + { item with Link = "" } \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTryFinallyReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTryFinallyReturn.fs new file mode 100644 index 00000000000..0da75201cc0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTryFinallyReturn.fs @@ -0,0 +1,27 @@ +open Prelude + +module TestTryFinallyReturn = + let mutable x = 1 + let mutable y = 1 + + type C() = + static member M inp = try &x with _ -> &y + + let test() = + let addr = &C.M 3 + addr <- addr + 1 + check2 "mepojcwem6b" 2 x + check2 "mepojcwem7b" 1 y + let addr = &C.M 4 + addr <- addr + 1 + check2 "mepojcwem8b" 3 x + check2 "mepojcwem9b" 1 y + + let test2() = + let res = &C.M 3 + let res2 = res + 1 + check2 "mepojcwem2tf" 4 res2 + check2 "mepojcwem3qw" 3 res + + test() + test2() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTryWithReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTryWithReturn.fs new file mode 100644 index 00000000000..37687b5b28a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTryWithReturn.fs @@ -0,0 +1,27 @@ +open Prelude + +module TestTryWithReturn = + let mutable x = 1 + let mutable y = 1 + + type C() = + static member M inp = try &x with _ -> &y + + let test() = + let addr = &C.M 3 + addr <- addr + 1 + check2 "mepojcwem6b" 2 x + check2 "mepojcwem7b" 1 y + let addr = &C.M 4 + addr <- addr + 1 + check2 "mepojcwem8b" 3 x + check2 "mepojcwem9b" 1 y + + let test2() = + let res = &C.M 3 + let res2 = res + 1 + check2 "mepojcwem2ff" 4 res2 + check2 "mepojcwem3gg" 3 res + + test() + test2() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTwoArguments.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTwoArguments.fs new file mode 100644 index 00000000000..e49f40d7536 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTwoArguments.fs @@ -0,0 +1,15 @@ +open Prelude + +module TestTwoArguments = + + type C() = + static member M (x:byref, y:byref) = &x + + let test() = + let mutable r1 = 1 + let mutable r2 = 0 + let addr = &C.M (&r1, &r2) + addr <- addr + 1 + check2 "mepojcwem11" 2 r1 + + test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs index 6517e0a7734..16637ac9106 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -7,7 +7,720 @@ open FSharp.Test open FSharp.Test.Compiler module ByrefSafetyAnalysis = + let withPrelude = + withReferences [ + FsFromPath (__SOURCE_DIRECTORY__ ++ "Prelude.fs") + |> withName "Prelude" + ] + + let verifyCompile compilation = + compilation + |> asExe + |> withNoWarn 3370 + |> withOptions ["--test:ErrorRanges"] + |> withPrelude + |> compile + + let verifyCompileAndRun compilation = + compilation + |> asExe + |> withNoWarn 3370 + |> withOptions ["--test:ErrorRanges"] + |> withPrelude + |> compileAndRun + + // SOURCE=Migrated02.fs SCFLAGS="--test:ErrorRanges" # Migrated02.fs + [] + let``MigratedTest02_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + // SOURCE=E_Migrated02.fs SCFLAGS="--test:ErrorRanges" # E_Migrated02.fs + [] + let``E_Migrated02_fs`` compilation = + compilation + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Warning 193, Line 165, Col 9, Line 165, Col 22, "This expression is a function value, i.e. is missing arguments. Its type is byref -> unit.") + (Warning 193, Line 183, Col 9, Line 183, Col 20, "This expression is a function value, i.e. is missing arguments. Its type is int -> byref -> unit.") + (Warning 193, Line 198, Col 9, Line 198, Col 24, "This expression is a function value, i.e. is missing arguments. Its type is inref * int -> unit.") + (Warning 20, Line 206, Col 9, Line 206, Col 18, "The result of this expression has type 'byref * 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'.") + (Error 3209, Line 13, Col 18, Line 13, Col 19, "The address of the variable 'y' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3209, Line 20, Col 18, Line 20, Col 19, "The address of the variable 'z' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3209, Line 29, Col 14, Line 29, Col 15, "The address of the variable 'x' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3209, Line 33, Col 14, Line 33, Col 15, "The address of the variable 'y' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3209, Line 40, Col 14, Line 40, Col 15, "The address of the variable 'x' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3209, Line 43, Col 14, Line 43, Col 15, "The address of the variable 'y' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3209, Line 52, Col 18, Line 52, Col 19, "The address of the variable 'z' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3209, Line 53, Col 10, Line 53, Col 11, "The address of the variable 'y' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3228, Line 63, Col 14, Line 63, Col 29, "The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3228, Line 71, Col 14, Line 71, Col 29, "The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 412, Line 77, Col 13, Line 77, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 77, Col 17, Line 77, Col 29, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 421, Line 77, Col 28, Line 77, Col 29, "The address of the variable 'x' cannot be used at this point") + (Error 425, Line 77, Col 17, Line 77, Col 29, "The type of a first-class function cannot contain byrefs") + (Error 3209, Line 96, Col 53, Line 96, Col 54, "The address of the variable 'x' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 3209, Line 108, Col 41, Line 108, Col 42, "The address of the variable 'x' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + (Error 438, Line 117, Col 23, Line 117, Col 33, "Duplicate method. The method 'TestMethod' has the same name and signature as another method in type 'NegativeTests.TestNegativeOverloading'.") + (Error 438, Line 115, Col 23, Line 115, Col 33, "Duplicate method. The method 'TestMethod' has the same name and signature as another method in type 'NegativeTests.TestNegativeOverloading'.") + (Error 438, Line 113, Col 23, Line 113, Col 33, "Duplicate method. The method 'TestMethod' has the same name and signature as another method in type 'NegativeTests.TestNegativeOverloading'.") + (Error 412, Line 121, Col 18, Line 121, Col 22, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 123, Col 18, Line 123, Col 23, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 3301, Line 125, Col 9, Line 125, Col 14, "The function or method has an invalid return type '(byref * int)'. This is not permitted by the rules of Common IL.") + (Error 412, Line 125, Col 34, Line 125, Col 39, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 418, Line 125, Col 35, Line 125, Col 36, "The byref typed value 'x' cannot be used at this point") + (Error 3301, Line 127, Col 9, Line 127, Col 14, "The function or method has an invalid return type '(byref -> unit)'. This is not permitted by the rules of Common IL.") + (Error 412, Line 129, Col 14, Line 129, Col 15, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 3300, Line 131, Col 17, Line 131, Col 18, "The parameter 'x' has an invalid type '((byref -> unit) * int)'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 133, Col 17, Line 133, Col 18, "The parameter 'x' has an invalid type '(byref -> unit)'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 133, Col 41, Line 133, Col 42, "The parameter 'y' has an invalid type '(byref * int)'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 139, Col 36, Line 139, Col 39, "The parameter 'tup' has an invalid type '(inref * int)'. This is not permitted by the rules of Common IL.") + (Error 412, Line 140, Col 13, Line 140, Col 33, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 3300, Line 142, Col 37, Line 142, Col 38, "The parameter 'x' has an invalid type '(byref -> unit)'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 144, Col 37, Line 144, Col 38, "The parameter 'x' has an invalid type 'byref option'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 146, Col 17, Line 146, Col 18, "The parameter 'x' has an invalid type 'byref option'. This is not permitted by the rules of Common IL.") + (Error 412, Line 151, Col 13, Line 151, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 151, Col 17, Line 151, Col 30, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 3301, Line 154, Col 9, Line 154, Col 15, "The function or method has an invalid return type '(byref -> unit)'. This is not permitted by the rules of Common IL.") + (Error 412, Line 155, Col 9, Line 155, Col 22, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 158, Col 13, Line 158, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 160, Col 13, Line 160, Col 26, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 165, Col 9, Line 165, Col 22, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 169, Col 13, Line 169, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 169, Col 17, Line 169, Col 28, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 3301, Line 172, Col 9, Line 172, Col 15, "The function or method has an invalid return type '(int -> byref -> unit)'. This is not permitted by the rules of Common IL.") + (Error 412, Line 173, Col 9, Line 173, Col 20, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 176, Col 13, Line 176, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 178, Col 13, Line 178, Col 24, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 183, Col 9, Line 183, Col 20, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 187, Col 13, Line 187, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 187, Col 17, Line 187, Col 32, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 425, Line 187, Col 17, Line 187, Col 32, "The type of a first-class function cannot contain byrefs") + (Error 412, Line 191, Col 13, Line 191, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 193, Col 13, Line 193, Col 28, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 198, Col 9, Line 198, Col 24, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 3301, Line 201, Col 9, Line 201, Col 15, "The function or method has an invalid return type '(byref * int)'. This is not permitted by the rules of Common IL.") + (Error 412, Line 203, Col 10, Line 203, Col 15, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 421, Line 203, Col 11, Line 203, Col 12, "The address of the variable 'x' cannot be used at this point") + (Error 412, Line 206, Col 9, Line 206, Col 18, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 210, Col 13, Line 210, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + (Error 412, Line 210, Col 17, Line 210, Col 26, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") + ] + + // SOURCE=Migrated03.fs SCFLAGS="--test:ErrorRanges" # Migrated03.fs + [] + let``MigratedTest03_fs`` compilation = + let csharpLib = + CSharpFromPath (__SOURCE_DIRECTORY__ ++ "MigratedTest03CSharpLib.cs") + |> withName "CSharpLib3" + + compilation + |> withReferences [ csharpLib ] + |> withOptions ["--nowarn:3370"] + |> compileExeAndRun + |> shouldSucceed + + // SOURCE=E_Migrated03.fs SCFLAGS="--test:ErrorRanges" # E_Migrated03.fs + [] + let``E_Migrated03_fs`` compilation = + let csharpLib = + CSharpFromPath (__SOURCE_DIRECTORY__ ++ "MigratedTest03CSharpLib.cs") + |> withName "CSharpLib3" + + compilation + |> asExe + |> withReferences [ csharpLib ] + |> withNoWarn 52 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3237, Line 23, Col 18, Line 23, Col 28, "Cannot call the byref extension method 'Test2. The first parameter requires the value to be mutable or a non-readonly byref type.") + (Error 1, Line 24, Col 9, Line 24, Col 11, "Type mismatch. Expecting a + 'byref' +but given a + 'inref' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + (Error 3237, Line 28, Col 9, Line 28, Col 20, "Cannot call the byref extension method 'Change. The first parameter requires the value to be mutable or a non-readonly byref type.") + (Error 3237, Line 33, Col 19, Line 33, Col 30, "Cannot call the byref extension method 'Test2. The first parameter requires the value to be mutable or a non-readonly byref type.") + (Error 3237, Line 39, Col 9, Line 39, Col 21, "Cannot call the byref extension method 'Change. The first parameter requires the value to be mutable or a non-readonly byref type.") + (Error 3239, Line 43, Col 17, Line 43, Col 29, "Cannot partially apply the extension method 'NotChange' because the first parameter is a byref type.") + (Error 3239, Line 44, Col 17, Line 44, Col 24, "Cannot partially apply the extension method 'Test' because the first parameter is a byref type.") + (Error 3239, Line 45, Col 17, Line 45, Col 26, "Cannot partially apply the extension method 'Change' because the first parameter is a byref type.") + (Error 3239, Line 46, Col 17, Line 46, Col 25, "Cannot partially apply the extension method 'Test2' because the first parameter is a byref type.") + ] + + [] + let``TryGetValue_fs`` compilation = + compilation |> withPrelude |> compileExeAndRun |> shouldSucceed + + [] + let``CompareExchange_fs`` compilation = + compilation + |> withPrelude + |> withOptions ["--nowarn:3370"] + |> compileExeAndRun + |> shouldSucceed + + [] + let``ByRefParam_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``ByRefParam_ExplicitOutAttribute_fs`` compilation = + compilation |> withPrelude |> withOptions ["--nowarn:3370"] |> compileExeAndRun |> shouldSucceed + + [] + let``ByRefParam_ExplicitInAttribute_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``ByRefReturn_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``Slot_ByRefReturn_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefReturn_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``Slot_InRefReturn_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``OutRefParam_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``OutRefParam_ExplicitOutAttribute_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``Slot_OutRefParam_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``ByRefParam_OverloadedTest_ExplicitOutAttribute_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``OutRefParam_Overloaded_ExplicitOutAttribute_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``OutRefParam_Overloaded_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParam_ExplicitInAttribute_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParam_ExplicitInAttributeDateTime_fs`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParam`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParamOverload_ExplicitAddressOfAtCallSite`` compilation = + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParamOverload_ImplicitAddressOfAtCallSite`` compilation = + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParamOverload_ImplicitAddressOfAtCallSite2`` compilation = + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed + + // TODO: Delete this, move into feature branch, or finish this. See: https://github.com/dotnet/fsharp/pull/7989#discussion_r369841104 +#if IMPLICIT_ADDRESS_OF + module FeatureImplicitAddressOf = + [] + let``InRefParam_DateTime`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParam_DateTime_ImplicitAddressOfAtCallSite`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParam_DateTime_ImplicitAddressOfAtCallSite2`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + + [] + let``InRefParam_DateTime_ImplicitAddressOfAtCallSite3`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParam_DateTime_ImplicitAddressOfAtCallSite4`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed +#endif + + [] + let``InRefParam_Generic_ExplicitAddressOfAttCallSite1`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParam_Generic_ExplicitAddressOfAttCallSite2`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + module ByrefReturn = + [] + let``TestImmediateReturn`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestMatchReturn`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestConditionalReturn`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestTryWithReturn`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestTryFinallyReturn`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestOneArgument`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestTwoArguments`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestRecordParam`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestRecordParam2`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestClassParamMutableField`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestArrayParam`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestStructParam`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestInterfaceMethod`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestInterfaceProperty`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestDelegateMethod`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestBaseCall`` compilation = + compilation |> withNoWarn 988 |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestDelegateMethod2`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + module ByrefReturnMember = + [] + let``TestImmediateReturn`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestMatchReturn`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestConditionalReturn`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestTryWithReturn`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestOneArgument`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestOneArgumentInRefReturned`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestOneArgumentOutRef`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestTwoArguments`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestRecordParam`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestRecordParam2`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestClassParamMutableField`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestArrayParam`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestStructParam`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestInterfaceMethod`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestInterfaceProperty`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestDelegateMethod`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestBaseCall`` compilation = + compilation |> withNoWarn 988 |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestDelegateMethod2`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``ByRefExtensionMethods1`` compilation = + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed + + // [] + // let``ByRefExtensionMethodsOverloading`` compilation = + // compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestReadOnlyAddressOfStaticField`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestAssignToReturnByref`` compilation = + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestAssignToReturnByref2`` compilation = + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed + + [] + let``BaseCallByref`` compilation = + compilation |> withNoWarn 988 |> verifyCompileAndRun |> shouldSucceed + + [] + let``Bug820`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``Bug820b`` compilation = + compilation |> withNoWarn 988 |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestNameModuleGeneric`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestNameModuleNonGeneric`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestNameModuleNonGenericSubsume`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``GenericTestNameRecursive`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``NonGenericTestNameRecursiveInClass`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``NonGenericTestNameRecursiveInClassSubsume`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``StaticGenericTestNameRecursiveInClass`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``StaticNonGenericTestNameRecursiveInClass`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestInRefMutation`` compilation = + compilation |> withNoWarn 52 |> withNoWarn 20 |> verifyCompileAndRun |> shouldSucceed + + [] + let``MutateInRef3`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``MatrixOfTests`` compilation = + compilation |> withNoWarn 988 |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestStructRecord`` compilation = + compilation |> withNoWarn 988 |> verifyCompileAndRun |> shouldSucceed + + [] + let``NoTailcallToByrefsWithModReq`` compilation = + compilation |> withNoWarn 20 |> verifyCompileAndRun |> shouldSucceed + + [] + let``E_CantTakeAddressOfExpressionReturningReferenceType`` compilation = + compilation + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3236, Line 15, Col 17, Line 15, Col 32, "Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address.") + (Error 1, Line 15, Col 17, Line 15, Col 32, "Type mismatch. Expecting a + 'byref' +but given a + 'inref' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + (Error 3236, Line 20, Col 17, Line 20, Col 25, "Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address.") + ] + + + + [] + let ``E_WriteToInRef`` () = + FSharp """let f1 (x: inref) = x <- 1""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3224, Line 1, Col 26, Line 1, Col 32, "The byref pointer is readonly, so this write is not permitted.") + ] + + [] + let ``E_WriteToInRefStructInner`` () = + FSharp """let f1 (x: inref) = x.X <- 1""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 39, Line 1, Col 18, Line 1, Col 19, "The type 'S' is not defined.") + (Error 72, Line 1, Col 24, Line 1, Col 27, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.") + ] + + [] + let ``E_InRefToByRef`` () = + FSharp """ +let f1 (x: byref<'T>) = 1 +let f2 (x: inref<'T>) = f1 &x // not allowed +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 3, Col 28, Line 3, Col 30, "Type mismatch. Expecting a + 'byref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + ] + + [] + let ``E_InRefToOutRef`` () = + FSharp """ +let f1 (x: outref<'T>) = 1 +let f2 (x: inref<'T>) = f1 &x // not allowed +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 3, Col 28, Line 3, Col 30, "Type mismatch. Expecting a + 'outref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'") + ] + + [] + let ``E_InRefToByRefClassMethod`` () = + FSharp """ +type C() = + static member f1 (x: byref<'T>) = 1 +let f2 (x: inref<'T>) = C.f1 &x // not allowed +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 4, Col 30, Line 4, Col 32, "Type mismatch. Expecting a + 'byref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + ] + + [] + let ``E_InRefToOutRefClassMethod`` () = + FSharp """ +type C() = + static member f1 (x: byref<'T>) = 1 +let f2 (x: inref<'T>) = C.f1 &x // not allowed +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 4, Col 30, Line 4, Col 32, "Type mismatch. Expecting a + 'byref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + ] + + [] + let ``E_InRefToByRefClassMethod2`` () = + FSharp """ +type C() = + static member f1 (x: byref<'T>) = 1 +let f2 (x: inref<'T>) = C.f1(&x) // not allowed +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 4, Col 30, Line 4, Col 32, "Type mismatch. Expecting a + 'byref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + ] + + [] + let ``E_InRefToOutRefClassMethod2`` () = + FSharp """ +type C() = + static member f1 (x: outref<'T>) = 1 // not allowed (not yet) +let f2 (x: inref<'T>) = C.f1(&x) // not allowed +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 4, Col 30, Line 4, Col 32, "Type mismatch. Expecting a + 'outref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'") + ] + + [] + let ``E_UseOfLibraryOnly`` () = + FSharp """ +type C() = + static member f1 (x: byref<'T, 'U>) = 1 +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1204, Line 3, Col 26, Line 3, Col 39, "This construct is for use in the FSharp.Core library and should not be used directly") + ] + + [] + let ``E_CantTakeAddress`` () = + FSharp """ +let test1 () = + let x = &1 // not allowed + let y = &2 // not allowed + x + y + +let test2_helper (x: byref) = x +let test2 () = + let mutable x = 1 + let y = &test2_helper &x // not allowed + () +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3236, Line 3, Col 13, Line 3, Col 15, "Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address."); + (Error 3236, Line 4, Col 13, Line 4, Col 15, "Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address."); + (Error 3236, Line 10, Col 13, Line 10, Col 29, "Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address.") + ] + + [] + let ``E_InRefParam_DateTime`` () = + FSharp """ +type C() = + static member M(x: inref) = x +let w = System.DateTime.Now +let v = C.M(w) // not allowed +check "cweweoiwe51btw" v w +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 5, Col 14, Line 5, Col 15, "This expression was expected to have type + 'inref' +but here has type + 'System.DateTime' "); + (Error 39, Line 6, Col 1, Line 6, Col 6, "The value or constructor 'check' is not defined. Maybe you want one of the following: + Checked + Unchecked") + ] + + [] + let ``E_ExtensionMethodOnByrefType`` () = + FSharp """ +type byref<'T> with + member this.Test() = 1 + +type inref<'T> with + member this.Test() = 1 +type outref<'T> with + member this.Test() = 1 +""" + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3238, Line 2, Col 6, Line 2, Col 11, "Byref types are not allowed to have optional type extensions.") + (Error 3238, Line 5, Col 6, Line 5, Col 11, "Byref types are not allowed to have optional type extensions.") + (Error 3238, Line 8, Col 6, Line 8, Col 12, "Byref types are not allowed to have optional type extensions.") + ] + + // SOURCE=E_ByrefAsArrayElement.fs SCFLAGS="--test:ErrorRanges" # E_ByrefAsArrayElement.fs [] let``E_ByrefAsArrayElement_fs`` compilation = @@ -174,4 +887,54 @@ module ByrefSafetyAnalysis = |> withOptions ["--warnaserror+"; "--nowarn:988"] |> compileExeAndRun |> shouldSucceed + +#if NET7_0_OR_GREATER +// This constructor added in .NET 7: https://learn.microsoft.com/en-us/dotnet/api/system.span-1.-ctor?view=net-7.0#system-span-1-ctor(-0@) + [] + let``ReturnFieldSetBySpan_fs`` compilation = + compilation + |> asExe + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> compileExeAndRun + |> shouldSucceed + + [] + let``ReturnSpan01_fs`` compilation = + compilation + |> asExe + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> compileExeAndRun + |> shouldSucceed +#endif +#if NETSTANDARD2_1_OR_GREATER + [] + let``E_TopLevelByref_fs`` compilation = + compilation + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 431, Line 6, Col 5, Line 6, Col 13, "A byref typed value would be stored here. Top-level let-bound byref values are not permitted.") + ] + + [] + let``E_SpanUsedInInnerLambda01_fs`` compilation = + compilation + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 406, Line 8, Col 34, Line 8, Col 45, "The byref-typed variable 'span' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.") + ] + + [] + let``E_SpanUsedInInnerLambda02_fs`` compilation = + compilation + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 406, Line 8, Col 34, Line 8, Col 45, "The byref-typed variable 'span' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.") + ] +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/CompareExchange.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/CompareExchange.fs new file mode 100644 index 00000000000..7e37a911e34 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/CompareExchange.fs @@ -0,0 +1,9 @@ +open Prelude + +// Test a simple ref argument +module CompareExchangeTests = + let mutable x = 3 + let v = System.Threading.Interlocked.CompareExchange(&x, 4, 3) + check "cweweoiwekla" v 3 + let v2 = System.Threading.Interlocked.CompareExchange(&x, 5, 3) + check "cweweoiweklb" v2 4 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_ByrefFieldEscapingLocalScope01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_ByrefFieldEscapingLocalScope01.fs new file mode 100644 index 00000000000..99f09259159 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_ByrefFieldEscapingLocalScope01.fs @@ -0,0 +1,10 @@ +// #Regression #Conformance #TypeInference #ByRef +open System + +let testFunction() = + let mutable local = 42 + let span = Span(&local) + span + +// Code shouldn't compile +exit 1 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_ByrefFieldEscapingLocalScope02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_ByrefFieldEscapingLocalScope02.fs new file mode 100644 index 00000000000..50a1cbeaccf --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_ByrefFieldEscapingLocalScope02.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #TypeInference #ByRef +open System + +let testFunction = + fun () -> + let mutable local = 42 + let span = Span(&local) + span + +// Code shouldn't compile +exit 1 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_CantTakeAddressOfExpressionReturningReferenceType.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_CantTakeAddressOfExpressionReturningReferenceType.fs new file mode 100644 index 00000000000..4cbd2c8c739 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_CantTakeAddressOfExpressionReturningReferenceType.fs @@ -0,0 +1,21 @@ +module CantTakeAddressOfExpressionReturningReferenceType = + open System.Collections.Concurrent + open System.Collections.Generic + + let test1 () = + let aggregator = + new ConcurrentDictionary< + string, ConcurrentDictionary + >() + + for kvp in aggregator do + for kvpInner in kvp.Value do + kvp.Value.TryRemove( + kvpInner.Key, + &kvpInner.Value) + |> ignore + + let test2 () = + let x = KeyValuePair(1, [||]) + let y = &x.Value + () \ No newline at end of file diff --git a/tests/fsharp/core/byrefs/test2.fsx b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest02.fs similarity index 68% rename from tests/fsharp/core/byrefs/test2.fsx rename to tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest02.fs index ab7ec8cd730..d91c9a3b56d 100644 --- a/tests/fsharp/core/byrefs/test2.fsx +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest02.fs @@ -1,24 +1,8 @@ +// #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable #if TESTS_AS_APP module Core_byrefs #endif -let failures = ref false -let report_failure (s) = - stderr.WriteLine ("NO: " + s); failures := true -let test s b = if b then () else report_failure(s) - -(* TEST SUITE FOR Int32 *) - -let out r (s:string) = r := !r @ [s] - -let check s actual expected = - if actual = expected then printfn "%s: OK" s - else report_failure (sprintf "%s: FAILED, expected %A, got %A" s expected actual) - -let check2 s expected actual = check s actual expected - -// POST INFERENCE CHECKS -#if NEGATIVE module NegativeTests = let test1 doIt = @@ -225,55 +209,4 @@ module NegativeTests = let test26 () = let x = test24 () () - -#endif - -module Tests = - - let test1 () = - let x = 1 - let f = fun () -> - let y = &x // is allowed - () - - let g = fun () -> - let y = &x // is allowed - () - () - - type TestPositiveOverloading() = - - static member TestMethod(dt: byref) = () - - static member TestMethod(dt: inref) = () - - static member TestMethod(dt: outref) = () - - type PositiveInterface = - - abstract Test : byref * byref -> byref - - // This looks like it should fail, but its sig is 'val test2 : x: byref -> y: byref -> unit' - // unless a signature tells it otherwise, e.g. 'val test2 : (byref -> byref) -> unit' - let test2 (x: byref) = - fun (y: byref) -> () - - type StaticTest private () = - - static member Test (x: byref, y: int) = () - - static member Test2 (x: inref, y: int) = () - - // This passes because tup becomes 'int ref * int', which is valid and produces valid code. - // We include this to test current behavior with inference and byrefs. - static member PositiveTest(tup) = - StaticTest.Test(tup) - - let test3 () = - StaticTest.Test2 // is passing, but probably shouldn't be - -let aa = - if !failures then (stdout.WriteLine "Test Failed"; exit 1) - else (stdout.WriteLine "Test Passed"; - System.IO.File.WriteAllText("test2.ok","ok"); - exit 0) \ No newline at end of file + \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest03.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest03.fs new file mode 100644 index 00000000000..35add5f495a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest03.fs @@ -0,0 +1,47 @@ +#if TESTS_AS_APP +module Core_byrefs +#endif + +open System +open System.Runtime.CompilerServices +open CSharpLib3 + +// Test extension members for byrefs + +[] +type Ext() = + [] + static member inline Change(dt: byref) = () + + [] + static member inline NotChange(dt: inref) = () + +module Negatives = + + let test1 () : byref = + let dt = DateTime.Now + let x = &dt.Test2() // should fail + &x // should fail + + let test2 () = + let dt = DateTime.Now + dt.Change() // should fail + + let test3 () = + let dt = DateTime.Now + let dtr = &dt + let _x = &dtr.Test2() // should fail + () + + let test4 () = + let dt = DateTime.Now + let dtr = &dt + dtr.Change() // should fail + + let test5 () = + let dt = DateTime.Now + let x = dt.NotChange // should fail + let y = dt.Test // should fail + let z = dt.Change // should fail + let w = dt.Test2 // should fail + () diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SpanUsedInInnerLambda01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SpanUsedInInnerLambda01.fs new file mode 100644 index 00000000000..887d03e7291 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SpanUsedInInnerLambda01.fs @@ -0,0 +1,13 @@ +// #Regression #Conformance #TypeInference #ByRef +open System + +let testFunction() = + let mutable x = [| 1; 2; 3|] + let span = Span(x) + + let nestedLambda (x : int) = span[0] + x + + nestedLambda 42 + +// Code shouldn't compile +exit 1 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SpanUsedInInnerLambda02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SpanUsedInInnerLambda02.fs new file mode 100644 index 00000000000..0e1e1590462 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SpanUsedInInnerLambda02.fs @@ -0,0 +1,13 @@ +// #Regression #Conformance #TypeInference #ByRef +open System + +let testFunction() = + let mutable x = 0 + let span = Span(&x) + + let nestedLambda (x : int) = span[0] + x + + nestedLambda 42 + +// Code shouldn't compile +exit 1 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_TopLevelByref.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_TopLevelByref.fs new file mode 100644 index 00000000000..de89415f027 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_TopLevelByref.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #TypeInference #ByRef +module MyModule +open System + +let mutable moduleVar = 42 +let byrefVar = &moduleVar + +// Code shouldn't compile +exit 1 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime.fs new file mode 100644 index 00000000000..f382bd02bdf --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime.fs @@ -0,0 +1,8 @@ +open Prelude + +module InRefParam_DateTime = + type C() = + static member M(x: inref) = x + let w = System.DateTime.Now + let v = C.M(w) + check "cweweoiwe51btw" v w \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite.fs new file mode 100644 index 00000000000..a92b31d26b2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite.fs @@ -0,0 +1,7 @@ +open Prelude + +module InRefParam_DateTime_ImplicitAddressOfAtCallSite = + type C() = + static member M(x: inref) = x + let v = C.M(System.DateTime.Now) + check "cweweoiwe51btw" v.Date System.DateTime.Now.Date \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite2.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite2.fs new file mode 100644 index 00000000000..27f9b0f0da7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite2.fs @@ -0,0 +1,7 @@ +open Prelude + +module InRefParam_DateTime_ImplicitAddressOfAtCallSite2 = + type C() = + static member M(x: inref) = x + let v = C.M(System.DateTime.Now.AddDays(1.0)) + check "cweweoiwe51btw" v.Date (System.DateTime.Now.AddDays(1.0).Date) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite3.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite3.fs new file mode 100644 index 00000000000..7c7feb9d6d5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite3.fs @@ -0,0 +1,8 @@ +open Prelude + +module InRefParam_DateTime_ImplicitAddressOfAtCallSite3 = + type C() = + static member M(x: inref) = x + let mutable w = System.DateTime.Now + let v = C.M(w) + check "cweweoiwe51btw" v w \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite4.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite4.fs new file mode 100644 index 00000000000..aed55843049 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite4.fs @@ -0,0 +1,9 @@ +open Prelude + +module InRefParam_DateTime_ImplicitAddressOfAtCallSite4 = + type C() = + static member M(x: inref) = x + let date = System.DateTime.Now.Date + let w = [| date |] + let v = C.M(w.[0]) + check "lmvjvwo1" v date \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam.fs new file mode 100644 index 00000000000..6350992e0be --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam.fs @@ -0,0 +1,14 @@ +open Prelude + +module InRefParam = + type C() = + static member M(x: inref) = x + let Test() = + let res = System.DateTime.Now + let v = C.M(&res) + check "cweweoiwe51btw" v res + + let minfo = typeof.GetMethod("M") + check "cwnoreekerf" (minfo.GetParameters().[0].IsIn) true + check "cwnoreekerg" (minfo.GetParameters().[0].IsOut) false + Test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ExplicitAddressOfAtCallSite.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ExplicitAddressOfAtCallSite.fs new file mode 100644 index 00000000000..37586989a33 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ExplicitAddressOfAtCallSite.fs @@ -0,0 +1,17 @@ +open Prelude + +module InRefParamOverload_ExplicitAddressOfAtCallSite = + type C() = + static member M(x: System.DateTime) = x.AddDays(1.0) + static member M(x: inref) = x.AddDays(2.0) + static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) + static member M2(x: inref, y: int) = x.AddDays(2.0) + + let Test() = + let res = System.DateTime.Now + let v = C.M(&res) + check "cweweoiwe51btw8" v (res.AddDays(2.0)) + let v2 = C.M2(&res, 0) + check "cweweoiwe51btw6" v2 (res.AddDays(2.0)) + + Test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ImplicitAddressOfAtCallSite.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ImplicitAddressOfAtCallSite.fs new file mode 100644 index 00000000000..8e6fff8a1f7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ImplicitAddressOfAtCallSite.fs @@ -0,0 +1,13 @@ +open Prelude + +module InRefParamOverload_ImplicitAddressOfAtCallSite = + type C() = + static member M(x: System.DateTime) = x.AddDays(1.0) + static member M(x: inref) = x.AddDays(2.0) + static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) + static member M2(x: inref, y: int) = x.AddDays(2.0) + let res = System.DateTime.Now + let v = C.M(res) + check "cweweoiwe51btw1" v (res.AddDays(1.0)) + let v2 = C.M2(res, 4) + check "cweweoiwe51btw2" v2 (res.AddDays(1.0)) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ImplicitAddressOfAtCallSite2.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ImplicitAddressOfAtCallSite2.fs new file mode 100644 index 00000000000..be6c7efbbf4 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ImplicitAddressOfAtCallSite2.fs @@ -0,0 +1,15 @@ +open Prelude + +module InRefParamOverload_ImplicitAddressOfAtCallSite2 = + type C() = + static member M(x: System.DateTime) = x.AddDays(1.0) + static member M(x: inref) = x.AddDays(2.0) + static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) + static member M2(x: inref, y: int) = x.AddDays(2.0) + let Test() = + let res = System.DateTime.Now + let v = C.M(res) + check "cweweoiwe51btw1" v (res.AddDays(1.0)) + let v2 = C.M2(res, 4) + check "cweweoiwe51btw2" v2 (res.AddDays(1.0)) + Test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_ExplicitInAttribute.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_ExplicitInAttribute.fs new file mode 100644 index 00000000000..60ae45f8943 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_ExplicitInAttribute.fs @@ -0,0 +1,8 @@ +open Prelude + +module InRefParam_ExplicitInAttribute = + type C() = + static member M([] x: inref) = () + let mutable res = 9 + C.M(&res) + check "cweweoiwe519btr" res 9 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_ExplicitInAttributeDateTime.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_ExplicitInAttributeDateTime.fs new file mode 100644 index 00000000000..0624e5f65bd --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_ExplicitInAttributeDateTime.fs @@ -0,0 +1,10 @@ +open Prelude + +module InRefParam_ExplicitInAttributeDateTime = + type C() = + static member M([] x: inref) = x + let Test() = + let res = System.DateTime.Now + let v = C.M(&res) + check "cweweoiwe519cw" v res + Test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_Generic_ExplicitAddressOfAttCallSite1.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_Generic_ExplicitAddressOfAttCallSite1.fs new file mode 100644 index 00000000000..7e7c84acc24 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_Generic_ExplicitAddressOfAttCallSite1.fs @@ -0,0 +1,11 @@ +open Prelude + +module InRefParam_Generic_ExplicitAddressOfAttCallSite1 = + type C() = + static member M(x: inref<'T>) = x + let Test() = + let res = "abc" + let v = C.M(&res) + check "lmvjvwo2" res "abc" + check "lmvjvwo3" v "abc" + Test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_Generic_ExplicitAddressOfAttCallSite2.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_Generic_ExplicitAddressOfAttCallSite2.fs new file mode 100644 index 00000000000..3bcc44d6faa --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_Generic_ExplicitAddressOfAttCallSite2.fs @@ -0,0 +1,10 @@ +open Prelude + +module InRefParam_Generic_ExplicitAddressOfAttCallSite2 = + type C() = + static member M(x: inref<'T>) = x + let Test() = + let res = "abc" + let v = C.M(&res) + check "lmvjvwo4" v "abc" + Test() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefReturn.fs new file mode 100644 index 00000000000..4c8b9065f72 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefReturn.fs @@ -0,0 +1,16 @@ +open Prelude + +module InRefReturn = + type C() = + static member M(x: inref) = &x + let mutable res = 9 + let v = C.M(&res) + check "cwvereweoiwvw4" v 9 + + let minfo = typeof.GetMethod("M") + check "cwnoreekerp" (minfo.GetParameters().[0].IsIn) true + check "cwnoreekera" (minfo.GetParameters().[0].IsOut) false + check "cwnoreeker6f" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 // modreq only placed on abstract/virtual + check "cwnoreekers3" (minfo.ReturnParameter.IsIn) false // has modreq 'In' but reflection never returns true for ReturnParameter.IsIn + check "cwnoreekers4" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 1 + check "cwnoreekerd" (minfo.ReturnParameter.IsOut) false \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs new file mode 100644 index 00000000000..c34bd114f35 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs @@ -0,0 +1,60 @@ +// #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable +module Core_byrefs + +let test s b = if b then () else failwith s + +(* TEST SUITE FOR Int32 *) + +let out r (s:string) = r := !r @ [s] + +let check s actual expected = + if actual = expected then printfn "%s: OK" s + else failwithf "%s: FAILED, expected %A, got %A" s expected actual + +let check2 s expected actual = check s actual expected + +module Tests = + + let test1 () = + let x = 1 + let f = fun () -> + let y = &x // is allowed + () + + let g = fun () -> + let y = &x // is allowed + () + () + + type TestPositiveOverloading() = + + static member TestMethod(dt: byref) = () + + static member TestMethod(dt: inref) = () + + static member TestMethod(dt: outref) = () + + type PositiveInterface = + + abstract Test : byref * byref -> byref + + // This looks like it should fail, but its sig is 'val test2 : x: byref -> y: byref -> unit' + // unless a signature tells it otherwise, e.g. 'val test2 : (byref -> byref) -> unit' + let test2 (x: byref) = + fun (y: byref) -> () + + type StaticTest private () = + + static member Test (x: byref, y: int) = () + + static member Test2 (x: inref, y: int) = () + + // This passes because tup becomes 'int ref * int', which is valid and produces valid code. + // We include this to test current behavior with inference and byrefs. + static member PositiveTest(tup) = + StaticTest.Test(tup) + + let test3 () = + StaticTest.Test2 // is passing, but probably shouldn't be + +printfn "Test Passed" diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03.fs new file mode 100644 index 00000000000..163f4a3b723 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03.fs @@ -0,0 +1,60 @@ +// #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable +module Core_byrefs + +open System +open System.Runtime.CompilerServices +open CSharpLib3 + +let test s b = if b then () else failwith s + +(* TEST SUITE FOR Int32 *) + +let out r (s:string) = r := !r @ [s] + +let check s actual expected = + if actual = expected then printfn "%s: OK" s + else failwithf "%s: FAILED, expected %A, got %A" s expected actual + +let check2 s expected actual = check s actual expected + +// Test extension members for byrefs + +[] +type Ext() = + [] + static member inline Change(dt: byref) = () + + [] + static member inline NotChange(dt: inref) = () + +module Positives = + + let test1 () = + let dt = DateTime.Now + let _x = dt.Test() + let dtr = &dt + dtr.Test() + + let test2 () = + let dt = DateTime.Now + dt.NotChange() + let dtr = &dt + dtr.NotChange() + + let test3 () = + let mutable dt = DateTime.Now + let _x = dt.Test2() + dt.Test() + let dtr = &dt + let _x = dtr.Test2() + dtr.Test() + + let test4 () = + let mutable dt = DateTime.Now + dt.Change() + dt.NotChange() + let dtr = &dt + dtr.Change() + dtr.NotChange() + +stdout.WriteLine "Test Passed" diff --git a/tests/fsharp/core/byrefs/cslib3.cs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03CSharpLib.cs similarity index 100% rename from tests/fsharp/core/byrefs/cslib3.cs rename to tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03CSharpLib.cs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/NoTailcallToByrefsWithModReq.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/NoTailcallToByrefsWithModReq.fs new file mode 100644 index 00000000000..2355470c8fe --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/NoTailcallToByrefsWithModReq.fs @@ -0,0 +1,20 @@ +// https://github.com/dotnet/fsharp/issues/12085 +module NoTailcallToByrefsWithModReq = + module ClassLibrary = + + // F# equivalent of `public delegate FieldType Getter(in DeclaringType);` + type Getter<'DeclaringType, 'FieldType> = delegate of inref<'DeclaringType> -> 'FieldType + + type GetterWrapper<'DeclaringType, 'FieldType> (getter : Getter<'DeclaringType, 'FieldType>) = + member _.Get (instance : 'DeclaringType) = getter.Invoke &instance + + open ClassLibrary + type MyRecord = { Value: int[] } + let App() = + + let wrapper = new GetterWrapper(fun (record: inref) -> record.Value) + + let record = { Value = [| 42 |] } + let value = wrapper.Get(record) + value.GetEnumerator() + App() \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam.fs new file mode 100644 index 00000000000..f788e4c7e4e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam.fs @@ -0,0 +1,8 @@ +open Prelude + +module OutRefParam = + type C() = + static member M(x: outref) = x <- 5 + let mutable res = 9 + C.M(&res) + check "cweweoiwek28989" res 5 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_ExplicitOutAttribute.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_ExplicitOutAttribute.fs new file mode 100644 index 00000000000..ad58031a6c1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_ExplicitOutAttribute.fs @@ -0,0 +1,8 @@ +open Prelude + +module OutRefParam_ExplicitOutAttribute = + type C() = + static member M([] x: outref) = x <- 5 + let mutable res = 9 + C.M(&res) + check "cweweoiweklceew4" res 5 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_Overloaded.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_Overloaded.fs new file mode 100644 index 00000000000..ef8a20caba5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_Overloaded.fs @@ -0,0 +1,11 @@ +open Prelude + +module OutRefParam_Overloaded = + type C() = + static member M(a: int, x: outref) = x <- 7 + static member M(a: string, x: outref) = x <- 8 + let mutable res = 9 + C.M("a", &res) + check "cweweoiwek2v99323" res 8 + C.M(3, &res) + check "cweweoiwe519" res 7 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_Overloaded_ExplicitOutAttribute.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_Overloaded_ExplicitOutAttribute.fs new file mode 100644 index 00000000000..2a67aeab8d0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_Overloaded_ExplicitOutAttribute.fs @@ -0,0 +1,11 @@ +open Prelude + +module OutRefParam_Overloaded_ExplicitOutAttribute = + type C() = + static member M(a: int, [] x: outref) = x <- 7 + static member M(a: string, [] x: outref) = x <- 8 + let mutable res = 9 + C.M("a", &res) + check "cweweoiwek2v90" res 8 + C.M(3, &res) + check "cweweoiwek2c98" res 7 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Prelude.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Prelude.fs new file mode 100644 index 00000000000..a8e4c9ab45f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Prelude.fs @@ -0,0 +1,13 @@ +module Prelude + +#nowarn "3370" + +let test s b = if b then () else failwith s + +let out r (s:string) = r := !r @ [s] + +let check s actual expected = + if actual = expected then printfn "%s: OK" s + else failwithf "%s: FAILED, expected %A, got %A" s expected actual + +let check2 s expected actual = check s actual expected \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ReturnFieldSetBySpan.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ReturnFieldSetBySpan.fs new file mode 100644 index 00000000000..5bb42474102 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ReturnFieldSetBySpan.fs @@ -0,0 +1,10 @@ +// #Conformance #TypeInference #ByRef +open System + +let testFunction() = + let mutable local = 42 + let span = Span(&local) + span[0] <- 13 + local + +if testFunction () <> 13 then failwith "Failed" diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ReturnSpan01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ReturnSpan01.fs new file mode 100644 index 00000000000..514ecc520d5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ReturnSpan01.fs @@ -0,0 +1,13 @@ +// #Conformance #TypeInference #ByRef +open System + +let testFunction() = + let arr = [| 1; 2; 3 |] + let span = Span(arr) + span[0] <- 13 + span + +do + let result = testFunction() + let x = &result[0] + if x <> 13 then failwith "Failed" diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_ByRefReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_ByRefReturn.fs new file mode 100644 index 00000000000..73c0979ef04 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_ByRefReturn.fs @@ -0,0 +1,20 @@ +open Prelude + +module Slot_ByRefReturn = + type I = + abstract M : x: byref -> byref + type C() = + interface I with + member __.M(x: byref) = x <- 5; &x + let mutable res = 9 + let v = (C() :> I).M(&res) + check "cweweoiwek28989" res 5 + check "cweweoiwek28989" v 5 + + let minfo = typeof.GetMethod("M") + check "cwnoreeker6e" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 + check "cwnoreekery" (minfo.GetParameters().[0].IsIn) false + check "cwnoreekeru" (minfo.GetParameters().[0].IsOut) false + check "cwnoreekeri" (minfo.ReturnParameter.IsIn) false + check "cwnoreekers" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 + check "cwnoreekero" (minfo.ReturnParameter.IsOut) false \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_InRefReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_InRefReturn.fs new file mode 100644 index 00000000000..8c50306a3cc --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_InRefReturn.fs @@ -0,0 +1,20 @@ +open Prelude + +module Slot_InRefReturn = + type I = + abstract M : x: inref -> inref + type C() = + interface I with + member __.M(x: inref) = &x + let mutable res = 9 + let v = (C() :> I).M(&res) + check "cweweoiwek28989" res 9 + check "cweweoiwek28989" v 9 + + let minfo = typeof.GetMethod("M") + check "cwnoreekerp" (minfo.GetParameters().[0].IsIn) true + check "cwnoreekera" (minfo.GetParameters().[0].IsOut) false + check "cwnoreeker6g" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 1 + check "cwnoreekers5" (minfo.ReturnParameter.IsIn) false // has modreq 'In' but reflection never returns true for ReturnParameter.IsIn + check "cwnoreekers6" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 1 + check "cwnoreekerd" (minfo.ReturnParameter.IsOut) false \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_OutRefParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_OutRefParam.fs new file mode 100644 index 00000000000..27fdb7d861e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_OutRefParam.fs @@ -0,0 +1,11 @@ +open Prelude + +module Slot_OutRefParam = + type I = + abstract M : x: outref -> unit + type C() = + interface I with + member __.M(x: outref) = x <- 5 + let mutable res = 9 + (C() :> I).M(&res) + check "cweweoiwek28989" res 5 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/TryGetValue.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/TryGetValue.fs new file mode 100644 index 00000000000..d2468617919 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/TryGetValue.fs @@ -0,0 +1,12 @@ +open Prelude + +// Test a simple out argument +module TryGetValueTests = + let d = dict [ (3,4) ] + let mutable res = 9 + let v = d.TryGetValue(3, &res) + check "cweweoiwekl1" v true + check "cweweoiwekl2" res 4 + let v2 = d.TryGetValue(5, &res) + check "cweweoiwekl3" v2 false + check "cweweoiwekl4" res 4 \ No newline at end of file diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index ce5252136e0..aabefaf4b35 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -1404,11 +1404,13 @@ module rec Compiler = $"""({errorType}, Line {range.StartLine}, Col {range.StartColumn}, Line {range.EndLine}, Col {range.EndColumn}, "{message}")""".Replace("\r\n", "\n") let expectedErrors = expected |> List.map (fun error -> errorMessage error) + let expectedErrorsAsStr = expectedErrors |> String.concat ";\n" |> sprintf "[%s]" let sourceErrors = source |> List.map (fun error -> errorMessage { error with Range = adjustRange error.Range libAdjust }) + let sourceErrorsAsStr = sourceErrors |> String.concat ";\n" |> sprintf "[%s]" let inline checkEqual k a b = if a <> b then - Assert.AreEqual(a, b, sprintf "%s: Mismatch in %s, expected '%A', got '%A'.\nAll errors:\n%A\nExpected errors:\n%A" what k a b sourceErrors expectedErrors) + Assert.AreEqual(a, b, $"%s{what}: Mismatch in %s{k}, expected '%A{a}', got '%A{b}'.\nAll errors:\n%s{sourceErrorsAsStr}\nExpected errors:\n%s{expectedErrorsAsStr}") // For lists longer than 100 errors: expectedErrors |> List.iter System.Diagnostics.Debug.WriteLine diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs index 429a1a035c5..a0eea96e1d4 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -405,18 +405,31 @@ module rec CompilerAssertHelpers = | _ -> disposeList.Dispose() reraise() - + let assertErrors libAdjust ignoreWarnings (errors: FSharpDiagnostic []) expectedErrors = + let errorMessage (error: FSharpDiagnostic) = + let errN, range, message = error.ErrorNumber, error.Range, error.Message + let errorType = + match error.Severity with + | FSharpDiagnosticSeverity.Error -> $"Error {errN}" + | FSharpDiagnosticSeverity.Warning-> $"Warning {errN}" + | FSharpDiagnosticSeverity.Hidden-> $"Hidden {errN}" + | FSharpDiagnosticSeverity.Info -> $"Information {errN}" + $"""({errorType}, Line {range.StartLine}, Col {range.StartColumn}, Line {range.EndLine}, Col {range.EndColumn}, "{message}")""".Replace("\r\n", "\n") + let errors = errors |> Array.filter (fun error -> if ignoreWarnings then error.Severity <> FSharpDiagnosticSeverity.Warning && error.Severity <> FSharpDiagnosticSeverity.Info else true) |> Array.distinctBy (fun e -> e.Severity, e.ErrorNumber, e.StartLine, e.StartColumn, e.EndLine, e.EndColumn, e.Message) + let errorsAsStr = errors |> Array.map errorMessage |> String.concat ";\n" |> sprintf "[%s]" + let errors = + errors |> Array.map (fun info -> (info.Severity, info.ErrorNumber, (info.StartLine - libAdjust, info.StartColumn + 1, info.EndLine - libAdjust, info.EndColumn + 1), info.Message)) - + let checkEqual k a b = if a <> b then - Assert.AreEqual(a, b, sprintf "Mismatch in %s, expected '%A', got '%A'.\nAll errors:\n%A" k a b errors) + Assert.AreEqual(a, b, sprintf $"Mismatch in %s{k}, expected '%A{a}', got '%A{b}'.\nAll errors:\n%s{errorsAsStr}") checkEqual "Errors" (Array.length expectedErrors) errors.Length diff --git a/tests/FSharp.Test.Utilities/DirectoryAttribute.fs b/tests/FSharp.Test.Utilities/DirectoryAttribute.fs index 39b1065fe01..fbb40b70b17 100644 --- a/tests/FSharp.Test.Utilities/DirectoryAttribute.fs +++ b/tests/FSharp.Test.Utilities/DirectoryAttribute.fs @@ -25,7 +25,7 @@ type DirectoryAttribute(dir: string) = let outputDirectory methodName extraDirectory = getTestOutputDirectory dir methodName extraDirectory let mutable baselineSuffix = "" let mutable includes = Array.empty - + let readFileOrDefault (path: string) : string option = match FileSystem.FileExistsShim(path) with | true -> Some (File.ReadAllText path) @@ -101,6 +101,8 @@ type DirectoryAttribute(dir: string) = StaticLink = false } |> FS + new([] dirs: string[]) = DirectoryAttribute(Path.Combine(dirs) : string) + member _.BaselineSuffix with get() = baselineSuffix and set v = baselineSuffix <- v member _.Includes with get() = includes and set v = includes <- v diff --git a/tests/fsharp/core/byrefs/.gitignore b/tests/fsharp/core/byrefs/.gitignore deleted file mode 100644 index 6a7461313bb..00000000000 --- a/tests/fsharp/core/byrefs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.dll diff --git a/tests/fsharp/core/byrefs/test.bsl b/tests/fsharp/core/byrefs/test.bsl deleted file mode 100644 index 71542c8be42..00000000000 --- a/tests/fsharp/core/byrefs/test.bsl +++ /dev/null @@ -1,71 +0,0 @@ - -test.fsx(31,34,31,40): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted. - -test.fsx(34,32,34,40): typecheck error FS0257: Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. - -test.fsx(38,36,38,38): typecheck error FS0001: Type mismatch. Expecting a - 'byref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' - -test.fsx(42,36,42,38): typecheck error FS0001: Type mismatch. Expecting a - 'outref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In' - -test.fsx(47,38,47,40): typecheck error FS0001: Type mismatch. Expecting a - 'byref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' - -test.fsx(52,38,52,40): typecheck error FS0001: Type mismatch. Expecting a - 'outref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In' - -test.fsx(57,38,57,40): typecheck error FS0001: Type mismatch. Expecting a - 'byref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' - -test.fsx(62,38,62,40): typecheck error FS0001: Type mismatch. Expecting a - 'outref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In' - -test.fsx(66,34,66,47): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -test.fsx(66,34,66,47): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -test.fsx(71,21,71,23): typecheck error FS3236: Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address. - -test.fsx(72,21,72,23): typecheck error FS3236: Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address. - -test.fsx(78,21,78,37): typecheck error FS3236: Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address. - -test.fsx(85,22,85,23): typecheck error FS0001: This expression was expected to have type - 'inref' -but here has type - 'System.DateTime' - -test.fsx(88,10,88,15): typecheck error FS3238: Byref types are not allowed to have optional type extensions. - -test.fsx(92,10,92,15): typecheck error FS3238: Byref types are not allowed to have optional type extensions. - -test.fsx(96,10,96,16): typecheck error FS3238: Byref types are not allowed to have optional type extensions. - -test.fsx(114,21,114,36): typecheck error FS3236: Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address. - -test.fsx(114,21,114,36): typecheck error FS0001: Type mismatch. Expecting a - 'byref' -but given a - 'inref' -The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' - -test.fsx(119,21,119,29): typecheck error FS3236: Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address. diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx deleted file mode 100644 index ad3623e1d37..00000000000 --- a/tests/fsharp/core/byrefs/test.fsx +++ /dev/null @@ -1,1530 +0,0 @@ -// #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable -#if TESTS_AS_APP -module Core_byrefs -#endif - - -let failures = ref false -let report_failure (s) = - stderr.WriteLine ("NO: " + s); failures := true -let test s b = if b then () else report_failure(s) - -(* TEST SUITE FOR Int32 *) - -let out r (s:string) = r := !r @ [s] - -let check s actual expected = - if actual = expected then printfn "%s: OK" s - else report_failure (sprintf "%s: FAILED, expected %A, got %A" s expected actual) - -let check2 s expected actual = check s actual expected - -[] -type S = - [] - val mutable X : int - -#if NEGATIVE -module ByrefNegativeTests = - - module WriteToInRef = - let f1 (x: inref) = x <- 1 // not allowed - - module WriteToInRefStructInner = - let f1 (x: inref) = x.X <- 1 //not allowed - - module InRefToByRef = - let f1 (x: byref<'T>) = 1 - let f2 (x: inref<'T>) = f1 &x // not allowed - - module InRefToOutRef = - let f1 (x: outref<'T>) = 1 - let f2 (x: inref<'T>) = f1 &x // not allowed - - module InRefToByRefClassMethod = - type C() = - static member f1 (x: byref<'T>) = 1 - let f2 (x: inref<'T>) = C.f1 &x // not allowed - - module InRefToOutRefClassMethod = - type C() = - static member f1 (x: outref<'T>) = 1 // not allowed (not yet) - let f2 (x: inref<'T>) = C.f1 &x // not allowed - - module InRefToByRefClassMethod2 = - type C() = - static member f1 (x: byref<'T>) = 1 - let f2 (x: inref<'T>) = C.f1(&x) // not allowed - - module InRefToOutRefClassMethod2 = - type C() = - static member f1 (x: outref<'T>) = 1 // not allowed (not yet) - let f2 (x: inref<'T>) = C.f1(&x) // not allowed - - module UseOfLibraryOnly = - type C() = - static member f1 (x: byref<'T, 'U>) = 1 - - module CantTakeAddress = - - let test1 () = - let x = &1 // not allowed - let y = &2 // not allowed - x + y - - let test2_helper (x: byref) = x - let test2 () = - let mutable x = 1 - let y = &test2_helper &x // not allowed - () - - module InRefParam_DateTime = - type C() = - static member M(x: inref) = x - let w = System.DateTime.Now - let v = C.M(w) // not allowed - check "cweweoiwe51btw" v w - - type byref<'T> with - - member this.Test() = 1 - - type inref<'T> with - - member this.Test() = 1 - - type outref<'T> with - - member this.Test() = 1 - - module CantTakeAddressOfExpressionReturningReferenceType = - open System.Collections.Concurrent - open System.Collections.Generic - - let test1 () = - let aggregator = - new ConcurrentDictionary< - string, ConcurrentDictionary - >() - - for kvp in aggregator do - for kvpInner in kvp.Value do - kvp.Value.TryRemove( - kvpInner.Key, - &kvpInner.Value) - |> ignore - - let test2 () = - let x = KeyValuePair(1, [||]) - let y = &x.Value - () -#endif - -// Test a simple ref argument -module CompareExchangeTests = - let mutable x = 3 - let v = System.Threading.Interlocked.CompareExchange(&x, 4, 3) - check "cweweoiwekla" v 3 - let v2 = System.Threading.Interlocked.CompareExchange(&x, 5, 3) - check "cweweoiweklb" v2 4 - -// Test a simple out argument -module TryGetValueTests = - let d = dict [ (3,4) ] - let mutable res = 9 - let v = d.TryGetValue(3, &res) - check "cweweoiwekl1" v true - check "cweweoiwekl2" res 4 - let v2 = d.TryGetValue(5, &res) - check "cweweoiwekl3" v2 false - check "cweweoiwekl4" res 4 - - -module ByRefParam = - type C() = - static member M(x: byref) = x <- 5 - let mutable res = 9 - let v = C.M(&res) - check "cwvereweoiwekl4" res 5 - - let minfo = typeof.GetMethod("M") - check "cwnoreeker1" (minfo.GetParameters().[0].IsIn) false - check "cwnoreeker2" (minfo.GetParameters().[0].IsOut) false - check "cwnoreeker3" (minfo.ReturnParameter.IsIn) false - check "cwnoreeker4" (minfo.ReturnParameter.IsOut) false - -module ByRefParam_ExplicitOutAttribute = - type C() = - static member M([] x: byref) = x <- 5 - let mutable res = 9 - let v = C.M(&res) - check "cwvereweoiwekl4" res 5 - - let minfo = typeof.GetMethod("M") - check "cwnoreeker5" (minfo.GetParameters().[0].IsIn) false - check "cwnoreeker6a" (minfo.GetParameters().[0].IsOut) true - check "cwnoreeker6b" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 - check "cwnoreekers1" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 - check "cwnoreeker7" (minfo.ReturnParameter.IsIn) false - check "cwnoreeker8" (minfo.ReturnParameter.IsOut) false - -module ByRefParam_ExplicitInAttribute = - type C() = - static member M([] x: byref) = x <- 5 - let mutable res = 9 - let v = C.M(&res) - check "cwvereweoiwekl4" res 5 - - let minfo = typeof.GetMethod("M") - check "cwnoreeker9" (minfo.GetParameters().[0].IsIn) true - check "cwnoreekerq" (minfo.GetParameters().[0].IsOut) false - check "cwnoreeker6c" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 - check "cwnoreekers2" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 - check "cwnoreekerw" (minfo.ReturnParameter.IsIn) false - check "cwnoreekere" (minfo.ReturnParameter.IsOut) false - -module ByRefReturn = - type C() = - static member M(x: byref) = x <- x + 1; &x - let mutable res = 9 - let v = C.M(&res) - check "cwvereweoiwvw4" v 10 - - let minfo = typeof.GetMethod("M") - check "cwnoreeker6d" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 - check "cwnoreekerr" (minfo.ReturnParameter.IsIn) false - check "cwnoreekert" (minfo.ReturnParameter.IsOut) false - - -module Slot_ByRefReturn = - type I = - abstract M : x: byref -> byref - type C() = - interface I with - member __.M(x: byref) = x <- 5; &x - let mutable res = 9 - let v = (C() :> I).M(&res) - check "cweweoiwek28989" res 5 - check "cweweoiwek28989" v 5 - - let minfo = typeof.GetMethod("M") - check "cwnoreeker6e" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 - check "cwnoreekery" (minfo.GetParameters().[0].IsIn) false - check "cwnoreekeru" (minfo.GetParameters().[0].IsOut) false - check "cwnoreekeri" (minfo.ReturnParameter.IsIn) false - check "cwnoreekers" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 - check "cwnoreekero" (minfo.ReturnParameter.IsOut) false - -module InRefReturn = - type C() = - static member M(x: inref) = &x - let mutable res = 9 - let v = C.M(&res) - check "cwvereweoiwvw4" v 9 - - let minfo = typeof.GetMethod("M") - check "cwnoreekerp" (minfo.GetParameters().[0].IsIn) true - check "cwnoreekera" (minfo.GetParameters().[0].IsOut) false - check "cwnoreeker6f" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 // modreq only placed on abstract/virtual - check "cwnoreekers3" (minfo.ReturnParameter.IsIn) false // has modreq 'In' but reflection never returns true for ReturnParameter.IsIn - check "cwnoreekers4" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 1 - check "cwnoreekerd" (minfo.ReturnParameter.IsOut) false - -module Slot_InRefReturn = - type I = - abstract M : x: inref -> inref - type C() = - interface I with - member __.M(x: inref) = &x - let mutable res = 9 - let v = (C() :> I).M(&res) - check "cweweoiwek28989" res 9 - check "cweweoiwek28989" v 9 - - let minfo = typeof.GetMethod("M") - check "cwnoreekerp" (minfo.GetParameters().[0].IsIn) true - check "cwnoreekera" (minfo.GetParameters().[0].IsOut) false - check "cwnoreeker6g" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 1 - check "cwnoreekers5" (minfo.ReturnParameter.IsIn) false // has modreq 'In' but reflection never returns true for ReturnParameter.IsIn - check "cwnoreekers6" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 1 - check "cwnoreekerd" (minfo.ReturnParameter.IsOut) false - - -module OutRefParam_ExplicitOutAttribute = - type C() = - static member M([] x: outref) = x <- 5 - let mutable res = 9 - C.M(&res) - check "cweweoiweklceew4" res 5 - -module OutRefParam = - type C() = - static member M(x: outref) = x <- 5 - let mutable res = 9 - C.M(&res) - check "cweweoiwek28989" res 5 - -module Slot_OutRefParam = - type I = - abstract M : x: outref -> unit - type C() = - interface I with - member __.M(x: outref) = x <- 5 - let mutable res = 9 - (C() :> I).M(&res) - check "cweweoiwek28989" res 5 - -module ByRefParam_OverloadedTest_ExplicitOutAttribute = - type C() = - static member M(a: int, [] x: byref) = x <- 7 - static member M(a: string, [] x: byref) = x <- 8 - let mutable res = 9 - C.M("a", &res) - check "cweweoiwek2cbe9" res 8 - C.M(3, &res) - check "cweweoiwek28498" res 7 - -module OutRefParam_Overloaded_ExplicitOutAttribute = - type C() = - static member M(a: int, [] x: outref) = x <- 7 - static member M(a: string, [] x: outref) = x <- 8 - let mutable res = 9 - C.M("a", &res) - check "cweweoiwek2v90" res 8 - C.M(3, &res) - check "cweweoiwek2c98" res 7 - -module OutRefParam_Overloaded = - type C() = - static member M(a: int, x: outref) = x <- 7 - static member M(a: string, x: outref) = x <- 8 - let mutable res = 9 - C.M("a", &res) - check "cweweoiwek2v99323" res 8 - C.M(3, &res) - check "cweweoiwe519" res 7 - -module InRefParam_ExplicitInAttribute = - type C() = - static member M([] x: inref) = () - let mutable res = 9 - C.M(&res) - check "cweweoiwe519btr" res 9 - -module InRefParam_ExplicitInAttributeDateTime = - type C() = - static member M([] x: inref) = x - let Test() = - let res = System.DateTime.Now - let v = C.M(&res) - check "cweweoiwe519cw" v res - Test() - -module InRefParam = - type C() = - static member M(x: inref) = x - let Test() = - let res = System.DateTime.Now - let v = C.M(&res) - check "cweweoiwe51btw" v res - - let minfo = typeof.GetMethod("M") - check "cwnoreekerf" (minfo.GetParameters().[0].IsIn) true - check "cwnoreekerg" (minfo.GetParameters().[0].IsOut) false - Test() - -module InRefParamOverload_ExplicitAddressOfAtCallSite = - type C() = - static member M(x: System.DateTime) = x.AddDays(1.0) - static member M(x: inref) = x.AddDays(2.0) - static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) - static member M2(x: inref, y: int) = x.AddDays(2.0) - - let Test() = - let res = System.DateTime.Now - let v = C.M(&res) - check "cweweoiwe51btw8" v (res.AddDays(2.0)) - let v2 = C.M2(&res, 0) - check "cweweoiwe51btw6" v2 (res.AddDays(2.0)) - - Test() - -module InRefParamOverload_ImplicitAddressOfAtCallSite = - type C() = - static member M(x: System.DateTime) = x.AddDays(1.0) - static member M(x: inref) = x.AddDays(2.0) - static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) - static member M2(x: inref, y: int) = x.AddDays(2.0) - let res = System.DateTime.Now - let v = C.M(res) - check "cweweoiwe51btw1" v (res.AddDays(1.0)) - let v2 = C.M2(res, 4) - check "cweweoiwe51btw2" v2 (res.AddDays(1.0)) - - -module InRefParamOverload_ImplicitAddressOfAtCallSite2 = - type C() = - static member M(x: System.DateTime) = x.AddDays(1.0) - static member M(x: inref) = x.AddDays(2.0) - static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) - static member M2(x: inref, y: int) = x.AddDays(2.0) - let Test() = - let res = System.DateTime.Now - let v = C.M(res) - check "cweweoiwe51btw1" v (res.AddDays(1.0)) - let v2 = C.M2(res, 4) - check "cweweoiwe51btw2" v2 (res.AddDays(1.0)) - Test() - -#if IMPLICIT_ADDRESS_OF -module InRefParam_DateTime = - type C() = - static member M(x: inref) = x - let w = System.DateTime.Now - let v = C.M(w) - check "cweweoiwe51btw" v w - -module InRefParam_DateTime_ImplicitAddressOfAtCallSite = - type C() = - static member M(x: inref) = x - let v = C.M(System.DateTime.Now) - check "cweweoiwe51btw" v.Date System.DateTime.Now.Date - -module InRefParam_DateTime_ImplicitAddressOfAtCallSite2 = - type C() = - static member M(x: inref) = x - let v = C.M(System.DateTime.Now.AddDays(1.0)) - check "cweweoiwe51btw" v.Date (System.DateTime.Now.AddDays(1.0).Date) - -module InRefParam_DateTime_ImplicitAddressOfAtCallSite3 = - type C() = - static member M(x: inref) = x - let mutable w = System.DateTime.Now - let v = C.M(w) - check "cweweoiwe51btw" v w - -module InRefParam_DateTime_ImplicitAddressOfAtCallSite4 = - type C() = - static member M(x: inref) = x - let date = System.DateTime.Now.Date - let w = [| date |] - let v = C.M(w.[0]) - check "lmvjvwo1" v date -#endif - -module InRefParam_Generic_ExplicitAddressOfAttCallSite1 = - type C() = - static member M(x: inref<'T>) = x - let Test() = - let res = "abc" - let v = C.M(&res) - check "lmvjvwo2" res "abc" - check "lmvjvwo3" v "abc" - Test() - -module InRefParam_Generic_ExplicitAddressOfAttCallSite2 = - type C() = - static member M(x: inref<'T>) = x - let Test() = - let res = "abc" - let v = C.M(&res) - check "lmvjvwo4" v "abc" - Test() - -module ByrefReturnTests = - - module TestImmediateReturn = - let mutable x = 1 - - let f () = &x - - let test() = - let addr : byref = &f() - addr <- addr + 1 - check2 "cepojcwem1" 2 x - - - let test2() = - let v = f() - let res = v + 1 - check2 "cepojcwem1b" 3 res - - test() - test2() - - module TestMatchReturn = - let mutable x = 1 - let mutable y = 1 - - let f inp = match inp with 3 -> &x | _ -> &y - - let test() = - let addr = &f 3 - addr <- addr + 1 - check2 "cepojcwem2" 2 x - check2 "cepojcwem3" 1 y - let addr = &f 4 - addr <- addr + 1 - check2 "cepojcwem4" 2 x - check2 "cepojcwem5" 2 y - - let test2() = - let res = f 3 - let res2 = res + 1 - check2 "cepojcwem2b" 3 res2 - check2 "cepojcwem3b" 2 res - - test() - test2() - - module TestConditionalReturn = - let mutable x = 1 - let mutable y = 1 - - let f inp = if inp = 3 then &x else &y - - let test() = - let addr = &f 3 - addr <- addr + 1 - check2 "cepojcwem6" 2 x - check2 "cepojcwem7" 1 y - let addr = &f 4 - addr <- addr + 1 - check2 "cepojcwem8" 2 x - check2 "cepojcwem9" 2 y - - let test2() = - let res = f 3 - let res2 = res + 1 - check2 "cepojcwem8b" 3 res2 - check2 "cepojcwem9b" 2 res - - test() - test2() - - module TestTryWithReturn = - let mutable x = 1 - let mutable y = 1 - - let f inp = try &x with _ -> &y - - let test() = - let addr = &f 3 - addr <- addr + 1 - check2 "cepojcwem6b" 2 x - check2 "cepojcwem7b" 1 y - let addr = &f 4 - addr <- addr + 1 - check2 "cepojcwem8b" 3 x - check2 "cepojcwem9b" 1 y - - let test2() = - let res = f 3 - let res2 = res + 1 - check2 "cepojcwem2ff" 4 res2 - check2 "cepojcwem3gg" 3 res - - test() - test2() - - module TestTryFinallyReturn = - let mutable x = 1 - let mutable y = 1 - - let f inp = try &x with _ -> &y - - let test() = - let addr = &f 3 - addr <- addr + 1 - check2 "cepojcwem6b" 2 x - check2 "cepojcwem7b" 1 y - let addr = &f 4 - addr <- addr + 1 - check2 "cepojcwem8b" 3 x - check2 "cepojcwem9b" 1 y - - let test2() = - let res = f 3 - let res2 = res + 1 - check2 "cepojcwem2tf" 4 res2 - check2 "cepojcwem3qw" 3 res - - test() - test2() - - module TestOneArgument = - - let f (x:byref) = &x - - let test() = - let mutable r1 = 1 - let addr = &f &r1 - addr <- addr + 1 - check2 "cepojcwem10" 2 r1 - - test() - - module TestTwoArguments = - - let f (x:byref, y:byref) = &x - - let test() = - let mutable r1 = 1 - let mutable r2 = 0 - let addr = &f (&r1, &r2) - addr <- addr + 1 - check2 "cepojcwem11" 2 r1 - - test() - - module TestRecordParam = - - type R = { mutable z : int } - let f (x:R) = &x.z - - let test() = - let r = { z = 1 } - let addr = &f r - addr <- addr + 1 - check2 "cepojcwem12" 2 r.z - - test() - - module TestRecordParam2 = - - type R = { mutable z : int } - let f (x:byref) = &x.z - - let test() = - let mutable r = { z = 1 } - let addr = &f &r - addr <- addr + 1 - check2 "cepojcwem13a" 2 r.z - - test() - - module TestClassParamMutableField = - - type C() = [] val mutable z : int - - let f (x:C) = &x.z - - let test() = - let c = C() - let addr = &f c - addr <- addr + 1 - check2 "cepojcwem13b" 1 c.z - - test() - - module TestArrayParam = - - let f (x:int[]) = &x.[0] - - let test() = - let r = [| 1 |] - let addr = &f r - addr <- addr + 1 - check2 "cepojcwem14" 2 r.[0] - - test() - - module TestStructParam = - - [] - type R = { mutable z : int } - - let f (x:byref) = &x.z - - let test() = - let mutable r = { z = 1 } - let addr = &f &r - addr <- addr + 1 - check2 "cepojcwem15" 2 r.z - - test() - - module TestInterfaceMethod = - let mutable x = 1 - - type I = - abstract M : unit -> byref - - type C() = - interface I with - member this.M() = &x - - let ObjExpr() = - { new I with - member this.M() = &x } - - let f (i:I) = &i.M() - - let test() = - let addr = &f (C()) - addr <- addr + 1 - let addr = &f (ObjExpr()) - addr <- addr + 1 - check2 "cepojcwem16" 3 x - - test() - - module TestInterfaceProperty = - let mutable x = 1 - - type I = - abstract P : byref - - type C() = - interface I with - member this.P = &x - - let ObjExpr() = - { new I with - member this.P = &x } - - let f (i:I) = &i.P - - let test() = - let addr = &f (C()) - addr <- addr + 1 - let addr = &f (ObjExpr()) - addr <- addr + 1 - check2 "cepojcwem17" 3 x - - test() - - module TestDelegateMethod = - let mutable x = 1 - - type D = delegate of unit -> byref - - let d() = D(fun () -> &x) - - let f (d:D) = &d.Invoke() - - let test() = - let addr = &f (d()) - check2 "cepojcwem18a" 1 x - addr <- addr + 1 - check2 "cepojcwem18b" 2 x - - test() - - module TestBaseCall = - type Incrementor(z) = - abstract member Increment : int byref * int byref -> unit - default this.Increment(i : int byref,j : int byref) = - i <- i + z - - type Decrementor(z) = - inherit Incrementor(z) - override this.Increment(i, j) = - base.Increment(&i, &j) - - i <- i - z - - module TestDelegateMethod2 = - let mutable x = 1 - - type D = delegate of byref -> byref - - let d() = D(fun xb -> &xb) - - let f (d:D) = &d.Invoke(&x) - - let test() = - let addr = &f (d()) - check2 "cepojcwem18a2" 1 x - addr <- addr + 1 - check2 "cepojcwem18b3" 2 x - - test() - -module ByrefReturnMemberTests = - - module TestImmediateReturn = - let mutable x = 1 - - type C() = - static member M () = &x - - let test() = - let addr : byref = &C.M() - addr <- addr + 1 - check2 "mepojcwem1" 2 x - - - let test2() = - let v = &C.M() - let res = v + 1 - check2 "mepojcwem1b" 3 res - - test() - test2() - - module TestMatchReturn = - let mutable x = 1 - let mutable y = 1 - - type C() = - static member M inp = match inp with 3 -> &x | _ -> &y - - let test() = - let addr = &C.M 3 - addr <- addr + 1 - check2 "mepojcwem2" 2 x - check2 "mepojcwem3" 1 y - let addr = &C.M 4 - addr <- addr + 1 - check2 "mepojcwem4" 2 x - check2 "mepojcwem5" 2 y - - let test2() = - let res = &C.M 3 - let res2 = res + 1 - check2 "mepojcwem2b" 3 res2 - check2 "mepojcwem3b" 2 res - - test() - test2() - - module TestConditionalReturn = - let mutable x = 1 - let mutable y = 1 - - type C() = - static member M inp = if inp = 3 then &x else &y - - let test() = - let addr = &C.M 3 - addr <- addr + 1 - check2 "mepojcwem6" 2 x - check2 "mepojcwem7" 1 y - let addr = &C.M 4 - addr <- addr + 1 - check2 "mepojcwem8" 2 x - check2 "mepojcwem9" 2 y - - let test2() = - let res = &C.M 3 - let res2 = res + 1 - check2 "mepojcwem8b" 3 res2 - check2 "mepojcwem9b" 2 res - - test() - test2() - - module TestTryWithReturn = - let mutable x = 1 - let mutable y = 1 - - type C() = - static member M inp = try &x with _ -> &y - - let test() = - let addr = &C.M 3 - addr <- addr + 1 - check2 "mepojcwem6b" 2 x - check2 "mepojcwem7b" 1 y - let addr = &C.M 4 - addr <- addr + 1 - check2 "mepojcwem8b" 3 x - check2 "mepojcwem9b" 1 y - - let test2() = - let res = &C.M 3 - let res2 = res + 1 - check2 "mepojcwem2ff" 4 res2 - check2 "mepojcwem3gg" 3 res - - test() - test2() - - module TestTryFinallyReturn = - let mutable x = 1 - let mutable y = 1 - - type C() = - static member M inp = try &x with _ -> &y - - let test() = - let addr = &C.M 3 - addr <- addr + 1 - check2 "mepojcwem6b" 2 x - check2 "mepojcwem7b" 1 y - let addr = &C.M 4 - addr <- addr + 1 - check2 "mepojcwem8b" 3 x - check2 "mepojcwem9b" 1 y - - let test2() = - let res = &C.M 3 - let res2 = res + 1 - check2 "mepojcwem2tf" 4 res2 - check2 "mepojcwem3qw" 3 res - - test() - test2() - - module TestOneArgument = - - type C() = - static member M (x:byref) = &x - - let test() = - let mutable r1 = 1 - let addr = &C.M (&r1) - addr <- addr + 1 - check2 "mepojcwem10" 2 r1 - - test() - - module TestOneArgumentInRefReturned = - - type C() = - static member M (x:inref) = &x - - let test() = - let mutable r1 = 1 - let addr = &C.M (&r1) - let x = addr + 1 - check2 "mepojcwem10" 1 r1 - check2 "mepojcwem10vr" 2 x - - test() - - module TestOneArgumentOutRef = - - type C() = - static member M (x:outref) = &x - - let test() = - let mutable r1 = 1 - let addr = &C.M (&r1) - addr <- addr + 1 - check2 "mepojcwem10" 2 r1 - - test() - - module TestTwoArguments = - - type C() = - static member M (x:byref, y:byref) = &x - - let test() = - let mutable r1 = 1 - let mutable r2 = 0 - let addr = &C.M (&r1, &r2) - addr <- addr + 1 - check2 "mepojcwem11" 2 r1 - - test() - - module TestRecordParam = - - type R = { mutable z : int } - type C() = - static member M (x:R) = &x.z - - let test() = - let r = { z = 1 } - let addr = &C.M r - addr <- addr + 1 - check2 "mepojcwem12" 2 r.z - - test() - - module TestRecordParam2 = - - type R = { mutable z : int } - type C() = - static member M (x:byref) = &x.z - - let test() = - let mutable r = { z = 1 } - let addr = &C.M(&r) - addr <- addr + 1 - check2 "mepojcwem13a" 2 r.z - - test() - - module TestClassParamMutableField = - - type C() = [] val mutable z : int - - type C2() = - static member M (x:C) = &x.z - - let test() = - let c = C() - let addr = &C2.M c - addr <- addr + 1 - check2 "mepojcwem13b" 1 c.z - - test() - - module TestArrayParam = - - type C() = - static member M (x:int[]) = &x.[0] - - let test() = - let r = [| 1 |] - let addr = &C.M r - addr <- addr + 1 - check2 "mepojcwem14" 2 r.[0] - - test() - - module TestStructParam = - - [] - type R = { mutable z : int } - - type C() = - static member M (x:byref) = &x.z - - let test() = - let mutable r = { z = 1 } - let addr = &C.M(&r) - addr <- addr + 1 - check2 "mepojcwem15" 2 r.z - - test() - - module TestInterfaceMethod = - let mutable x = 1 - - type I = - abstract M : unit -> byref - - type C() = - interface I with - member this.M() = &x - - let ObjExpr() = - { new I with - member this.M() = &x } - - let test() = - let addr = &(C() :> I).M() - addr <- addr + 1 - let addr = &(ObjExpr()).M() - addr <- addr + 1 - check2 "mepojcwem16" 3 x - - test() - - module TestInterfaceProperty = - let mutable x = 1 - - type I = - abstract P : byref - - type C() = - interface I with - member this.P = &x - - let ObjExpr() = - { new I with - member this.P = &x } - - let test() = - let addr = &(C() :> I).P - addr <- addr + 1 - let addr = &(ObjExpr()).P - addr <- addr + 1 - check2 "mepojcwem17" 3 x - - test() - - module TestDelegateMethod = - let mutable x = 1 - - type D = delegate of unit -> byref - - let test() = - let d = D(fun () -> &x) - let addr = &d.Invoke() - check2 "mepojcwem18a" 1 x - addr <- addr + 1 - check2 "mepojcwem18b" 2 x - - test() - - module TestBaseCall = - type Incrementor(z) = - abstract member Increment : int byref * int byref -> unit - default this.Increment(i : int byref,j : int byref) = - i <- i + z - - type Decrementor(z) = - inherit Incrementor(z) - override this.Increment(i, j) = - base.Increment(&i, &j) - - i <- i - z - - module TestDelegateMethod2 = - let mutable x = 1 - - type D = delegate of byref -> byref - - let d = D(fun xb -> &xb) - - let test() = - let addr = &d.Invoke(&x) - check2 "mepojcwem18a2" 1 x - addr <- addr + 1 - check2 "mepojcwem18b3" 2 x - - test() - - - module ByRefExtensionMethods1 = - - open System - open System.Runtime.CompilerServices - - [] - type Ext = - - [] - static member ExtDateTime2(dt: inref, x:int) = dt.AddDays(double x) - - module UseExt = - let now = DateTime.Now - let dt2 = now.ExtDateTime2(3) - check "£f3mllkm2" dt2 (now.AddDays(3.0)) - - -(* - module ByRefExtensionMethodsOverloading = - - open System - open System.Runtime.CompilerServices - - [] - type Ext = - [] - static member ExtDateTime(dt: DateTime, x:int) = dt.AddDays(double x) - - [] - static member ExtDateTime(dt: inref, x:int) = dt.AddDays(2.0 * double x) - - module UseExt = - let dt = DateTime.Now.ExtDateTime(3) - let dt2 = DateTime.Now.ExtDateTime(3) -*) - module TestReadOnlyAddressOfStaticField = - type C() = - static let x = 1 - static member F() = &x - - let test() = - let addr = &C.F() - check2 "mepojcwem18a2dw" 1 addr - - test() - - module TestAssignToReturnByref = - type C() = - static let mutable v = System.DateTime.Now - static member M() = &v - static member P = &v - member __.InstanceM() = &v - member __.InstanceP with get() = &v - static member Value = v - - let F1() = - let today = System.DateTime.Now.Date - C.M() <- today - check "cwecjc" C.Value today - C.P <- C.M().AddDays(1.0) - check "cwecjc1" C.Value (today.AddDays(1.0)) - let c = C() - c.InstanceM() <- today.AddDays(2.0) - check "cwecjc2" C.Value (today.AddDays(2.0)) - c.InstanceP <- today.AddDays(3.0) - check "cwecjc1" C.Value (today.AddDays(3.0)) - - F1() - - module TestAssignToReturnByref2 = - let mutable v = System.DateTime.Now - let M() = &v - - let F1() = - let today = System.DateTime.Now.Date - M() <- today - check "cwecjc" v today - - F1() - - module BaseCallByref = - - type Incrementor(z) = - abstract member Increment : int byref * int byref -> unit - default this.Increment(i : int byref,j : int byref) = - i <- i + z - - type Decrementor(z) = - inherit Incrementor(z) - override this.Increment(i, j) = - base.Increment(&i, &j) - - i <- i - z - - - module Bug820 = - - let inline f (x, r:byref<_>) = r <- x - let mutable x = Unchecked.defaultof<_> - f (0, &x) - - module Bug820b = - - type Bug820x() = - let f (x, r:byref<_>) = r <- x - let mutable x = Unchecked.defaultof<_> - member __.P = f (0, &x) - - // check recursive functions - module TestNameModuleGeneric = - - let rec testValue (unused: 'T) id (data: byref) : unit = - if id = 10 then - data <- 3uy - else - testValue unused (id + 1) &data - let Test() = - let mutable x = 0uy - testValue "unused" 0 &x - check "vruoer" x 3uy - Test() - - module TestNameModuleNonGeneric = - - let rec testValue id (data: byref) : unit = - if id = 10 then - data <- 3uy - else - testValue (id + 1) &data - - let Test() = - let mutable x = 0uy - testValue 0 &x - check "vruoer3r" x 3uy - Test() - - module TestNameModuleNonGenericSubsume = - - let rec testValue id (data: byref) (y: System.IComparable) : unit = - if id = 10 then - data <- 3uy - else - testValue (id + 1) &data y - - let Test() = - let mutable x = 0uy - testValue 0 &x Unchecked.defaultof - check "vruoer3r" x 3uy - - Test() - - type GenericTestNameRecursive() = - - let rec testValue unused id (data: byref) : unit = - if id = 10 then data <- 3uy else testValue unused (id + 1) &data - - static do GenericTestNameRecursive().Test() - - member __.Test() = - let mutable x = 0uy - testValue "unused" 0 &x - check "vruoer3rv" x 3uy - let mutable z = 0uy - testValue 6L 0 &z - check "vruoer3rvwqf" z 3uy - - type NonGenericTestNameRecursiveInClass() = - - let rec testValue id (data: byref) : unit = - if id = 10 then - data <- 3uy - else - testValue (id + 1) &data - - static do NonGenericTestNameRecursiveInClass().Test() - - member __.Test() = - let mutable x = 0uy - testValue 0 &x - check "vruoer3rvvremtys" x 3uy - - - type NonGenericTestNameRecursiveInClassSubsume() = - - let rec testValue id (data: byref) (y:System.IComparable) : unit = - if id = 10 then - data <- 3uy - else - testValue (id + 1) &data y - - static do NonGenericTestNameRecursiveInClassSubsume().Test() - - member __.Test() = - let mutable x = 0uy - testValue 0 &x Unchecked.defaultof - check "vruoer3rvvremtys" x 3uy - - type StaticGenericTestNameRecursiveInClass() = - - static let rec testValue unused id (data: byref) : unit = - if id = 10 then data <- 3uy else testValue unused (id + 1) &data - - static do StaticGenericTestNameRecursiveInClass.Test() - - static member Test() = - let mutable x = 0uy - testValue "unused" 0 &x - check "vruoer3rv" x 3uy - let mutable z = 0uy - testValue 6L 0 &z - check "vruoer3rvwqfgw" z 3uy - - type StaticNonGenericTestNameRecursiveInClass() = - - static let rec testValue id (data: byref) : unit = - if id = 10 then data <- 3uy else testValue (id + 1) &data - - static do StaticNonGenericTestNameRecursiveInClass.Test() - - static member Test() = - let mutable x = 0uy - testValue 0 &x - check "vruoer3rvvrebae" x 3uy - - module TestInRefMutation = - [] - type TestMut = - - val mutable x : int - - member this.AnAction() = - this.x <- 1 - - let testAction (m: inref) = - m.AnAction() - check "vleoij" m.x 0 - - let test() = - let x = TestMut() - //testIn (&x) - testAction (&x) - x - test() - - module MutateInRef3 = - [] - type TestMut(x: int ref) = - - member this.X = x.contents - member this.XAddr = &x.contents - - let testIn (m: inref) = - // If the struct API indirectly reveals a byref return of a field in a reference type then - // there is nothing stopping it being written to. - m.XAddr <- 1 - - let test() = - let m = TestMut(ref 0) - testIn (&m) - check "vleoij" m.X 1 - - test() - - module MatrixOfTests = - - module ReturnAddressOfByRef = - let f1 (x: byref) = &x - - module ReturnAddressOfInRef = - let f1 (x: inref) = &x - - module ReturnAddressOfOutRef = - let f1 (x: outref) = &x - - //----- - - module ReadByRef = - let f1 (x: byref) = x - - module ReadInRef = - let f1 (x: inref) = x - - module ReadOutRef = - let f1 (x: outref) = x - - //----- - - module ReadByRefStructInner = - let f1 (x: byref) = x.X - - module ReadInRefStructInner = - let f1 (x: inref) = x.X - - module ReadOutRefStructInner = - let f1 (x: outref) = x.X - - //----- - module WriteToByRef = - let f1 (x: byref) = x <- 1 - - module WriteToOutRef = - let f1 (x: outref) = x <- 1 - - //----- - module WriteToByRefStructInner = - let f1 (x: byref) = x.X <- 1 - - module WriteToOutRefStructInner = - let f1 (x: outref) = x.X <- 1 - - //----- - module OutRefToByRef = - let f1 (x: byref<'T>) = 1 - let f2 (x: outref<'T>) = f1 &x - - module ByRefToByRef = - let f1 (x: byref<'T>) = 1 - let f2 (x: byref<'T>) = f1 &x - - module ByRefToOutRef = - let f1 (x: outref<'T>) = 1 - let f2 (x: byref<'T>) = f1 &x - - module OutRefToOutRef = - let f1 (x: outref<'T>) = 1 - let f2 (x: outref<'T>) = f1 &x - - module ByRefToInRef = - let f1 (x: inref<'T>) = 1 - let f2 (x: byref<'T>) = f1 &x - - module InRefToInRef = - let f1 (x: inref<'T>) = 1 - let f2 (x: inref<'T>) = f1 &x - - module OutRefToInRef = - let f1 (x: inref<'T>) = 1 - let f2 (x: outref<'T>) = f1 &x // allowed, because &outref are treated as byref, see RFC - - //--------------- - module OutRefToByRefClassMethod = - type C() = - static member f1 (x: byref<'T>) = 1 - let f2 (x: outref<'T>) = C.f1 &x - - module ByRefToByRefClassMethod = - type C() = - static member f1 (x: byref<'T>) = 1 - let f2 (x: byref<'T>) = C.f1 &x - - module ByRefToOutRefClassMethod = - type C() = - static member f1 (x: outref<'T>) = 1 - let f2 (x: byref<'T>) = C.f1 &x - - module OutRefToOutRefClassMethod = - type C() = - static member f1 (x: outref<'T>) = 1 - let f2 (x: outref<'T>) = C.f1 &x - - module ByRefToInRefClassMethod = - type C() = - static member f1 (x: inref<'T>) = 1 - let f2 (x: byref<'T>) = C.f1 &x - - module InRefToInRefClassMethod = - type C() = - static member f1 (x: inref<'T>) = 1 - let f2 (x: inref<'T>) = C.f1 &x - - module OutRefToInRefClassMethod = - type C() = - static member f1 (x: inref<'T>) = 1 - let f2 (x: outref<'T>) = C.f1 &x - - //--------------- - module OutRefToByRefClassMethod2 = - type C() = - static member f1 (x: byref<'T>) = 1 - let f2 (x: outref<'T>) = C.f1(&x) - - module ByRefToByRefClassMethod2 = - type C() = - static member f1 (x: byref<'T>) = 1 - let f2 (x: byref<'T>) = C.f1(&x) - - module ByRefToOutRefClassMethod2 = - type C() = - static member f1 (x: outref<'T>) = 1 - let f2 (x: byref<'T>) = C.f1(&x) - - module OutRefToOutRefClassMethod2 = - type C() = - static member f1 (x: outref<'T>) = 1 - let f2 (x: outref<'T>) = C.f1(&x) - - module ByRefToInRefClassMethod2 = - type C() = - static member f1 (x: inref<'T>) = 1 - let f2 (x: byref<'T>) = C.f1(&x) - - module InRefToInRefClassMethod2 = - type C() = - static member f1 (x: inref<'T>) = 1 - let f2 (x: inref<'T>) = C.f1(&x) - - module OutRefToInRefClassMethod2 = - type C() = - static member f1 (x: inref<'T>) = 1 - let f2 (x: outref<'T>) = C.f1(&x) - - module TestStructRecord = - [] - type AnItem = - { Link: string } - - let link item = - { item with Link = "" } - -// https://github.com/dotnet/fsharp/issues/12085 -module NoTailcallToByrefsWithModReq = - module ClassLibrary = - - // F# equivalent of `public delegate FieldType Getter(in DeclaringType);` - type Getter<'DeclaringType, 'FieldType> = delegate of inref<'DeclaringType> -> 'FieldType - - type GetterWrapper<'DeclaringType, 'FieldType> (getter : Getter<'DeclaringType, 'FieldType>) = - member _.Get (instance : 'DeclaringType) = getter.Invoke &instance - - open ClassLibrary - type MyRecord = { Value: int[] } - let App() = - - let wrapper = new GetterWrapper(fun (record: inref) -> record.Value) - - let record = { Value = [| 42 |] } - let value = wrapper.Get(record) - value.GetEnumerator() - App() - -let aa = - if !failures then (stdout.WriteLine "Test Failed"; exit 1) - else (stdout.WriteLine "Test Passed"; - System.IO.File.WriteAllText("test.ok","ok"); - exit 0) - diff --git a/tests/fsharp/core/byrefs/test2.bsl b/tests/fsharp/core/byrefs/test2.bsl deleted file mode 100644 index 80a3a45f55e..00000000000 --- a/tests/fsharp/core/byrefs/test2.bsl +++ /dev/null @@ -1,138 +0,0 @@ - -test2.fsx(181,9,181,22): typecheck warning FS0193: This expression is a function value, i.e. is missing arguments. Its type is byref -> unit. - -test2.fsx(199,9,199,20): typecheck warning FS0193: This expression is a function value, i.e. is missing arguments. Its type is int -> byref -> unit. - -test2.fsx(214,9,214,24): typecheck warning FS0193: This expression is a function value, i.e. is missing arguments. Its type is inref * int -> unit. - -test2.fsx(7,43,7,45): typecheck info FS3370: The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'. - -test2.fsx(12,26,12,28): typecheck info FS3370: The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'. - -test2.fsx(12,29,12,30): typecheck info FS3370: The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'. - -test2.fsx(29,18,29,19): typecheck error FS3209: The address of the variable 'y' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(36,18,36,19): typecheck error FS3209: The address of the variable 'z' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(45,14,45,15): typecheck error FS3209: The address of the variable 'x' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(49,14,49,15): typecheck error FS3209: The address of the variable 'y' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(56,14,56,15): typecheck error FS3209: The address of the variable 'x' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(59,14,59,15): typecheck error FS3209: The address of the variable 'y' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(68,18,68,19): typecheck error FS3209: The address of the variable 'z' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(69,10,69,11): typecheck error FS3209: The address of the variable 'y' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(79,14,79,29): typecheck error FS3228: The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(87,14,87,29): typecheck error FS3228: The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(93,13,93,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(93,17,93,29): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(93,28,93,29): typecheck error FS0421: The address of the variable 'x' cannot be used at this point - -test2.fsx(93,17,93,29): typecheck error FS0425: The type of a first-class function cannot contain byrefs - -test2.fsx(93,17,93,29): typecheck error FS0425: The type of a first-class function cannot contain byrefs - -test2.fsx(112,53,112,54): typecheck error FS3209: The address of the variable 'x' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(124,41,124,42): typecheck error FS3209: The address of the variable 'x' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. - -test2.fsx(133,23,133,33): typecheck error FS0438: Duplicate method. The method 'TestMethod' has the same name and signature as another method in type 'NegativeTests.TestNegativeOverloading'. - -test2.fsx(131,23,131,33): typecheck error FS0438: Duplicate method. The method 'TestMethod' has the same name and signature as another method in type 'NegativeTests.TestNegativeOverloading'. - -test2.fsx(129,23,129,33): typecheck error FS0438: Duplicate method. The method 'TestMethod' has the same name and signature as another method in type 'NegativeTests.TestNegativeOverloading'. - -test2.fsx(137,18,137,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(137,18,137,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(139,18,139,23): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(141,9,141,14): typecheck error FS3301: The function or method has an invalid return type '(byref * int)'. This is not permitted by the rules of Common IL. - -test2.fsx(141,34,141,39): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(141,35,141,36): typecheck error FS0418: The byref typed value 'x' cannot be used at this point - -test2.fsx(143,9,143,14): typecheck error FS3301: The function or method has an invalid return type '(byref -> unit)'. This is not permitted by the rules of Common IL. - -test2.fsx(145,14,145,15): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(147,17,147,18): typecheck error FS3300: The parameter 'x' has an invalid type '((byref -> unit) * int)'. This is not permitted by the rules of Common IL. - -test2.fsx(149,17,149,18): typecheck error FS3300: The parameter 'x' has an invalid type '(byref -> unit)'. This is not permitted by the rules of Common IL. - -test2.fsx(149,41,149,42): typecheck error FS3300: The parameter 'y' has an invalid type '(byref * int)'. This is not permitted by the rules of Common IL. - -test2.fsx(155,36,155,39): typecheck error FS3300: The parameter 'tup' has an invalid type '(inref * int)'. This is not permitted by the rules of Common IL. - -test2.fsx(156,13,156,33): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(158,37,158,38): typecheck error FS3300: The parameter 'x' has an invalid type '(byref -> unit)'. This is not permitted by the rules of Common IL. - -test2.fsx(160,37,160,38): typecheck error FS3300: The parameter 'x' has an invalid type 'byref option'. This is not permitted by the rules of Common IL. - -test2.fsx(162,17,162,18): typecheck error FS3300: The parameter 'x' has an invalid type 'byref option'. This is not permitted by the rules of Common IL. - -test2.fsx(167,13,167,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(167,17,167,30): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(170,9,170,15): typecheck error FS3301: The function or method has an invalid return type '(byref -> unit)'. This is not permitted by the rules of Common IL. - -test2.fsx(171,9,171,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(174,13,174,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(176,13,176,26): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(181,9,181,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(185,13,185,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(185,17,185,28): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(188,9,188,15): typecheck error FS3301: The function or method has an invalid return type '(int -> byref -> unit)'. This is not permitted by the rules of Common IL. - -test2.fsx(189,9,189,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(192,13,192,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(194,13,194,24): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(199,9,199,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(203,13,203,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(203,17,203,32): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(203,17,203,32): typecheck error FS0425: The type of a first-class function cannot contain byrefs - -test2.fsx(207,13,207,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(209,13,209,28): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(214,9,214,24): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(217,9,217,15): typecheck error FS3301: The function or method has an invalid return type '(byref * int)'. This is not permitted by the rules of Common IL. - -test2.fsx(219,10,219,15): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(219,11,219,12): typecheck error FS0421: The address of the variable 'x' cannot be used at this point - -test2.fsx(222,9,222,18): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(226,13,226,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(226,17,226,26): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -test2.fsx(276,6,276,7): typecheck info FS3370: The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'. diff --git a/tests/fsharp/core/byrefs/test3.bsl b/tests/fsharp/core/byrefs/test3.bsl deleted file mode 100644 index 6fe9b7ec397..00000000000 --- a/tests/fsharp/core/byrefs/test3.bsl +++ /dev/null @@ -1,22 +0,0 @@ - -test3.fsx(39,18,39,28): typecheck error FS3237: Cannot call the byref extension method 'Test2. The first parameter requires the value to be mutable or a non-readonly byref type. - -test3.fsx(40,9,40,11): typecheck error FS0001: Type mismatch. Expecting a - 'byref' -but given a - 'inref' -The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' - -test3.fsx(44,9,44,20): typecheck error FS3237: Cannot call the byref extension method 'Change. The first parameter requires the value to be mutable or a non-readonly byref type. - -test3.fsx(49,19,49,30): typecheck error FS3237: Cannot call the byref extension method 'Test2. The first parameter requires the value to be mutable or a non-readonly byref type. - -test3.fsx(55,9,55,21): typecheck error FS3237: Cannot call the byref extension method 'Change. The first parameter requires the value to be mutable or a non-readonly byref type. - -test3.fsx(59,17,59,29): typecheck error FS3239: Cannot partially apply the extension method 'NotChange' because the first parameter is a byref type. - -test3.fsx(60,17,60,24): typecheck error FS3239: Cannot partially apply the extension method 'Test' because the first parameter is a byref type. - -test3.fsx(61,17,61,26): typecheck error FS3239: Cannot partially apply the extension method 'Change' because the first parameter is a byref type. - -test3.fsx(62,17,62,25): typecheck error FS3239: Cannot partially apply the extension method 'Test2' because the first parameter is a byref type. diff --git a/tests/fsharp/core/byrefs/test3.fsx b/tests/fsharp/core/byrefs/test3.fsx deleted file mode 100644 index 5cc0f379da8..00000000000 --- a/tests/fsharp/core/byrefs/test3.fsx +++ /dev/null @@ -1,101 +0,0 @@ -#if TESTS_AS_APP -module Core_byrefs -#endif - -open System -open System.Runtime.CompilerServices -open CSharpLib3 - -let failures = ref false -let report_failure (s) = - stderr.WriteLine ("NO: " + s); failures := true -let test s b = if b then () else report_failure(s) - -(* TEST SUITE FOR Int32 *) - -let out r (s:string) = r := !r @ [s] - -let check s actual expected = - if actual = expected then printfn "%s: OK" s - else report_failure (sprintf "%s: FAILED, expected %A, got %A" s expected actual) - -let check2 s expected actual = check s actual expected - -// Test extension members for byrefs - -[] -type Ext() = - [] - static member inline Change(dt: byref) = () - - [] - static member inline NotChange(dt: inref) = () - -#if NEGATIVE -module Negatives = - - let test1 () : byref = - let dt = DateTime.Now - let x = &dt.Test2() // should fail - &x // should fail - - let test2 () = - let dt = DateTime.Now - dt.Change() // should fail - - let test3 () = - let dt = DateTime.Now - let dtr = &dt - let _x = &dtr.Test2() // should fail - () - - let test4 () = - let dt = DateTime.Now - let dtr = &dt - dtr.Change() // should fail - - let test5 () = - let dt = DateTime.Now - let x = dt.NotChange // should fail - let y = dt.Test // should fail - let z = dt.Change // should fail - let w = dt.Test2 // should fail - () - -#endif - -module Positives = - - let test1 () = - let dt = DateTime.Now - let _x = dt.Test() - let dtr = &dt - dtr.Test() - - let test2 () = - let dt = DateTime.Now - dt.NotChange() - let dtr = &dt - dtr.NotChange() - - let test3 () = - let mutable dt = DateTime.Now - let _x = dt.Test2() - dt.Test() - let dtr = &dt - let _x = dtr.Test2() - dtr.Test() - - let test4 () = - let mutable dt = DateTime.Now - dt.Change() - dt.NotChange() - let dtr = &dt - dtr.Change() - dtr.NotChange() - -let aa = - if !failures then (stdout.WriteLine "Test Failed"; exit 1) - else (stdout.WriteLine "Test Passed"; - System.IO.File.WriteAllText("test3.ok","ok"); - exit 0) \ No newline at end of file diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index f2aaad809cc..65f558630cd 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -76,60 +76,6 @@ module CoreTests = [] let ``attributes-FSI`` () = singleTestBuildAndRun "core/attributes" FSI - [] - let byrefs () = - - let cfg = testConfig "core/byrefs" - - begin - use testOkFile = fileguard cfg "test.ok" - - fsc cfg "%s -o:test.exe -g --langversion:4.7" cfg.fsc_flags ["test.fsx"] - - 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") "" - - testOkFile.CheckExists() - end - - begin - use testOkFile = fileguard cfg "test2.ok" - - fsc cfg "%s -o:test2.exe -g" cfg.fsc_flags ["test2.fsx"] - - singleNegTest { cfg with fsc_flags = sprintf "%s --warnaserror-" cfg.fsc_flags } "test2" - - exec cfg ("." ++ "test2.exe") "" - - testOkFile.CheckExists() - end - - begin - csc cfg """/langversion:7.2 /nologo /target:library /out:cslib3.dll""" ["cslib3.cs"] - - use testOkFile = fileguard cfg "test3.ok" - - fsc cfg "%s -r:cslib3.dll -o:test3.exe -g" cfg.fsc_flags ["test3.fsx"] - - singleNegTest { cfg with fsc_flags = sprintf "%s -r:cslib3.dll" cfg.fsc_flags } "test3" - - exec cfg ("." ++ "test3.exe") "" - - testOkFile.CheckExists() - end - [] let span () =