From 0e034af3975f840bbbcefefb0cb03dd9dd25f7f3 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Mon, 7 Aug 2023 15:50:25 -0600 Subject: [PATCH 1/9] Add some additional tests --- .../ByrefSafetyAnalysis.fs | 54 ++++++++++++++++++- .../E_ByrefFieldEscapingLocalScope01.fs | 10 ++++ .../E_ByrefFieldEscapingLocalScope02.fs | 11 ++++ .../E_SpanUsedInInnerLambda01.fs | 13 +++++ .../E_SpanUsedInInnerLambda02.fs | 13 +++++ .../ByrefSafetyAnalysis/E_TopLevelByref.fs | 9 ++++ .../ReturnFieldSetBySpan.fs | 10 ++++ .../ByrefSafetyAnalysis/ReturnSpan01.fs | 13 +++++ 8 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_ByrefFieldEscapingLocalScope01.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_ByrefFieldEscapingLocalScope02.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SpanUsedInInnerLambda01.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SpanUsedInInnerLambda02.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_TopLevelByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ReturnFieldSetBySpan.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ReturnSpan01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs index 6517e0a773..2c1115c41b 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -174,4 +174,56 @@ module ByrefSafetyAnalysis = |> withOptions ["--warnaserror+"; "--nowarn:988"] |> compileExeAndRun |> shouldSucceed - + +#if NET7_0_OR_GREATER + // SOURCE=ReturnFieldSetBySpan.fs # ReturnFieldSetBySpan.fs + [] + let``ReturnFieldSetBySpan_fs`` compilation = + compilation + |> asExe + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> compileExeAndRun + |> shouldSucceed + + // SOURCE=ReturnSpan02.fs # ReturnSpan02.fs + [] + let``ReturnSpan01_fs`` compilation = + compilation + |> asExe + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> compileExeAndRun + |> shouldSucceed +#endif + + // SOURCE=E_TopLevelByref.fs SCFLAGS="--test:ErrorRanges" # E_TopLevelByref.f + [] + 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.") + ] + + // SOURCE=E_SpanUsedInInnerLambda01.fs SCFLAGS="--test:ErrorRanges" # E_SpanUsedInInnerLambda01.f + [] + 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.") + ] + + // SOURCE=E_SpanUsedInInnerLambda02.fs SCFLAGS="--test:ErrorRanges" # E_SpanUsedInInnerLambda02.f + [] + 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.") + ] 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 0000000000..99f0925915 --- /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 0000000000..50a1cbeacc --- /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_SpanUsedInInnerLambda01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SpanUsedInInnerLambda01.fs new file mode 100644 index 0000000000..887d03e729 --- /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 0000000000..0e1e159046 --- /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 0000000000..de89415f02 --- /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/ReturnFieldSetBySpan.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ReturnFieldSetBySpan.fs new file mode 100644 index 0000000000..5bb4247410 --- /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 0000000000..514ecc520d --- /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" From 4e96642690c5a6856747204ada5b903a61786ed8 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Mon, 7 Aug 2023 23:37:47 -0600 Subject: [PATCH 2/9] Migrate byref tests from legacy test suite --- .../ByrefSafetyAnalysis.fs | 233 +++++++++++++++++- .../ByrefSafetyAnalysis/E_MigratedTest01.fs | 98 ++++++++ .../ByrefSafetyAnalysis/E_MigratedTest02.fs} | 71 +----- .../ByrefSafetyAnalysis/E_MigratedTest03.fs | 47 ++++ .../ByrefSafetyAnalysis/MigratedTest01.fs} | 111 +-------- .../ByrefSafetyAnalysis/MigratedTest02.fs | 62 +++++ .../ByrefSafetyAnalysis/MigratedTest03.fs | 61 +++++ .../MigratedTest03CSharpLib.cs} | 0 tests/fsharp/core/byrefs/.gitignore | 1 - tests/fsharp/core/byrefs/test.bsl | 71 ------ tests/fsharp/core/byrefs/test2.bsl | 138 ----------- tests/fsharp/core/byrefs/test3.bsl | 22 -- tests/fsharp/core/byrefs/test3.fsx | 101 -------- tests/fsharp/tests.fs | 54 ---- 14 files changed, 505 insertions(+), 565 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest01.fs rename tests/{fsharp/core/byrefs/test2.fsx => FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest02.fs} (68%) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest03.fs rename tests/{fsharp/core/byrefs/test.fsx => FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs} (92%) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03.fs rename tests/{fsharp/core/byrefs/cslib3.cs => FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03CSharpLib.cs} (100%) delete mode 100644 tests/fsharp/core/byrefs/.gitignore delete mode 100644 tests/fsharp/core/byrefs/test.bsl delete mode 100644 tests/fsharp/core/byrefs/test2.bsl delete mode 100644 tests/fsharp/core/byrefs/test3.bsl delete mode 100644 tests/fsharp/core/byrefs/test3.fsx diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs index 2c1115c41b..2762a9a73f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -8,6 +8,215 @@ open FSharp.Test.Compiler module ByrefSafetyAnalysis = + // SOURCE=MigratedTest01.fs SCFLAGS="--test:ErrorRanges" # MigratedTest01.fs + [] + let``MigratedTest01_fs`` compilation = + compilation + |> ignoreWarnings + |> compileExeAndRun + |> withDiagnostics [ + (Warning 52, Line 1219, Col 13, Line 1219, Col 25, "The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed") + (Warning 20, Line 1227, Col 9, Line 1227, Col 15, "The result of this expression has type 'TestMut' 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'.") + (Warning 20, Line 1423, Col 5, Line 1423, Col 10, "The result of this expression has type 'System.Collections.IEnumerator' 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'.") + (Information 3370, Line 10, Col 26, Line 10, Col 28, "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'.") + (Information 3370, Line 10, Col 29, Line 10, Col 30, "The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.") + ] + |> shouldSucceed + + // SOURCE=E_Migrated01.fs SCFLAGS="--test:ErrorRanges" # E_Migrated01.fs + [] + let``E_Migrated01_fs`` compilation = + compilation + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3224, Line 9, Col 34, Line 9, Col 40, "The byref pointer is readonly, so this write is not permitted.") + (Error 39, Line 12, Col 26, Line 12, Col 27, "The type 'S' is not defined.") + (Error 72, Line 12, Col 32, Line 12, Col 35, "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.") + (Error 1, Line 16, Col 36, Line 16, Col 38, "Type mismatch. Expecting a + 'byref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + (Error 1, Line 20, Col 36, Line 20, Col 38, "Type mismatch. Expecting a + 'outref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'") + (Error 1, Line 25, Col 38, Line 25, Col 40, "Type mismatch. Expecting a + 'byref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + (Error 1, Line 30, Col 38, Line 30, Col 40, "Type mismatch. Expecting a + 'outref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'") + (Error 1, Line 35, Col 38, Line 35, Col 40, "Type mismatch. Expecting a + 'byref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + (Error 1, Line 40, Col 38, Line 40, Col 40, "Type mismatch. Expecting a + 'outref<'T>' +but given a + 'inref<'T>' +The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'") + (Error 1204, Line 44, Col 34, Line 44, Col 47, "This construct is for use in the FSharp.Core library and should not be used directly") + (Error 3236, Line 49, Col 21, Line 49, Col 23, "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 50, Col 21, Line 50, Col 23, "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 56, Col 21, Line 56, Col 37, "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 63, Col 22, Line 63, Col 23, "This expression was expected to have type + 'inref' +but here has type + 'System.DateTime' ") + (Error 39, Line 64, Col 9, Line 64, Col 14, "The value or constructor 'check' is not defined. Maybe you want one of the following: + Checked + Unchecked") + (Error 3238, Line 66, Col 10, Line 66, Col 15, "Byref types are not allowed to have optional type extensions.") + (Error 3238, Line 70, Col 10, Line 70, Col 15, "Byref types are not allowed to have optional type extensions.") + (Error 3238, Line 74, Col 10, Line 74, Col 16, "Byref types are not allowed to have optional type extensions.") + (Error 3236, Line 92, Col 21, Line 92, Col 36, "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 92, Col 21, Line 92, Col 36, "Type mismatch. Expecting a + 'byref' +but given a + 'inref' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") + (Error 3236, Line 97, Col 21, Line 97, 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.") + ] + + // SOURCE=Migrated02.fs SCFLAGS="--test:ErrorRanges" # Migrated02.fs + [] + let``MigratedTest02_fs`` compilation = + compilation + |> ignoreWarnings + |> compileExeAndRun + |> shouldSucceed + |> withDiagnostics [ + (Information 3370, Line 10, Col 26, Line 10, Col 28, "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'.") + (Information 3370, Line 10, Col 29, Line 10, Col 30, "The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.") + ] + + // SOURCE=E_Migrated02.fs SCFLAGS="--test:ErrorRanges" # E_Migrated02.fs + [] + let``E_Migrated02_fs`` compilation = + compilation + |> asExe + |> compile + |> 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 ] + |> ignoreWarnings + |> compileExeAndRun + |> shouldSucceed + |> withDiagnostics [ + (Information 3370, Line 13, Col 26, Line 13, Col 28, "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'.") + (Information 3370, Line 13, Col 29, Line 13, Col 30, "The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.")] + + // 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 ] + |> 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.") + ] + // SOURCE=E_ByrefAsArrayElement.fs SCFLAGS="--test:ErrorRanges" # E_ByrefAsArrayElement.fs [] let``E_ByrefAsArrayElement_fs`` compilation = @@ -194,6 +403,28 @@ module ByrefSafetyAnalysis = |> compileExeAndRun |> shouldSucceed #endif + + // // SOURCE=E_ByrefFieldEscapingLocalScope01.fs SCFLAGS="--test:ErrorRanges" # E_ByrefFieldEscapingLocalScope01.fs + // [] + // let``E_ByrefEscapingLocalScope01_fs`` compilation = + // compilation + // |> asExe + // |> compile + // |> shouldFail + // |> withDiagnostics [ + // (Error 3234, Line 7, Col 5, Line 7, Col 9, "The Span or IsByRefLike variable 'span' cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + // ] + // + // // SOURCE=E_ByrefFieldEscapingLocalScope02.fs SCFLAGS="--test:ErrorRanges" # E_ByrefFieldEscapingLocalScope02.f + // [] + // let``E_ByrefEscapingLocalScope02_fs`` compilation = + // compilation + // |> asExe + // |> compile + // |> shouldFail + // |> withDiagnostics [ + // (Error 3234, Line 8, Col 9, Line 8, Col 13, "The Span or IsByRefLike variable 'span' cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") + // ] // SOURCE=E_TopLevelByref.fs SCFLAGS="--test:ErrorRanges" # E_TopLevelByref.f [] @@ -205,7 +436,7 @@ module ByrefSafetyAnalysis = |> 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.") ] - + // SOURCE=E_SpanUsedInInnerLambda01.fs SCFLAGS="--test:ErrorRanges" # E_SpanUsedInInnerLambda01.f [] let``E_SpanUsedInInnerLambda01_fs`` compilation = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest01.fs new file mode 100644 index 0000000000..2aefe33bf3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest01.fs @@ -0,0 +1,98 @@ +// #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable +#if TESTS_AS_APP +module Core_byrefs +#endif + +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 + () 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 ab7ec8cd73..d91c9a3b56 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 0000000000..35add5f495 --- /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/core/byrefs/test.fsx b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs similarity index 92% rename from tests/fsharp/core/byrefs/test.fsx rename to tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs index ad3623e1d3..7bd4e1e484 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs @@ -3,11 +3,7 @@ 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) +let test s b = if b then () else failwith s (* TEST SUITE FOR Int32 *) @@ -15,7 +11,7 @@ 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) + else failwithf "%s: FAILED, expected %A, got %A" s expected actual let check2 s expected actual = check s actual expected @@ -24,102 +20,6 @@ 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 @@ -1522,9 +1422,4 @@ module NoTailcallToByrefsWithModReq = 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) - +printfn "Test Passed" 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 0000000000..6365c79169 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs @@ -0,0 +1,62 @@ +// #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable +#if TESTS_AS_APP +module Core_byrefs +#endif + +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 0000000000..ce20c1e7a5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03.fs @@ -0,0 +1,61 @@ +#if TESTS_AS_APP +module Core_byrefs +#endif + +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/core/byrefs/.gitignore b/tests/fsharp/core/byrefs/.gitignore deleted file mode 100644 index 6a7461313b..0000000000 --- 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 71542c8be4..0000000000 --- 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/test2.bsl b/tests/fsharp/core/byrefs/test2.bsl deleted file mode 100644 index 80a3a45f55..0000000000 --- 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 6fe9b7ec39..0000000000 --- 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 5cc0f379da..0000000000 --- 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 f2aaad809c..65f558630c 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 () = From f46decdbba01c779aa1b482fa954bee505deb8ef Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Tue, 8 Aug 2023 10:10:53 -0600 Subject: [PATCH 3/9] Pretty print test error mismatches in a way which makes them copy-pastable --- tests/FSharp.Test.Utilities/Compiler.fs | 4 +++- tests/FSharp.Test.Utilities/CompilerAssert.fs | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 0ce5b995ad..5312e29995 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 ac593abf49..e629994fee 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -406,18 +406,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 From 145f75cc8e412c24dbc68d3b4fda5aa74d4c5bfe Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Tue, 8 Aug 2023 10:11:29 -0600 Subject: [PATCH 4/9] Extract some tests out of MigratedTests01.fs --- .../ByrefSafetyAnalysis/ByRefParam.fs | 14 + .../ByRefParam_ExplicitInAttribute.fs | 16 ++ .../ByRefParam_ExplicitOutAttribute.fs | 16 ++ ...ram_OverloadedTest_ExplicitOutAttribute.fs | 11 + .../ByrefSafetyAnalysis/ByRefReturn.fs | 13 + .../ByrefSafetyAnalysis.fs | 151 ++++++++-- .../ByrefSafetyAnalysis/CompareExchange.fs | 9 + .../ByrefSafetyAnalysis/InRefParam.fs | 14 + ...ramOverload_ExplicitAddressOfAtCallSite.fs | 17 ++ ...ramOverload_ImplicitAddressOfAtCallSite.fs | 13 + ...amOverload_ImplicitAddressOfAtCallSite2.fs | 15 + .../InRefParam_ExplicitInAttribute.fs | 8 + .../InRefParam_ExplicitInAttributeDateTime.fs | 10 + .../ByrefSafetyAnalysis/InRefReturn.fs | 16 ++ .../ByrefSafetyAnalysis/MigratedTest01.fs | 260 +----------------- .../ByrefSafetyAnalysis/MigratedTest02.fs | 2 - .../ByrefSafetyAnalysis/MigratedTest03.fs | 3 +- .../ByrefSafetyAnalysis/OutRefParam.fs | 8 + .../OutRefParam_ExplicitOutAttribute.fs | 8 + .../OutRefParam_Overloaded.fs | 11 + ...efParam_Overloaded_ExplicitOutAttribute.fs | 11 + .../ByrefSafetyAnalysis/Prelude.fs | 13 + .../ByrefSafetyAnalysis/Slot_ByRefReturn.fs | 20 ++ .../ByrefSafetyAnalysis/Slot_InRefReturn.fs | 20 ++ .../ByrefSafetyAnalysis/Slot_OutRefParam.fs | 11 + .../ByrefSafetyAnalysis/TryGetValue.fs | 12 + 26 files changed, 409 insertions(+), 293 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_ExplicitInAttribute.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_ExplicitOutAttribute.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefParam_OverloadedTest_ExplicitOutAttribute.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByRefReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/CompareExchange.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ExplicitAddressOfAtCallSite.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ImplicitAddressOfAtCallSite.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParamOverload_ImplicitAddressOfAtCallSite2.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_ExplicitInAttribute.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_ExplicitInAttributeDateTime.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_ExplicitOutAttribute.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_Overloaded.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/OutRefParam_Overloaded_ExplicitOutAttribute.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Prelude.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_ByRefReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_InRefReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_OutRefParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/TryGetValue.fs 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 0000000000..117cee6914 --- /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 0000000000..8923fe7427 --- /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 0000000000..1606d19a78 --- /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 0000000000..a52bd3bb71 --- /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 0000000000..ac41aba2cc --- /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/ByrefSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs index 2762a9a73f..c15af33479 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -7,28 +7,41 @@ open FSharp.Test open FSharp.Test.Compiler module ByrefSafetyAnalysis = - - // SOURCE=MigratedTest01.fs SCFLAGS="--test:ErrorRanges" # MigratedTest01.fs - [] - let``MigratedTest01_fs`` compilation = - compilation - |> ignoreWarnings - |> compileExeAndRun - |> withDiagnostics [ - (Warning 52, Line 1219, Col 13, Line 1219, Col 25, "The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed") - (Warning 20, Line 1227, Col 9, Line 1227, Col 15, "The result of this expression has type 'TestMut' 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'.") - (Warning 20, Line 1423, Col 5, Line 1423, Col 10, "The result of this expression has type 'System.Collections.IEnumerator' 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'.") - (Information 3370, Line 10, Col 26, Line 10, Col 28, "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'.") - (Information 3370, Line 10, Col 29, Line 10, Col 30, "The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.") + let withPrelude = + withReferences [ + FsFromPath (__SOURCE_DIRECTORY__ ++ "prelude.fs") + |> withName "Prelude" ] - |> shouldSucceed + + let verifyCompile compilation = + compilation + |> asExe + |> withOptions ["--nowarn:3370"; "--test:ErrorRanges"] + |> withPrelude + |> compile + + let verifyCompileAndRun compilation = + compilation + |> asExe + |> withOptions ["--nowarn:3370"; "--test:ErrorRanges"] + |> withPrelude + |> compileAndRun + + // // SOURCE=MigratedTest01.fs SCFLAGS="--test:ErrorRanges" # MigratedTest01.fs + // [] + // let``MigratedTest01_fs`` compilation = + // compilation + // |> ignoreWarnings + // |> compileExeAndRun + // |> withDiagnostics [ + // ] + // |> shouldSucceed // SOURCE=E_Migrated01.fs SCFLAGS="--test:ErrorRanges" # E_Migrated01.fs [] let``E_Migrated01_fs`` compilation = compilation - |> asExe - |> compile + |> verifyCompile |> shouldFail |> withDiagnostics [ (Error 3224, Line 9, Col 34, Line 9, Col 40, "The byref pointer is readonly, so this write is not permitted.") @@ -90,21 +103,13 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") // SOURCE=Migrated02.fs SCFLAGS="--test:ErrorRanges" # Migrated02.fs [] let``MigratedTest02_fs`` compilation = - compilation - |> ignoreWarnings - |> compileExeAndRun - |> shouldSucceed - |> withDiagnostics [ - (Information 3370, Line 10, Col 26, Line 10, Col 28, "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'.") - (Information 3370, Line 10, Col 29, Line 10, Col 30, "The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.") - ] + compilation |> verifyCompileAndRun |> shouldSucceed // SOURCE=E_Migrated02.fs SCFLAGS="--test:ErrorRanges" # E_Migrated02.fs [] let``E_Migrated02_fs`` compilation = compilation - |> asExe - |> compile + |> 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.") @@ -182,12 +187,9 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") compilation |> withReferences [ csharpLib ] - |> ignoreWarnings + |> withOptions ["--nowarn:3370"] |> compileExeAndRun |> shouldSucceed - |> withDiagnostics [ - (Information 3370, Line 13, Col 26, Line 13, Col 28, "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'.") - (Information 3370, Line 13, Col 29, Line 13, Col 30, "The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.")] // SOURCE=E_Migrated03.fs SCFLAGS="--test:ErrorRanges" # E_Migrated03.fs [] @@ -217,6 +219,95 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") (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 |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParamOverload_ImplicitAddressOfAtCallSite`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``InRefParamOverload_ImplicitAddressOfAInRefParamOverload_ImplicitAddressOfAtCallSite2tCallSite`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + // SOURCE=E_ByrefAsArrayElement.fs SCFLAGS="--test:ErrorRanges" # E_ByrefAsArrayElement.fs [] let``E_ByrefAsArrayElement_fs`` compilation = 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 0000000000..7e37a911e3 --- /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/InRefParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam.fs new file mode 100644 index 0000000000..6350992e0b --- /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 0000000000..37586989a3 --- /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 0000000000..8e6fff8a1f --- /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 0000000000..be6c7efbbf --- /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 0000000000..60ae45f894 --- /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 0000000000..0624e5f65b --- /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/InRefReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefReturn.fs new file mode 100644 index 0000000000..4c8b9065f7 --- /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/MigratedTest01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs index 7bd4e1e484..28df36cf8f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs @@ -1,7 +1,5 @@ // #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable -#if TESTS_AS_APP module Core_byrefs -#endif let test s b = if b then () else failwith s @@ -18,263 +16,7 @@ let check2 s expected actual = check s actual expected [] type S = [] - val mutable X : int - -// 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() + val mutable X : int #if IMPLICIT_ADDRESS_OF module InRefParam_DateTime = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs index 6365c79169..c34bd114f3 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest02.fs @@ -1,7 +1,5 @@ // #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable -#if TESTS_AS_APP module Core_byrefs -#endif let test s b = if b then () else failwith s diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03.fs index ce20c1e7a5..163f4a3b72 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest03.fs @@ -1,6 +1,5 @@ -#if TESTS_AS_APP +// #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable module Core_byrefs -#endif open System open System.Runtime.CompilerServices 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 0000000000..f788e4c7e4 --- /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 0000000000..ad58031a6c --- /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 0000000000..ef8a20caba --- /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 0000000000..2a67aeab8d --- /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 0000000000..a8e4c9ab45 --- /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/Slot_ByRefReturn.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/Slot_ByRefReturn.fs new file mode 100644 index 0000000000..73c0979ef0 --- /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 0000000000..8c50306a3c --- /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 0000000000..27fdb7d861 --- /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 0000000000..d246861791 --- /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 From 7e3025fe692a2485225184adc8e1b05592201a90 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Tue, 8 Aug 2023 11:44:10 -0600 Subject: [PATCH 5/9] Extract the rest of MigratedTest01 to individual files --- .../ByrefReturn/TestArrayParam.fs | 13 + .../ByrefReturn/TestBaseCall.fs | 14 + .../ByrefReturn/TestClassParamMutableField.fs | 15 + .../ByrefReturn/TestConditionalReturn.fs | 26 + .../ByrefReturn/TestDelegateMethod.fs | 18 + .../ByrefReturn/TestDelegateMethod2.fs | 18 + .../ByrefReturn/TestImmediateReturn.fs | 20 + .../ByrefReturn/TestInterfaceMethod.fs | 26 + .../ByrefReturn/TestInterfaceProperty.fs | 26 + .../ByrefReturn/TestMatchReturn.fs | 26 + .../ByrefReturn/TestOneArgument.fs | 13 + .../ByrefReturn/TestRecordParam.fs | 14 + .../ByrefReturn/TestRecordParam2.fs | 14 + .../ByrefReturn/TestStructParam.fs | 16 + .../ByrefReturn/TestTryFinallyReturn.fs | 26 + .../ByrefReturn/TestTryWithReturn.fs | 26 + .../ByrefReturn/TestTwoArguments.fs | 14 + .../ByrefReturnMember/BaseCallByref.fs | 14 + .../ByrefReturnMember/Bug820.fs | 7 + .../ByrefReturnMember/Bug820b.fs | 8 + .../ByRefExtensionMethods1.fs | 18 + .../ByRefExtensionMethodsOverloading.fs | 18 + .../GenericTestNameRecursive.fs | 16 + .../ByrefReturnMember/MatrixOfTests.fs | 154 +++ .../ByrefReturnMember/MutateInRef3.fs | 20 + .../NonGenericTestNameRecursiveInClass.fs | 16 + ...nGenericTestNameRecursiveInClassSubsume.fs | 16 + .../StaticGenericTestNameRecursiveInClass.fs | 16 + ...taticNonGenericTestNameRecursiveInClass.fs | 13 + .../ByrefReturnMember/TestArrayParam.fs | 14 + .../TestAssignToReturnByref.fs | 24 + .../TestAssignToReturnByref2.fs | 12 + .../ByrefReturnMember/TestBaseCall.fs | 14 + .../TestClassParamMutableField.fs | 16 + .../TestConditionalReturn.fs | 27 + .../ByrefReturnMember/TestDelegateMethod.fs | 15 + .../ByrefReturnMember/TestDelegateMethod2.fs | 16 + .../ByrefReturnMember/TestImmediateReturn.fs | 21 + .../ByrefReturnMember/TestInRefMutation.fs | 21 + .../ByrefReturnMember/TestInterfaceMethod.fs | 24 + .../TestInterfaceProperty.fs | 24 + .../ByrefReturnMember/TestMatchReturn.fs | 27 + .../TestNameModuleGeneric.fs | 15 + .../TestNameModuleNonGeneric.fs | 15 + .../TestNameModuleNonGenericSubsume.fs | 16 + .../ByrefReturnMember/TestOneArgument.fs | 14 + .../TestOneArgumentInRefReturned.fs | 15 + .../TestOneArgumentOutRef.fs | 14 + .../TestReadOnlyAddressOfStaticField.fs | 12 + .../ByrefReturnMember/TestRecordParam.fs | 15 + .../ByrefReturnMember/TestRecordParam2.fs | 15 + .../ByrefReturnMember/TestStructParam.fs | 17 + .../ByrefReturnMember/TestStructRecord.fs | 9 + .../ByrefReturnMember/TestTryFinallyReturn.fs | 27 + .../ByrefReturnMember/TestTryWithReturn.fs | 27 + .../ByrefReturnMember/TestTwoArguments.fs | 15 + .../ByrefSafetyAnalysis.fs | 286 +++- .../ImplicitAddressOf/InRefParam_DateTime.fs | 8 + ...am_DateTime_ImplicitAddressOfAtCallSite.fs | 7 + ...m_DateTime_ImplicitAddressOfAtCallSite2.fs | 7 + ...m_DateTime_ImplicitAddressOfAtCallSite3.fs | 8 + ...m_DateTime_ImplicitAddressOfAtCallSite4.fs | 9 + ...m_Generic_ExplicitAddressOfAttCallSite1.fs | 11 + ...m_Generic_ExplicitAddressOfAttCallSite2.fs | 10 + .../ByrefSafetyAnalysis/MigratedTest01.fs | 1167 ----------------- .../NoTailcallToByrefsWithModReq.fs | 20 + .../DirectoryAttribute.fs | 4 +- 67 files changed, 1467 insertions(+), 1192 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestArrayParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestBaseCall.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestClassParamMutableField.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestConditionalReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestDelegateMethod.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestDelegateMethod2.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestImmediateReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestInterfaceMethod.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestInterfaceProperty.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestMatchReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestOneArgument.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestRecordParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestRecordParam2.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestStructParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTryFinallyReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTryWithReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturn/TestTwoArguments.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/BaseCallByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/Bug820.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/Bug820b.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/ByRefExtensionMethods1.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/ByRefExtensionMethodsOverloading.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/GenericTestNameRecursive.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/MatrixOfTests.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/MutateInRef3.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/NonGenericTestNameRecursiveInClass.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/NonGenericTestNameRecursiveInClassSubsume.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/StaticGenericTestNameRecursiveInClass.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/StaticNonGenericTestNameRecursiveInClass.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestArrayParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestAssignToReturnByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestAssignToReturnByref2.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestBaseCall.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestClassParamMutableField.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestConditionalReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestDelegateMethod.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestDelegateMethod2.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestImmediateReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInRefMutation.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInterfaceMethod.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestInterfaceProperty.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestMatchReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleGeneric.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleNonGeneric.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestNameModuleNonGenericSubsume.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgument.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgumentInRefReturned.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestOneArgumentOutRef.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestReadOnlyAddressOfStaticField.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestRecordParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestRecordParam2.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestStructParam.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestStructRecord.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTryFinallyReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTryWithReturn.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefReturnMember/TestTwoArguments.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite2.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite3.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ImplicitAddressOf/InRefParam_DateTime_ImplicitAddressOfAtCallSite4.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_Generic_ExplicitAddressOfAttCallSite1.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_Generic_ExplicitAddressOfAttCallSite2.fs delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/NoTailcallToByrefsWithModReq.fs 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 0000000000..848a9c7732 --- /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 0000000000..acd8797df8 --- /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 0000000000..3374a948d9 --- /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 0000000000..7918219ab6 --- /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 0000000000..cdb5cb2163 --- /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 0000000000..38445e80dd --- /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 0000000000..281c2e70ff --- /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 0000000000..7eef5444b0 --- /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 0000000000..fd36f7ae98 --- /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 0000000000..742bba96e4 --- /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 0000000000..c2ae2a8b20 --- /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 0000000000..ff27acbf6d --- /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 0000000000..8b5404d330 --- /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 0000000000..cb5cd1f08e --- /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 0000000000..35c237dc5c --- /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 0000000000..31f4b6fe0b --- /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 0000000000..84c1472e4f --- /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 0000000000..315f4af710 --- /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 0000000000..9683efb8f6 --- /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 0000000000..3abbbca2e0 --- /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 0000000000..d79a94cb74 --- /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 0000000000..12db461f32 --- /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 0000000000..9cdf1b27a6 --- /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 0000000000..5d1f006f80 --- /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 0000000000..26eeef6e5f --- /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 0000000000..8c9a913b7e --- /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 0000000000..0b075d00ce --- /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 0000000000..63a71e7192 --- /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 0000000000..27495aee9c --- /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 0000000000..959e18d508 --- /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 0000000000..5cfba19159 --- /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 0000000000..27b9b76f28 --- /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 0000000000..acd8797df8 --- /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 0000000000..efc89a89c8 --- /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 0000000000..3a9737c8f8 --- /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 0000000000..20e1056c54 --- /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 0000000000..550cfd20f8 --- /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 0000000000..1b3f1c29c0 --- /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 0000000000..ac592fd103 --- /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 0000000000..39c94a1dec --- /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 0000000000..a0035f526f --- /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 0000000000..ef29ad77b1 --- /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 0000000000..c5826ae846 --- /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 0000000000..005435649b --- /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 0000000000..b5af70ab71 --- /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 0000000000..db6992196e --- /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 0000000000..ec4f12ed4d --- /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 0000000000..12f4ee8050 --- /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 0000000000..237f20f767 --- /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 0000000000..92b0c0a17a --- /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 0000000000..3a0ee11ed9 --- /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 0000000000..984470b78a --- /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 0000000000..8666dbd494 --- /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 0000000000..0da75201cc --- /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 0000000000..37687b5b28 --- /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 0000000000..e49f40d753 --- /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 c15af33479..df84735744 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -16,14 +16,16 @@ module ByrefSafetyAnalysis = let verifyCompile compilation = compilation |> asExe - |> withOptions ["--nowarn:3370"; "--test:ErrorRanges"] + |> withNoWarn 3370 + |> withOptions ["--test:ErrorRanges"] |> withPrelude |> compile let verifyCompileAndRun compilation = compilation |> asExe - |> withOptions ["--nowarn:3370"; "--test:ErrorRanges"] + |> withNoWarn 3370 + |> withOptions ["--test:ErrorRanges"] |> withPrelude |> compileAndRun @@ -306,7 +308,265 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") [] let``InRefParamOverload_ImplicitAddressOfAInRefParamOverload_ImplicitAddressOfAtCallSite2tCallSite`` compilation = compilation |> 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 |> verifyCompileAndRun |> shouldSucceed + + // [] + // let``ByRefExtensionMethodsOverloading`` compilation = + // compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestReadOnlyAddressOfStaticField`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestAssignToReturnByref`` compilation = + compilation |> verifyCompileAndRun |> shouldSucceed + + [] + let``TestAssignToReturnByref2`` compilation = + compilation |> 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 // SOURCE=E_ByrefAsArrayElement.fs SCFLAGS="--test:ErrorRanges" # E_ByrefAsArrayElement.fs [] @@ -494,28 +754,6 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") |> compileExeAndRun |> shouldSucceed #endif - - // // SOURCE=E_ByrefFieldEscapingLocalScope01.fs SCFLAGS="--test:ErrorRanges" # E_ByrefFieldEscapingLocalScope01.fs - // [] - // let``E_ByrefEscapingLocalScope01_fs`` compilation = - // compilation - // |> asExe - // |> compile - // |> shouldFail - // |> withDiagnostics [ - // (Error 3234, Line 7, Col 5, Line 7, Col 9, "The Span or IsByRefLike variable 'span' cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") - // ] - // - // // SOURCE=E_ByrefFieldEscapingLocalScope02.fs SCFLAGS="--test:ErrorRanges" # E_ByrefFieldEscapingLocalScope02.f - // [] - // let``E_ByrefEscapingLocalScope02_fs`` compilation = - // compilation - // |> asExe - // |> compile - // |> shouldFail - // |> withDiagnostics [ - // (Error 3234, Line 8, Col 9, Line 8, Col 13, "The Span or IsByRefLike variable 'span' cannot be used at this point. This is to ensure the address of the local value does not escape its scope.") - // ] // SOURCE=E_TopLevelByref.fs SCFLAGS="--test:ErrorRanges" # E_TopLevelByref.f [] 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 0000000000..f382bd02bd --- /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 0000000000..a92b31d26b --- /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 0000000000..27f9b0f0da --- /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 0000000000..7c7feb9d6d --- /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 0000000000..aed5584304 --- /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_Generic_ExplicitAddressOfAttCallSite1.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/InRefParam_Generic_ExplicitAddressOfAttCallSite1.fs new file mode 100644 index 0000000000..7e7c84acc2 --- /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 0000000000..3bcc44d6fa --- /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/MigratedTest01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs deleted file mode 100644 index 28df36cf8f..0000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/MigratedTest01.fs +++ /dev/null @@ -1,1167 +0,0 @@ -// #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 - -[] -type S = - [] - val mutable X : int - -#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() - -printfn "Test Passed" 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 0000000000..2355470c8f --- /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.Test.Utilities/DirectoryAttribute.fs b/tests/FSharp.Test.Utilities/DirectoryAttribute.fs index 39b1065fe0..fbb40b70b1 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 From 92db5f6a8e10ae01ef88ee357c34d9be9f0d2a01 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Tue, 8 Aug 2023 12:24:11 -0600 Subject: [PATCH 6/9] Extract individual tests of out E_MigratedTest01 --- .../ByrefSafetyAnalysis.fs | 298 +++++++++++++----- ...dressOfExpressionReturningReferenceType.fs | 21 ++ .../ByrefSafetyAnalysis/E_MigratedTest01.fs | 98 ------ 3 files changed, 246 insertions(+), 171 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_CantTakeAddressOfExpressionReturningReferenceType.fs delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs index df84735744..aaf813f4f5 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -29,79 +29,6 @@ module ByrefSafetyAnalysis = |> withPrelude |> compileAndRun - // // SOURCE=MigratedTest01.fs SCFLAGS="--test:ErrorRanges" # MigratedTest01.fs - // [] - // let``MigratedTest01_fs`` compilation = - // compilation - // |> ignoreWarnings - // |> compileExeAndRun - // |> withDiagnostics [ - // ] - // |> shouldSucceed - - // SOURCE=E_Migrated01.fs SCFLAGS="--test:ErrorRanges" # E_Migrated01.fs - [] - let``E_Migrated01_fs`` compilation = - compilation - |> verifyCompile - |> shouldFail - |> withDiagnostics [ - (Error 3224, Line 9, Col 34, Line 9, Col 40, "The byref pointer is readonly, so this write is not permitted.") - (Error 39, Line 12, Col 26, Line 12, Col 27, "The type 'S' is not defined.") - (Error 72, Line 12, Col 32, Line 12, Col 35, "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.") - (Error 1, Line 16, Col 36, Line 16, Col 38, "Type mismatch. Expecting a - 'byref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") - (Error 1, Line 20, Col 36, Line 20, Col 38, "Type mismatch. Expecting a - 'outref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'") - (Error 1, Line 25, Col 38, Line 25, Col 40, "Type mismatch. Expecting a - 'byref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") - (Error 1, Line 30, Col 38, Line 30, Col 40, "Type mismatch. Expecting a - 'outref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'") - (Error 1, Line 35, Col 38, Line 35, Col 40, "Type mismatch. Expecting a - 'byref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") - (Error 1, Line 40, Col 38, Line 40, Col 40, "Type mismatch. Expecting a - 'outref<'T>' -but given a - 'inref<'T>' -The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'") - (Error 1204, Line 44, Col 34, Line 44, Col 47, "This construct is for use in the FSharp.Core library and should not be used directly") - (Error 3236, Line 49, Col 21, Line 49, Col 23, "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 50, Col 21, Line 50, Col 23, "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 56, Col 21, Line 56, Col 37, "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 63, Col 22, Line 63, Col 23, "This expression was expected to have type - 'inref' -but here has type - 'System.DateTime' ") - (Error 39, Line 64, Col 9, Line 64, Col 14, "The value or constructor 'check' is not defined. Maybe you want one of the following: - Checked - Unchecked") - (Error 3238, Line 66, Col 10, Line 66, Col 15, "Byref types are not allowed to have optional type extensions.") - (Error 3238, Line 70, Col 10, Line 70, Col 15, "Byref types are not allowed to have optional type extensions.") - (Error 3238, Line 74, Col 10, Line 74, Col 16, "Byref types are not allowed to have optional type extensions.") - (Error 3236, Line 92, Col 21, Line 92, Col 36, "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 92, Col 21, Line 92, Col 36, "Type mismatch. Expecting a - 'byref' -but given a - 'inref' -The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") - (Error 3236, Line 97, Col 21, Line 97, 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.") - ] - // SOURCE=Migrated02.fs SCFLAGS="--test:ErrorRanges" # Migrated02.fs [] let``MigratedTest02_fs`` compilation = @@ -568,6 +495,231 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") 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 = 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 0000000000..4cbd2c8c73 --- /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.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest01.fs deleted file mode 100644 index 2aefe33bf3..0000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_MigratedTest01.fs +++ /dev/null @@ -1,98 +0,0 @@ -// #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable -#if TESTS_AS_APP -module Core_byrefs -#endif - -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 - () From ccf8c91cf79e8a664993a34c80199fc61c4bb650 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Tue, 8 Aug 2023 16:53:10 -0600 Subject: [PATCH 7/9] Appease CI --- .../ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs index aaf813f4f5..f33a97d28d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -226,14 +226,14 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") [] let``InRefParamOverload_ExplicitAddressOfAtCallSite`` compilation = - compilation |> verifyCompileAndRun |> shouldSucceed + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed - [] + [] let``InRefParamOverload_ImplicitAddressOfAtCallSite`` compilation = - compilation |> verifyCompileAndRun |> shouldSucceed + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed [] - let``InRefParamOverload_ImplicitAddressOfAInRefParamOverload_ImplicitAddressOfAtCallSite2tCallSite`` compilation = + let``InRefParamOverload_ImplicitAddressOfAtCallSite2`` compilation = compilation |> verifyCompileAndRun |> shouldSucceed // TODO: Delete this, move into feature branch, or finish this. See: https://github.com/dotnet/fsharp/pull/7989#discussion_r369841104 @@ -888,7 +888,7 @@ type outref<'T> with |> shouldSucceed #if NET7_0_OR_GREATER - // SOURCE=ReturnFieldSetBySpan.fs # ReturnFieldSetBySpan.fs +// 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 @@ -897,7 +897,6 @@ type outref<'T> with |> compileExeAndRun |> shouldSucceed - // SOURCE=ReturnSpan02.fs # ReturnSpan02.fs [] let``ReturnSpan01_fs`` compilation = compilation @@ -906,8 +905,8 @@ type outref<'T> with |> compileExeAndRun |> shouldSucceed #endif - - // SOURCE=E_TopLevelByref.fs SCFLAGS="--test:ErrorRanges" # E_TopLevelByref.f + +#if NETSTANDARD2_1_OR_GREATER [] let``E_TopLevelByref_fs`` compilation = compilation @@ -918,7 +917,6 @@ type outref<'T> with (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.") ] - // SOURCE=E_SpanUsedInInnerLambda01.fs SCFLAGS="--test:ErrorRanges" # E_SpanUsedInInnerLambda01.f [] let``E_SpanUsedInInnerLambda01_fs`` compilation = compilation @@ -929,7 +927,6 @@ type outref<'T> with (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.") ] - // SOURCE=E_SpanUsedInInnerLambda02.fs SCFLAGS="--test:ErrorRanges" # E_SpanUsedInInnerLambda02.f [] let``E_SpanUsedInInnerLambda02_fs`` compilation = compilation @@ -939,3 +936,4 @@ type outref<'T> with |> 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 From 03c1ee69f1cc136228b3804db767af2df5f8b6cd Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Tue, 8 Aug 2023 19:08:29 -0600 Subject: [PATCH 8/9] Appease CI x2 --- .../ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs index f33a97d28d..bee84c3ca1 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -130,6 +130,7 @@ module ByrefSafetyAnalysis = compilation |> asExe |> withReferences [ csharpLib ] + |> withNoWarn 52 |> compile |> shouldFail |> withDiagnostics [ @@ -234,7 +235,7 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") [] let``InRefParamOverload_ImplicitAddressOfAtCallSite2`` compilation = - compilation |> verifyCompileAndRun |> shouldSucceed + 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 From 1bd5a9499a2000740ebd9f2d8827baf14192e9b2 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 9 Aug 2023 09:08:40 -0600 Subject: [PATCH 9/9] Appease compiler x3 --- .../ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs index bee84c3ca1..16637ac910 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -9,7 +9,7 @@ open FSharp.Test.Compiler module ByrefSafetyAnalysis = let withPrelude = withReferences [ - FsFromPath (__SOURCE_DIRECTORY__ ++ "prelude.fs") + FsFromPath (__SOURCE_DIRECTORY__ ++ "Prelude.fs") |> withName "Prelude" ] @@ -414,7 +414,7 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") [] let``ByRefExtensionMethods1`` compilation = - compilation |> verifyCompileAndRun |> shouldSucceed + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed // [] // let``ByRefExtensionMethodsOverloading`` compilation = @@ -426,11 +426,11 @@ The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'") [] let``TestAssignToReturnByref`` compilation = - compilation |> verifyCompileAndRun |> shouldSucceed + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed [] let``TestAssignToReturnByref2`` compilation = - compilation |> verifyCompileAndRun |> shouldSucceed + compilation |> withNoWarn 52 |> verifyCompileAndRun |> shouldSucceed [] let``BaseCallByref`` compilation =