From 3b8bf4541a80d2804450ab545cef940201998579 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Sat, 22 Jul 2023 07:15:44 -0600 Subject: [PATCH 01/51] Add compiler tests for currently allowed fixed expressions --- .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../Language/FixedExpressionTests.fs | 131 ++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 9a9c99c347b..e00fc636199 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -185,6 +185,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs new file mode 100644 index 00000000000..b980154d04a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -0,0 +1,131 @@ +namespace Language.FixedExpressionTests + +open Xunit +open FSharp.Test.Compiler + +module Legacy = + [] + let ``Pin naked string`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt (str: string) = + use ptr = fixed str + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin naked array`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt (arr: char[]) = + use ptr = fixed arr + NativePtr.get ptr 0 + """ + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin address of array element`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt (arr: char[]) = + use ptr = fixed &arr[1] + NativePtr.get ptr 0 + """ + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin address of record field`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +type Point = { mutable X: int; mutable Y: int } + +let pinIt (thing: Point) = + use ptr = fixed &thing.X + NativePtr.get ptr 0 + """ + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 7, Col 9, Line 7, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 8, Col 5, Line 8, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin address of explicit field on this`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +type Point = + val mutable X: int + val mutable Y: int + + new(x: int, y: int) = { X = x; Y = y } + + member this.PinIt() = + use ptr = fixed &this.X + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 11, Col 13, Line 11, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 12, Col 9, Line 12, Col 22, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin naked object`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: obj) = + use ptr = fixed thing + NativePtr.get ptr 0 + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + ] + + + [] + let ``Pin naked int`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: int) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + ] From fa02474d8f05a02457d5b8e145849779801cf851 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Sat, 22 Jul 2023 08:21:23 -0600 Subject: [PATCH 02/51] Make typechecker accept arbitrary byref pinning in `fixed` expressions --- src/Compiler/Checking/CheckExpressions.fs | 2 + .../Language/FixedExpressionTests.fs | 71 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 489456fe026..8759c381a17 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10276,7 +10276,9 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true | TOp.RefAddrGet _, _, _ -> true + | TOp.LValueOp (LValueOperation.LAddrOf _, _), _, _ -> true | _ -> false + | Expr.Val _ -> true | _ -> false if not okByRef then error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index b980154d04a..58187f0afd5 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -129,3 +129,74 @@ let pinIt (thing: int) = (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") ] + +// FS-1081 - Extend fixed expressions +module ExtendedFixedExpressions = + [] + let ``Pin int byref parmeter`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: byref) = + use ptr = fixed &thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin int inref parmeter`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: inref) = + use ptr = fixed &thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin int outref parmeter`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: outref) = + use ptr = fixed &thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin int byref local variable`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt () = + let mutable thing = 42 + use ptr = fixed &thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] From 819890b88f32f817b8338c2f69bd8170ac1eaa3f Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Tue, 25 Jul 2023 20:01:36 -0600 Subject: [PATCH 03/51] Make typechecker accept GetPinnableReference() in fixed expressions --- src/Compiler/Checking/CheckExpressions.fs | 19 ++- .../Language/FixedExpressionTests.fs | 154 +++++++++++++++++- 2 files changed, 169 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 8759c381a17..c68596298f1 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10265,7 +10265,7 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy let g = cenv.g warning(PossibleUnverifiableCode mBinding) - + match overallExprTy with | ty when isByrefTy g ty -> let okByRef = @@ -10336,7 +10336,22 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy zero) zero) - | _ -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + | _ -> + + let getPinnableReferenceMInfo = + TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env mBinding env.eAccessRights "GetPinnableReference" overallExprTy + |> List.map (fun mInfo -> mInfo, mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst)) + |> List.tryFind (fun (mInfo, paramDatas) -> + // GetPinnableReference must be a parameterless method with a byref or inref return value + match paramDatas with + | [[]] when isByrefTy g (mInfo.GetFSharpReturnType(cenv.amap, mBinding, mInfo.FormalMethodInst)) -> true + | _ -> false + ) + System.Diagnostics.Debugger.Break() + if Option.isSome getPinnableReferenceMInfo then + fixedExpr + else + error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) /// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index 58187f0afd5..e377073b1ca 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -98,7 +98,7 @@ type Point = ] [] - let ``Pin naked object`` () = + let ``Pin naked object - illegal`` () = Fsx """ open Microsoft.FSharp.NativeInterop @@ -115,7 +115,7 @@ let pinIt (thing: obj) = [] - let ``Pin naked int`` () = + let ``Pin naked int - illegal`` () = Fsx """ open Microsoft.FSharp.NativeInterop @@ -200,3 +200,153 @@ let pinIt () = (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] + + [] + let ``Pin Span`` () = + Fsx """ +open System +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: Span) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin type with method GetPinnableReference : unit -> byref`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +type RefField<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference () : byref<'T> = &_value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin type with method GetPinnableReference : unit -> inref`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +type RefField<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference () : inref<'T> = &_value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin type with extension method GetPinnableReference : unit -> byref`` () = + Fsx """ +open System.Runtime.CompilerServices +open Microsoft.FSharp.NativeInterop + +type RefField<'T> = { mutable _value: 'T } + +[] +type RefFieldExtensions = + [] + static member GetPinnableReference(refField: RefField<'T>) : byref<'T> = &refField._value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] + + [] + let ``Pin type with method GetPinnableReference with parameters - illegal`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +type StrangeType<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference(someValue: string) : byref<'T> = &_value + +let pinIt (thing: StrangeType<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + ] + + [] + let ``Pin type with method GetPinnableReference with non-byref return type - illegal`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +type StrangeType<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference() : 'T = _value + +let pinIt (thing: StrangeType<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + ] + + [] + let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +type RefField<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference (x: int) : string = string x + member this.GetPinnableReference (x: int, y: string) = string x + y + member this.GetPinnableReference () : byref<'T> = &_value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] From c0fca863686d5cafda97dd3dae229e05fa38fe42 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 26 Jul 2023 21:34:12 -0600 Subject: [PATCH 04/51] Add IL compiler tests for currently allowed fixed expressions --- .../EmittedIL/FixedExpressionTests.fs | 217 ++++++++++++++++++ .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../Language/FixedExpressionTests.fs | 10 +- tests/FSharp.Test.Utilities/Compiler.fs | 2 +- 4 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs new file mode 100644 index 00000000000..0f8b12df670 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -0,0 +1,217 @@ +module EmittedIL.FixedExpressionTests + +open Xunit +open FSharp.Compiler.Diagnostics +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Test.Compiler + +module Legacy = + [] + let ``Pin naked string``() = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop + +let pinIt (str: string) = + use ptr = fixed str + NativePtr.get ptr 0 +""" + |> withOptions ["--nowarn:9"] + |> compile + |> verifyIL [""" + .method public static char pinIt(string str) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + string pinned V_1) + IL_0000: ldarg.0 + IL_0001: stloc.1 + IL_0002: ldarg.0 + IL_0003: brfalse.s IL_000f + + IL_0005: ldarg.0 + IL_0006: conv.i + IL_0007: call int32 [runtime]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData() + IL_000c: add + IL_000d: br.s IL_0010 + + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldloc.0 + IL_0012: ldc.i4.0 + IL_0013: conv.i + IL_0014: sizeof [runtime]System.Char + IL_001a: mul + IL_001b: add + IL_001c: ldobj [runtime]System.Char + IL_0021: ret + }""" ] + + [] + let ``Pin naked array`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop + +let pinIt (arr: char[]) = + use ptr = fixed arr + NativePtr.get ptr 0 +""" + |> withOptions ["--nowarn:9"] + |> compile + |> verifyIL [""" + .method public static char pinIt(char[] arr) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + char& pinned V_1) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_001b + + IL_0003: ldarg.0 + IL_0004: call int32 [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Length(!!0[]) + IL_0009: brfalse.s IL_0017 + + IL_000b: ldarg.0 + IL_000c: ldc.i4.0 + IL_000d: ldelema [runtime]System.Char + IL_0012: stloc.1 + IL_0013: ldloc.1 + IL_0014: conv.i + IL_0015: br.s IL_001d + + IL_0017: ldc.i4.0 + IL_0018: conv.i + IL_0019: br.s IL_001d + + IL_001b: ldc.i4.0 + IL_001c: conv.i + IL_001d: stloc.0 + IL_001e: ldloc.0 + IL_001f: ldc.i4.0 + IL_0020: conv.i + IL_0021: sizeof [runtime]System.Char + IL_0027: mul + IL_0028: add + IL_0029: ldobj [runtime]System.Char + IL_002e: ret + } """ ] + + [] + let ``Pin address of record field`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop + +type Point = { mutable X: int; mutable Y: int } + +let pinIt (thing: Point) = + use ptr = fixed &thing.X + NativePtr.get ptr 0 +""" + |> withOptions ["--nowarn:9"] + |> compile + |> verifyIL [""" + .method public static int32 pinIt(class FixedExpressions/Point thing) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + int32& pinned V_1) + IL_0000: ldarg.0 + IL_0001: ldflda int32 FixedExpressions/Point::X@ + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: conv.i + IL_0009: stloc.0 + IL_000a: ldloc.0 + IL_000b: ldc.i4.0 + IL_000c: conv.i + IL_000d: sizeof [runtime]System.Int32 + IL_0013: mul + IL_0014: add + IL_0015: ldobj [runtime]System.Int32 + IL_001a: ret + } """ ] + + [] + let ``Pin address of explicit field on this`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop + +type Point = + val mutable X: int + val mutable Y: int + + new(x: int, y: int) = { X = x; Y = y } + + member this.PinIt() = + use ptr = fixed &this.X + NativePtr.get ptr 0 +""" + |> withOptions ["--nowarn:9"] + |> compile + |> verifyIL [""" + .method public hidebysig instance int32 + PinIt() cil managed + { + + .maxstack 5 + .locals init (native int V_0, + int32& pinned V_1) + IL_0000: ldarg.0 + IL_0001: ldflda int32 FixedExpressions/Point::X + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: conv.i + IL_0009: stloc.0 + IL_000a: ldloc.0 + IL_000b: ldc.i4.0 + IL_000c: conv.i + IL_000d: sizeof [System.Runtime]System.Int32 + IL_0013: mul + IL_0014: add + IL_0015: ldobj [System.Runtime]System.Int32 + IL_001a: ret + } """ ] + + [] + let ``Pin address of array element`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop + +let pinIt (arr: char[]) = + use ptr = fixed &arr[42] + NativePtr.get ptr 0 +""" + |> withOptions ["--nowarn:9"] + |> compile + |> verifyIL [""" + .method public static char pinIt(char[] arr) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + char& pinned V_1) + IL_0000: ldarg.0 + IL_0001: ldc.i4.s 42 + IL_0003: ldelema [runtime]System.Char + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: conv.i + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ldc.i4.0 + IL_000e: conv.i + IL_000f: sizeof [runtime]System.Char + IL_0015: mul + IL_0016: add + IL_0017: ldobj [runtime]System.Char + IL_001c: ret + } """ ] + \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index e00fc636199..0b54cee6d83 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -143,6 +143,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index e377073b1ca..7dc8338f5cb 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -29,7 +29,7 @@ open Microsoft.FSharp.NativeInterop let pinIt (arr: char[]) = use ptr = fixed arr NativePtr.get ptr 0 - """ +""" |> ignoreWarnings |> typecheck |> shouldSucceed @@ -46,7 +46,7 @@ open Microsoft.FSharp.NativeInterop let pinIt (arr: char[]) = use ptr = fixed &arr[1] NativePtr.get ptr 0 - """ +""" |> ignoreWarnings |> typecheck |> shouldSucceed @@ -65,7 +65,7 @@ type Point = { mutable X: int; mutable Y: int } let pinIt (thing: Point) = use ptr = fixed &thing.X NativePtr.get ptr 0 - """ +""" |> ignoreWarnings |> typecheck |> shouldSucceed @@ -105,7 +105,7 @@ open Microsoft.FSharp.NativeInterop let pinIt (thing: obj) = use ptr = fixed thing NativePtr.get ptr 0 - """ +""" |> typecheck |> shouldFail |> withDiagnostics [ @@ -319,7 +319,7 @@ type StrangeType<'T>(_value) = let pinIt (thing: StrangeType<'T>) = use ptr = fixed thing NativePtr.get ptr 0 - """ +""" |> ignoreWarnings |> typecheck |> shouldFail diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 0ce5b995ad2..548957ce3f5 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -1113,7 +1113,7 @@ module rec Compiler = match s.OutputPath with | None -> failwith "Operation didn't produce any output!" | Some p -> func p il - | CompilationResult.Failure _ -> failwith "Result should be \"Success\" in order to get IL." + | CompilationResult.Failure f -> failwith $"Result should be \"Success\" in order to get IL. Failure: {Environment.NewLine}{f}" let verifyIL = doILCheck ILChecker.checkIL From d5237442be8f083a586507c5e12d40ca01759093 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 26 Jul 2023 22:55:14 -0600 Subject: [PATCH 05/51] Write codegen tests for fixed expressions with byrefs --- .../EmittedIL/FixedExpressionTests.fs | 145 +++++++++++++++--- 1 file changed, 126 insertions(+), 19 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 0f8b12df670..89a80902d7d 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -111,9 +111,13 @@ type Point = { mutable X: int; mutable Y: int } let pinIt (thing: Point) = use ptr = fixed &thing.X NativePtr.get ptr 0 + +let p = { X = 10; Y = 20 } +let xCopy = pinIt p +if xCopy <> p.X then failwith "xCopy was not equal to X" """ |> withOptions ["--nowarn:9"] - |> compile + |> compileExeAndRun |> verifyIL [""" .method public static int32 pinIt(class FixedExpressions/Point thing) cil managed { @@ -152,9 +156,14 @@ type Point = member this.PinIt() = use ptr = fixed &this.X NativePtr.get ptr 0 + +let p = Point(10,20) +let xCopy = p.PinIt() +if xCopy <> p.X then failwith "xCopy was not equal to X" """ |> withOptions ["--nowarn:9"] - |> compile + |> compileExeAndRun + |> shouldSucceed |> verifyIL [""" .method public hidebysig instance int32 PinIt() cil managed @@ -186,11 +195,16 @@ module FixedExpressions open Microsoft.FSharp.NativeInterop let pinIt (arr: char[]) = - use ptr = fixed &arr[42] + use ptr = fixed &arr[0] NativePtr.get ptr 0 + +let x = [|'a';'b';'c'|] +let y = pinIt x +if y <> 'a' then failwithf "y did not equal first element of x" """ |> withOptions ["--nowarn:9"] - |> compile + |> compileExeAndRun + |> shouldSucceed |> verifyIL [""" .method public static char pinIt(char[] arr) cil managed { @@ -199,19 +213,112 @@ let pinIt (arr: char[]) = .locals init (native int V_0, char& pinned V_1) IL_0000: ldarg.0 - IL_0001: ldc.i4.s 42 - IL_0003: ldelema [runtime]System.Char - IL_0008: stloc.1 - IL_0009: ldloc.1 - IL_000a: conv.i - IL_000b: stloc.0 - IL_000c: ldloc.0 - IL_000d: ldc.i4.0 - IL_000e: conv.i - IL_000f: sizeof [runtime]System.Char - IL_0015: mul - IL_0016: add - IL_0017: ldobj [runtime]System.Char - IL_001c: ret + IL_0001: ldc.i4.0 + IL_0002: ldelema [runtime]System.Char + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: conv.i + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: conv.i + IL_000e: sizeof [runtime]System.Char + IL_0014: mul + IL_0015: add + IL_0016: ldobj [runtime]System.Char + IL_001b: ret + } """ ] + +module ExtendedFixedExpressions = + [] + let ``Pin int byref of parameter`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: byref) = + use ptr = fixed &thing + NativePtr.get ptr 0 + +let mutable x = 42 +let xCopy = pinIt &x +if x <> xCopy then failwith "xCopy was not the same as x" +""" + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static int32 pinIt(int32& thing) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + int32& pinned V_1) + IL_0000: ldarg.0 + IL_0001: stloc.1 + IL_0002: ldarg.0 + IL_0003: conv.i + IL_0004: stloc.0 + IL_0005: ldloc.0 + IL_0006: ldc.i4.0 + IL_0007: conv.i + IL_0008: sizeof [runtime]System.Int32 + IL_000e: mul + IL_000f: add + IL_0010: ldobj [runtime]System.Int32 + IL_0015: ret + } """] + + [] + let ``Pin int byref of local variable`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop + +let pinIt (x: int) = + let mutable thing = x + 1 + use ptr = fixed &thing + let thingCopy = NativePtr.get ptr 0 + if thingCopy <> thing then failwith "thingCopy was not the same as thing" + +pinIt 100 +""" + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static void pinIt(int32 x) cil managed + { + + .maxstack 5 + .locals init (int32 V_0, + native int V_1, + int32& pinned V_2, + int32 V_3) + IL_0000: ldarg.0 + IL_0001: ldc.i4.1 + IL_0002: add + IL_0003: stloc.0 + IL_0004: ldloca.s V_0 + IL_0006: stloc.2 + IL_0007: ldloca.s V_0 + IL_0009: conv.i + IL_000a: stloc.1 + IL_000b: ldloc.1 + IL_000c: ldc.i4.0 + IL_000d: conv.i + IL_000e: sizeof [runtime]System.Int32 + IL_0014: mul + IL_0015: add + IL_0016: ldobj [runtime]System.Int32 + IL_001b: stloc.3 + IL_001c: ldloc.3 + IL_001d: ldloc.0 + IL_001e: beq.s IL_002b + + IL_0020: ldstr "thingCopy was not the same as thing" + IL_0025: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_002a: throw + + IL_002b: ret } """ ] - \ No newline at end of file From 56b9eb00289c7d9ec16dc5a3585b286f06badc55 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 26 Jul 2023 23:58:13 -0600 Subject: [PATCH 06/51] Write codegen for pinning custom byref type via GetPinnableReference --- src/Compiler/Checking/CheckExpressions.fs | 32 ++++-- .../EmittedIL/FixedExpressionTests.fs | 107 ++++++++++++++++++ .../Language/FixedExpressionTests.fs | 17 +++ 3 files changed, 147 insertions(+), 9 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index c68596298f1..2f4cea23651 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10340,17 +10340,31 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy let getPinnableReferenceMInfo = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env mBinding env.eAccessRights "GetPinnableReference" overallExprTy - |> List.map (fun mInfo -> mInfo, mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst)) - |> List.tryFind (fun (mInfo, paramDatas) -> + // |> List.map (fun mInfo -> mInfo, mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst)) + |> List.tryPick (fun mInfo -> // GetPinnableReference must be a parameterless method with a byref or inref return value - match paramDatas with - | [[]] when isByrefTy g (mInfo.GetFSharpReturnType(cenv.amap, mBinding, mInfo.FormalMethodInst)) -> true - | _ -> false + match mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst), mInfo.GetFSharpReturnType(cenv.amap, mBinding, mInfo.FormalMethodInst) with + | [[]], retTy when isByrefTy g retTy -> Some (mInfo, retTy) + | _ -> None ) - System.Diagnostics.Debugger.Break() - if Option.isSome getPinnableReferenceMInfo then - fixedExpr - else + + match getPinnableReferenceMInfo with + | Some (mInfo, pinnedByrefTy) -> + // fixedExpr + let elemTy = destByrefTy g pinnedByrefTy + UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy + + let pinnableReference, actualRetTy = BuildPossiblyConditionalMethodCall cenv env NeverMutates mBinding false mInfo NormalValUse [] [ fixedExpr ] [] None + + assert (typeEquiv cenv.g actualRetTy pinnedByrefTy) + + let result = + mkCompGenLetIn mBinding "pinnedByref" overallExprTy pinnableReference (fun (v, ve) -> + v.SetIsFixed() + mkConvToNativeInt g ve mBinding) + System.Diagnostics.Debugger.Break() + result + | None -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 89a80902d7d..84a7a78c181 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -322,3 +322,110 @@ pinIt 100 IL_002b: ret } """ ] + + [] + let ``Pin Span`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open System + +let pinIt (thing: Span) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let span = Span("The quick brown fox jumped over the lazy dog".ToCharArray()) + let x = pinIt span + if x <> 'T' then failwith "x did not equal the first char of the span" + 0 +""" + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static void pinIt(int32 x) cil managed + { + + .maxstack 5 + .locals init (int32 V_0, + native int V_1, + int32& pinned V_2, + int32 V_3) + IL_0000: ldarg.0 + IL_0001: ldc.i4.1 + IL_0002: add + IL_0003: stloc.0 + IL_0004: ldloca.s V_0 + IL_0006: stloc.2 + IL_0007: ldloca.s V_0 + IL_0009: conv.i + IL_000a: stloc.1 + IL_000b: ldloc.1 + IL_000c: ldc.i4.0 + IL_000d: conv.i + IL_000e: sizeof [runtime]System.Int32 + IL_0014: mul + IL_0015: add + IL_0016: ldobj [runtime]System.Int32 + IL_001b: stloc.3 + IL_001c: ldloc.3 + IL_001d: ldloc.0 + IL_001e: beq.s IL_002b + + IL_0020: ldstr "thingCopy was not the same as thing" + IL_0025: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_002a: throw + + IL_002b: ret + } """ ] + + [] + let ``Pin type with method GetPinnableReference : unit -> byref`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open System + +type RefField<'T>(_value) = + let mutable _value = _value + member this.Value = _value + member this.GetPinnableReference () : byref<'T> = &_value + +let pinIt (thing: RefField) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let x = RefField(42) + let y = pinIt x + if y <> x.Value then failwith "y did not equal x value" + 0 +""" + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static int32 pinIt(class FixedExpressions/RefField`1 thing) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + class FixedExpressions/RefField`1 pinned V_1) + IL_0000: ldarg.0 + IL_0001: ldflda !0 class FixedExpressions/RefField`1::_value@7 + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: conv.i + IL_0009: stloc.0 + IL_000a: ldloc.0 + IL_000b: ldc.i4.0 + IL_000c: conv.i + IL_000d: sizeof [runtime]System.Int32 + IL_0013: mul + IL_0014: add + IL_0015: ldobj [runtime]System.Int32 + IL_001a: ret + } """ ] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index 7dc8338f5cb..dcc1ab58ee3 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -218,6 +218,23 @@ let pinIt (thing: Span) = (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] + + let ``Pin custom byref type without GetPinnableReference method - illegal`` () = + Fsx """ +open System +open System.Runtime.CompilerServices +open Microsoft.FSharp.NativeInterop + +[] +type BoringRefField<'T> = { Value: 'T } + +let pinIt (thing: BoringRefField) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldFail [] let ``Pin type with method GetPinnableReference : unit -> byref`` () = From c5e9fbd14d77f1e5c9fcaef7fa09489d1d8520cf Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 27 Jul 2023 17:28:01 -0600 Subject: [PATCH 07/51] Make fixed expressions work properly with Span and Span-like types --- src/Compiler/Checking/CheckExpressions.fs | 38 ++- .../EmittedIL/FixedExpressionTests.fs | 233 +++++++++++++++--- tests/FSharp.Test.Utilities/CompilerAssert.fs | 2 + 3 files changed, 224 insertions(+), 49 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 2f4cea23651..0087babe7cf 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10268,20 +10268,20 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy match overallExprTy with | ty when isByrefTy g ty -> - let okByRef = - match stripDebugPoints (stripExpr fixedExpr) with - | Expr.Op (op, tyargs, args, _) -> - match op, tyargs, args with - | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon - | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject - | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true - | TOp.RefAddrGet _, _, _ -> true - | TOp.LValueOp (LValueOperation.LAddrOf _, _), _, _ -> true - | _ -> false - | Expr.Val _ -> true - | _ -> false - if not okByRef then - error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + // let okByRef = + // match stripDebugPoints (stripExpr fixedExpr) with + // | Expr.Op (op, tyargs, args, _) -> + // match op, tyargs, args with + // | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon + // | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject + // | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true + // | TOp.RefAddrGet _, _, _ -> true + // | TOp.LValueOp (LValueOperation.LAddrOf _, _), _, _ -> true + // | _ -> false + // | Expr.Val _ -> true + // | _ -> false + // if not okByRef then + // error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) let elemTy = destByrefTy g overallExprTy UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy @@ -10340,7 +10340,6 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy let getPinnableReferenceMInfo = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env mBinding env.eAccessRights "GetPinnableReference" overallExprTy - // |> List.map (fun mInfo -> mInfo, mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst)) |> List.tryPick (fun mInfo -> // GetPinnableReference must be a parameterless method with a byref or inref return value match mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst), mInfo.GetFSharpReturnType(cenv.amap, mBinding, mInfo.FormalMethodInst) with @@ -10358,12 +10357,9 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy assert (typeEquiv cenv.g actualRetTy pinnedByrefTy) - let result = - mkCompGenLetIn mBinding "pinnedByref" overallExprTy pinnableReference (fun (v, ve) -> - v.SetIsFixed() - mkConvToNativeInt g ve mBinding) - System.Diagnostics.Debugger.Break() - result + mkCompGenLetIn mBinding "pinnedByref" pinnedByrefTy pinnableReference (fun (v, ve) -> + v.SetIsFixed() + mkConvToNativeInt g ve mBinding) | None -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 84a7a78c181..4d60fb01993 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -1,4 +1,4 @@ -module EmittedIL.FixedExpressionTests +namespace EmittedIL.FixedExpressionTests open Xunit open FSharp.Compiler.Diagnostics @@ -323,6 +323,50 @@ pinIt 100 IL_002b: ret } """ ] + [] + let ``Pin Span via manual GetPinnableReference call`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open System + +let pinIt (thing: Span) = + use ptr = fixed &thing.GetPinnableReference() + NativePtr.get ptr 0 + +[] +let main _ = + let span = Span("The quick brown fox jumped over the lazy dog".ToCharArray()) + let x = pinIt span + if x <> 'T' then failwith "x did not equal the first char of the span" + 0 +""" + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static char pinIt(valuetype [runtime]System.Span`1 thing) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + char& pinned V_1) + IL_0000: ldarga.s thing + IL_0002: call instance !0& valuetype [runtime]System.Span`1::GetPinnableReference() + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: conv.i + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: conv.i + IL_000e: sizeof [runtime]System.Char + IL_0014: mul + IL_0015: add + IL_0016: ldobj [runtime]System.Char + IL_001b: ret + } """ ] + [] let ``Pin Span`` () = FSharp """ @@ -345,40 +389,26 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static void pinIt(int32 x) cil managed + .method public static char pinIt(valuetype [runtime]System.Span`1 thing) cil managed { .maxstack 5 - .locals init (int32 V_0, - native int V_1, - int32& pinned V_2, - int32 V_3) - IL_0000: ldarg.0 - IL_0001: ldc.i4.1 - IL_0002: add - IL_0003: stloc.0 - IL_0004: ldloca.s V_0 - IL_0006: stloc.2 - IL_0007: ldloca.s V_0 + .locals init (native int V_0, + char& pinned V_1) + IL_0000: ldarga.s thing + IL_0002: call instance !0& valuetype [runtime]System.Span`1::GetPinnableReference() + IL_0007: stloc.1 + IL_0008: ldloc.1 IL_0009: conv.i - IL_000a: stloc.1 - IL_000b: ldloc.1 + IL_000a: stloc.0 + IL_000b: ldloc.0 IL_000c: ldc.i4.0 IL_000d: conv.i - IL_000e: sizeof [runtime]System.Int32 + IL_000e: sizeof [runtime]System.Char IL_0014: mul IL_0015: add - IL_0016: ldobj [runtime]System.Int32 - IL_001b: stloc.3 - IL_001c: ldloc.3 - IL_001d: ldloc.0 - IL_001e: beq.s IL_002b - - IL_0020: ldstr "thingCopy was not the same as thing" - IL_0025: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) - IL_002a: throw - - IL_002b: ret + IL_0016: ldobj [runtime]System.Char + IL_001b: ret } """ ] [] @@ -413,7 +443,7 @@ let main _ = .maxstack 5 .locals init (native int V_0, - class FixedExpressions/RefField`1 pinned V_1) + int32& pinned V_1) IL_0000: ldarg.0 IL_0001: ldflda !0 class FixedExpressions/RefField`1::_value@7 IL_0006: stloc.1 @@ -429,3 +459,150 @@ let main _ = IL_0015: ldobj [runtime]System.Int32 IL_001a: ret } """ ] + + + [] + let ``Pin C# type with method GetPinnableReference : unit -> byref`` () = + let csLib = + CSharp """ +namespace CSharpLib +{ + public class PinnableReference + { + private T _value; + + public T Value + { + get => _value; + set => _value = value; + } + + public PinnableReference(T value) + { + this._value = value; + } + + public ref T GetPinnableReference() + { + return ref _value; + } + } +} +""" |> withName "CsLib" + + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open System +open CSharpLib + +let pinIt (thing: PinnableReference) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let x = PinnableReference(42) + let y = pinIt x + if y <> x.Value then failwith "y did not equal x value" + 0 +""" + |> withReferences [csLib] + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static int32 pinIt(class [CsLib]CSharpLib.PinnableReference`1 thing) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + int32& pinned V_1) + IL_0000: ldarg.0 + IL_0001: callvirt instance !0& class [CsLib]CSharpLib.PinnableReference`1::GetPinnableReference() + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: conv.i + IL_0009: stloc.0 + IL_000a: ldloc.0 + IL_000b: ldc.i4.0 + IL_000c: conv.i + IL_000d: sizeof [runtime]System.Int32 + IL_0013: mul + IL_0014: add + IL_0015: ldobj [runtime]System.Int32 + IL_001a: ret + } """ ] + + [] + let ``Pin C# byref struct type with method GetPinnableReference : unit -> byref`` () = + // TODO: Could be a good idea to test a version of this type written in F# too once we get ref fields in byref-like structs: + // https://github.com/fsharp/fslang-suggestions/issues/1143 + let csLib = + CSharp """ +namespace CsLib +{ + public ref struct RefField + { + private readonly ref T _value; + + public T Value + { + get => _value; + set => _value = value; + } + + public RefField(ref T value) + { + this._value = ref value; + } + + public ref T GetPinnableReference() => ref _value; + } +} + +""" |> withName "CsLib" |> withCSharpLanguageVersion CSharpLanguageVersion.CSharp11 + + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open CsLib + +let pinIt (refField: RefField) = + use ptr = fixed refField + NativePtr.get ptr 0 + +[] +let main _ = + let mutable x = 42 + let refToX = new RefField<_>(&x) + let y = pinIt refToX + if y <> x then failwith "y did not equal x" + 0 +""" + |> withReferences [csLib] + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static int32 pinIt(valuetype [CsLib]CsLib.RefField`1 refField) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + int32& pinned V_1) + IL_0000: ldarga.s refField + IL_0002: call instance !0& valuetype [CsLib]CsLib.RefField`1::GetPinnableReference() + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: conv.i + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: conv.i + IL_000e: sizeof [runtime]System.Int32 + IL_0014: mul + IL_0015: add + IL_0016: ldobj [runtime]System.Int32 + IL_001b: ret + } """ ] diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs index f9af77086df..f657fb7f38c 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -133,6 +133,7 @@ type TestCompilation = type CSharpLanguageVersion = | CSharp8 = 0 | CSharp9 = 1 + | CSharp11 = 11 | Preview = 99 [] @@ -143,6 +144,7 @@ type CompilationUtil private () = match lv with | CSharpLanguageVersion.CSharp8 -> LanguageVersion.CSharp8 | CSharpLanguageVersion.CSharp9 -> LanguageVersion.CSharp9 + | CSharpLanguageVersion.CSharp11 -> LanguageVersion.CSharp11 | CSharpLanguageVersion.Preview -> LanguageVersion.Preview | _ -> LanguageVersion.Default From 4d00bb5521784fdde024620de22acd14ad20008d Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 27 Jul 2023 18:03:34 -0600 Subject: [PATCH 08/51] Make fixed expr work with generic extension GetPinnableReference method --- src/Compiler/Checking/CheckExpressions.fs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 0087babe7cf..fb8c323138e 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10340,24 +10340,22 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy let getPinnableReferenceMInfo = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env mBinding env.eAccessRights "GetPinnableReference" overallExprTy - |> List.tryPick (fun mInfo -> + |> List.tryFind (fun mInfo -> // GetPinnableReference must be a parameterless method with a byref or inref return value match mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst), mInfo.GetFSharpReturnType(cenv.amap, mBinding, mInfo.FormalMethodInst) with - | [[]], retTy when isByrefTy g retTy -> Some (mInfo, retTy) - | _ -> None + | [[]], retTy when isByrefTy g retTy -> true + | _ -> false ) match getPinnableReferenceMInfo with - | Some (mInfo, pinnedByrefTy) -> - // fixedExpr - let elemTy = destByrefTy g pinnedByrefTy - UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy + | Some mInfo -> + let mInst = FreshenMethInfo mBinding mInfo + let pinnableReference, actualRetTy = BuildPossiblyConditionalMethodCall cenv env NeverMutates mBinding false mInfo NormalValUse mInst [ fixedExpr ] [] None - let pinnableReference, actualRetTy = BuildPossiblyConditionalMethodCall cenv env NeverMutates mBinding false mInfo NormalValUse [] [ fixedExpr ] [] None - - assert (typeEquiv cenv.g actualRetTy pinnedByrefTy) + let elemTy = destByrefTy g actualRetTy + UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy - mkCompGenLetIn mBinding "pinnedByref" pinnedByrefTy pinnableReference (fun (v, ve) -> + mkCompGenLetIn mBinding "pinnedByref" actualRetTy pinnableReference (fun (v, ve) -> v.SetIsFixed() mkConvToNativeInt g ve mBinding) | None -> From 53b59208a7b4a80fd380074697aae46cb609c272 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 27 Jul 2023 18:54:20 -0600 Subject: [PATCH 09/51] Reject fixed expressions when used with static GetPinnableReference method --- src/Compiler/Checking/CheckExpressions.fs | 2 +- .../EmittedIL/FixedExpressionTests.fs | 52 +++++++++++++++++++ .../Language/FixedExpressionTests.fs | 42 +++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index fb8c323138e..00ce10cb5c6 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10343,7 +10343,7 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy |> List.tryFind (fun mInfo -> // GetPinnableReference must be a parameterless method with a byref or inref return value match mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst), mInfo.GetFSharpReturnType(cenv.amap, mBinding, mInfo.FormalMethodInst) with - | [[]], retTy when isByrefTy g retTy -> true + | [[]], retTy when isByrefTy g retTy && mInfo.IsInstance -> true | _ -> false ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 4d60fb01993..6e8918799be 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -606,3 +606,55 @@ let main _ = IL_0016: ldobj [runtime]System.Int32 IL_001b: ret } """ ] + + [] + let ``Pin type with extension method GetPinnableReference : unit -> byref`` () = + Fsx """ +module FixedExpressions +open System.Runtime.CompilerServices +open Microsoft.FSharp.NativeInterop + +type RefField<'T> = { mutable _value: 'T } + +[] +type RefFieldExtensions = + [] + static member GetPinnableReference(refField: RefField<'T>) : byref<'T> = &refField._value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let mutable x = 42 + let refToX = { _value = x } + let y = pinIt refToX + if y <> x then failwith "y did not equal x" + 0 +""" + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static !!a pinIt(class FixedExpressions/RefField`1 thing) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + !!a& pinned V_1) + IL_0000: ldarg.0 + IL_0001: ldflda !0 class FixedExpressions/RefField`1::_value@ + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: conv.i + IL_0009: stloc.0 + IL_000a: ldloc.0 + IL_000b: ldc.i4.0 + IL_000c: conv.i + IL_000d: sizeof !!a + IL_0013: mul + IL_0014: add + IL_0015: ldobj !!a + IL_001a: ret + } """ ] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index dcc1ab58ee3..d573f8810ad 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -367,3 +367,45 @@ let pinIt (thing: RefField<'T>) = (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] + + [] + let ``Pin type with private method GetPinnableReference - illegal`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +type StrangeType<'T>(_value) = + let mutable _value = _value + member private this.GetPinnableReference() : byref<'T> = _value + +let pinIt (thing: StrangeType<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + ] + + [] + let ``Pin type with static method GetPinnableReference - illegal`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +type StrangeType<'T>(_value) = + let mutable _value = _value + static member GetPinnableReference() : byref<'T> = Unchecked.defaultof<'T> + +let pinIt (thing: StrangeType<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + ] From 653daca7566ac7a2ceb0adb9954d3c22bc4ae04e Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 00:11:53 -0600 Subject: [PATCH 10/51] Write more fixed expression codegen tests --- .../EmittedIL/FixedExpressionTests.fs | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 6e8918799be..de71f0dc32e 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -411,6 +411,50 @@ let main _ = IL_001b: ret } """ ] + [] + let ``Pin generic ReadOnlySpan`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open System + +let pinIt (thing: ReadOnlySpan<'a>) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let span = ReadOnlySpan("The quick brown fox jumped over the lazy dog".ToCharArray()) + let x = pinIt span + if x <> 'T' then failwith "x did not equal the first char of the span" + 0 +""" + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static !!a pinIt(valuetype [runtime]System.ReadOnlySpan`1 thing) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + !!a& pinned V_1) + IL_0000: ldarga.s thing + IL_0002: call instance !0& modreq([runtime]System.Runtime.InteropServices.InAttribute) valuetype [runtime]System.ReadOnlySpan`1::GetPinnableReference() + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: conv.i + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: conv.i + IL_000e: sizeof !!a + IL_0014: mul + IL_0015: add + IL_0016: ldobj !!a + IL_001b: ret + } """ ] + [] let ``Pin type with method GetPinnableReference : unit -> byref`` () = FSharp """ @@ -460,6 +504,54 @@ let main _ = IL_001a: ret } """ ] + [] + let ``Pin type with method GetPinnableReference : unit -> inref`` () = + FSharp """ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open System + +type ReadonlyRefField<'T>(_value) = + let mutable _value = _value + member this.Value = _value + member this.GetPinnableReference () : inref<'T> = &_value + +let pinIt (thing: ReadonlyRefField) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let x = ReadonlyRefField(42) + let y = pinIt x + if y <> x.Value then failwith "y did not equal x value" + 0 +""" + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static int32 pinIt(class FixedExpressions/ReadonlyRefField`1 thing) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + int32& pinned V_1) + IL_0000: ldarg.0 + IL_0001: ldflda !0 class FixedExpressions/ReadonlyRefField`1::_value@7 + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: conv.i + IL_0009: stloc.0 + IL_000a: ldloc.0 + IL_000b: ldc.i4.0 + IL_000c: conv.i + IL_000d: sizeof [runtime]System.Int32 + IL_0013: mul + IL_0014: add + IL_0015: ldobj [runtime]System.Int32 + IL_001a: ret + } """ ] [] let ``Pin C# type with method GetPinnableReference : unit -> byref`` () = From fda843a0e86f5d36f468687709a298ac3416975c Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 00:18:17 -0600 Subject: [PATCH 11/51] Try to make test pass in CI --- .../EmittedIL/FixedExpressionTests.fs | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index de71f0dc32e..c7f09eae071 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -275,11 +275,13 @@ if x <> xCopy then failwith "xCopy was not the same as x" module FixedExpressions open Microsoft.FSharp.NativeInterop +let fail () = failwith "thingCopy was not the same as thing" |> ignore + let pinIt (x: int) = let mutable thing = x + 1 use ptr = fixed &thing let thingCopy = NativePtr.get ptr 0 - if thingCopy <> thing then failwith "thingCopy was not the same as thing" + if thingCopy <> thing then fail () pinIt 100 """ @@ -294,7 +296,8 @@ pinIt 100 .locals init (int32 V_0, native int V_1, int32& pinned V_2, - int32 V_3) + int32 V_3, + object V_4) IL_0000: ldarg.0 IL_0001: ldc.i4.1 IL_0002: add @@ -314,13 +317,23 @@ pinIt 100 IL_001b: stloc.3 IL_001c: ldloc.3 IL_001d: ldloc.0 - IL_001e: beq.s IL_002b + IL_001e: beq.s IL_0039 + + IL_0020: ldc.i4.0 + IL_0021: brfalse.s IL_002b + + IL_0023: ldnull + IL_0024: unbox.any [runtime]System.Object + IL_0029: br.s IL_0036 + + IL_002b: ldstr "thingCopy was not the same as thing" + IL_0030: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0035: throw - IL_0020: ldstr "thingCopy was not the same as thing" - IL_0025: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) - IL_002a: throw + IL_0036: stloc.s V_4 + IL_0038: ret - IL_002b: ret + IL_0039: ret } """ ] [] From aadc045eb30b024f86a0f1d09e40586612090d12 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 01:08:31 -0600 Subject: [PATCH 12/51] Fix test mistakes - all new tests should be green now --- .../EmittedIL/FixedExpressionTests.fs | 30 +++++++------------ .../Language/FixedExpressionTests.fs | 2 +- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index c7f09eae071..8b3bb25c30e 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -273,9 +273,12 @@ if x <> xCopy then failwith "xCopy was not the same as x" let ``Pin int byref of local variable`` () = FSharp """ module FixedExpressions +open System.Runtime.CompilerServices open Microsoft.FSharp.NativeInterop -let fail () = failwith "thingCopy was not the same as thing" |> ignore +[] +let fail () = + failwith "thingCopy was not the same as thing" let pinIt (x: int) = let mutable thing = x + 1 @@ -289,15 +292,14 @@ pinIt 100 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static void pinIt(int32 x) cil managed +.method public static void pinIt(int32 x) cil managed { .maxstack 5 .locals init (int32 V_0, native int V_1, int32& pinned V_2, - int32 V_3, - object V_4) + int32 V_3) IL_0000: ldarg.0 IL_0001: ldc.i4.1 IL_0002: add @@ -317,23 +319,13 @@ pinIt 100 IL_001b: stloc.3 IL_001c: ldloc.3 IL_001d: ldloc.0 - IL_001e: beq.s IL_0039 - - IL_0020: ldc.i4.0 - IL_0021: brfalse.s IL_002b - - IL_0023: ldnull - IL_0024: unbox.any [runtime]System.Object - IL_0029: br.s IL_0036 - - IL_002b: ldstr "thingCopy was not the same as thing" - IL_0030: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) - IL_0035: throw + IL_001e: beq.s IL_0027 - IL_0036: stloc.s V_4 - IL_0038: ret + IL_0020: call !!0 FixedExpressions::fail() + IL_0025: pop + IL_0026: ret - IL_0039: ret + IL_0027: ret } """ ] [] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index d573f8810ad..4441efddc6f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -396,7 +396,7 @@ open Microsoft.FSharp.NativeInterop type StrangeType<'T>(_value) = let mutable _value = _value - static member GetPinnableReference() : byref<'T> = Unchecked.defaultof<'T> + static member GetPinnableReference() : byref<'T> = Unchecked.defaultof> let pinIt (thing: StrangeType<'T>) = use ptr = fixed thing From cd4c932c5b26fb6ffcb59ce9d52c7249e9dcafaf Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 01:56:30 -0600 Subject: [PATCH 13/51] Create extended-fixed-bindings language switch --- src/Compiler/FSComp.txt | 1 + src/Compiler/Facilities/LanguageFeatures.fs | 3 +++ src/Compiler/Facilities/LanguageFeatures.fsi | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 +++++ 16 files changed, 70 insertions(+) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index fa7a00cf972..1c0cf84ba08 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1579,6 +1579,7 @@ featureImprovedImpliedArgumentNames,"Improved implied argument names" featureStrictIndentation,"Raises errors on incorrect indentation, allows better recovery and analysis during editing" featureChkNotTailRecursive,"Raises warnings if a member or function has the 'TailCall' attribute, but is not being used in a tail recursive way." featureWhileBang,"'while!' expression" +featureExtendedFixedBindings,"Extends fixed expressions to byrefs, inrefs, and GetPinnableReference()." 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index b158a501b17..2094037a6e7 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -75,6 +75,7 @@ type LanguageFeature = | StaticLetInRecordsDusEmptyTypes | WarningWhenTailRecAttributeButNonTailRecUsage | WhileBang + | ExtendedFixedBindings /// LanguageVersion management type LanguageVersion(versionText) = @@ -173,6 +174,7 @@ type LanguageVersion(versionText) = LanguageFeature.StaticLetInRecordsDusEmptyTypes, previewVersion LanguageFeature.StrictIndentation, previewVersion LanguageFeature.WhileBang, previewVersion + LanguageFeature.ExtendedFixedBindings, previewVersion ] static let defaultLanguageVersion = LanguageVersion("default") @@ -303,6 +305,7 @@ type LanguageVersion(versionText) = | LanguageFeature.StrictIndentation -> FSComp.SR.featureStrictIndentation () | LanguageFeature.WarningWhenTailRecAttributeButNonTailRecUsage -> FSComp.SR.featureChkNotTailRecursive () | LanguageFeature.WhileBang -> FSComp.SR.featureWhileBang () + | LanguageFeature.ExtendedFixedBindings -> FSComp.SR.featureExtendedFixedBindings () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index 06880bb600f..ae601aaceb2 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -65,6 +65,7 @@ type LanguageFeature = | StaticLetInRecordsDusEmptyTypes | WarningWhenTailRecAttributeButNonTailRecUsage | WhileBang + | ExtendedFixedBindings /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index caf29840d67..2daeebcaaf5 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -267,6 +267,11 @@ více typů podporuje měrné jednotky + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 664a6102e60..fc09c5ee29d 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -267,6 +267,11 @@ Maßeinheitenunterstützung durch weitere Typen + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 68389afe04e..dde3cd98fe2 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -267,6 +267,11 @@ más tipos admiten las unidades de medida + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 7eada02df37..a77c466250d 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -267,6 +267,11 @@ d'autres types prennent en charge les unités de mesure + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index cfd07256a43..4c9c6b1b814 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -267,6 +267,11 @@ più tipi supportano le unità di misura + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 51245fdcfce..c648d55c35a 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -267,6 +267,11 @@ 単位をサポートするその他の型 + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 5ef00861cc7..946742056d2 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -267,6 +267,11 @@ 더 많은 형식이 측정 단위를 지원함 + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 2bb2056d482..ef2051524d0 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -267,6 +267,11 @@ więcej typów obsługuje jednostki miary + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 0ae0aba2cb2..07e4af3b10b 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -267,6 +267,11 @@ mais tipos dão suporte para unidades de medida + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 76ae929db46..2626218a541 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -267,6 +267,11 @@ другие типы поддерживают единицы измерения + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index a54cba13092..c13a1139853 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -267,6 +267,11 @@ tür daha ölçü birimlerini destekler + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index c475951fb39..d6f65e6bdd8 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -267,6 +267,11 @@ 更多类型支持度量单位 + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 2b758889088..4661859e5e4 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -267,6 +267,11 @@ 更多支援測量單位的類型 + + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + + Extended string interpolation similar to C# raw string literals. Extended string interpolation similar to C# raw string literals. From b52e1b409570ff86eae9e03a9fe23e001ea3f1d6 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 02:23:29 -0600 Subject: [PATCH 14/51] Update FS3207 error message text to include new criteria --- src/Compiler/FSComp.txt | 2 +- src/Compiler/xlf/FSComp.txt.cs.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.de.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.es.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.it.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 4 ++-- .../Language/FixedExpressionTests.fs | 12 ++++++------ tests/fsharp/typecheck/sigs/neg97.bsl | 8 ++++---- tests/fsharp/typecheck/sigs/neg97.vsbsl | 8 ++++---- 17 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 1c0cf84ba08..397401ce98f 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1380,7 +1380,7 @@ tcTupleStructMismatch,"One tuple type is a struct tuple, the other is a referenc 3203,parsInvalidUseOfRec,"Invalid use of 'rec' keyword" 3204,tcStructUnionMultiCaseDistinctFields,"If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'." 3206,CallerMemberNameIsOverriden,"The CallerMemberNameAttribute applied to parameter '%s' will have no effect. It is overridden by the CallerFilePathAttribute." -3207,tcFixedNotAllowed,"Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'" +3207,tcFixedNotAllowed,"Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()" 3208,tcCouldNotFindOffsetToStringData,"Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression." 3209,chkNoByrefAddressOfLocal,"The address of the variable '%s' 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." 3210,tcNamedActivePattern,"%s is an active pattern and cannot be treated as a discriminated union case with named fields." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 2daeebcaaf5..9129a503e5e 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - Neplatné použití fixed. fixed se dá použít jenom v deklaraci ve tvaru use x = fixed expr, kde výraz je pole, adresa pole nebo adresa prvku pole nebo řetězce. + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Neplatné použití fixed. fixed se dá použít jenom v deklaraci ve tvaru use x = fixed expr, kde výraz je pole, adresa pole nebo adresa prvku pole nebo řetězce. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index fc09c5ee29d..0ce2c908def 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - Ungültige Verwendung von "fixed". "fixed" darf ausschließlich in einer Deklaration der Form "use x = fixed expr" verwendet werden. Dabei ist der Ausdruck ein Array, die Adresse eines Felds, die Adresse eines Arrayelements oder eine Zeichenfolge. + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Ungültige Verwendung von "fixed". "fixed" darf ausschließlich in einer Deklaration der Form "use x = fixed expr" verwendet werden. Dabei ist der Ausdruck ein Array, die Adresse eines Felds, die Adresse eines Arrayelements oder eine Zeichenfolge. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index dde3cd98fe2..047c28e9f50 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - Uso no válido de 'fixed'. 'fixed' debe utilizarse solo en una declaración del formulario 'use x = fixed expr' donde la expresión es una matriz, la dirección de un campo, la dirección de un elemento de matriz o una cadena' + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Uso no válido de 'fixed'. 'fixed' debe utilizarse solo en una declaración del formulario 'use x = fixed expr' donde la expresión es una matriz, la dirección de un campo, la dirección de un elemento de matriz o una cadena' diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index a77c466250d..afc7c2165fc 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - Utilisation non valide de 'fixed'. Utilisez uniquement 'fixed' dans une déclaration de la forme 'use x = fixed expr' où l'expression est un tableau, l'adresse d'un champ, l'adresse d'un élément de tableau ou une chaîne + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Utilisation non valide de 'fixed'. Utilisez uniquement 'fixed' dans une déclaration de la forme 'use x = fixed expr' où l'expression est un tableau, l'adresse d'un champ, l'adresse d'un élément de tableau ou une chaîne diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 4c9c6b1b814..b84b7da9db6 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - Uso non valido di 'fixed'. 'fixed' può essere usato solo in una dichiarazione in formato 'use x = fixed expr', in cui l'espressione è una matrice, l'indirizzo di un campo, l'indirizzo di un elemento di matrice oppure una stringa + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Uso non valido di 'fixed'. 'fixed' può essere usato solo in una dichiarazione in formato 'use x = fixed expr', in cui l'espressione è una matrice, l'indirizzo di un campo, l'indirizzo di un elemento di matrice oppure una stringa diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index c648d55c35a..f6c2240d51c 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - 'fixed' の使い方が正しくありません。'fixed' を使用できるのは書式 'use x = fixed expr' の宣言内だけで、この式は配列、フィールドのアドレス、配列要素のアドレス、または文字列です + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + 'fixed' の使い方が正しくありません。'fixed' を使用できるのは書式 'use x = fixed expr' の宣言内だけで、この式は配列、フィールドのアドレス、配列要素のアドレス、または文字列です diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 946742056d2..71faf2a4fa8 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - 'fixed'를 잘못 사용했습니다. 'fixed'는 식이 배열, 필드의 주소, 배열 요소 또는 문자열의 주소인 경우 'use x = fixed expr' 형식의 선언에만 사용할 수 있습니다. + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + 'fixed'를 잘못 사용했습니다. 'fixed'는 식이 배열, 필드의 주소, 배열 요소 또는 문자열의 주소인 경우 'use x = fixed expr' 형식의 선언에만 사용할 수 있습니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index ef2051524d0..92d7a9e5881 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - Nieprawidłowe użycie wyrażenia „fixed”. Wyrażenia „fixed” można użyć tylko w deklaracji w postaci „use x = fixed expr”, gdzie wyrażenie jest tablicą, adresem pola, adresem elementu tablicy lub ciągiem + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Nieprawidłowe użycie wyrażenia „fixed”. Wyrażenia „fixed” można użyć tylko w deklaracji w postaci „use x = fixed expr”, gdzie wyrażenie jest tablicą, adresem pola, adresem elementu tablicy lub ciągiem diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 07e4af3b10b..581e87a31ca 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - Uso inválido da 'fixed'. 'fixed' somente pode ser usada em uma declaração no formato 'use x = fixed expr', em que a expressão é uma matriz, o endereço de um campo, o endereço de um elemento de matriz ou uma cadeia de caracteres + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Uso inválido da 'fixed'. 'fixed' somente pode ser usada em uma declaração no formato 'use x = fixed expr', em que a expressão é uma matriz, o endereço de um campo, o endereço de um elemento de matriz ou uma cadeia de caracteres diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 2626218a541..db428173485 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - Недопустимое использование выражения "fixed". Выражение "fixed" можно использовать только в объявлении формы "use x = fixed expr", где выражение является массивом, адресом поля, адресом элемента массива или строки. + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Недопустимое использование выражения "fixed". Выражение "fixed" можно использовать только в объявлении формы "use x = fixed expr", где выражение является массивом, адресом поля, адресом элемента массива или строки. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index c13a1139853..a3301960763 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - Geçersiz 'fixed' kullanımı. 'fixed' yalnızca 'use x = fixed expr' biçimindeki bir bildirimde kullanılabilir. Burada ifade bir dizi, bir alanın adresi, bir dizi öğesinin adresi veya bir dizedir + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Geçersiz 'fixed' kullanımı. 'fixed' yalnızca 'use x = fixed expr' biçimindeki bir bildirimde kullanılabilir. Burada ifade bir dizi, bir alanın adresi, bir dizi öğesinin adresi veya bir dizedir diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index d6f65e6bdd8..0dbd6463878 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - 无效的 "fixed" 使用。"fixed" 只能用在 "use x = fixed expr" 形式的声明中,其中表达式为数组、字段的地址、数组元素或字符串的地址 + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + 无效的 "fixed" 使用。"fixed" 只能用在 "use x = fixed expr" 形式的声明中,其中表达式为数组、字段的地址、数组元素或字符串的地址 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 4661859e5e4..59c7bcb9e74 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -7793,8 +7793,8 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' - 使用 'fixed' 無效。'fixed' 僅能用於格式為 'use x = fixed expr' 的宣告中,其中運算式為陣列、欄位的位址、陣列元素的位址或字串 + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + 使用 'fixed' 無效。'fixed' 僅能用於格式為 'use x = fixed expr' 的宣告中,其中運算式為陣列、欄位的位址、陣列元素的位址或字串 diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index 4441efddc6f..f8ea4ed4d79 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -110,7 +110,7 @@ let pinIt (thing: obj) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] @@ -127,7 +127,7 @@ let pinIt (thing: int) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] // FS-1081 - Extend fixed expressions @@ -321,7 +321,7 @@ let pinIt (thing: StrangeType<'T>) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -342,7 +342,7 @@ let pinIt (thing: StrangeType<'T>) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -386,7 +386,7 @@ let pinIt (thing: StrangeType<'T>) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -407,5 +407,5 @@ let pinIt (thing: StrangeType<'T>) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] diff --git a/tests/fsharp/typecheck/sigs/neg97.bsl b/tests/fsharp/typecheck/sigs/neg97.bsl index 1a4d97f87d9..18f5229dbe0 100644 --- a/tests/fsharp/typecheck/sigs/neg97.bsl +++ b/tests/fsharp/typecheck/sigs/neg97.bsl @@ -3,19 +3,19 @@ neg97.fs(13,1,13,10): typecheck error FS0256: A value must be mutable in order t neg97.fs(16,9,16,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(16,9,16,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' +neg97.fs(16,9,16,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(20,9,20,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' +neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(25,9,25,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(25,9,25,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' +neg97.fs(25,9,25,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(30,9,30,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(30,9,30,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' +neg97.fs(30,9,30,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(36,20,36,32): typecheck error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution diff --git a/tests/fsharp/typecheck/sigs/neg97.vsbsl b/tests/fsharp/typecheck/sigs/neg97.vsbsl index 1a4d97f87d9..18f5229dbe0 100644 --- a/tests/fsharp/typecheck/sigs/neg97.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg97.vsbsl @@ -3,19 +3,19 @@ neg97.fs(13,1,13,10): typecheck error FS0256: A value must be mutable in order t neg97.fs(16,9,16,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(16,9,16,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' +neg97.fs(16,9,16,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(20,9,20,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' +neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(25,9,25,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(25,9,25,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' +neg97.fs(25,9,25,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(30,9,30,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(30,9,30,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string' +neg97.fs(30,9,30,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(36,20,36,32): typecheck error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution From a202926b8bc6c1033de862f4f9911a7ee1b4a77a Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 02:29:43 -0600 Subject: [PATCH 15/51] Exclude some tests for .net framework, which lacks Span --- .../EmittedIL/FixedExpressionTests.fs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 8b3bb25c30e..ba9e0c05b40 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -328,6 +328,7 @@ pinIt 100 IL_0027: ret } """ ] +#if NETCOREAPP [] let ``Pin Span via manual GetPinnableReference call`` () = FSharp """ @@ -415,6 +416,7 @@ let main _ = IL_0016: ldobj [runtime]System.Char IL_001b: ret } """ ] +#endif [] let ``Pin generic ReadOnlySpan`` () = From 771f021fa31d6c481dbefadac535794417d0f6ef Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 09:41:38 -0600 Subject: [PATCH 16/51] Fix more CI test issues --- .../EmittedIL/FixedExpressionTests.fs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index ba9e0c05b40..67bb9c953fd 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -416,7 +416,6 @@ let main _ = IL_0016: ldobj [runtime]System.Char IL_001b: ret } """ ] -#endif [] let ``Pin generic ReadOnlySpan`` () = @@ -461,6 +460,7 @@ let main _ = IL_0016: ldobj !!a IL_001b: ret } """ ] +#endif [] let ``Pin type with method GetPinnableReference : unit -> byref`` () = @@ -564,7 +564,7 @@ let main _ = let ``Pin C# type with method GetPinnableReference : unit -> byref`` () = let csLib = CSharp """ -namespace CSharpLib +namespace CsLib { public class PinnableReference { @@ -593,7 +593,7 @@ namespace CSharpLib module FixedExpressions open Microsoft.FSharp.NativeInterop open System -open CSharpLib +open CsLib let pinIt (thing: PinnableReference) = use ptr = fixed thing @@ -611,14 +611,14 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static int32 pinIt(class [CsLib]CSharpLib.PinnableReference`1 thing) cil managed + .method public static int32 pinIt(class [CsLib]CsLib.PinnableReference`1 thing) cil managed { .maxstack 5 .locals init (native int V_0, int32& pinned V_1) IL_0000: ldarg.0 - IL_0001: callvirt instance !0& class [CsLib]CSharpLib.PinnableReference`1::GetPinnableReference() + IL_0001: callvirt instance !0& class [CsLib]CsLib.PinnableReference`1::GetPinnableReference() IL_0006: stloc.1 IL_0007: ldloc.1 IL_0008: conv.i @@ -633,6 +633,7 @@ let main _ = IL_001a: ret } """ ] +#if NETCOREAPP [] let ``Pin C# byref struct type with method GetPinnableReference : unit -> byref`` () = // TODO: Could be a good idea to test a version of this type written in F# too once we get ref fields in byref-like structs: @@ -660,7 +661,8 @@ namespace CsLib } } -""" |> withName "CsLib" |> withCSharpLanguageVersion CSharpLanguageVersion.CSharp11 +""" |> withName "CsLib" + |> withCSharpLanguageVersion CSharpLanguageVersion.CSharp11 FSharp """ module FixedExpressions @@ -705,6 +707,7 @@ let main _ = IL_0016: ldobj [runtime]System.Int32 IL_001b: ret } """ ] +#endif [] let ``Pin type with extension method GetPinnableReference : unit -> byref`` () = From 224bae91f68078444448756214b7cb522192d413 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 10:34:18 -0600 Subject: [PATCH 17/51] Add a fixed expr struct test that works under .net framework --- .../EmittedIL/FixedExpressionTests.fs | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 67bb9c953fd..9f44628ef67 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -560,6 +560,67 @@ let main _ = IL_001a: ret } """ ] + [] + let ``Pin struct type with method GetPinnableReference : unit -> byref`` () = + // Effectively tests the same thing as the test with Span, but this works on .NET Framework + FSharp """ +module FixedExpressions +open System.Runtime.CompilerServices +open Microsoft.FSharp.NativeInterop +open System + +[] +type ArrayElementRef<'T> = + private { Values: 'T[]; Index: int } + + static member Create(values: 'T[], index) = + if index > values.Length then + raise (ArgumentOutOfRangeException(nameof(index), "")) + { Values = values; Index = index } + member this.Value = this.Values[this.Index] + member this.GetPinnableReference () : byref<'T> = &this.Values[this.Index] + +let pinIt (thing: ArrayElementRef<'a>) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let arr = [|'a';'b';'c'|] + let x = ArrayElementRef.Create(arr, 1) + let y = pinIt x + if y <> x.Value then failwith "y did not equal x value" + 0 +""" + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static !!a pinIt(valuetype FixedExpressions/ArrayElementRef`1 thing) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + !!a& pinned V_1) + IL_0000: ldarga.s thing + IL_0002: ldfld !0[] valuetype FixedExpressions/ArrayElementRef`1::Values@ + IL_0007: ldarga.s thing + IL_0009: ldfld int32 valuetype FixedExpressions/ArrayElementRef`1::Index@ + IL_000e: ldelema !!a + IL_0013: stloc.1 + IL_0014: ldloc.1 + IL_0015: conv.i + IL_0016: stloc.0 + IL_0017: ldloc.0 + IL_0018: ldc.i4.0 + IL_0019: conv.i + IL_001a: sizeof !!a + IL_0020: mul + IL_0021: add + IL_0022: ldobj !!a + IL_0027: ret + } """ ] + [] let ``Pin C# type with method GetPinnableReference : unit -> byref`` () = let csLib = From 33e595b994d274a96f8b9477a8fa66e71b9786d8 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 12:09:54 -0600 Subject: [PATCH 18/51] Update baselines --- tests/fsharp/typecheck/sigs/neg97.bsl | 16 ++++------------ tests/fsharp/typecheck/sigs/neg97.fs | 10 ---------- tests/fsharp/typecheck/sigs/neg97.vsbsl | 16 ++++------------ 3 files changed, 8 insertions(+), 34 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg97.bsl b/tests/fsharp/typecheck/sigs/neg97.bsl index 18f5229dbe0..3da9fec6878 100644 --- a/tests/fsharp/typecheck/sigs/neg97.bsl +++ b/tests/fsharp/typecheck/sigs/neg97.bsl @@ -9,18 +9,10 @@ neg97.fs(20,9,20,10): typecheck error FS0009: Uses of this construct may result neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() -neg97.fs(25,9,25,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. +neg97.fs(26,20,26,32): typecheck error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution -neg97.fs(25,9,25,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() +neg97.fs(26,20,26,32): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'string'. -neg97.fs(30,9,30,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. +neg97.fs(26,12,26,14): typecheck error FS0663: This type parameter has been used in a way that constrains it to always be 'string' -neg97.fs(30,9,30,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() - -neg97.fs(36,20,36,32): typecheck error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution - -neg97.fs(36,20,36,32): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'string'. - -neg97.fs(36,12,36,14): typecheck error FS0663: This type parameter has been used in a way that constrains it to always be 'string' - -neg97.fs(42,20,42,22): typecheck error FS0039: The type parameter 'T is not defined. +neg97.fs(32,20,32,22): typecheck error FS0039: The type parameter 'T is not defined. diff --git a/tests/fsharp/typecheck/sigs/neg97.fs b/tests/fsharp/typecheck/sigs/neg97.fs index 5cd8743df21..c035cdc958f 100644 --- a/tests/fsharp/typecheck/sigs/neg97.fs +++ b/tests/fsharp/typecheck/sigs/neg97.fs @@ -20,16 +20,6 @@ let pinAnyNotAllowed(x: 'T) = use p = fixed x () -let pinStackAddressNotAllowed(x: 'T) = - let mutable v = 0 - use p = fixed &v - () - -let pinStructAddressNotAllowed(x: 'T) = - let mutable v = { X = 1.0; Y = 1.0 } - use p = fixed &v.Y - () - module Example1 = type X<'T> = Y of 'T diff --git a/tests/fsharp/typecheck/sigs/neg97.vsbsl b/tests/fsharp/typecheck/sigs/neg97.vsbsl index 18f5229dbe0..3da9fec6878 100644 --- a/tests/fsharp/typecheck/sigs/neg97.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg97.vsbsl @@ -9,18 +9,10 @@ neg97.fs(20,9,20,10): typecheck error FS0009: Uses of this construct may result neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() -neg97.fs(25,9,25,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. +neg97.fs(26,20,26,32): typecheck error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution -neg97.fs(25,9,25,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() +neg97.fs(26,20,26,32): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'string'. -neg97.fs(30,9,30,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. +neg97.fs(26,12,26,14): typecheck error FS0663: This type parameter has been used in a way that constrains it to always be 'string' -neg97.fs(30,9,30,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() - -neg97.fs(36,20,36,32): typecheck error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution - -neg97.fs(36,20,36,32): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'string'. - -neg97.fs(36,12,36,14): typecheck error FS0663: This type parameter has been used in a way that constrains it to always be 'string' - -neg97.fs(42,20,42,22): typecheck error FS0039: The type parameter 'T is not defined. +neg97.fs(32,20,32,22): typecheck error FS0039: The type parameter 'T is not defined. From 287caa9fec73c4b4f917f331d680c2b324993f25 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 12:21:17 -0600 Subject: [PATCH 19/51] Add more tests to cover original baselines --- .../Language/FixedExpressionTests.fs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index f8ea4ed4d79..ae2b942d2f9 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -130,6 +130,38 @@ let pinIt (thing: int) = (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] + [] + let ``Pin generic - illegal`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: 'a) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + [] + let ``Pin generic with unmanaged - illegal`` () = + Fsx """ +open Microsoft.FSharp.NativeInterop + +let pinIt<'a when 'a : unmanaged> (thing: 'a) = + use ptr = fixed thing + NativePtr.get ptr 0 +""" + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + // FS-1081 - Extend fixed expressions module ExtendedFixedExpressions = [] From 2a1f50a3ac68eef0d928601c7c06e42b986d0cd8 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 12:45:52 -0600 Subject: [PATCH 20/51] Attempt more CI test fixes --- .../EmittedIL/FixedExpressionTests.fs | 36 +++++++++---------- .../Language/FixedExpressionTests.fs | 2 ++ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 9f44628ef67..069bc8d3d4c 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -625,27 +625,24 @@ let main _ = let ``Pin C# type with method GetPinnableReference : unit -> byref`` () = let csLib = CSharp """ -namespace CsLib +public class PinnableReference { - public class PinnableReference - { - private T _value; + private T _value; - public T Value - { - get => _value; - set => _value = value; - } + public T Value + { + get => _value; + set => _value = value; + } - public PinnableReference(T value) - { - this._value = value; - } + public PinnableReference(T value) + { + this._value = value; + } - public ref T GetPinnableReference() - { - return ref _value; - } + public ref T GetPinnableReference() + { + return ref _value; } } """ |> withName "CsLib" @@ -654,7 +651,6 @@ namespace CsLib module FixedExpressions open Microsoft.FSharp.NativeInterop open System -open CsLib let pinIt (thing: PinnableReference) = use ptr = fixed thing @@ -672,14 +668,14 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static int32 pinIt(class [CsLib]CsLib.PinnableReference`1 thing) cil managed + .method public static int32 pinIt(class [CsLib]PinnableReference`1 thing) cil managed { .maxstack 5 .locals init (native int V_0, int32& pinned V_1) IL_0000: ldarg.0 - IL_0001: callvirt instance !0& class [CsLib]CsLib.PinnableReference`1::GetPinnableReference() + IL_0001: callvirt instance !0& class [CsLib]PinnableReference`1::GetPinnableReference() IL_0006: stloc.1 IL_0007: ldloc.1 IL_0008: conv.i diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index ae2b942d2f9..f09006c069c 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -233,6 +233,7 @@ let pinIt () = (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] +#if NETCOREAPP [] let ``Pin Span`` () = Fsx """ @@ -250,6 +251,7 @@ let pinIt (thing: Span) = (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] +#endif let ``Pin custom byref type without GetPinnableReference method - illegal`` () = Fsx """ From e57d48a115f2835a5a11d57300ab50a09532cae0 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 13:18:00 -0600 Subject: [PATCH 21/51] Feature-flag fixed expr codegen tests --- .../EmittedIL/FixedExpressionTests.fs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 069bc8d3d4c..a71cd296b5e 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -245,6 +245,7 @@ let xCopy = pinIt &x if x <> xCopy then failwith "xCopy was not the same as x" """ |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -289,6 +290,7 @@ let pinIt (x: int) = pinIt 100 """ |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -348,6 +350,7 @@ let main _ = 0 """ |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -392,6 +395,7 @@ let main _ = 0 """ |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -436,6 +440,7 @@ let main _ = 0 """ |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -486,6 +491,7 @@ let main _ = 0 """ |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -535,6 +541,7 @@ let main _ = 0 """ |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -593,6 +600,7 @@ let main _ = 0 """ |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -665,6 +673,7 @@ let main _ = """ |> withReferences [csLib] |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -740,6 +749,7 @@ let main _ = """ |> withReferences [csLib] |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -793,6 +803,7 @@ let main _ = 0 """ |> withOptions ["--nowarn:9"] + |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" From cd3d09bda22197f0a6cbf70e2d8222e0f1d40fc2 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 13:35:32 -0600 Subject: [PATCH 22/51] Add missing [] to activate a test --- .../Language/FixedExpressionTests.fs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index f09006c069c..14da2501c29 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -252,8 +252,9 @@ let pinIt (thing: Span) = (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] #endif - - let ``Pin custom byref type without GetPinnableReference method - illegal`` () = + + [] + let ``Pin custom struct byref type without GetPinnableReference method - illegal`` () = Fsx """ open System open System.Runtime.CompilerServices @@ -269,6 +270,10 @@ let pinIt (thing: BoringRefField) = |> ignoreWarnings |> typecheck |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] [] let ``Pin type with method GetPinnableReference : unit -> byref`` () = From 98d114d494688c44e82624e46c8fafbba441494c Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 13:56:02 -0600 Subject: [PATCH 23/51] Parameterize all fixed expr tests with feature flags --- .../EmittedIL/FixedExpressionTests.fs | 101 ++++++----- .../Language/FixedExpressionTests.fs | 161 +++++++++++++----- 2 files changed, 173 insertions(+), 89 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index a71cd296b5e..56e033f6593 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -7,8 +7,10 @@ open FSharp.Test.Utilities open FSharp.Test.Compiler module Legacy = - [] - let ``Pin naked string``() = + [] + [] + [] + let ``Pin naked string`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -17,6 +19,7 @@ let pinIt (str: string) = use ptr = fixed str NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compile |> verifyIL [""" @@ -49,8 +52,10 @@ let pinIt (str: string) = IL_0021: ret }""" ] - [] - let ``Pin naked array`` () = + [] + [] + [] + let ``Pin naked array`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -59,6 +64,7 @@ let pinIt (arr: char[]) = use ptr = fixed arr NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compile |> verifyIL [""" @@ -100,8 +106,10 @@ let pinIt (arr: char[]) = IL_002e: ret } """ ] - [] - let ``Pin address of record field`` () = + [] + [] + [] + let ``Pin address of record field`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -116,6 +124,7 @@ let p = { X = 10; Y = 20 } let xCopy = pinIt p if xCopy <> p.X then failwith "xCopy was not equal to X" """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun |> verifyIL [""" @@ -141,8 +150,10 @@ if xCopy <> p.X then failwith "xCopy was not equal to X" IL_001a: ret } """ ] - [] - let ``Pin address of explicit field on this`` () = + [] + [] + [] + let ``Pin address of explicit field on this`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -161,6 +172,7 @@ let p = Point(10,20) let xCopy = p.PinIt() if xCopy <> p.X then failwith "xCopy was not equal to X" """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun |> shouldSucceed @@ -188,8 +200,10 @@ if xCopy <> p.X then failwith "xCopy was not equal to X" IL_001a: ret } """ ] - [] - let ``Pin address of array element`` () = + [] + [] + [] + let ``Pin address of array element`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -202,6 +216,7 @@ let x = [|'a';'b';'c'|] let y = pinIt x if y <> 'a' then failwithf "y did not equal first element of x" """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun |> shouldSucceed @@ -230,8 +245,8 @@ if y <> 'a' then failwithf "y did not equal first element of x" } """ ] module ExtendedFixedExpressions = - [] - let ``Pin int byref of parameter`` () = + [] + let ``Pin int byref of parameter`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -244,8 +259,8 @@ let mutable x = 42 let xCopy = pinIt &x if x <> xCopy then failwith "xCopy was not the same as x" """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -270,8 +285,8 @@ if x <> xCopy then failwith "xCopy was not the same as x" IL_0015: ret } """] - [] - let ``Pin int byref of local variable`` () = + [] + let ``Pin int byref of local variable`` langVersion = FSharp """ module FixedExpressions open System.Runtime.CompilerServices @@ -289,8 +304,8 @@ let pinIt (x: int) = pinIt 100 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -331,8 +346,8 @@ pinIt 100 } """ ] #if NETCOREAPP - [] - let ``Pin Span via manual GetPinnableReference call`` () = + [] + let ``Pin Span via manual GetPinnableReference call`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -349,8 +364,8 @@ let main _ = if x <> 'T' then failwith "x did not equal the first char of the span" 0 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -376,8 +391,8 @@ let main _ = IL_001b: ret } """ ] - [] - let ``Pin Span`` () = + [] + let ``Pin Span`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -394,8 +409,8 @@ let main _ = if x <> 'T' then failwith "x did not equal the first char of the span" 0 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -421,8 +436,8 @@ let main _ = IL_001b: ret } """ ] - [] - let ``Pin generic ReadOnlySpan`` () = + [] + let ``Pin generic ReadOnlySpan`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -439,8 +454,8 @@ let main _ = if x <> 'T' then failwith "x did not equal the first char of the span" 0 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -467,8 +482,8 @@ let main _ = } """ ] #endif - [] - let ``Pin type with method GetPinnableReference : unit -> byref`` () = + [] + let ``Pin type with method GetPinnableReference : unit -> byref`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -490,8 +505,8 @@ let main _ = if y <> x.Value then failwith "y did not equal x value" 0 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -517,8 +532,8 @@ let main _ = IL_001a: ret } """ ] - [] - let ``Pin type with method GetPinnableReference : unit -> inref`` () = + [] + let ``Pin type with method GetPinnableReference : unit -> inref`` langVersion = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -540,8 +555,8 @@ let main _ = if y <> x.Value then failwith "y did not equal x value" 0 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -567,8 +582,8 @@ let main _ = IL_001a: ret } """ ] - [] - let ``Pin struct type with method GetPinnableReference : unit -> byref`` () = + [] + let ``Pin struct type with method GetPinnableReference : unit -> byref`` langVersion = // Effectively tests the same thing as the test with Span, but this works on .NET Framework FSharp """ module FixedExpressions @@ -599,8 +614,8 @@ let main _ = if y <> x.Value then failwith "y did not equal x value" 0 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -629,8 +644,8 @@ let main _ = IL_0027: ret } """ ] - [] - let ``Pin C# type with method GetPinnableReference : unit -> byref`` () = + [] + let ``Pin C# type with method GetPinnableReference : unit -> byref`` langVersion = let csLib = CSharp """ public class PinnableReference @@ -671,9 +686,9 @@ let main _ = if y <> x.Value then failwith "y did not equal x value" 0 """ + |> withLangVersion langVersion |> withReferences [csLib] |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -700,8 +715,8 @@ let main _ = } """ ] #if NETCOREAPP - [] - let ``Pin C# byref struct type with method GetPinnableReference : unit -> byref`` () = + [] + let ``Pin C# byref struct type with method GetPinnableReference : unit -> byref`` langVersion = // TODO: Could be a good idea to test a version of this type written in F# too once we get ref fields in byref-like structs: // https://github.com/fsharp/fslang-suggestions/issues/1143 let csLib = @@ -747,9 +762,9 @@ let main _ = if y <> x then failwith "y did not equal x" 0 """ + |> withLangVersion langVersion |> withReferences [csLib] |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -776,8 +791,8 @@ let main _ = } """ ] #endif - [] - let ``Pin type with extension method GetPinnableReference : unit -> byref`` () = + [] + let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = Fsx """ module FixedExpressions open System.Runtime.CompilerServices @@ -802,8 +817,8 @@ let main _ = if y <> x then failwith "y did not equal x" 0 """ + |> withLangVersion langVersion |> withOptions ["--nowarn:9"] - |> withLangVersionPreview |> compileExeAndRun |> shouldSucceed |> verifyIL [""" diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index 14da2501c29..1aedc771573 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -4,8 +4,10 @@ open Xunit open FSharp.Test.Compiler module Legacy = - [] - let ``Pin naked string`` () = + [] + [] + [] + let ``Pin naked string`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -13,6 +15,7 @@ let pinIt (str: string) = use ptr = fixed str NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -21,8 +24,10 @@ let pinIt (str: string) = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin naked array`` () = + [] + [] + [] + let ``Pin naked array`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -30,6 +35,7 @@ let pinIt (arr: char[]) = use ptr = fixed arr NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -38,8 +44,10 @@ let pinIt (arr: char[]) = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin address of array element`` () = + [] + [] + [] + let ``Pin address of array element`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -47,6 +55,7 @@ let pinIt (arr: char[]) = use ptr = fixed &arr[1] NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -55,8 +64,10 @@ let pinIt (arr: char[]) = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin address of record field`` () = + [] + [] + [] + let ``Pin address of record field`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -66,6 +77,7 @@ let pinIt (thing: Point) = use ptr = fixed &thing.X NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -74,8 +86,10 @@ let pinIt (thing: Point) = (Warning 9, Line 8, Col 5, Line 8, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin address of explicit field on this`` () = + [] + [] + [] + let ``Pin address of explicit field on this`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -89,6 +103,7 @@ type Point = use ptr = fixed &this.X NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -97,8 +112,10 @@ type Point = (Warning 9, Line 12, Col 9, Line 12, Col 22, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin naked object - illegal`` () = + [] + [] + [] + let ``Pin naked object - illegal`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -106,6 +123,7 @@ let pinIt (thing: obj) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> typecheck |> shouldFail |> withDiagnostics [ @@ -114,8 +132,10 @@ let pinIt (thing: obj) = ] - [] - let ``Pin naked int - illegal`` () = + [] + [] + [] + let ``Pin naked int - illegal`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -123,6 +143,7 @@ let pinIt (thing: int) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> typecheck |> shouldFail |> withDiagnostics [ @@ -130,8 +151,10 @@ let pinIt (thing: int) = (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] - [] - let ``Pin generic - illegal`` () = + [] + [] + [] + let ``Pin generic - illegal`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -139,6 +162,7 @@ let pinIt (thing: 'a) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> typecheck |> shouldFail |> withDiagnostics [ @@ -146,8 +170,10 @@ let pinIt (thing: 'a) = (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] - [] - let ``Pin generic with unmanaged - illegal`` () = + [] + [] + [] + let ``Pin generic with unmanaged - illegal`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -155,6 +181,7 @@ let pinIt<'a when 'a : unmanaged> (thing: 'a) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> typecheck |> shouldFail |> withDiagnostics [ @@ -164,8 +191,10 @@ let pinIt<'a when 'a : unmanaged> (thing: 'a) = // FS-1081 - Extend fixed expressions module ExtendedFixedExpressions = - [] - let ``Pin int byref parmeter`` () = + [] + [] + [] + let ``Pin int byref parmeter`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -173,6 +202,7 @@ let pinIt (thing: byref) = use ptr = fixed &thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -181,8 +211,10 @@ let pinIt (thing: byref) = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin int inref parmeter`` () = + [] + [] + [] + let ``Pin int inref parmeter`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -190,6 +222,7 @@ let pinIt (thing: inref) = use ptr = fixed &thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -198,8 +231,10 @@ let pinIt (thing: inref) = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin int outref parmeter`` () = + [] + [] + [] + let ``Pin int outref parmeter`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -207,6 +242,7 @@ let pinIt (thing: outref) = use ptr = fixed &thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -215,8 +251,10 @@ let pinIt (thing: outref) = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin int byref local variable`` () = + [] + [] + [] + let ``Pin int byref local variable`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -225,6 +263,7 @@ let pinIt () = use ptr = fixed &thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -234,8 +273,10 @@ let pinIt () = ] #if NETCOREAPP - [] - let ``Pin Span`` () = + [] + [] + [] + let ``Pin Span`` langVersion = Fsx """ open System open Microsoft.FSharp.NativeInterop @@ -244,6 +285,7 @@ let pinIt (thing: Span) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -253,8 +295,10 @@ let pinIt (thing: Span) = ] #endif - [] - let ``Pin custom struct byref type without GetPinnableReference method - illegal`` () = + [] + [] + [] + let ``Pin custom struct byref type without GetPinnableReference method - illegal`` langVersion = Fsx """ open System open System.Runtime.CompilerServices @@ -267,6 +311,7 @@ let pinIt (thing: BoringRefField) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldFail @@ -275,8 +320,10 @@ let pinIt (thing: BoringRefField) = (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] - [] - let ``Pin type with method GetPinnableReference : unit -> byref`` () = + [] + [] + [] + let ``Pin type with method GetPinnableReference : unit -> byref`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -288,6 +335,7 @@ let pinIt (thing: RefField<'T>) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -296,8 +344,10 @@ let pinIt (thing: RefField<'T>) = (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin type with method GetPinnableReference : unit -> inref`` () = + [] + [] + [] + let ``Pin type with method GetPinnableReference : unit -> inref`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -309,6 +359,7 @@ let pinIt (thing: RefField<'T>) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -317,8 +368,10 @@ let pinIt (thing: RefField<'T>) = (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin type with extension method GetPinnableReference : unit -> byref`` () = + [] + [] + [] + let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = Fsx """ open System.Runtime.CompilerServices open Microsoft.FSharp.NativeInterop @@ -334,6 +387,7 @@ let pinIt (thing: RefField<'T>) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -342,8 +396,10 @@ let pinIt (thing: RefField<'T>) = (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin type with method GetPinnableReference with parameters - illegal`` () = + [] + [] + [] + let ``Pin type with method GetPinnableReference with parameters - illegal`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -355,6 +411,7 @@ let pinIt (thing: StrangeType<'T>) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldFail @@ -363,8 +420,10 @@ let pinIt (thing: StrangeType<'T>) = (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] - [] - let ``Pin type with method GetPinnableReference with non-byref return type - illegal`` () = + [] + [] + [] + let ``Pin type with method GetPinnableReference with non-byref return type - illegal`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -376,6 +435,7 @@ let pinIt (thing: StrangeType<'T>) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldFail @@ -384,8 +444,10 @@ let pinIt (thing: StrangeType<'T>) = (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] - [] - let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` () = + [] + [] + [] + let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -399,6 +461,7 @@ let pinIt (thing: RefField<'T>) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldSucceed @@ -407,8 +470,10 @@ let pinIt (thing: RefField<'T>) = (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] - [] - let ``Pin type with private method GetPinnableReference - illegal`` () = + [] + [] + [] + let ``Pin type with private method GetPinnableReference - illegal`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -420,6 +485,7 @@ let pinIt (thing: StrangeType<'T>) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldFail @@ -428,8 +494,10 @@ let pinIt (thing: StrangeType<'T>) = (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] - [] - let ``Pin type with static method GetPinnableReference - illegal`` () = + [] + [] + [] + let ``Pin type with static method GetPinnableReference - illegal`` langVersion = Fsx """ open Microsoft.FSharp.NativeInterop @@ -441,6 +509,7 @@ let pinIt (thing: StrangeType<'T>) = use ptr = fixed thing NativePtr.get ptr 0 """ + |> withLangVersion langVersion |> ignoreWarnings |> typecheck |> shouldFail From 69281a67e7775573c3d57ade09fc216dffb82cbf Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 14:34:38 -0600 Subject: [PATCH 24/51] Add negative tests for fixed expr feature flagging --- .../Language/FixedExpressionTests.fs | 307 +++++++++++------- 1 file changed, 195 insertions(+), 112 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index 1aedc771573..7f1058b75c7 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -192,9 +192,9 @@ let pinIt<'a when 'a : unmanaged> (thing: 'a) = // FS-1081 - Extend fixed expressions module ExtendedFixedExpressions = [] - [] - [] - let ``Pin int byref parmeter`` langVersion = + [] + [] + let ``Pin int byref parmeter`` (langVersion, featureShouldActivate) = Fsx """ open Microsoft.FSharp.NativeInterop @@ -205,16 +205,22 @@ let pinIt (thing: byref) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail [] - [] - [] - let ``Pin int inref parmeter`` langVersion = + [] + [] + let ``Pin int inref parmeter`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -225,16 +231,22 @@ let pinIt (thing: inref) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail [] - [] - [] - let ``Pin int outref parmeter`` langVersion = + [] + [] + let ``Pin int outref parmeter`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -245,16 +257,22 @@ let pinIt (thing: outref) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail [] - [] - [] - let ``Pin int byref local variable`` langVersion = + [] + [] + let ``Pin int byref local variable`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -266,17 +284,23 @@ let pinIt () = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail #if NETCOREAPP [] - [] - [] - let ``Pin Span`` langVersion = + [] + [] + let ``Pin Span`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open System open Microsoft.FSharp.NativeInterop @@ -288,17 +312,23 @@ let pinIt (thing: Span) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail #endif [] - [] - [] - let ``Pin custom struct byref type without GetPinnableReference method - illegal`` langVersion = + [] + [] + let ``Pin custom struct byref type without GetPinnableReference method - illegal`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open System open System.Runtime.CompilerServices @@ -314,16 +344,22 @@ let pinIt (thing: BoringRefField) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) + else + shouldFail [] - [] - [] - let ``Pin type with method GetPinnableReference : unit -> byref`` langVersion = + [] + [] + let ``Pin type with method GetPinnableReference : unit -> byref`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -338,16 +374,22 @@ let pinIt (thing: RefField<'T>) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail [] - [] - [] - let ``Pin type with method GetPinnableReference : unit -> inref`` langVersion = + [] + [] + let ``Pin type with method GetPinnableReference : unit -> inref`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -362,16 +404,22 @@ let pinIt (thing: RefField<'T>) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail [] - [] - [] - let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = + [] + [] + let ``Pin type with extension method GetPinnableReference : unit -> byref`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open System.Runtime.CompilerServices open Microsoft.FSharp.NativeInterop @@ -390,16 +438,22 @@ let pinIt (thing: RefField<'T>) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail [] - [] - [] - let ``Pin type with method GetPinnableReference with parameters - illegal`` langVersion = + [] + [] + let ``Pin type with method GetPinnableReference with parameters - illegal`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -414,16 +468,22 @@ let pinIt (thing: StrangeType<'T>) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) + else + shouldFail [] - [] - [] - let ``Pin type with method GetPinnableReference with non-byref return type - illegal`` langVersion = + [] + [] + let ``Pin type with method GetPinnableReference with non-byref return type - illegal`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -438,16 +498,22 @@ let pinIt (thing: StrangeType<'T>) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) + else + shouldFail [] - [] - [] - let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` langVersion = + [] + [] + let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -464,16 +530,22 @@ let pinIt (thing: RefField<'T>) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail [] - [] - [] - let ``Pin type with private method GetPinnableReference - illegal`` langVersion = + [] + [] + let ``Pin type with private method GetPinnableReference - illegal`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -488,16 +560,22 @@ let pinIt (thing: StrangeType<'T>) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) + else + shouldFail [] - [] - [] - let ``Pin type with static method GetPinnableReference - illegal`` langVersion = + [] + [] + let ``Pin type with static method GetPinnableReference - illegal`` (langVersion, featureShouldActivate) = + featureShouldActivate |> ignore Fsx """ open Microsoft.FSharp.NativeInterop @@ -512,8 +590,13 @@ let pinIt (thing: StrangeType<'T>) = |> withLangVersion langVersion |> ignoreWarnings |> typecheck - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ] + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) + else + shouldFail From f827244fcfbd5bf48a078ad04a0f46556e1c2fc5 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 16:11:38 -0600 Subject: [PATCH 25/51] Make extended fixed bindings obey feature flag --- src/Compiler/Checking/CheckExpressions.fs | 35 ++++++++++++----------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index f9efb5e5a9c..e24b1826127 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10265,23 +10265,24 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy let g = cenv.g warning(PossibleUnverifiableCode mBinding) - + + let activateExtendedFixedBindings = g.langVersion.SupportsFeature LanguageFeature.ExtendedFixedBindings + match overallExprTy with | ty when isByrefTy g ty -> - // let okByRef = - // match stripDebugPoints (stripExpr fixedExpr) with - // | Expr.Op (op, tyargs, args, _) -> - // match op, tyargs, args with - // | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon - // | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject - // | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true - // | TOp.RefAddrGet _, _, _ -> true - // | TOp.LValueOp (LValueOperation.LAddrOf _, _), _, _ -> true - // | _ -> false - // | Expr.Val _ -> true - // | _ -> false - // if not okByRef then - // error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + if not activateExtendedFixedBindings then + let okByRef = + match stripDebugPoints (stripExpr fixedExpr) with + | Expr.Op (op, tyargs, args, _) -> + match op, tyargs, args with + | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon + | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject + | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true + | TOp.RefAddrGet _, _, _ -> true + | _ -> false + | _ -> false + if not okByRef then + error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) let elemTy = destByrefTy g overallExprTy UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy @@ -10336,7 +10337,7 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy zero) zero) - | _ -> + | _ when activateExtendedFixedBindings -> let getPinnableReferenceMInfo = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env mBinding env.eAccessRights "GetPinnableReference" overallExprTy @@ -10360,6 +10361,8 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy mkConvToNativeInt g ve mBinding) | None -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + + | _ -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) /// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and From 2e0826004c5bd028fabdf763abb067412613b075 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 16:26:36 -0600 Subject: [PATCH 26/51] Add a test case highlighting a new (fixed?) behavior --- .../EmittedIL/FixedExpressionTests.fs | 2 +- .../Language/FixedExpressionTests.fs | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 56e033f6593..c0cc01b0516 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -283,7 +283,7 @@ if x <> xCopy then failwith "xCopy was not the same as x" IL_000f: add IL_0010: ldobj [runtime]System.Int32 IL_0015: ret - } """] + } """ ] [] let ``Pin int byref of local variable`` langVersion = diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index 7f1058b75c7..3a489977fbe 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -268,6 +268,36 @@ let pinIt (thing: outref) = else shouldFail + [] + [] + [] + let ``Pin address of explicit field on this with default constructor class syntax`` (langVersion, featureShouldActivate) = + // I think F# 7 and lower should have allowed this and that this was really just a bug, but we should preserve the existing behavior + // when turning the feature off + Fsx """ +open Microsoft.FSharp.NativeInterop + +type Point() = + let mutable value = 42 + + member this.PinIt() = + let ptr = fixed &value + NativePtr.get ptr 0 +""" + |> withLangVersion langVersion + |> ignoreWarnings + |> typecheck + |> if featureShouldActivate then + (fun comp -> + comp + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 8, Col 13, Line 8, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 9, Col 9, Line 9, Col 22, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ]) + else + shouldFail + [] [] [] From 79817cae343064fbcdd1aceaa751c41a29dcf25b Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 17:28:37 -0600 Subject: [PATCH 27/51] Raise FS3350 (feature unavailable) when necessary for fixed bindings --- src/Compiler/Checking/CheckExpressions.fs | 33 +++-- src/Compiler/FSComp.txt | 2 +- src/Compiler/xlf/FSComp.txt.cs.xlf | 4 +- src/Compiler/xlf/FSComp.txt.de.xlf | 4 +- src/Compiler/xlf/FSComp.txt.es.xlf | 4 +- src/Compiler/xlf/FSComp.txt.fr.xlf | 4 +- src/Compiler/xlf/FSComp.txt.it.xlf | 4 +- src/Compiler/xlf/FSComp.txt.ja.xlf | 4 +- src/Compiler/xlf/FSComp.txt.ko.xlf | 4 +- src/Compiler/xlf/FSComp.txt.pl.xlf | 4 +- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 4 +- src/Compiler/xlf/FSComp.txt.ru.xlf | 4 +- src/Compiler/xlf/FSComp.txt.tr.xlf | 4 +- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 4 +- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 4 +- .../Language/FixedExpressionTests.fs | 119 +++++++++++++++--- 16 files changed, 146 insertions(+), 60 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index e24b1826127..be6e1863afe 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10266,23 +10266,20 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy warning(PossibleUnverifiableCode mBinding) - let activateExtendedFixedBindings = g.langVersion.SupportsFeature LanguageFeature.ExtendedFixedBindings - match overallExprTy with | ty when isByrefTy g ty -> - if not activateExtendedFixedBindings then - let okByRef = - match stripDebugPoints (stripExpr fixedExpr) with - | Expr.Op (op, tyargs, args, _) -> - match op, tyargs, args with - | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon - | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject - | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true - | TOp.RefAddrGet _, _, _ -> true - | _ -> false - | _ -> false - if not okByRef then - error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + let okByRef = + match stripDebugPoints (stripExpr fixedExpr) with + | Expr.Op (op, tyargs, args, _) -> + match op, tyargs, args with + | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon + | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject + | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true + | TOp.RefAddrGet _, _, _ -> true + | _ -> false + | _ -> false + if not okByRef then + checkLanguageFeatureError g.langVersion LanguageFeature.ExtendedFixedBindings mBinding let elemTy = destByrefTy g overallExprTy UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy @@ -10337,7 +10334,7 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy zero) zero) - | _ when activateExtendedFixedBindings -> + | _ -> let getPinnableReferenceMInfo = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env mBinding env.eAccessRights "GetPinnableReference" overallExprTy @@ -10350,6 +10347,8 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy match getPinnableReferenceMInfo with | Some mInfo -> + checkLanguageFeatureError g.langVersion LanguageFeature.ExtendedFixedBindings mBinding + let mInst = FreshenMethInfo mBinding mInfo let pinnableReference, actualRetTy = BuildPossiblyConditionalMethodCall cenv env NeverMutates mBinding false mInfo NormalValUse mInst [ fixedExpr ] [] None @@ -10361,8 +10360,6 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy mkConvToNativeInt g ve mBinding) | None -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) - - | _ -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) /// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 397401ce98f..ccc87fc1c98 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1579,7 +1579,7 @@ featureImprovedImpliedArgumentNames,"Improved implied argument names" featureStrictIndentation,"Raises errors on incorrect indentation, allows better recovery and analysis during editing" featureChkNotTailRecursive,"Raises warnings if a member or function has the 'TailCall' attribute, but is not being used in a tail recursive way." featureWhileBang,"'while!' expression" -featureExtendedFixedBindings,"Extends fixed expressions to byrefs, inrefs, and GetPinnableReference()." +featureExtendedFixedBindings,"extended fixed expressions for byrefs, inrefs, and GetPinnableReference" 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 9129a503e5e..a27a68cb59a 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 0ce2c908def..0d6d1af9366 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 047c28e9f50..c3ae8b570ef 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index afc7c2165fc..cf4772eed14 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index b84b7da9db6..6f1d2639dfb 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index f6c2240d51c..56d3f54536a 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 71faf2a4fa8..2c1eab96f6d 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 92d7a9e5881..f8f1b053556 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 581e87a31ca..cdf250d0b54 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index db428173485..efc3985bdcc 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index a3301960763..117195d0bef 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 0dbd6463878..6e27d291c01 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 59c7bcb9e74..1aedb4d9f1d 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -268,8 +268,8 @@ - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). - Extends fixed expressions to byrefs, inrefs, and GetPinnableReference(). + extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed expressions for byrefs, inrefs, and GetPinnableReference diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs index 3a489977fbe..44df5b3bcc0 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs @@ -214,7 +214,13 @@ let pinIt (thing: byref) = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ]) [] [] @@ -240,7 +246,13 @@ let pinIt (thing: inref) = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ]) [] [] @@ -266,7 +278,13 @@ let pinIt (thing: outref) = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ]) [] [] @@ -296,7 +314,13 @@ type Point() = (Warning 9, Line 9, Col 9, Line 9, Col 22, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 8, Col 13, Line 8, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 8, Col 13, Line 8, Col 16, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ]) [] [] @@ -323,7 +347,13 @@ let pinIt () = (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ]) #if NETCOREAPP [] @@ -351,7 +381,13 @@ let pinIt (thing: Span) = (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'."""); + (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ]) #endif [] @@ -383,7 +419,13 @@ let pinIt (thing: BoringRefField) = (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) [] [] @@ -413,7 +455,12 @@ let pinIt (thing: RefField<'T>) = (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")]) [] [] @@ -443,7 +490,13 @@ let pinIt (thing: RefField<'T>) = (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ]) [] [] @@ -477,7 +530,13 @@ let pinIt (thing: RefField<'T>) = (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ]) [] [] @@ -507,7 +566,13 @@ let pinIt (thing: StrangeType<'T>) = (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) [] [] @@ -537,7 +602,13 @@ let pinIt (thing: StrangeType<'T>) = (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) [] [] @@ -569,7 +640,13 @@ let pinIt (thing: RefField<'T>) = (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 11, Col 9, Line 11, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")] + ) [] [] @@ -599,7 +676,13 @@ let pinIt (thing: StrangeType<'T>) = (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) [] [] @@ -629,4 +712,10 @@ let pinIt (thing: StrangeType<'T>) = (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ]) else - shouldFail + (fun comp -> + comp + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ]) From 1e4b10b7f332b592892c20c63f6f187960ed97ef Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Fri, 28 Jul 2023 23:48:03 -0600 Subject: [PATCH 28/51] Use GetPinnableReference method on strings when available --- src/Compiler/Checking/CheckExpressions.fs | 90 +++++++++++-------- src/Compiler/FSComp.txt | 1 + src/Compiler/Facilities/LanguageFeatures.fs | 3 + src/Compiler/Facilities/LanguageFeatures.fsi | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 ++ .../EmittedIL/FixedExpressionTests.fs | 55 ++++++++++-- 18 files changed, 172 insertions(+), 43 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index be6e1863afe..9fd6af12be1 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10264,6 +10264,33 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy let g = cenv.g + let tryBuildGetPinnableReferenceCall () = + let getPinnableReferenceMInfo = + TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env mBinding env.eAccessRights "GetPinnableReference" overallExprTy + |> List.tryFind (fun mInfo -> + // GetPinnableReference must be a parameterless method with a byref or inref return value + match mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst), mInfo.GetFSharpReturnType(cenv.amap, mBinding, mInfo.FormalMethodInst) with + | [[]], retTy when isByrefTy g retTy && mInfo.IsInstance -> true + | _ -> false + ) + + match getPinnableReferenceMInfo with + | Some mInfo -> + checkLanguageFeatureError g.langVersion LanguageFeature.ExtendedFixedBindings mBinding + + let mInst = FreshenMethInfo mBinding mInfo + let pinnableReference, actualRetTy = BuildPossiblyConditionalMethodCall cenv env NeverMutates mBinding false mInfo NormalValUse mInst [ fixedExpr ] [] None + + let elemTy = destByrefTy g actualRetTy + UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy + + Some ( + mkCompGenLetIn mBinding "pinnedByref" actualRetTy pinnableReference (fun (v, ve) -> + v.SetIsFixed() + mkConvToNativeInt g ve mBinding)) + | None -> + None + warning(PossibleUnverifiableCode mBinding) match overallExprTy with @@ -10288,20 +10315,29 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy mkConvToNativeInt g ve mBinding) | ty when isStringTy g ty -> - let charPtrTy = mkNativePtrTy g g.char_ty - UnifyTypes cenv env mBinding charPtrTy overallPatTy - // - // let ptr: nativeptr = - // let pinned s = str - // (nativeptr)s + get_OffsettoStringData() + let getPinnableRefCall = + if g.langVersion.SupportsFeature LanguageFeature.PreferStringGetPinnableReference then + tryBuildGetPinnableReferenceCall () + else + None + + match getPinnableRefCall with + | Some expr -> expr + | None -> + let charPtrTy = mkNativePtrTy g g.char_ty + UnifyTypes cenv env mBinding charPtrTy overallPatTy + // + // let ptr: nativeptr = + // let pinned s = str + // (nativeptr)s + get_OffsettoStringData() - mkCompGenLetIn mBinding "pinnedString" g.string_ty fixedExpr (fun (v, ve) -> - v.SetIsFixed() - let addrOffset = BuildOffsetToStringData cenv env mBinding - let stringAsNativeInt = mkConvToNativeInt g ve mBinding - let plusOffset = Expr.Op (TOp.ILAsm ([ AI_add ], [ g.nativeint_ty ]), [], [stringAsNativeInt; addrOffset], mBinding) - // check for non-null - mkNullTest g mBinding ve plusOffset ve) + mkCompGenLetIn mBinding "pinnedString" g.string_ty fixedExpr (fun (v, ve) -> + v.SetIsFixed() + let addrOffset = BuildOffsetToStringData cenv env mBinding + let stringAsNativeInt = mkConvToNativeInt g ve mBinding + let plusOffset = Expr.Op (TOp.ILAsm ([ AI_add ], [ g.nativeint_ty ]), [], [stringAsNativeInt; addrOffset], mBinding) + // check for non-null + mkNullTest g mBinding ve plusOffset ve) | ty when isArray1DTy g ty -> let elemTy = destArrayTy g overallExprTy @@ -10335,31 +10371,9 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy zero) | _ -> - - let getPinnableReferenceMInfo = - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env mBinding env.eAccessRights "GetPinnableReference" overallExprTy - |> List.tryFind (fun mInfo -> - // GetPinnableReference must be a parameterless method with a byref or inref return value - match mInfo.GetParamDatas(cenv.amap, mBinding, mInfo.FormalMethodInst), mInfo.GetFSharpReturnType(cenv.amap, mBinding, mInfo.FormalMethodInst) with - | [[]], retTy when isByrefTy g retTy && mInfo.IsInstance -> true - | _ -> false - ) - - match getPinnableReferenceMInfo with - | Some mInfo -> - checkLanguageFeatureError g.langVersion LanguageFeature.ExtendedFixedBindings mBinding - - let mInst = FreshenMethInfo mBinding mInfo - let pinnableReference, actualRetTy = BuildPossiblyConditionalMethodCall cenv env NeverMutates mBinding false mInfo NormalValUse mInst [ fixedExpr ] [] None - - let elemTy = destByrefTy g actualRetTy - UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy - - mkCompGenLetIn mBinding "pinnedByref" actualRetTy pinnableReference (fun (v, ve) -> - v.SetIsFixed() - mkConvToNativeInt g ve mBinding) - | None -> - error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + match tryBuildGetPinnableReferenceCall () with + | Some expr -> expr + | None -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) /// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index ccc87fc1c98..e3d2a226cfb 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1580,6 +1580,7 @@ featureStrictIndentation,"Raises errors on incorrect indentation, allows better featureChkNotTailRecursive,"Raises warnings if a member or function has the 'TailCall' attribute, but is not being used in a tail recursive way." featureWhileBang,"'while!' expression" featureExtendedFixedBindings,"extended fixed expressions for byrefs, inrefs, and GetPinnableReference" +featurePreferStringGetPinnableReference,"prefer String.GetPinnableReference in fixed bindings" 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 2094037a6e7..d95cc8a4e66 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -76,6 +76,7 @@ type LanguageFeature = | WarningWhenTailRecAttributeButNonTailRecUsage | WhileBang | ExtendedFixedBindings + | PreferStringGetPinnableReference /// LanguageVersion management type LanguageVersion(versionText) = @@ -175,6 +176,7 @@ type LanguageVersion(versionText) = LanguageFeature.StrictIndentation, previewVersion LanguageFeature.WhileBang, previewVersion LanguageFeature.ExtendedFixedBindings, previewVersion + LanguageFeature.PreferStringGetPinnableReference, previewVersion ] static let defaultLanguageVersion = LanguageVersion("default") @@ -306,6 +308,7 @@ type LanguageVersion(versionText) = | LanguageFeature.WarningWhenTailRecAttributeButNonTailRecUsage -> FSComp.SR.featureChkNotTailRecursive () | LanguageFeature.WhileBang -> FSComp.SR.featureWhileBang () | LanguageFeature.ExtendedFixedBindings -> FSComp.SR.featureExtendedFixedBindings () + | LanguageFeature.PreferStringGetPinnableReference -> FSComp.SR.featurePreferStringGetPinnableReference () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index ae601aaceb2..e4ca06ffe8b 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -66,6 +66,7 @@ type LanguageFeature = | WarningWhenTailRecAttributeButNonTailRecUsage | WhileBang | ExtendedFixedBindings + | PreferStringGetPinnableReference /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index a27a68cb59a..5e3f810b9fd 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -377,6 +377,11 @@ správa balíčků + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers formátování typu binary pro integery diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 0d6d1af9366..71b989a5494 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -377,6 +377,11 @@ Paketverwaltung + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers binäre Formatierung für ganze Zahlen diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index c3ae8b570ef..11eb283f8c1 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -377,6 +377,11 @@ administración de paquetes + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers formato binario para enteros diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index cf4772eed14..a6e84f4a60b 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -377,6 +377,11 @@ Package Management + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers mise en forme binaire pour les entiers diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 6f1d2639dfb..e7416fe478e 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -377,6 +377,11 @@ gestione pacchetti + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers formattazione binaria per interi diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 56d3f54536a..52bf054a970 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -377,6 +377,11 @@ パッケージの管理 + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers 整数のバイナリ形式 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 2c1eab96f6d..a6ee407cdbc 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -377,6 +377,11 @@ 패키지 관리 + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers 정수에 대한 이진 서식 지정 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index f8f1b053556..68da1b2d13a 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -377,6 +377,11 @@ zarządzanie pakietami + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers formatowanie danych binarnych dla liczb całkowitych diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index cdf250d0b54..6b9a713a70b 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -377,6 +377,11 @@ gerenciamento de pacotes + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers formatação binária para números inteiros diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index efc3985bdcc..0d9b366dc5a 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -377,6 +377,11 @@ управление пакетами + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers двоичное форматирование для целых чисел diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 117195d0bef..a80caa00b86 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -377,6 +377,11 @@ paket yönetimi + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers tamsayılar için ikili biçim diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 6e27d291c01..6a9d5b2f53c 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -377,6 +377,11 @@ 包管理 + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers 整数的二进制格式设置 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 1aedb4d9f1d..f916389fed0 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -377,6 +377,11 @@ 套件管理 + + prefer String.GetPinnableReference in fixed bindings + prefer String.GetPinnableReference in fixed bindings + + binary formatting for integers 整數的二進位格式化 diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index c0cc01b0516..cfbc27a03f6 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -1,5 +1,6 @@ namespace EmittedIL.FixedExpressionTests +open System.Reflection open Xunit open FSharp.Compiler.Diagnostics open FSharp.Test @@ -8,9 +9,20 @@ open FSharp.Test.Compiler module Legacy = [] - [] - [] - let ``Pin naked string`` langVersion = + [] + [] + let ``Pin naked string`` (langVersion, featureShouldActivate) = + let runtimeSupportsStringGetPinnableReference = + typeof.GetMethods() + |> Seq.exists (fun m -> m.Name = "GetPinnableReference") + +// Sanity check precondition: if .Net Framework were to ever get GetPinnableReference, we'll know here +#if NETCOREAPP3_0_OR_GREATER + Assert.True(runtimeSupportsStringGetPinnableReference) +#else + Assert.False(runtimeSupportsStringGetPinnableReference) +#endif + FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop @@ -22,7 +34,35 @@ let pinIt (str: string) = |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compile - |> verifyIL [""" + |> if featureShouldActivate && runtimeSupportsStringGetPinnableReference then + (fun comp -> + comp + |> verifyIL [""" + .method public static char pinIt(string str) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + char& pinned V_1) + IL_0000: ldarg.0 + IL_0001: callvirt instance char& modreq([runtime]System.Runtime.InteropServices.InAttribute) [runtime]System.String::GetPinnableReference() + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: conv.i + IL_0009: stloc.0 + IL_000a: ldloc.0 + IL_000b: ldc.i4.0 + IL_000c: conv.i + IL_000d: sizeof [runtime]System.Char + IL_0013: mul + IL_0014: add + IL_0015: ldobj [runtime]System.Char + IL_001a: ret + } """ ]) + else + (fun comp -> + comp + |> verifyIL [""" .method public static char pinIt(string str) cil managed { @@ -50,7 +90,7 @@ let pinIt (str: string) = IL_001b: add IL_001c: ldobj [runtime]System.Char IL_0021: ret - }""" ] + } """ ]) [] [] @@ -843,3 +883,8 @@ let main _ = IL_0015: ldobj !!a IL_001a: ret } """ ] + + // let runtimeHasStringGetPinnableReference = + // let strType = typeof + // strType. + // () From 1ecf841888594a1687ff5cd6110c6fe151cf64d5 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Sat, 29 Jul 2023 00:05:59 -0600 Subject: [PATCH 29/51] Prevent method inlining to make tests clearer --- .../EmittedIL/FixedExpressionTests.fs | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index cfbc27a03f6..05597d28da8 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -349,7 +349,7 @@ pinIt 100 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" -.method public static void pinIt(int32 x) cil managed + .method public static void pinIt(int32 x) cil managed { .maxstack 5 @@ -527,11 +527,13 @@ let main _ = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop +open System.Runtime.CompilerServices open System type RefField<'T>(_value) = let mutable _value = _value member this.Value = _value + [] member this.GetPinnableReference () : byref<'T> = &_value let pinIt (thing: RefField) = @@ -557,7 +559,7 @@ let main _ = .locals init (native int V_0, int32& pinned V_1) IL_0000: ldarg.0 - IL_0001: ldflda !0 class FixedExpressions/RefField`1::_value@7 + IL_0001: callvirt instance !0& class FixedExpressions/RefField`1::GetPinnableReference() IL_0006: stloc.1 IL_0007: ldloc.1 IL_0008: conv.i @@ -577,11 +579,13 @@ let main _ = FSharp """ module FixedExpressions open Microsoft.FSharp.NativeInterop +open System.Runtime.CompilerServices open System type ReadonlyRefField<'T>(_value) = let mutable _value = _value member this.Value = _value + [] member this.GetPinnableReference () : inref<'T> = &_value let pinIt (thing: ReadonlyRefField) = @@ -607,7 +611,7 @@ let main _ = .locals init (native int V_0, int32& pinned V_1) IL_0000: ldarg.0 - IL_0001: ldflda !0 class FixedExpressions/ReadonlyRefField`1::_value@7 + IL_0001: callvirt instance !0& modreq([runtime]System.Runtime.InteropServices.InAttribute) class FixedExpressions/ReadonlyRefField`1::GetPinnableReference() IL_0006: stloc.1 IL_0007: ldloc.1 IL_0008: conv.i @@ -640,6 +644,7 @@ type ArrayElementRef<'T> = raise (ArgumentOutOfRangeException(nameof(index), "")) { Values = values; Index = index } member this.Value = this.Values[this.Index] + [] member this.GetPinnableReference () : byref<'T> = &this.Values[this.Index] let pinIt (thing: ArrayElementRef<'a>) = @@ -666,22 +671,19 @@ let main _ = .locals init (native int V_0, !!a& pinned V_1) IL_0000: ldarga.s thing - IL_0002: ldfld !0[] valuetype FixedExpressions/ArrayElementRef`1::Values@ - IL_0007: ldarga.s thing - IL_0009: ldfld int32 valuetype FixedExpressions/ArrayElementRef`1::Index@ - IL_000e: ldelema !!a - IL_0013: stloc.1 - IL_0014: ldloc.1 - IL_0015: conv.i - IL_0016: stloc.0 - IL_0017: ldloc.0 - IL_0018: ldc.i4.0 - IL_0019: conv.i - IL_001a: sizeof !!a - IL_0020: mul - IL_0021: add - IL_0022: ldobj !!a - IL_0027: ret + IL_0002: call instance !0& valuetype FixedExpressions/ArrayElementRef`1::GetPinnableReference() + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: conv.i + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldc.i4.0 + IL_000d: conv.i + IL_000e: sizeof !!a + IL_0014: mul + IL_0015: add + IL_0016: ldobj !!a + IL_001b: ret } """ ] [] @@ -835,14 +837,14 @@ let main _ = let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = Fsx """ module FixedExpressions -open System.Runtime.CompilerServices open Microsoft.FSharp.NativeInterop +open System.Runtime.CompilerServices type RefField<'T> = { mutable _value: 'T } [] type RefFieldExtensions = - [] + [] static member GetPinnableReference(refField: RefField<'T>) : byref<'T> = &refField._value let pinIt (thing: RefField<'T>) = @@ -869,7 +871,7 @@ let main _ = .locals init (native int V_0, !!a& pinned V_1) IL_0000: ldarg.0 - IL_0001: ldflda !0 class FixedExpressions/RefField`1::_value@ + IL_0001: call !!0& FixedExpressions/RefFieldExtensions::GetPinnableReference(class FixedExpressions/RefField`1) IL_0006: stloc.1 IL_0007: ldloc.1 IL_0008: conv.i @@ -883,8 +885,3 @@ let main _ = IL_0015: ldobj !!a IL_001a: ret } """ ] - - // let runtimeHasStringGetPinnableReference = - // let strType = typeof - // strType. - // () From 76479904abac1904060c97cf666f03008aef92be Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Sat, 29 Jul 2023 01:36:41 -0600 Subject: [PATCH 30/51] Add a generated null check for reference types --- src/Compiler/Checking/CheckExpressions.fs | 31 +++- .../EmittedIL/FixedExpressionTests.fs | 160 +++++++++++------- 2 files changed, 122 insertions(+), 69 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 9fd6af12be1..8cf267508f8 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10264,6 +10264,8 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy let g = cenv.g + // Search for GetPinnableReference (like https://learn.microsoft.com/en-us/dotnet/api/system.span-1.getpinnablereference?view=net-7.0) + // on the target expression, and, if it exists, call it let tryBuildGetPinnableReferenceCall () = let getPinnableReferenceMInfo = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env mBinding env.eAccessRights "GetPinnableReference" overallExprTy @@ -10284,10 +10286,31 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy let elemTy = destByrefTy g actualRetTy UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy - Some ( - mkCompGenLetIn mBinding "pinnedByref" actualRetTy pinnableReference (fun (v, ve) -> - v.SetIsFixed() - mkConvToNativeInt g ve mBinding)) + // For value types: + // let ptr: nativeptr = + // let pinned x = &(expr: 'a).GetPinnableReference() + // (nativeint) x + + // For reference types: + // let ptr: nativeptr = + // if isNull expr then + // expr + // else + // let pinned x = &(expr: 'a).GetPinnableReference() + // (nativeint) x + + if isStructTy g overallExprTy then + Some ( + mkCompGenLetIn mBinding "pinnedByref" actualRetTy pinnableReference (fun (v, ve) -> + v.SetIsFixed() + mkConvToNativeInt g ve mBinding)) + else + Some ( + mkNullTest g mBinding fixedExpr ( + mkCompGenLetIn mBinding "pinnedByref" actualRetTy pinnableReference (fun (v, ve) -> + v.SetIsFixed() + mkConvToNativeInt g ve mBinding)) + fixedExpr) | None -> None diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index 05597d28da8..b88b218bb61 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -45,19 +45,25 @@ let pinIt (str: string) = .locals init (native int V_0, char& pinned V_1) IL_0000: ldarg.0 - IL_0001: callvirt instance char& modreq([runtime]System.Runtime.InteropServices.InAttribute) [runtime]System.String::GetPinnableReference() - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: conv.i - IL_0009: stloc.0 - IL_000a: ldloc.0 - IL_000b: ldc.i4.0 - IL_000c: conv.i - IL_000d: sizeof [runtime]System.Char - IL_0013: mul - IL_0014: add - IL_0015: ldobj [runtime]System.Char - IL_001a: ret + IL_0001: brfalse.s IL_000e + + IL_0003: ldarg.0 + IL_0004: callvirt instance char& modreq([runtime]System.Runtime.InteropServices.InAttribute) [runtime]System.String::GetPinnableReference() + IL_0009: stloc.1 + IL_000a: ldloc.1 + IL_000b: conv.i + IL_000c: br.s IL_000f + + IL_000e: ldarg.0 + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: ldc.i4.0 + IL_0012: conv.i + IL_0013: sizeof [runtime]System.Char + IL_0019: mul + IL_001a: add + IL_001b: ldobj [runtime]System.Char + IL_0020: ret } """ ]) else (fun comp -> @@ -559,19 +565,25 @@ let main _ = .locals init (native int V_0, int32& pinned V_1) IL_0000: ldarg.0 - IL_0001: callvirt instance !0& class FixedExpressions/RefField`1::GetPinnableReference() - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: conv.i - IL_0009: stloc.0 - IL_000a: ldloc.0 - IL_000b: ldc.i4.0 - IL_000c: conv.i - IL_000d: sizeof [runtime]System.Int32 - IL_0013: mul - IL_0014: add - IL_0015: ldobj [runtime]System.Int32 - IL_001a: ret + IL_0001: brfalse.s IL_000e + + IL_0003: ldarg.0 + IL_0004: callvirt instance !0& class FixedExpressions/RefField`1::GetPinnableReference() + IL_0009: stloc.1 + IL_000a: ldloc.1 + IL_000b: conv.i + IL_000c: br.s IL_000f + + IL_000e: ldarg.0 + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: ldc.i4.0 + IL_0012: conv.i + IL_0013: sizeof [runtime]System.Int32 + IL_0019: mul + IL_001a: add + IL_001b: ldobj [runtime]System.Int32 + IL_0020: ret } """ ] [] @@ -611,19 +623,25 @@ let main _ = .locals init (native int V_0, int32& pinned V_1) IL_0000: ldarg.0 - IL_0001: callvirt instance !0& modreq([runtime]System.Runtime.InteropServices.InAttribute) class FixedExpressions/ReadonlyRefField`1::GetPinnableReference() - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: conv.i - IL_0009: stloc.0 - IL_000a: ldloc.0 - IL_000b: ldc.i4.0 - IL_000c: conv.i - IL_000d: sizeof [runtime]System.Int32 - IL_0013: mul - IL_0014: add - IL_0015: ldobj [runtime]System.Int32 - IL_001a: ret + IL_0001: brfalse.s IL_000e + + IL_0003: ldarg.0 + IL_0004: callvirt instance !0& modreq([runtime]System.Runtime.InteropServices.InAttribute) class FixedExpressions/ReadonlyRefField`1::GetPinnableReference() + IL_0009: stloc.1 + IL_000a: ldloc.1 + IL_000b: conv.i + IL_000c: br.s IL_000f + + IL_000e: ldarg.0 + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: ldc.i4.0 + IL_0012: conv.i + IL_0013: sizeof [runtime]System.Int32 + IL_0019: mul + IL_001a: add + IL_001b: ldobj [runtime]System.Int32 + IL_0020: ret } """ ] [] @@ -741,19 +759,25 @@ let main _ = .locals init (native int V_0, int32& pinned V_1) IL_0000: ldarg.0 - IL_0001: callvirt instance !0& class [CsLib]PinnableReference`1::GetPinnableReference() - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: conv.i - IL_0009: stloc.0 - IL_000a: ldloc.0 - IL_000b: ldc.i4.0 - IL_000c: conv.i - IL_000d: sizeof [runtime]System.Int32 - IL_0013: mul - IL_0014: add - IL_0015: ldobj [runtime]System.Int32 - IL_001a: ret + IL_0001: brfalse.s IL_000e + + IL_0003: ldarg.0 + IL_0004: callvirt instance !0& class [CsLib]PinnableReference`1::GetPinnableReference() + IL_0009: stloc.1 + IL_000a: ldloc.1 + IL_000b: conv.i + IL_000c: br.s IL_000f + + IL_000e: ldarg.0 + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: ldc.i4.0 + IL_0012: conv.i + IL_0013: sizeof [runtime]System.Int32 + IL_0019: mul + IL_001a: add + IL_001b: ldobj [runtime]System.Int32 + IL_0020: ret } """ ] #if NETCOREAPP @@ -871,17 +895,23 @@ let main _ = .locals init (native int V_0, !!a& pinned V_1) IL_0000: ldarg.0 - IL_0001: call !!0& FixedExpressions/RefFieldExtensions::GetPinnableReference(class FixedExpressions/RefField`1) - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: conv.i - IL_0009: stloc.0 - IL_000a: ldloc.0 - IL_000b: ldc.i4.0 - IL_000c: conv.i - IL_000d: sizeof !!a - IL_0013: mul - IL_0014: add - IL_0015: ldobj !!a - IL_001a: ret + IL_0001: brfalse.s IL_000e + + IL_0003: ldarg.0 + IL_0004: call !!0& FixedExpressions/RefFieldExtensions::GetPinnableReference(class FixedExpressions/RefField`1) + IL_0009: stloc.1 + IL_000a: ldloc.1 + IL_000b: conv.i + IL_000c: br.s IL_000f + + IL_000e: ldarg.0 + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: ldc.i4.0 + IL_0012: conv.i + IL_0013: sizeof !!a + IL_0019: mul + IL_001a: add + IL_001b: ldobj !!a + IL_0020: ret } """ ] From 1ca84854fe0394b42f7a1f7a22e20e56c567ee84 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Sat, 29 Jul 2023 01:39:29 -0600 Subject: [PATCH 31/51] Refactor --- src/Compiler/Checking/CheckExpressions.fs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 8cf267508f8..b113fe8d35e 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10294,23 +10294,20 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy // For reference types: // let ptr: nativeptr = // if isNull expr then - // expr + // (nativeint) expr // else // let pinned x = &(expr: 'a).GetPinnableReference() // (nativeint) x + let pinnedBinding = + mkCompGenLetIn mBinding "pinnedByref" actualRetTy pinnableReference (fun (v, ve) -> + v.SetIsFixed() + mkConvToNativeInt g ve mBinding) + if isStructTy g overallExprTy then - Some ( - mkCompGenLetIn mBinding "pinnedByref" actualRetTy pinnableReference (fun (v, ve) -> - v.SetIsFixed() - mkConvToNativeInt g ve mBinding)) + Some pinnedBinding else - Some ( - mkNullTest g mBinding fixedExpr ( - mkCompGenLetIn mBinding "pinnedByref" actualRetTy pinnableReference (fun (v, ve) -> - v.SetIsFixed() - mkConvToNativeInt g ve mBinding)) - fixedExpr) + Some (mkNullTest g mBinding fixedExpr pinnedBinding fixedExpr) | None -> None From 8cb46a43ee89b7a37826405193de229f5c8a3bb9 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Mon, 31 Jul 2023 18:20:01 -0600 Subject: [PATCH 32/51] Fix baselines --- .../EmittedIL/FixedExpressionTests.fs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs index b88b218bb61..6015103af3f 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs @@ -505,8 +505,10 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static !!a pinIt(valuetype [runtime]System.ReadOnlySpan`1 thing) cil managed + .method public static !!a pinIt(valuetype [runtime]System.ReadOnlySpan`1 thing) cil managed { + .param type a + .custom instance void System.Runtime.CompilerServices.IsUnmanagedAttribute::.ctor() = ( 01 00 00 00 ) .maxstack 5 .locals init (native int V_0, @@ -682,8 +684,10 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static !!a pinIt(valuetype FixedExpressions/ArrayElementRef`1 thing) cil managed + .method public static !!a pinIt(valuetype FixedExpressions/ArrayElementRef`1 thing) cil managed { + .param type a + .custom instance void System.Runtime.CompilerServices.IsUnmanagedAttribute::.ctor() = ( 01 00 00 00 ) .maxstack 5 .locals init (native int V_0, @@ -888,8 +892,10 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static !!a pinIt(class FixedExpressions/RefField`1 thing) cil managed + .method public static !!a pinIt(class FixedExpressions/RefField`1 thing) cil managed { + .param type a + .custom instance void System.Runtime.CompilerServices.IsUnmanagedAttribute::.ctor() = ( 01 00 00 00 ) .maxstack 5 .locals init (native int V_0, From 6de6e007fbfd4b5635ed834b12c63f7a4690c60c Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 9 Aug 2023 17:11:40 -0600 Subject: [PATCH 33/51] Rewrite to increase comprehensibility, and add some clarifying comments --- src/Compiler/Checking/CheckExpressions.fs | 16 ++++++++++------ src/Compiler/Facilities/DiagnosticsLogger.fs | 11 +++++++---- src/Compiler/Facilities/DiagnosticsLogger.fsi | 2 ++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 868b17135d1..705b43f062f 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10361,18 +10361,22 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy match overallExprTy with | ty when isByrefTy g ty -> - let okByRef = - match stripDebugPoints (stripExpr fixedExpr) with - | Expr.Op (op, tyargs, args, _) -> + // Feature ExtendedFixedBindings allows *any* byref to be used with fixed bindings, whereas the old logic only allowed a specific + // subset. This preserves the old logic when the feature is turned off. + if not (g.langVersion.SupportsFeature LanguageFeature.ExtendedFixedBindings) then + let okByRef = + match stripDebugPoints (stripExpr fixedExpr) with + | Expr.Op (op, tyargs, args, _) -> match op, tyargs, args with | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true | TOp.RefAddrGet _, _, _ -> true | _ -> false - | _ -> false - if not okByRef then - checkLanguageFeatureError g.langVersion LanguageFeature.ExtendedFixedBindings mBinding + | _ -> false + + if not okByRef then + error (languageFeatureError g.langVersion LanguageFeature.ExtendedFixedBindings mBinding) let elemTy = destByrefTy g overallExprTy UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fs b/src/Compiler/Facilities/DiagnosticsLogger.fs index ef90d556a2b..e8d2cf724e3 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fs +++ b/src/Compiler/Facilities/DiagnosticsLogger.fs @@ -817,12 +817,15 @@ type internal SuppressLanguageFeatureCheck = | Yes | No +let internal languageFeatureError (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) = + let featureStr = LanguageVersion.GetFeatureString langFeature + let currentVersionStr = langVersion.SpecifiedVersionString + let suggestedVersionStr = LanguageVersion.GetFeatureVersionString langFeature + Error(FSComp.SR.chkFeatureNotLanguageSupported (featureStr, currentVersionStr, suggestedVersionStr), m) + let private tryLanguageFeatureErrorAux (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) = if not (langVersion.SupportsFeature langFeature) then - let featureStr = LanguageVersion.GetFeatureString langFeature - let currentVersionStr = langVersion.SpecifiedVersionString - let suggestedVersionStr = LanguageVersion.GetFeatureVersionString langFeature - Some(Error(FSComp.SR.chkFeatureNotLanguageSupported (featureStr, currentVersionStr, suggestedVersionStr), m)) + Some (languageFeatureError langVersion langFeature m) else None diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fsi b/src/Compiler/Facilities/DiagnosticsLogger.fsi index 03b27b922a0..2fe91400fbd 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fsi +++ b/src/Compiler/Facilities/DiagnosticsLogger.fsi @@ -432,6 +432,8 @@ type SuppressLanguageFeatureCheck = | Yes | No +val languageFeatureError: langVersion: LanguageVersion -> langFeature: LanguageFeature -> m: range -> exn + val checkLanguageFeatureError: langVersion: LanguageVersion -> langFeature: LanguageFeature -> m: range -> unit val checkLanguageFeatureAndRecover: langVersion: LanguageVersion -> langFeature: LanguageFeature -> m: range -> unit From ba2d08a122ef71e507aba307db4b69a6dc0e6157 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 9 Aug 2023 17:18:42 -0600 Subject: [PATCH 34/51] Rename fixed binding test files --- .../FixedBindings.fs} | 2 +- .../FSharp.Compiler.ComponentTests.fsproj | 4 ++-- .../FixedBindings.fs} | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) rename tests/FSharp.Compiler.ComponentTests/EmittedIL/{FixedExpressionTests.fs => FixedBindings/FixedBindings.fs} (99%) rename tests/FSharp.Compiler.ComponentTests/Language/{FixedExpressionTests.fs => FixedBindings/FixedBindings.fs} (99%) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs similarity index 99% rename from tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs rename to tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs index 6015103af3f..2375cd73cc3 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs @@ -1,4 +1,4 @@ -namespace EmittedIL.FixedExpressionTests +namespace EmittedIL.FixedBindings open System.Reflection open Xunit diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 95f07103f08..8af31988457 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -145,7 +145,7 @@ - + @@ -188,7 +188,7 @@ - + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs similarity index 99% rename from tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs rename to tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index 44df5b3bcc0..5bd46dda1b9 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -1,4 +1,4 @@ -namespace Language.FixedExpressionTests +namespace Language.FixedBindings open Xunit open FSharp.Test.Compiler @@ -189,8 +189,8 @@ let pinIt<'a when 'a : unmanaged> (thing: 'a) = (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] -// FS-1081 - Extend fixed expressions -module ExtendedFixedExpressions = +// FS-1081 - Extend fixed bindings +module ExtendedFixedBindings = [] [] [] From 2d13cfc47c91243a3a462217cbb24e40acef81dc Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 9 Aug 2023 17:19:13 -0600 Subject: [PATCH 35/51] More renames --- .../EmittedIL/FixedBindings/FixedBindings.fs | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs index 2375cd73cc3..5ccccdaafbb 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs @@ -24,7 +24,7 @@ module Legacy = #endif FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop let pinIt (str: string) = @@ -103,7 +103,7 @@ let pinIt (str: string) = [] let ``Pin naked array`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop let pinIt (arr: char[]) = @@ -157,7 +157,7 @@ let pinIt (arr: char[]) = [] let ``Pin address of record field`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop type Point = { mutable X: int; mutable Y: int } @@ -174,14 +174,14 @@ if xCopy <> p.X then failwith "xCopy was not equal to X" |> withOptions ["--nowarn:9"] |> compileExeAndRun |> verifyIL [""" - .method public static int32 pinIt(class FixedExpressions/Point thing) cil managed + .method public static int32 pinIt(class FixedBindings/Point thing) cil managed { .maxstack 5 .locals init (native int V_0, int32& pinned V_1) IL_0000: ldarg.0 - IL_0001: ldflda int32 FixedExpressions/Point::X@ + IL_0001: ldflda int32 FixedBindings/Point::X@ IL_0006: stloc.1 IL_0007: ldloc.1 IL_0008: conv.i @@ -201,7 +201,7 @@ if xCopy <> p.X then failwith "xCopy was not equal to X" [] let ``Pin address of explicit field on this`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop type Point = @@ -231,7 +231,7 @@ if xCopy <> p.X then failwith "xCopy was not equal to X" .locals init (native int V_0, int32& pinned V_1) IL_0000: ldarg.0 - IL_0001: ldflda int32 FixedExpressions/Point::X + IL_0001: ldflda int32 FixedBindings/Point::X IL_0006: stloc.1 IL_0007: ldloc.1 IL_0008: conv.i @@ -251,7 +251,7 @@ if xCopy <> p.X then failwith "xCopy was not equal to X" [] let ``Pin address of array element`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop let pinIt (arr: char[]) = @@ -290,11 +290,11 @@ if y <> 'a' then failwithf "y did not equal first element of x" IL_001b: ret } """ ] -module ExtendedFixedExpressions = +module ExtendedFixedBindings = [] let ``Pin int byref of parameter`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop let pinIt (thing: byref) = @@ -334,7 +334,7 @@ if x <> xCopy then failwith "xCopy was not the same as x" [] let ``Pin int byref of local variable`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open System.Runtime.CompilerServices open Microsoft.FSharp.NativeInterop @@ -384,7 +384,7 @@ pinIt 100 IL_001d: ldloc.0 IL_001e: beq.s IL_0027 - IL_0020: call !!0 FixedExpressions::fail() + IL_0020: call !!0 FixedBindings::fail() IL_0025: pop IL_0026: ret @@ -395,7 +395,7 @@ pinIt 100 [] let ``Pin Span via manual GetPinnableReference call`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop open System @@ -440,7 +440,7 @@ let main _ = [] let ``Pin Span`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop open System @@ -485,7 +485,7 @@ let main _ = [] let ``Pin generic ReadOnlySpan`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop open System @@ -533,7 +533,7 @@ let main _ = [] let ``Pin type with method GetPinnableReference : unit -> byref`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop open System.Runtime.CompilerServices open System @@ -560,7 +560,7 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static int32 pinIt(class FixedExpressions/RefField`1 thing) cil managed + .method public static int32 pinIt(class FixedBindings/RefField`1 thing) cil managed { .maxstack 5 @@ -570,7 +570,7 @@ let main _ = IL_0001: brfalse.s IL_000e IL_0003: ldarg.0 - IL_0004: callvirt instance !0& class FixedExpressions/RefField`1::GetPinnableReference() + IL_0004: callvirt instance !0& class FixedBindings/RefField`1::GetPinnableReference() IL_0009: stloc.1 IL_000a: ldloc.1 IL_000b: conv.i @@ -591,7 +591,7 @@ let main _ = [] let ``Pin type with method GetPinnableReference : unit -> inref`` langVersion = FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop open System.Runtime.CompilerServices open System @@ -618,7 +618,7 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static int32 pinIt(class FixedExpressions/ReadonlyRefField`1 thing) cil managed + .method public static int32 pinIt(class FixedBindings/ReadonlyRefField`1 thing) cil managed { .maxstack 5 @@ -628,7 +628,7 @@ let main _ = IL_0001: brfalse.s IL_000e IL_0003: ldarg.0 - IL_0004: callvirt instance !0& modreq([runtime]System.Runtime.InteropServices.InAttribute) class FixedExpressions/ReadonlyRefField`1::GetPinnableReference() + IL_0004: callvirt instance !0& modreq([runtime]System.Runtime.InteropServices.InAttribute) class FixedBindings/ReadonlyRefField`1::GetPinnableReference() IL_0009: stloc.1 IL_000a: ldloc.1 IL_000b: conv.i @@ -650,7 +650,7 @@ let main _ = let ``Pin struct type with method GetPinnableReference : unit -> byref`` langVersion = // Effectively tests the same thing as the test with Span, but this works on .NET Framework FSharp """ -module FixedExpressions +module FixedBindings open System.Runtime.CompilerServices open Microsoft.FSharp.NativeInterop open System @@ -684,7 +684,7 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static !!a pinIt(valuetype FixedExpressions/ArrayElementRef`1 thing) cil managed + .method public static !!a pinIt(valuetype FixedBindings/ArrayElementRef`1 thing) cil managed { .param type a .custom instance void System.Runtime.CompilerServices.IsUnmanagedAttribute::.ctor() = ( 01 00 00 00 ) @@ -693,7 +693,7 @@ let main _ = .locals init (native int V_0, !!a& pinned V_1) IL_0000: ldarga.s thing - IL_0002: call instance !0& valuetype FixedExpressions/ArrayElementRef`1::GetPinnableReference() + IL_0002: call instance !0& valuetype FixedBindings/ArrayElementRef`1::GetPinnableReference() IL_0007: stloc.1 IL_0008: ldloc.1 IL_0009: conv.i @@ -735,7 +735,7 @@ public class PinnableReference """ |> withName "CsLib" FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop open System @@ -816,7 +816,7 @@ namespace CsLib |> withCSharpLanguageVersion CSharpLanguageVersion.CSharp11 FSharp """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop open CsLib @@ -864,7 +864,7 @@ let main _ = [] let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = Fsx """ -module FixedExpressions +module FixedBindings open Microsoft.FSharp.NativeInterop open System.Runtime.CompilerServices @@ -892,7 +892,7 @@ let main _ = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static !!a pinIt(class FixedExpressions/RefField`1 thing) cil managed + .method public static !!a pinIt(class FixedBindings/RefField`1 thing) cil managed { .param type a .custom instance void System.Runtime.CompilerServices.IsUnmanagedAttribute::.ctor() = ( 01 00 00 00 ) @@ -904,7 +904,7 @@ let main _ = IL_0001: brfalse.s IL_000e IL_0003: ldarg.0 - IL_0004: call !!0& FixedExpressions/RefFieldExtensions::GetPinnableReference(class FixedExpressions/RefField`1) + IL_0004: call !!0& FixedBindings/RefFieldExtensions::GetPinnableReference(class FixedBindings/RefField`1) IL_0009: stloc.1 IL_000a: ldloc.1 IL_000b: conv.i From 9b47c4c069e1073e10d8cf2b97c4256d4e1cee74 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 9 Aug 2023 17:21:24 -0600 Subject: [PATCH 36/51] Rename all instances of 'fixed expressions' -> 'fixed bindings' --- src/Compiler/FSComp.txt | 2 +- src/Compiler/xlf/FSComp.txt.cs.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.de.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.es.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.it.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 4 ++-- .../Language/FixedBindings/FixedBindings.fs | 20 +++++++++---------- 15 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 3071425d184..9bf0b148669 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1586,7 +1586,7 @@ featureStrictIndentation,"Raises errors on incorrect indentation, allows better featureConstraintIntersectionOnFlexibleTypes,"Constraint intersection on flexible types" featureChkNotTailRecursive,"Raises warnings if a member or function has the 'TailCall' attribute, but is not being used in a tail recursive way." featureWhileBang,"'while!' expression" -featureExtendedFixedBindings,"extended fixed expressions for byrefs, inrefs, and GetPinnableReference" +featureExtendedFixedBindings,"extended fixed bindings for byrefs, inrefs, and GetPinnableReference" featurePreferStringGetPinnableReference,"prefer String.GetPinnableReference in fixed bindings" 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 4636fd634af..43f571d8949 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 0f427eb719b..eecc0f6a15c 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index be732e58559..cf432dd5e7e 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 8af9fad152c..3f7bdb33063 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index e838f7ad7c2..21ad24ac0bd 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 074134ab6fb..edbb9a09c15 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 4e7c37ef36d..56e2f9ca1ac 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index b37d0f6a2d4..4faff7245ee 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index bf3a004eafa..95bf5c7365d 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index faee91127d7..3877e9e92b2 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 9d128155758..4f6df292e2d 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 8cb7ecb98c7..56c92f12c1a 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 1c49ed71855..cce10525be0 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -288,8 +288,8 @@ - extended fixed expressions for byrefs, inrefs, and GetPinnableReference - extended fixed expressions for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byrefs, inrefs, and GetPinnableReference diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index 5bd46dda1b9..13f2144c6d4 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -219,7 +219,7 @@ let pinIt (thing: byref) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") ]) [] @@ -251,7 +251,7 @@ let pinIt (thing: inref) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") ]) [] @@ -283,7 +283,7 @@ let pinIt (thing: outref) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") ]) [] @@ -319,7 +319,7 @@ type Point() = |> shouldFail |> withDiagnostics [ (Warning 9, Line 8, Col 13, Line 8, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 8, Col 13, Line 8, Col 16, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 8, Col 13, Line 8, Col 16, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") ]) [] @@ -352,7 +352,7 @@ let pinIt () = |> shouldFail |> withDiagnostics [ (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") ]) #if NETCOREAPP @@ -386,7 +386,7 @@ let pinIt (thing: Span) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'."""); - (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") ]) #endif @@ -460,7 +460,7 @@ let pinIt (thing: RefField<'T>) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")]) + (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")]) [] [] @@ -495,7 +495,7 @@ let pinIt (thing: RefField<'T>) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") ]) [] @@ -535,7 +535,7 @@ let pinIt (thing: RefField<'T>) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") ]) [] @@ -645,7 +645,7 @@ let pinIt (thing: RefField<'T>) = |> shouldFail |> withDiagnostics [ (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 11, Col 9, Line 11, Col 12, """Feature 'extended fixed expressions for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")] + (Error 3350, Line 11, Col 9, Line 11, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")] ) [] From a3b980fb16ef507318e5d5d1aa7ccf6525a0a3fa Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 9 Aug 2023 17:56:54 -0600 Subject: [PATCH 37/51] Extract fixed binding IL test cases to their own files --- .../EmittedIL/FixedBindings/FixedBindings.fs | 340 ++---------------- .../FixedBindings/PinAddressOfArrayElement.fs | 10 + .../PinAddressOfExplicitFieldOnThis.fs | 16 + .../FixedBindings/PinAddressOfRecordField.fs | 12 + ...eWithGetPinnableReferenceReturningByref.cs | 20 ++ ...eWithGetPinnableReferenceReturningByref.fs | 15 + ...eWithGetPinnableReferenceReturningByref.cs | 20 ++ ...eWithGetPinnableReferenceReturningByref.fs | 14 + .../FixedBindings/PinGenericReadOnlySpan.fs | 14 + .../PinIntByrefOfLocalVariable.fs | 15 + .../FixedBindings/PinIntByrefOfParameter.fs | 10 + .../EmittedIL/FixedBindings/PinNakedArray.fs | 6 + .../EmittedIL/FixedBindings/PinNakedString.fs | 6 + .../EmittedIL/FixedBindings/PinSpan.fs | 14 + ...nSpanWithManualGetPinnableReferenceCall.fs | 14 + ...eWithGetPinnableReferenceReturningByref.fs | 28 ++ ...nsionGetPinnableReferenceReturningByref.fs | 22 ++ ...eWithGetPinnableReferenceReturningByref.fs | 21 ++ ...eWithGetPinnableReferenceReturningInref.fs | 21 ++ tests/FSharp.Test.Utilities/Compiler.fs | 2 +- 20 files changed, 301 insertions(+), 319 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfArrayElement.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfExplicitFieldOnThis.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfRecordField.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.cs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpTypeWithGetPinnableReferenceReturningByref.cs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpTypeWithGetPinnableReferenceReturningByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinGenericReadOnlySpan.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinIntByrefOfLocalVariable.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinIntByrefOfParameter.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNakedArray.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNakedString.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinSpan.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinSpanWithManualGetPinnableReferenceCall.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinStructTypeWithGetPinnableReferenceReturningByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithGetPinnableReferenceReturningByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithGetPinnableReferenceReturningInref.fs diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs index 5ccccdaafbb..a972f5bbdff 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs @@ -23,14 +23,7 @@ module Legacy = Assert.False(runtimeSupportsStringGetPinnableReference) #endif - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop - -let pinIt (str: string) = - use ptr = fixed str - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedString.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compile @@ -102,14 +95,7 @@ let pinIt (str: string) = [] [] let ``Pin naked array`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop - -let pinIt (arr: char[]) = - use ptr = fixed arr - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedArray.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compile @@ -156,20 +142,7 @@ let pinIt (arr: char[]) = [] [] let ``Pin address of record field`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop - -type Point = { mutable X: int; mutable Y: int } - -let pinIt (thing: Point) = - use ptr = fixed &thing.X - NativePtr.get ptr 0 - -let p = { X = 10; Y = 20 } -let xCopy = pinIt p -if xCopy <> p.X then failwith "xCopy was not equal to X" -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfRecordField.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -200,24 +173,7 @@ if xCopy <> p.X then failwith "xCopy was not equal to X" [] [] let ``Pin address of explicit field on this`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop - -type Point = - val mutable X: int - val mutable Y: int - - new(x: int, y: int) = { X = x; Y = y } - - member this.PinIt() = - use ptr = fixed &this.X - NativePtr.get ptr 0 - -let p = Point(10,20) -let xCopy = p.PinIt() -if xCopy <> p.X then failwith "xCopy was not equal to X" -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfExplicitFieldOnThis.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -250,18 +206,7 @@ if xCopy <> p.X then failwith "xCopy was not equal to X" [] [] let ``Pin address of array element`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop - -let pinIt (arr: char[]) = - use ptr = fixed &arr[0] - NativePtr.get ptr 0 - -let x = [|'a';'b';'c'|] -let y = pinIt x -if y <> 'a' then failwithf "y did not equal first element of x" -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfArrayElement.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -293,18 +238,7 @@ if y <> 'a' then failwithf "y did not equal first element of x" module ExtendedFixedBindings = [] let ``Pin int byref of parameter`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop - -let pinIt (thing: byref) = - use ptr = fixed &thing - NativePtr.get ptr 0 - -let mutable x = 42 -let xCopy = pinIt &x -if x <> xCopy then failwith "xCopy was not the same as x" -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefOfParameter.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -333,23 +267,7 @@ if x <> xCopy then failwith "xCopy was not the same as x" [] let ``Pin int byref of local variable`` langVersion = - FSharp """ -module FixedBindings -open System.Runtime.CompilerServices -open Microsoft.FSharp.NativeInterop - -[] -let fail () = - failwith "thingCopy was not the same as thing" - -let pinIt (x: int) = - let mutable thing = x + 1 - use ptr = fixed &thing - let thingCopy = NativePtr.get ptr 0 - if thingCopy <> thing then fail () - -pinIt 100 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefOfLocalVariable.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -394,22 +312,7 @@ pinIt 100 #if NETCOREAPP [] let ``Pin Span via manual GetPinnableReference call`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop -open System - -let pinIt (thing: Span) = - use ptr = fixed &thing.GetPinnableReference() - NativePtr.get ptr 0 - -[] -let main _ = - let span = Span("The quick brown fox jumped over the lazy dog".ToCharArray()) - let x = pinIt span - if x <> 'T' then failwith "x did not equal the first char of the span" - 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinSpanWithManualGetPinnableReferenceCall.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -439,22 +342,7 @@ let main _ = [] let ``Pin Span`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop -open System - -let pinIt (thing: Span) = - use ptr = fixed thing - NativePtr.get ptr 0 - -[] -let main _ = - let span = Span("The quick brown fox jumped over the lazy dog".ToCharArray()) - let x = pinIt span - if x <> 'T' then failwith "x did not equal the first char of the span" - 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinSpan.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -484,22 +372,7 @@ let main _ = [] let ``Pin generic ReadOnlySpan`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop -open System - -let pinIt (thing: ReadOnlySpan<'a>) = - use ptr = fixed thing - NativePtr.get ptr 0 - -[] -let main _ = - let span = ReadOnlySpan("The quick brown fox jumped over the lazy dog".ToCharArray()) - let x = pinIt span - if x <> 'T' then failwith "x did not equal the first char of the span" - 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinGenericReadOnlySpan.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -532,35 +405,13 @@ let main _ = [] let ``Pin type with method GetPinnableReference : unit -> byref`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop -open System.Runtime.CompilerServices -open System - -type RefField<'T>(_value) = - let mutable _value = _value - member this.Value = _value - [] - member this.GetPinnableReference () : byref<'T> = &_value - -let pinIt (thing: RefField) = - use ptr = fixed thing - NativePtr.get ptr 0 - -[] -let main _ = - let x = RefField(42) - let y = pinIt x - if y <> x.Value then failwith "y did not equal x value" - 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static int32 pinIt(class FixedBindings/RefField`1 thing) cil managed + .method public static int32 pinIt(class FixedExpressions/RefField`1 thing) cil managed { .maxstack 5 @@ -570,7 +421,7 @@ let main _ = IL_0001: brfalse.s IL_000e IL_0003: ldarg.0 - IL_0004: callvirt instance !0& class FixedBindings/RefField`1::GetPinnableReference() + IL_0004: callvirt instance !0& class FixedExpressions/RefField`1::GetPinnableReference() IL_0009: stloc.1 IL_000a: ldloc.1 IL_000b: conv.i @@ -590,29 +441,7 @@ let main _ = [] let ``Pin type with method GetPinnableReference : unit -> inref`` langVersion = - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop -open System.Runtime.CompilerServices -open System - -type ReadonlyRefField<'T>(_value) = - let mutable _value = _value - member this.Value = _value - [] - member this.GetPinnableReference () : inref<'T> = &_value - -let pinIt (thing: ReadonlyRefField) = - use ptr = fixed thing - NativePtr.get ptr 0 - -[] -let main _ = - let x = ReadonlyRefField(42) - let y = pinIt x - if y <> x.Value then failwith "y did not equal x value" - 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningInref.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -649,36 +478,7 @@ let main _ = [] let ``Pin struct type with method GetPinnableReference : unit -> byref`` langVersion = // Effectively tests the same thing as the test with Span, but this works on .NET Framework - FSharp """ -module FixedBindings -open System.Runtime.CompilerServices -open Microsoft.FSharp.NativeInterop -open System - -[] -type ArrayElementRef<'T> = - private { Values: 'T[]; Index: int } - - static member Create(values: 'T[], index) = - if index > values.Length then - raise (ArgumentOutOfRangeException(nameof(index), "")) - { Values = values; Index = index } - member this.Value = this.Values[this.Index] - [] - member this.GetPinnableReference () : byref<'T> = &this.Values[this.Index] - -let pinIt (thing: ArrayElementRef<'a>) = - use ptr = fixed thing - NativePtr.get ptr 0 - -[] -let main _ = - let arr = [|'a';'b';'c'|] - let x = ArrayElementRef.Create(arr, 1) - let y = pinIt x - if y <> x.Value then failwith "y did not equal x value" - 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinStructTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun @@ -711,45 +511,9 @@ let main _ = [] let ``Pin C# type with method GetPinnableReference : unit -> byref`` langVersion = let csLib = - CSharp """ -public class PinnableReference -{ - private T _value; - - public T Value - { - get => _value; - set => _value = value; - } - - public PinnableReference(T value) - { - this._value = value; - } - - public ref T GetPinnableReference() - { - return ref _value; - } -} -""" |> withName "CsLib" + CSharpFromPath (__SOURCE_DIRECTORY__ ++ "PinCSharpTypeWithGetPinnableReferenceReturningByref.cs") |> withName "CsLib" - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop -open System - -let pinIt (thing: PinnableReference) = - use ptr = fixed thing - NativePtr.get ptr 0 - -[] -let main _ = - let x = PinnableReference(42) - let y = pinIt x - if y <> x.Value then failwith "y did not equal x value" - 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinCSharpTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> withReferences [csLib] |> withOptions ["--nowarn:9"] @@ -790,48 +554,11 @@ let main _ = // TODO: Could be a good idea to test a version of this type written in F# too once we get ref fields in byref-like structs: // https://github.com/fsharp/fslang-suggestions/issues/1143 let csLib = - CSharp """ -namespace CsLib -{ - public ref struct RefField - { - private readonly ref T _value; - - public T Value - { - get => _value; - set => _value = value; - } - - public RefField(ref T value) - { - this._value = ref value; - } - - public ref T GetPinnableReference() => ref _value; - } -} - -""" |> withName "CsLib" + CSharpFromPath (__SOURCE_DIRECTORY__ ++ "PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.cs") + |> withName "CsLib" |> withCSharpLanguageVersion CSharpLanguageVersion.CSharp11 - FSharp """ -module FixedBindings -open Microsoft.FSharp.NativeInterop -open CsLib - -let pinIt (refField: RefField) = - use ptr = fixed refField - NativePtr.get ptr 0 - -[] -let main _ = - let mutable x = 42 - let refToX = new RefField<_>(&x) - let y = pinIt refToX - if y <> x then failwith "y did not equal x" - 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> withReferences [csLib] |> withOptions ["--nowarn:9"] @@ -860,33 +587,10 @@ let main _ = IL_001b: ret } """ ] #endif - + [] let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = - Fsx """ -module FixedBindings -open Microsoft.FSharp.NativeInterop -open System.Runtime.CompilerServices - -type RefField<'T> = { mutable _value: 'T } - -[] -type RefFieldExtensions = - [] - static member GetPinnableReference(refField: RefField<'T>) : byref<'T> = &refField._value - -let pinIt (thing: RefField<'T>) = - use ptr = fixed thing - NativePtr.get ptr 0 - -[] -let main _ = - let mutable x = 42 - let refToX = { _value = x } - let y = pinIt refToX - if y <> x then failwith "y did not equal x" - 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithExtensionGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compileExeAndRun diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfArrayElement.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfArrayElement.fs new file mode 100644 index 00000000000..b6eb61aea92 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfArrayElement.fs @@ -0,0 +1,10 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (arr: char[]) = + use ptr = fixed &arr[0] + NativePtr.get ptr 0 + +let x = [|'a';'b';'c'|] +let y = pinIt x +if y <> 'a' then failwithf "y did not equal first element of x" \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfExplicitFieldOnThis.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfExplicitFieldOnThis.fs new file mode 100644 index 00000000000..7320c742cad --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfExplicitFieldOnThis.fs @@ -0,0 +1,16 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type Point = + val mutable X: int + val mutable Y: int + + new(x: int, y: int) = { X = x; Y = y } + + member this.PinIt() = + use ptr = fixed &this.X + NativePtr.get ptr 0 + +let p = Point(10,20) +let xCopy = p.PinIt() +if xCopy <> p.X then failwith "xCopy was not equal to X" \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfRecordField.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfRecordField.fs new file mode 100644 index 00000000000..1aad39790a7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinAddressOfRecordField.fs @@ -0,0 +1,12 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type Point = { mutable X: int; mutable Y: int } + +let pinIt (thing: Point) = + use ptr = fixed &thing.X + NativePtr.get ptr 0 + +let p = { X = 10; Y = 20 } +let xCopy = pinIt p +if xCopy <> p.X then failwith "xCopy was not equal to X" \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.cs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.cs new file mode 100644 index 00000000000..b9c22320bb0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.cs @@ -0,0 +1,20 @@ +namespace CsLib +{ + public ref struct RefField + { + private readonly ref T _value; + + public T Value + { + get => _value; + set => _value = value; + } + + public RefField(ref T value) + { + this._value = ref value; + } + + public ref T GetPinnableReference() => ref _value; + } +} \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.fs new file mode 100644 index 00000000000..a39cb2a8432 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.fs @@ -0,0 +1,15 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop +open CsLib + +let pinIt (refField: RefField) = + use ptr = fixed refField + NativePtr.get ptr 0 + +[] +let main _ = + let mutable x = 42 + let refToX = new RefField<_>(&x) + let y = pinIt refToX + if y <> x then failwith "y did not equal x" + 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpTypeWithGetPinnableReferenceReturningByref.cs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpTypeWithGetPinnableReferenceReturningByref.cs new file mode 100644 index 00000000000..bbab6d945d3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpTypeWithGetPinnableReferenceReturningByref.cs @@ -0,0 +1,20 @@ +public class PinnableReference +{ + private T _value; + + public T Value + { + get => _value; + set => _value = value; + } + + public PinnableReference(T value) + { + this._value = value; + } + + public ref T GetPinnableReference() + { + return ref _value; + } +} \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpTypeWithGetPinnableReferenceReturningByref.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpTypeWithGetPinnableReferenceReturningByref.fs new file mode 100644 index 00000000000..d56c5cff860 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinCSharpTypeWithGetPinnableReferenceReturningByref.fs @@ -0,0 +1,14 @@ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open System + +let pinIt (thing: PinnableReference) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let x = PinnableReference(42) + let y = pinIt x + if y <> x.Value then failwith "y did not equal x value" + 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinGenericReadOnlySpan.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinGenericReadOnlySpan.fs new file mode 100644 index 00000000000..d63f946ba10 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinGenericReadOnlySpan.fs @@ -0,0 +1,14 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop +open System + +let pinIt (thing: ReadOnlySpan<'a>) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let span = ReadOnlySpan("The quick brown fox jumped over the lazy dog".ToCharArray()) + let x = pinIt span + if x <> 'T' then failwith "x did not equal the first char of the span" + 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinIntByrefOfLocalVariable.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinIntByrefOfLocalVariable.fs new file mode 100644 index 00000000000..ce08ac07fe6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinIntByrefOfLocalVariable.fs @@ -0,0 +1,15 @@ +module FixedBindings +open System.Runtime.CompilerServices +open Microsoft.FSharp.NativeInterop + +[] +let fail () = + failwith "thingCopy was not the same as thing" + +let pinIt (x: int) = + let mutable thing = x + 1 + use ptr = fixed &thing + let thingCopy = NativePtr.get ptr 0 + if thingCopy <> thing then fail () + +pinIt 100 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinIntByrefOfParameter.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinIntByrefOfParameter.fs new file mode 100644 index 00000000000..419ab9dc950 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinIntByrefOfParameter.fs @@ -0,0 +1,10 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: byref) = + use ptr = fixed &thing + NativePtr.get ptr 0 + +let mutable x = 42 +let xCopy = pinIt &x +if x <> xCopy then failwith "xCopy was not the same as x" \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNakedArray.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNakedArray.fs new file mode 100644 index 00000000000..a8853cb24eb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNakedArray.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (arr: char[]) = + use ptr = fixed arr + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNakedString.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNakedString.fs new file mode 100644 index 00000000000..95d259363d3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNakedString.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (str: string) = + use ptr = fixed str + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinSpan.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinSpan.fs new file mode 100644 index 00000000000..9d0d5e95adc --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinSpan.fs @@ -0,0 +1,14 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop +open System + +let pinIt (thing: Span) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let span = Span("The quick brown fox jumped over the lazy dog".ToCharArray()) + let x = pinIt span + if x <> 'T' then failwith "x did not equal the first char of the span" + 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinSpanWithManualGetPinnableReferenceCall.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinSpanWithManualGetPinnableReferenceCall.fs new file mode 100644 index 00000000000..f3054550b64 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinSpanWithManualGetPinnableReferenceCall.fs @@ -0,0 +1,14 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop +open System + +let pinIt (thing: Span) = + use ptr = fixed &thing.GetPinnableReference() + NativePtr.get ptr 0 + +[] +let main _ = + let span = Span("The quick brown fox jumped over the lazy dog".ToCharArray()) + let x = pinIt span + if x <> 'T' then failwith "x did not equal the first char of the span" + 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinStructTypeWithGetPinnableReferenceReturningByref.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinStructTypeWithGetPinnableReferenceReturningByref.fs new file mode 100644 index 00000000000..87f636881c5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinStructTypeWithGetPinnableReferenceReturningByref.fs @@ -0,0 +1,28 @@ +module FixedBindings +open System.Runtime.CompilerServices +open Microsoft.FSharp.NativeInterop +open System + +[] +type ArrayElementRef<'T> = + private { Values: 'T[]; Index: int } + + static member Create(values: 'T[], index) = + if index > values.Length then + raise (ArgumentOutOfRangeException(nameof(index), "")) + { Values = values; Index = index } + member this.Value = this.Values[this.Index] + [] + member this.GetPinnableReference () : byref<'T> = &this.Values[this.Index] + +let pinIt (thing: ArrayElementRef<'a>) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let arr = [|'a';'b';'c'|] + let x = ArrayElementRef.Create(arr, 1) + let y = pinIt x + if y <> x.Value then failwith "y did not equal x value" + 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs new file mode 100644 index 00000000000..e5256ecedd8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs @@ -0,0 +1,22 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop +open System.Runtime.CompilerServices + +type RefField<'T> = { mutable _value: 'T } + +[] +type RefFieldExtensions = + [] + static member GetPinnableReference(refField: RefField<'T>) : byref<'T> = &refField._value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let mutable x = 42 + let refToX = { _value = x } + let y = pinIt refToX + if y <> x then failwith "y did not equal x" + 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithGetPinnableReferenceReturningByref.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithGetPinnableReferenceReturningByref.fs new file mode 100644 index 00000000000..b276ae2672e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithGetPinnableReferenceReturningByref.fs @@ -0,0 +1,21 @@ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open System.Runtime.CompilerServices +open System + +type RefField<'T>(_value) = + let mutable _value = _value + member this.Value = _value + [] + member this.GetPinnableReference () : byref<'T> = &_value + +let pinIt (thing: RefField) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let x = RefField(42) + let y = pinIt x + if y <> x.Value then failwith "y did not equal x value" + 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithGetPinnableReferenceReturningInref.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithGetPinnableReferenceReturningInref.fs new file mode 100644 index 00000000000..43b580e574e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithGetPinnableReferenceReturningInref.fs @@ -0,0 +1,21 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop +open System.Runtime.CompilerServices +open System + +type ReadonlyRefField<'T>(_value) = + let mutable _value = _value + member this.Value = _value + [] + member this.GetPinnableReference () : inref<'T> = &_value + +let pinIt (thing: ReadonlyRefField) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let x = ReadonlyRefField(42) + let y = pinIt x + if y <> x.Value then failwith "y did not equal x value" + 0 \ No newline at end of file diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 548957ce3f5..ce5252136e0 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -355,7 +355,7 @@ module rec Compiler = let FsxFromPath (path: string) : CompilationUnit = fsFromString (SourceFromPath path) |> FS - + let Fs (source: string) : CompilationUnit = fsFromString (FsSource source) |> FS From 4873ec428c164fc1a28c594f605e1de3681e3cbf Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Wed, 9 Aug 2023 18:26:22 -0600 Subject: [PATCH 38/51] Extract fixed binding Language test cases to their own files --- .../Language/FixedBindings/FixedBindings.fs | 298 +++--------------- .../FixedBindings/PinAddressOfArrayElement.fs | 6 + .../PinAddressOfExplicitFieldOnThis.fs | 12 + ...itFieldOnThisWithDefaultCtorClassSyntax.fs | 9 + .../FixedBindings/PinAddressOfRecordField.fs | 8 + ...uctByrefTypeWithoutGetPinnableReference.fs | 11 + .../Language/FixedBindings/PinGeneric.fs | 6 + .../PinGenericWithUnmanagedConstraint.fs | 6 + .../FixedBindings/PinIntByrefLocalVariable.fs | 7 + .../FixedBindings/PinIntByrefParameter.fs | 6 + .../FixedBindings/PinIntInrefParameter.fs | 6 + .../FixedBindings/PinIntOutrefParameter.fs | 6 + .../Language/FixedBindings/PinNakedArray.fs | 6 + .../Language/FixedBindings/PinNakedInt.fs | 6 + .../Language/FixedBindings/PinNakedObject.fs | 6 + .../Language/FixedBindings/PinNakedString.fs | 6 + .../Language/FixedBindings/PinSpan.fs | 7 + ...ableReferenceAndSeveralInvalidOverloads.fs | 12 + ...nsionGetPinnableReferenceReturningByref.fs | 14 + ...eWithGetPinnableReferenceReturningByref.fs | 10 + ...eWithGetPinnableReferenceReturningInref.fs | 10 + ...PinnableReferenceWithNonByrefReturnType.fs | 10 + ...eWithGetPinnableReferenceWithParameters.fs | 10 + .../PinTypeWithPrivateGetPinnableReference.fs | 10 + .../PinTypeWithStaticGetPinnableReference.fs | 10 + 25 files changed, 249 insertions(+), 249 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfArrayElement.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfExplicitFieldOnThis.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfExplicitFieldOnThisWithDefaultCtorClassSyntax.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfRecordField.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinCustomStructByrefTypeWithoutGetPinnableReference.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinGeneric.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinGenericWithUnmanagedConstraint.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntByrefLocalVariable.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntByrefParameter.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntInrefParameter.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntOutrefParameter.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedArray.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedInt.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedObject.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedString.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinSpan.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWIthValidGetPinnableReferenceAndSeveralInvalidOverloads.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceReturningByref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceReturningInref.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceWithNonByrefReturnType.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceWithParameters.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithPrivateGetPinnableReference.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithStaticGetPinnableReference.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index 13f2144c6d4..fe3ad211366 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -8,16 +8,10 @@ module Legacy = [] [] let ``Pin naked string`` langVersion = - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt (str: string) = - use ptr = fixed str - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedString.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> shouldSucceed |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") @@ -28,16 +22,10 @@ let pinIt (str: string) = [] [] let ``Pin naked array`` langVersion = - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt (arr: char[]) = - use ptr = fixed arr - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedArray.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> shouldSucceed |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") @@ -48,16 +36,10 @@ let pinIt (arr: char[]) = [] [] let ``Pin address of array element`` langVersion = - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt (arr: char[]) = - use ptr = fixed &arr[1] - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfArrayElement.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> shouldSucceed |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") @@ -68,18 +50,10 @@ let pinIt (arr: char[]) = [] [] let ``Pin address of record field`` langVersion = - Fsx """ -open Microsoft.FSharp.NativeInterop - -type Point = { mutable X: int; mutable Y: int } - -let pinIt (thing: Point) = - use ptr = fixed &thing.X - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfRecordField.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> shouldSucceed |> withDiagnostics [ (Warning 9, Line 7, Col 9, Line 7, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") @@ -90,22 +64,10 @@ let pinIt (thing: Point) = [] [] let ``Pin address of explicit field on this`` langVersion = - Fsx """ -open Microsoft.FSharp.NativeInterop - -type Point = - val mutable X: int - val mutable Y: int - - new(x: int, y: int) = { X = x; Y = y } - - member this.PinIt() = - use ptr = fixed &this.X - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfExplicitFieldOnThis.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> shouldSucceed |> withDiagnostics [ (Warning 9, Line 11, Col 13, Line 11, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") @@ -116,15 +78,9 @@ type Point = [] [] let ``Pin naked object - illegal`` langVersion = - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt (thing: obj) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedObject.fs") |> withLangVersion langVersion - |> typecheck + |> compile |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") @@ -136,15 +92,9 @@ let pinIt (thing: obj) = [] [] let ``Pin naked int - illegal`` langVersion = - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt (thing: int) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedInt.fs") |> withLangVersion langVersion - |> typecheck + |> compile |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") @@ -155,15 +105,9 @@ let pinIt (thing: int) = [] [] let ``Pin generic - illegal`` langVersion = - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt (thing: 'a) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinGeneric.fs") |> withLangVersion langVersion - |> typecheck + |> compile |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") @@ -174,15 +118,9 @@ let pinIt (thing: 'a) = [] [] let ``Pin generic with unmanaged - illegal`` langVersion = - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt<'a when 'a : unmanaged> (thing: 'a) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinGenericWithUnmanagedConstraint.fs") |> withLangVersion langVersion - |> typecheck + |> compile |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") @@ -194,17 +132,11 @@ module ExtendedFixedBindings = [] [] [] - let ``Pin int byref parmeter`` (langVersion, featureShouldActivate) = - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt (thing: byref) = - use ptr = fixed &thing - NativePtr.get ptr 0 -""" + let ``Pin int byref parameter`` (langVersion, featureShouldActivate) = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefParameter.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -227,16 +159,10 @@ let pinIt (thing: byref) = [] let ``Pin int inref parmeter`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt (thing: inref) = - use ptr = fixed &thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntInrefParameter.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -259,16 +185,10 @@ let pinIt (thing: inref) = [] let ``Pin int outref parmeter`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt (thing: outref) = - use ptr = fixed &thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntOutrefParameter.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -292,19 +212,10 @@ let pinIt (thing: outref) = let ``Pin address of explicit field on this with default constructor class syntax`` (langVersion, featureShouldActivate) = // I think F# 7 and lower should have allowed this and that this was really just a bug, but we should preserve the existing behavior // when turning the feature off - Fsx """ -open Microsoft.FSharp.NativeInterop - -type Point() = - let mutable value = 42 - - member this.PinIt() = - let ptr = fixed &value - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfExplicitFieldOnThisWithDefaultCtorClassSyntax.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -327,17 +238,10 @@ type Point() = [] let ``Pin int byref local variable`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -let pinIt () = - let mutable thing = 42 - use ptr = fixed &thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefLocalVariable.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -361,17 +265,10 @@ let pinIt () = [] let ``Pin Span`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open System -open Microsoft.FSharp.NativeInterop - -let pinIt (thing: Span) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinSpan.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -395,21 +292,10 @@ let pinIt (thing: Span) = [] let ``Pin custom struct byref type without GetPinnableReference method - illegal`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open System -open System.Runtime.CompilerServices -open Microsoft.FSharp.NativeInterop - -[] -type BoringRefField<'T> = { Value: 'T } - -let pinIt (thing: BoringRefField) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinCustomStructByrefTypeWithoutGetPinnableReference.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -432,20 +318,10 @@ let pinIt (thing: BoringRefField) = [] let ``Pin type with method GetPinnableReference : unit -> byref`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -type RefField<'T>(_value) = - let mutable _value = _value - member this.GetPinnableReference () : byref<'T> = &_value - -let pinIt (thing: RefField<'T>) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -467,20 +343,10 @@ let pinIt (thing: RefField<'T>) = [] let ``Pin type with method GetPinnableReference : unit -> inref`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -type RefField<'T>(_value) = - let mutable _value = _value - member this.GetPinnableReference () : inref<'T> = &_value - -let pinIt (thing: RefField<'T>) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningInref.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -503,24 +369,10 @@ let pinIt (thing: RefField<'T>) = [] let ``Pin type with extension method GetPinnableReference : unit -> byref`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open System.Runtime.CompilerServices -open Microsoft.FSharp.NativeInterop - -type RefField<'T> = { mutable _value: 'T } - -[] -type RefFieldExtensions = - [] - static member GetPinnableReference(refField: RefField<'T>) : byref<'T> = &refField._value - -let pinIt (thing: RefField<'T>) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithExtensionGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -543,20 +395,10 @@ let pinIt (thing: RefField<'T>) = [] let ``Pin type with method GetPinnableReference with parameters - illegal`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -type StrangeType<'T>(_value) = - let mutable _value = _value - member this.GetPinnableReference(someValue: string) : byref<'T> = &_value - -let pinIt (thing: StrangeType<'T>) = - use ptr = fixed thing - NativePtr.get ptr 0 - """ + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceWithParameters.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -579,20 +421,10 @@ let pinIt (thing: StrangeType<'T>) = [] let ``Pin type with method GetPinnableReference with non-byref return type - illegal`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -type StrangeType<'T>(_value) = - let mutable _value = _value - member this.GetPinnableReference() : 'T = _value - -let pinIt (thing: StrangeType<'T>) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceWithNonByrefReturnType.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -615,22 +447,10 @@ let pinIt (thing: StrangeType<'T>) = [] let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -type RefField<'T>(_value) = - let mutable _value = _value - member this.GetPinnableReference (x: int) : string = string x - member this.GetPinnableReference (x: int, y: string) = string x + y - member this.GetPinnableReference () : byref<'T> = &_value - -let pinIt (thing: RefField<'T>) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithValidGetPinnableReferenceAndSeveralInvalidOverloads.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -653,20 +473,10 @@ let pinIt (thing: RefField<'T>) = [] let ``Pin type with private method GetPinnableReference - illegal`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -type StrangeType<'T>(_value) = - let mutable _value = _value - member private this.GetPinnableReference() : byref<'T> = _value - -let pinIt (thing: StrangeType<'T>) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithPrivateGetPinnableReference.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp @@ -689,20 +499,10 @@ let pinIt (thing: StrangeType<'T>) = [] let ``Pin type with static method GetPinnableReference - illegal`` (langVersion, featureShouldActivate) = featureShouldActivate |> ignore - Fsx """ -open Microsoft.FSharp.NativeInterop - -type StrangeType<'T>(_value) = - let mutable _value = _value - static member GetPinnableReference() : byref<'T> = Unchecked.defaultof> - -let pinIt (thing: StrangeType<'T>) = - use ptr = fixed thing - NativePtr.get ptr 0 -""" + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithStaticGetPinnableReference.fs") |> withLangVersion langVersion |> ignoreWarnings - |> typecheck + |> compile |> if featureShouldActivate then (fun comp -> comp diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfArrayElement.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfArrayElement.fs new file mode 100644 index 00000000000..c44f4c389fb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfArrayElement.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (arr: char[]) = + use ptr = fixed &arr[1] + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfExplicitFieldOnThis.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfExplicitFieldOnThis.fs new file mode 100644 index 00000000000..6215bccc864 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfExplicitFieldOnThis.fs @@ -0,0 +1,12 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type Point = + val mutable X: int + val mutable Y: int + + new(x: int, y: int) = { X = x; Y = y } + + member this.PinIt() = + use ptr = fixed &this.X + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfExplicitFieldOnThisWithDefaultCtorClassSyntax.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfExplicitFieldOnThisWithDefaultCtorClassSyntax.fs new file mode 100644 index 00000000000..88153fed1ce --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfExplicitFieldOnThisWithDefaultCtorClassSyntax.fs @@ -0,0 +1,9 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type Point() = + let mutable value = 42 + + member this.PinIt() = + let ptr = fixed &value + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfRecordField.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfRecordField.fs new file mode 100644 index 00000000000..707a0454dc1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinAddressOfRecordField.fs @@ -0,0 +1,8 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type Point = { mutable X: int; mutable Y: int } + +let pinIt (thing: Point) = + use ptr = fixed &thing.X + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinCustomStructByrefTypeWithoutGetPinnableReference.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinCustomStructByrefTypeWithoutGetPinnableReference.fs new file mode 100644 index 00000000000..936fd73f4a9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinCustomStructByrefTypeWithoutGetPinnableReference.fs @@ -0,0 +1,11 @@ +module FixedBindings +open System +open System.Runtime.CompilerServices +open Microsoft.FSharp.NativeInterop + +[] +type BoringRefField<'T> = { Value: 'T } + +let pinIt (thing: BoringRefField) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinGeneric.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinGeneric.fs new file mode 100644 index 00000000000..50bf16a6e0d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinGeneric.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: 'a) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinGenericWithUnmanagedConstraint.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinGenericWithUnmanagedConstraint.fs new file mode 100644 index 00000000000..81753f19205 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinGenericWithUnmanagedConstraint.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt<'a when 'a : unmanaged> (thing: 'a) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntByrefLocalVariable.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntByrefLocalVariable.fs new file mode 100644 index 00000000000..22cbe69a89c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntByrefLocalVariable.fs @@ -0,0 +1,7 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt () = + let mutable thing = 42 + use ptr = fixed &thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntByrefParameter.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntByrefParameter.fs new file mode 100644 index 00000000000..08499789c6b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntByrefParameter.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: byref) = + use ptr = fixed &thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntInrefParameter.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntInrefParameter.fs new file mode 100644 index 00000000000..2c147bfb57b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntInrefParameter.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: inref) = + use ptr = fixed &thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntOutrefParameter.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntOutrefParameter.fs new file mode 100644 index 00000000000..511fc200a0b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinIntOutrefParameter.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: outref) = + use ptr = fixed &thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedArray.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedArray.fs new file mode 100644 index 00000000000..a8853cb24eb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedArray.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (arr: char[]) = + use ptr = fixed arr + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedInt.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedInt.fs new file mode 100644 index 00000000000..0e9c150dcd5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedInt.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: int) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedObject.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedObject.fs new file mode 100644 index 00000000000..3e327811131 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedObject.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: obj) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedString.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedString.fs new file mode 100644 index 00000000000..95d259363d3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedString.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (str: string) = + use ptr = fixed str + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinSpan.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinSpan.fs new file mode 100644 index 00000000000..c8c53629802 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinSpan.fs @@ -0,0 +1,7 @@ +module FixedBindings +open System +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: Span) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWIthValidGetPinnableReferenceAndSeveralInvalidOverloads.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWIthValidGetPinnableReferenceAndSeveralInvalidOverloads.fs new file mode 100644 index 00000000000..be1242b4525 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWIthValidGetPinnableReferenceAndSeveralInvalidOverloads.fs @@ -0,0 +1,12 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type RefField<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference (x: int) : string = string x + member this.GetPinnableReference (x: int, y: string) = string x + y + member this.GetPinnableReference () : byref<'T> = &_value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs new file mode 100644 index 00000000000..c71f42eeb32 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs @@ -0,0 +1,14 @@ +module FixedBindings +open System.Runtime.CompilerServices +open Microsoft.FSharp.NativeInterop + +type RefField<'T> = { mutable _value: 'T } + +[] +type RefFieldExtensions = + [] + static member GetPinnableReference(refField: RefField<'T>) : byref<'T> = &refField._value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceReturningByref.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceReturningByref.fs new file mode 100644 index 00000000000..bf5981d0657 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceReturningByref.fs @@ -0,0 +1,10 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type RefField<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference () : byref<'T> = &_value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceReturningInref.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceReturningInref.fs new file mode 100644 index 00000000000..79f298d5809 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceReturningInref.fs @@ -0,0 +1,10 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type RefField<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference () : inref<'T> = &_value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceWithNonByrefReturnType.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceWithNonByrefReturnType.fs new file mode 100644 index 00000000000..1cb07ba948d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceWithNonByrefReturnType.fs @@ -0,0 +1,10 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type StrangeType<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference() : 'T = _value + +let pinIt (thing: StrangeType<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceWithParameters.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceWithParameters.fs new file mode 100644 index 00000000000..2d5bf5693ae --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithGetPinnableReferenceWithParameters.fs @@ -0,0 +1,10 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type StrangeType<'T>(_value) = + let mutable _value = _value + member this.GetPinnableReference(someValue: string) : byref<'T> = &_value + +let pinIt (thing: StrangeType<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithPrivateGetPinnableReference.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithPrivateGetPinnableReference.fs new file mode 100644 index 00000000000..a1223d8e9c4 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithPrivateGetPinnableReference.fs @@ -0,0 +1,10 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type StrangeType<'T>(_value) = + let mutable _value = _value + member private this.GetPinnableReference() : byref<'T> = _value + +let pinIt (thing: StrangeType<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithStaticGetPinnableReference.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithStaticGetPinnableReference.fs new file mode 100644 index 00000000000..db7317e9122 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithStaticGetPinnableReference.fs @@ -0,0 +1,10 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type StrangeType<'T>(_value) = + let mutable _value = _value + static member GetPinnableReference() : byref<'T> = Unchecked.defaultof> + +let pinIt (thing: StrangeType<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file From 01cbd18abb19f03d46873ae937d1fca837dd8a30 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 00:57:52 -0600 Subject: [PATCH 39/51] Split fixed binding Language test cases --- .../Language/FixedBindings/FixedBindings.fs | 594 +++++++++--------- 1 file changed, 300 insertions(+), 294 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index fe3ad211366..c672eb0c217 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -127,395 +127,401 @@ module Legacy = (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] + [] + [] + let ``Pin int byref parameter`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefParameter.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ] + + [] + [] + let ``Pin int inref parmeter`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntInrefParameter.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ] + + [] + [] + let ``Pin int outref parmeter`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntOutrefParameter.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ] + + [] + [] + let ``Pin address of explicit field on this with default constructor class syntax`` langVersion = + // I think F# 7 and lower should have allowed this and that this was really just a bug, but we should preserve the existing behavior + // when turning the feature off + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfExplicitFieldOnThisWithDefaultCtorClassSyntax.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 8, Col 13, Line 8, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 8, Col 13, Line 8, Col 16, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ] + + [] + [] + let ``Pin int byref local variable`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefLocalVariable.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ] + +#if NETCOREAPP + [] + [] + let ``Pin Span`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinSpan.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'."""); + (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ] +#endif + + [] + [] + let ``Pin custom struct byref type without GetPinnableReference method - illegal`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinCustomStructByrefTypeWithoutGetPinnableReference.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + [] + [] + let ``Pin type with method GetPinnableReference : unit -> byref`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningByref.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")] + + [] + [] + let ``Pin type with method GetPinnableReference : unit -> inref`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningInref.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ] + + [] + [] + let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithExtensionGetPinnableReferenceReturningByref.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + ] + + [] + [] + let ``Pin type with method GetPinnableReference with parameters - illegal`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceWithParameters.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + [] + [] + let ``Pin type with method GetPinnableReference with non-byref return type - illegal`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceWithNonByrefReturnType.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + [] + [] + let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithValidGetPinnableReferenceAndSeveralInvalidOverloads.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 11, Col 9, Line 11, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")] + + [] + [] + let ``Pin type with private method GetPinnableReference - illegal`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithPrivateGetPinnableReference.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + [] + [] + let ``Pin type with static method GetPinnableReference - illegal`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithStaticGetPinnableReference.fs") + |> withLangVersion langVersion + |> ignoreWarnings + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + // FS-1081 - Extend fixed bindings module ExtendedFixedBindings = [] - [] - [] - let ``Pin int byref parameter`` (langVersion, featureShouldActivate) = + [] + let ``Pin int byref parameter`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefParameter.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") - ]) + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] [] - [] - [] - let ``Pin int inref parmeter`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin int inref parmeter`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntInrefParameter.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") - ]) + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] [] - [] - [] - let ``Pin int outref parmeter`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin int outref parmeter`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntOutrefParameter.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") - ]) + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] [] - [] - [] - let ``Pin address of explicit field on this with default constructor class syntax`` (langVersion, featureShouldActivate) = + [] + let ``Pin address of explicit field on this with default constructor class syntax`` langVersion = // I think F# 7 and lower should have allowed this and that this was really just a bug, but we should preserve the existing behavior // when turning the feature off FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfExplicitFieldOnThisWithDefaultCtorClassSyntax.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 8, Col 13, Line 8, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 9, Col 9, Line 9, Col 22, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 8, Col 13, Line 8, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 8, Col 13, Line 8, Col 16, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") - ]) + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 8, Col 13, Line 8, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 9, Col 9, Line 9, Col 22, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] [] - [] - [] - let ``Pin int byref local variable`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin int byref local variable`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefLocalVariable.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") - ]) + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] #if NETCOREAPP [] - [] - [] - let ``Pin Span`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin Span`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinSpan.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'."""); - (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") - ]) + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] #endif [] - [] - [] - let ``Pin custom struct byref type without GetPinnableReference method - illegal`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin custom struct byref type without GetPinnableReference method - illegal`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinCustomStructByrefTypeWithoutGetPinnableReference.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] [] - [] - [] - let ``Pin type with method GetPinnableReference : unit -> byref`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin type with method GetPinnableReference : unit -> byref`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp |> shouldSucceed |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")]) - + ] + [] - [] - [] - let ``Pin type with method GetPinnableReference : unit -> inref`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin type with method GetPinnableReference : unit -> inref`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningInref.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") - ]) + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] [] - [] - [] - let ``Pin type with extension method GetPinnableReference : unit -> byref`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithExtensionGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") - ]) + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] [] - [] - [] - let ``Pin type with method GetPinnableReference with parameters - illegal`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin type with method GetPinnableReference with parameters - illegal`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceWithParameters.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] [] - [] - [] - let ``Pin type with method GetPinnableReference with non-byref return type - illegal`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin type with method GetPinnableReference with non-byref return type - illegal`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceWithNonByrefReturnType.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] [] - [] - [] - let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithValidGetPinnableReferenceAndSeveralInvalidOverloads.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldSucceed - |> withDiagnostics [ - (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 11, Col 9, Line 11, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")] - ) + |> shouldSucceed + |> withDiagnostics [ + (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] [] - [] - [] - let ``Pin type with private method GetPinnableReference - illegal`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin type with private method GetPinnableReference - illegal`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithPrivateGetPinnableReference.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] [] - [] - [] - let ``Pin type with static method GetPinnableReference - illegal`` (langVersion, featureShouldActivate) = - featureShouldActivate |> ignore + [] + let ``Pin type with static method GetPinnableReference - illegal`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithStaticGetPinnableReference.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile - |> if featureShouldActivate then - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) - else - (fun comp -> - comp - |> shouldFail - |> withDiagnostics [ - (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") - ]) + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] From 8c74b6d0d3e4fab162b194deeda96c96aa5a474e Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 01:12:13 -0600 Subject: [PATCH 40/51] Raise recoverable errors --- src/Compiler/Checking/CheckExpressions.fs | 4 ++-- .../Language/FixedBindings/FixedBindings.fs | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 705b43f062f..2f29fc27a8a 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10324,7 +10324,7 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy match getPinnableReferenceMInfo with | Some mInfo -> - checkLanguageFeatureError g.langVersion LanguageFeature.ExtendedFixedBindings mBinding + checkLanguageFeatureAndRecover g.langVersion LanguageFeature.ExtendedFixedBindings mBinding let mInst = FreshenMethInfo mBinding mInfo let pinnableReference, actualRetTy = BuildPossiblyConditionalMethodCall cenv env NeverMutates mBinding false mInfo NormalValUse mInst [ fixedExpr ] [] None @@ -10376,7 +10376,7 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy | _ -> false if not okByRef then - error (languageFeatureError g.langVersion LanguageFeature.ExtendedFixedBindings mBinding) + errorR (languageFeatureError g.langVersion LanguageFeature.ExtendedFixedBindings mBinding) let elemTy = destByrefTy g overallExprTy UnifyTypes cenv env mBinding (mkNativePtrTy g elemTy) overallPatTy diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index c672eb0c217..f2931f4150b 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -138,6 +138,7 @@ module Legacy = |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] [] @@ -151,6 +152,7 @@ module Legacy = |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] [] @@ -164,6 +166,7 @@ module Legacy = |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] [] @@ -179,6 +182,7 @@ module Legacy = |> withDiagnostics [ (Warning 9, Line 8, Col 13, Line 8, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3350, Line 8, Col 13, Line 8, Col 16, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 9, Col 9, Line 9, Col 22, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] [] @@ -192,6 +196,7 @@ module Legacy = |> withDiagnostics [ (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] #if NETCOREAPP @@ -204,8 +209,9 @@ module Legacy = |> compile |> shouldFail |> withDiagnostics [ - (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'."""); + (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] #endif @@ -232,7 +238,9 @@ module Legacy = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")] + (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] [] [] @@ -245,6 +253,7 @@ module Legacy = |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] [] @@ -258,6 +267,7 @@ module Legacy = |> withDiagnostics [ (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] [] @@ -296,7 +306,9 @@ module Legacy = |> shouldFail |> withDiagnostics [ (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 11, Col 9, Line 11, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""")] + (Error 3350, Line 11, Col 9, Line 11, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] [] [] From bb99236c66aa95a5d41dc65bd2d232936dca9c95 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 01:53:28 -0600 Subject: [PATCH 41/51] Add more negative fixed binding tests --- .../Language/FixedBindings/FixedBindings.fs | 91 +++++++++++++++++++ .../PinNakedArrayWithMismatchingType.fs | 6 ++ .../PinNakedStringWithMismatchingType.fs | 6 ++ ...ExtensionGetPinnableReferenceReturnType.fs | 14 +++ ...smatchingGetPinnableReferenceReturnType.fs | 10 ++ 5 files changed, 127 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedArrayWithMismatchingType.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedStringWithMismatchingType.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithMismatchingExtensionGetPinnableReferenceReturnType.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithMismatchingGetPinnableReferenceReturnType.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index f2931f4150b..935cc5ccf55 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -32,6 +32,40 @@ module Legacy = (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] + [] + [] + [] + let ``Pin naked array with mismatching type`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedArrayWithMismatchingType.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 31, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 1, Line 5, Col 9, Line 5, Col 31, """Type mismatch. Expecting a + 'nativeptr' +but given a + 'nativeptr' +The type 'int' does not match the type 'byte'""") + ] + + [] + [] + [] + let ``Pin naked string with mismatching type`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedStringWithMismatchingType.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 31, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 1, Line 5, Col 9, Line 5, Col 31, """Type mismatch. Expecting a + 'nativeptr' +but given a + 'nativeptr' +The type 'char' does not match the type 'byte'""") + ] + [] [] [] @@ -336,6 +370,35 @@ module Legacy = (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] + [] + [] + let ``Pin type with mismatching GetPinnableReference return type`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithMismatchingGetPinnableReferenceReturnType.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 31, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 9, Col 9, Line 9, Col 31, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 1, Line 9, Col 9, Line 9, Col 31, "Type mismatch. Expecting a + 'nativeptr' +but given a + 'nativeptr' +The type 'int' does not match the type 'char'") + ] + + [] + [] + let ``Pin type with mismatching extension GetPinnableReference return type`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithMismatchingExtensionGetPinnableReferenceReturnType.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + ] // FS-1081 - Extend fixed bindings module ExtendedFixedBindings = @@ -536,4 +599,32 @@ module ExtendedFixedBindings = |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + [] + [] + let ``Pin type with mismatching GetPinnableReference return type`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithMismatchingGetPinnableReferenceReturnType.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 9, Col 9, Line 9, Col 31, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 1, Line 9, Col 9, Line 9, Col 31, "Type mismatch. Expecting a + 'nativeptr' +but given a + 'nativeptr' +The type 'int' does not match the type 'char'") + ] + + [] + [] + let ``Pin type with mismatching extension GetPinnableReference return type`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithMismatchingExtensionGetPinnableReferenceReturnType.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedArrayWithMismatchingType.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedArrayWithMismatchingType.fs new file mode 100644 index 00000000000..af41d106065 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedArrayWithMismatchingType.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (arr: int[]) = + use (ptr: nativeptr) = fixed arr + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedStringWithMismatchingType.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedStringWithMismatchingType.fs new file mode 100644 index 00000000000..8481f91cfc3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedStringWithMismatchingType.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (thing: string) = + use (ptr: nativeptr) = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithMismatchingExtensionGetPinnableReferenceReturnType.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithMismatchingExtensionGetPinnableReferenceReturnType.fs new file mode 100644 index 00000000000..c71f42eeb32 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithMismatchingExtensionGetPinnableReferenceReturnType.fs @@ -0,0 +1,14 @@ +module FixedBindings +open System.Runtime.CompilerServices +open Microsoft.FSharp.NativeInterop + +type RefField<'T> = { mutable _value: 'T } + +[] +type RefFieldExtensions = + [] + static member GetPinnableReference(refField: RefField<'T>) : byref<'T> = &refField._value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithMismatchingGetPinnableReferenceReturnType.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithMismatchingGetPinnableReferenceReturnType.fs new file mode 100644 index 00000000000..3383d01055c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithMismatchingGetPinnableReferenceReturnType.fs @@ -0,0 +1,10 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type StrangeType() = + let mutable _value = 42 + member this.GetPinnableReference() = &_value + +let pinIt (thing: StrangeType) = + use (ptr: nativeptr) = fixed thing + NativePtr.get ptr 0 \ No newline at end of file From 0c4ea8b7d42192da7fa88308311833564c723b1f Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 02:07:05 -0600 Subject: [PATCH 42/51] Add test verifying that null guard in fixed bindings against GetPinnableReference works --- .../EmittedIL/FixedBindings/FixedBindings.fs | 44 +++++++++++++++++++ ...NullValueOfTypeWithGetPinnableReference.fs | 22 ++++++++++ 2 files changed, 66 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNullValueOfTypeWithGetPinnableReference.fs diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs index a972f5bbdff..b0f0d0dccb3 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs @@ -1,6 +1,7 @@ namespace EmittedIL.FixedBindings open System.Reflection +open Microsoft.FSharp.NativeInterop open Xunit open FSharp.Compiler.Diagnostics open FSharp.Test @@ -625,3 +626,46 @@ module ExtendedFixedBindings = IL_001b: ldobj !!a IL_0020: ret } """ ] + + [] + let ``Pin null value of type with GetPinnableReference`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNullValueOfTypeWithGetPinnableReference.fs") + |> withLangVersion langVersion + |> withOptions ["--nowarn:9"] + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static void pinIt(class FixedExpressions/RefField`1 thing) cil managed + { + + .maxstack 4 + .locals init (native int V_0, + int32& pinned V_1) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_000e + + IL_0003: ldarg.0 + IL_0004: callvirt instance !0& class FixedExpressions/RefField`1::GetPinnableReference() + IL_0009: stloc.1 + IL_000a: ldloc.1 + IL_000b: conv.i + IL_000c: br.s IL_000f + + IL_000e: ldarg.0 + IL_000f: stloc.0 + IL_0010: ldc.i8 0x0 + IL_0019: conv.i + IL_001a: ldloc.0 + IL_001b: bne.un.s IL_002e + + IL_001d: ldstr "Success - null guard worked" + IL_0022: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0027: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_002c: pop + IL_002d: ret + + IL_002e: ldstr "Test failed - null guard did not work" + IL_0033: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0038: throw + } +"""] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNullValueOfTypeWithGetPinnableReference.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNullValueOfTypeWithGetPinnableReference.fs new file mode 100644 index 00000000000..c393306599f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNullValueOfTypeWithGetPinnableReference.fs @@ -0,0 +1,22 @@ +module FixedExpressions +open Microsoft.FSharp.NativeInterop +open System.Runtime.CompilerServices +open System + +type RefField<'T>(_value) = + let mutable _value = _value + member this.Value = _value + [] + member this.GetPinnableReference () : byref<'T> = &_value + +let pinIt (thing: RefField) = + use ptr = fixed thing + if NativePtr.isNullPtr ptr then + printfn "Success - null guard worked" + else + failwith "Test failed - null guard did not work" + +[] +let main _ = + pinIt Unchecked.defaultof> + 0 \ No newline at end of file From 44f1e09714864a8c1bf3490f84876efbe65b30ab Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 02:12:24 -0600 Subject: [PATCH 43/51] Adjust wording --- src/Compiler/FSComp.txt | 4 +- src/Compiler/xlf/FSComp.txt.cs.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.de.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.es.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.fr.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.it.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.ja.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.ko.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.pl.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.ru.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.tr.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 6 +-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 6 +-- .../Language/FixedBindings/FixedBindings.fs | 52 +++++++++---------- tests/fsharp/typecheck/sigs/neg97.bsl | 4 +- tests/fsharp/typecheck/sigs/neg97.vsbsl | 4 +- 17 files changed, 71 insertions(+), 71 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 9bf0b148669..a9276e1fb00 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1381,7 +1381,7 @@ tcTupleStructMismatch,"One tuple type is a struct tuple, the other is a referenc 3203,parsInvalidUseOfRec,"Invalid use of 'rec' keyword" 3204,tcStructUnionMultiCaseDistinctFields,"If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'." 3206,CallerMemberNameIsOverriden,"The CallerMemberNameAttribute applied to parameter '%s' will have no effect. It is overridden by the CallerFilePathAttribute." -3207,tcFixedNotAllowed,"Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()" +3207,tcFixedNotAllowed,"Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()" 3208,tcCouldNotFindOffsetToStringData,"Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression." 3209,chkNoByrefAddressOfLocal,"The address of the variable '%s' 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." 3210,tcNamedActivePattern,"%s is an active pattern and cannot be treated as a discriminated union case with named fields." @@ -1586,7 +1586,7 @@ featureStrictIndentation,"Raises errors on incorrect indentation, allows better featureConstraintIntersectionOnFlexibleTypes,"Constraint intersection on flexible types" featureChkNotTailRecursive,"Raises warnings if a member or function has the 'TailCall' attribute, but is not being used in a tail recursive way." featureWhileBang,"'while!' expression" -featureExtendedFixedBindings,"extended fixed bindings for byrefs, inrefs, and GetPinnableReference" +featureExtendedFixedBindings,"extended fixed bindings for byref and GetPinnableReference" featurePreferStringGetPinnableReference,"prefer String.GetPinnableReference in fixed bindings" 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 43f571d8949..64fb8d7bff1 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() Neplatné použití fixed. fixed se dá použít jenom v deklaraci ve tvaru use x = fixed expr, kde výraz je pole, adresa pole nebo adresa prvku pole nebo řetězce. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index eecc0f6a15c..a0f465874b5 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() Ungültige Verwendung von "fixed". "fixed" darf ausschließlich in einer Deklaration der Form "use x = fixed expr" verwendet werden. Dabei ist der Ausdruck ein Array, die Adresse eines Felds, die Adresse eines Arrayelements oder eine Zeichenfolge. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index cf432dd5e7e..687fa4d6524 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() Uso no válido de 'fixed'. 'fixed' debe utilizarse solo en una declaración del formulario 'use x = fixed expr' donde la expresión es una matriz, la dirección de un campo, la dirección de un elemento de matriz o una cadena' diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 3f7bdb33063..014f244f72f 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() Utilisation non valide de 'fixed'. Utilisez uniquement 'fixed' dans une déclaration de la forme 'use x = fixed expr' où l'expression est un tableau, l'adresse d'un champ, l'adresse d'un élément de tableau ou une chaîne diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 21ad24ac0bd..ef5aee938b7 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() Uso non valido di 'fixed'. 'fixed' può essere usato solo in una dichiarazione in formato 'use x = fixed expr', in cui l'espressione è una matrice, l'indirizzo di un campo, l'indirizzo di un elemento di matrice oppure una stringa diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index edbb9a09c15..5e0d4816843 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() 'fixed' の使い方が正しくありません。'fixed' を使用できるのは書式 'use x = fixed expr' の宣言内だけで、この式は配列、フィールドのアドレス、配列要素のアドレス、または文字列です diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 56e2f9ca1ac..17f6a656387 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() 'fixed'를 잘못 사용했습니다. 'fixed'는 식이 배열, 필드의 주소, 배열 요소 또는 문자열의 주소인 경우 'use x = fixed expr' 형식의 선언에만 사용할 수 있습니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 4faff7245ee..33e6ceac663 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() Nieprawidłowe użycie wyrażenia „fixed”. Wyrażenia „fixed” można użyć tylko w deklaracji w postaci „use x = fixed expr”, gdzie wyrażenie jest tablicą, adresem pola, adresem elementu tablicy lub ciągiem diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 95bf5c7365d..5122f8a160a 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() Uso inválido da 'fixed'. 'fixed' somente pode ser usada em uma declaração no formato 'use x = fixed expr', em que a expressão é uma matriz, o endereço de um campo, o endereço de um elemento de matriz ou uma cadeia de caracteres diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 3877e9e92b2..8e1430bd842 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() Недопустимое использование выражения "fixed". Выражение "fixed" можно использовать только в объявлении формы "use x = fixed expr", где выражение является массивом, адресом поля, адресом элемента массива или строки. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 4f6df292e2d..ab4079f393a 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() Geçersiz 'fixed' kullanımı. 'fixed' yalnızca 'use x = fixed expr' biçimindeki bir bildirimde kullanılabilir. Burada ifade bir dizi, bir alanın adresi, bir dizi öğesinin adresi veya bir dizedir diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 56c92f12c1a..6c6d4861b46 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() 无效的 "fixed" 使用。"fixed" 只能用在 "use x = fixed expr" 形式的声明中,其中表达式为数组、字段的地址、数组元素或字符串的地址 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index cce10525be0..281190c3b17 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -288,8 +288,8 @@ - extended fixed bindings for byrefs, inrefs, and GetPinnableReference - extended fixed bindings for byrefs, inrefs, and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference + extended fixed bindings for byref and GetPinnableReference @@ -7858,7 +7858,7 @@ - Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() + Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() 使用 'fixed' 無效。'fixed' 僅能用於格式為 'use x = fixed expr' 的宣告中,其中運算式為陣列、欄位的位址、陣列元素的位址或字串 diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index 935cc5ccf55..1104c9aa143 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -118,7 +118,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] @@ -132,7 +132,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -145,7 +145,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -158,7 +158,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -171,7 +171,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -185,7 +185,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -199,7 +199,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 5, Col 9, Line 5, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 6, Col 5, Line 6, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -215,7 +215,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 8, Col 13, Line 8, Col 16, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 8, Col 13, Line 8, Col 16, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 8, Col 13, Line 8, Col 16, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 9, Col 9, Line 9, Col 22, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -229,7 +229,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -244,7 +244,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 6, Col 9, Line 6, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 6, Col 9, Line 6, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 7, Col 5, Line 7, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] #endif @@ -259,7 +259,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -272,7 +272,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -286,7 +286,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 9, Col 9, Line 9, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 10, Col 5, Line 10, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -300,7 +300,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -314,7 +314,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -327,7 +327,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -340,7 +340,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 11, Col 9, Line 11, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 11, Col 9, Line 11, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 11, Col 9, Line 11, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 12, Col 5, Line 12, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -354,7 +354,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -367,7 +367,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -379,7 +379,7 @@ The type 'char' does not match the type 'byte'""") |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 31, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 9, Col 9, Line 9, Col 31, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 9, Col 9, Line 9, Col 31, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Error 1, Line 9, Col 9, Line 9, Col 31, "Type mismatch. Expecting a 'nativeptr' but given a @@ -396,7 +396,7 @@ The type 'int' does not match the type 'char'") |> shouldFail |> withDiagnostics [ (Warning 9, Line 13, Col 9, Line 13, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed bindings for byrefs, inrefs, and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") + (Error 3350, Line 13, Col 9, Line 13, Col 12, """Feature 'extended fixed bindings for byref and GetPinnableReference' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.""") (Warning 9, Line 14, Col 5, Line 14, Col 18, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") ] @@ -494,7 +494,7 @@ module ExtendedFixedBindings = |> shouldFail |> withDiagnostics [ (Warning 9, Line 10, Col 9, Line 10, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 10, Col 9, Line 10, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -546,7 +546,7 @@ module ExtendedFixedBindings = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -559,7 +559,7 @@ module ExtendedFixedBindings = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -585,7 +585,7 @@ module ExtendedFixedBindings = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] @@ -598,7 +598,7 @@ module ExtendedFixedBindings = |> shouldFail |> withDiagnostics [ (Warning 9, Line 9, Col 9, Line 9, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") - (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + (Error 3207, Line 9, Col 9, Line 9, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") ] [] diff --git a/tests/fsharp/typecheck/sigs/neg97.bsl b/tests/fsharp/typecheck/sigs/neg97.bsl index 3da9fec6878..4681334f765 100644 --- a/tests/fsharp/typecheck/sigs/neg97.bsl +++ b/tests/fsharp/typecheck/sigs/neg97.bsl @@ -3,11 +3,11 @@ neg97.fs(13,1,13,10): typecheck error FS0256: A value must be mutable in order t neg97.fs(16,9,16,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(16,9,16,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() +neg97.fs(16,9,16,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(20,9,20,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() +neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(26,20,26,32): typecheck error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution diff --git a/tests/fsharp/typecheck/sigs/neg97.vsbsl b/tests/fsharp/typecheck/sigs/neg97.vsbsl index 3da9fec6878..4681334f765 100644 --- a/tests/fsharp/typecheck/sigs/neg97.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg97.vsbsl @@ -3,11 +3,11 @@ neg97.fs(13,1,13,10): typecheck error FS0256: A value must be mutable in order t neg97.fs(16,9,16,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(16,9,16,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() +neg97.fs(16,9,16,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(20,9,20,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. -neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, a string, a byref, an inref, or a type implementing GetPinnableReference() +neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference() neg97.fs(26,20,26,32): typecheck error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution From cfaf3e3bd0d19bcd50737b5a3732f70472340ec3 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 02:27:58 -0600 Subject: [PATCH 44/51] Split one remaining test case --- .../EmittedIL/FixedBindings/FixedBindings.fs | 125 ++++++++++++------ 1 file changed, 86 insertions(+), 39 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs index b0f0d0dccb3..a3c729d6e9b 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs @@ -10,9 +10,8 @@ open FSharp.Test.Compiler module Legacy = [] - [] - [] - let ``Pin naked string`` (langVersion, featureShouldActivate) = + [] + let ``Pin naked string`` langVersion = let runtimeSupportsStringGetPinnableReference = typeof.GetMethods() |> Seq.exists (fun m -> m.Name = "GetPinnableReference") @@ -28,41 +27,7 @@ module Legacy = |> withLangVersion langVersion |> withOptions ["--nowarn:9"] |> compile - |> if featureShouldActivate && runtimeSupportsStringGetPinnableReference then - (fun comp -> - comp - |> verifyIL [""" - .method public static char pinIt(string str) cil managed - { - - .maxstack 5 - .locals init (native int V_0, - char& pinned V_1) - IL_0000: ldarg.0 - IL_0001: brfalse.s IL_000e - - IL_0003: ldarg.0 - IL_0004: callvirt instance char& modreq([runtime]System.Runtime.InteropServices.InAttribute) [runtime]System.String::GetPinnableReference() - IL_0009: stloc.1 - IL_000a: ldloc.1 - IL_000b: conv.i - IL_000c: br.s IL_000f - - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldloc.0 - IL_0011: ldc.i4.0 - IL_0012: conv.i - IL_0013: sizeof [runtime]System.Char - IL_0019: mul - IL_001a: add - IL_001b: ldobj [runtime]System.Char - IL_0020: ret - } """ ]) - else - (fun comp -> - comp - |> verifyIL [""" + |> verifyIL [""" .method public static char pinIt(string str) cil managed { @@ -90,7 +55,7 @@ module Legacy = IL_001b: add IL_001c: ldobj [runtime]System.Char IL_0021: ret - } """ ]) + } """ ] [] [] @@ -237,6 +202,88 @@ module Legacy = } """ ] module ExtendedFixedBindings = + [] + [] + let ``Pin naked string`` langVersion = + let runtimeSupportsStringGetPinnableReference = + typeof.GetMethods() + |> Seq.exists (fun m -> m.Name = "GetPinnableReference") + +// Sanity check precondition: if .Net Framework were to ever get GetPinnableReference, we'll know here +#if NETCOREAPP3_0_OR_GREATER + Assert.True(runtimeSupportsStringGetPinnableReference) +#else + Assert.False(runtimeSupportsStringGetPinnableReference) +#endif + + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedString.fs") + |> withLangVersion langVersion + |> withOptions ["--nowarn:9"] + |> compile + |> if runtimeSupportsStringGetPinnableReference then + (fun comp -> + comp + |> verifyIL [""" + .method public static char pinIt(string str) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + char& pinned V_1) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_000e + + IL_0003: ldarg.0 + IL_0004: callvirt instance char& modreq([runtime]System.Runtime.InteropServices.InAttribute) [runtime]System.String::GetPinnableReference() + IL_0009: stloc.1 + IL_000a: ldloc.1 + IL_000b: conv.i + IL_000c: br.s IL_000f + + IL_000e: ldarg.0 + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: ldc.i4.0 + IL_0012: conv.i + IL_0013: sizeof [runtime]System.Char + IL_0019: mul + IL_001a: add + IL_001b: ldobj [runtime]System.Char + IL_0020: ret + } """ ]) + else + (fun comp -> + comp + |> verifyIL [""" + .method public static char pinIt(string str) cil managed + { + + .maxstack 5 + .locals init (native int V_0, + string pinned V_1) + IL_0000: ldarg.0 + IL_0001: stloc.1 + IL_0002: ldarg.0 + IL_0003: brfalse.s IL_000f + + IL_0005: ldarg.0 + IL_0006: conv.i + IL_0007: call int32 [runtime]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData() + IL_000c: add + IL_000d: br.s IL_0010 + + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldloc.0 + IL_0012: ldc.i4.0 + IL_0013: conv.i + IL_0014: sizeof [runtime]System.Char + IL_001a: mul + IL_001b: add + IL_001c: ldobj [runtime]System.Char + IL_0021: ret + } """ ]) + [] let ``Pin int byref of parameter`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefOfParameter.fs") From 351b155102f19736e692c274cf7a16e8b49c8575 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 02:46:19 -0600 Subject: [PATCH 45/51] Small test refactor --- .../EmittedIL/FixedBindings/FixedBindings.fs | 47 +++++++------------ 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs index a3c729d6e9b..72862e84970 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs @@ -12,20 +12,9 @@ module Legacy = [] [] let ``Pin naked string`` langVersion = - let runtimeSupportsStringGetPinnableReference = - typeof.GetMethods() - |> Seq.exists (fun m -> m.Name = "GetPinnableReference") - -// Sanity check precondition: if .Net Framework were to ever get GetPinnableReference, we'll know here -#if NETCOREAPP3_0_OR_GREATER - Assert.True(runtimeSupportsStringGetPinnableReference) -#else - Assert.False(runtimeSupportsStringGetPinnableReference) -#endif - FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedString.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compile |> verifyIL [""" .method public static char pinIt(string str) cil managed @@ -63,7 +52,7 @@ module Legacy = let ``Pin naked array`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedArray.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compile |> verifyIL [""" .method public static char pinIt(char[] arr) cil managed @@ -110,7 +99,7 @@ module Legacy = let ``Pin address of record field`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfRecordField.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> verifyIL [""" .method public static int32 pinIt(class FixedBindings/Point thing) cil managed @@ -141,7 +130,7 @@ module Legacy = let ``Pin address of explicit field on this`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfExplicitFieldOnThis.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -174,7 +163,7 @@ module Legacy = let ``Pin address of array element`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinAddressOfArrayElement.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -218,7 +207,7 @@ module ExtendedFixedBindings = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedString.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compile |> if runtimeSupportsStringGetPinnableReference then (fun comp -> @@ -288,7 +277,7 @@ module ExtendedFixedBindings = let ``Pin int byref of parameter`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefOfParameter.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -317,7 +306,7 @@ module ExtendedFixedBindings = let ``Pin int byref of local variable`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinIntByrefOfLocalVariable.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -362,7 +351,7 @@ module ExtendedFixedBindings = let ``Pin Span via manual GetPinnableReference call`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinSpanWithManualGetPinnableReferenceCall.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -392,7 +381,7 @@ module ExtendedFixedBindings = let ``Pin Span`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinSpan.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -422,7 +411,7 @@ module ExtendedFixedBindings = let ``Pin generic ReadOnlySpan`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinGenericReadOnlySpan.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -455,7 +444,7 @@ module ExtendedFixedBindings = let ``Pin type with method GetPinnableReference : unit -> byref`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -491,7 +480,7 @@ module ExtendedFixedBindings = let ``Pin type with method GetPinnableReference : unit -> inref`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithGetPinnableReferenceReturningInref.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -528,7 +517,7 @@ module ExtendedFixedBindings = // Effectively tests the same thing as the test with Span, but this works on .NET Framework FsFromPath (__SOURCE_DIRECTORY__ ++ "PinStructTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -564,7 +553,7 @@ module ExtendedFixedBindings = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinCSharpTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> withReferences [csLib] - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -609,7 +598,7 @@ module ExtendedFixedBindings = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinCSharpByrefStructTypeWithGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> withReferences [csLib] - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -640,7 +629,7 @@ module ExtendedFixedBindings = let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithExtensionGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" @@ -678,7 +667,7 @@ module ExtendedFixedBindings = let ``Pin null value of type with GetPinnableReference`` langVersion = FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNullValueOfTypeWithGetPinnableReference.fs") |> withLangVersion langVersion - |> withOptions ["--nowarn:9"] + |> withNoWarn 9 |> compileExeAndRun |> shouldSucceed |> verifyIL [""" From 45db0e614b8f2c9353ef7492a7e80a9e828afb9b Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 10:13:13 -0600 Subject: [PATCH 46/51] Add an F# style extension method test for GetPinnableReference --- .../EmittedIL/FixedBindings/FixedBindings.fs | 42 ++++++++++++++++++- ...sionGetPinnableReferenceReturningByref.fs} | 0 ...nsionGetPinnableReferenceReturningByref.fs | 20 +++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) rename tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/{PinTypeWithExtensionGetPinnableReferenceReturningByref.fs => PinTypeWithCSharpStyleExtensionGetPinnableReferenceReturningByref.fs} (100%) create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithFSharpStyleExtensionGetPinnableReferenceReturningByref.fs diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs index 72862e84970..edf188f4076 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs @@ -626,8 +626,8 @@ module ExtendedFixedBindings = #endif [] - let ``Pin type with extension method GetPinnableReference : unit -> byref`` langVersion = - FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithExtensionGetPinnableReferenceReturningByref.fs") + let ``Pin type with C# style extension method GetPinnableReference : unit -> byref`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithCSharpStyleExtensionGetPinnableReferenceReturningByref.fs") |> withLangVersion langVersion |> withNoWarn 9 |> compileExeAndRun @@ -662,6 +662,44 @@ module ExtendedFixedBindings = IL_001b: ldobj !!a IL_0020: ret } """ ] + + [] + let ``Pin type with F# style extension method GetPinnableReference : unit -> byref`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithFSharpStyleExtensionGetPinnableReferenceReturningByref.fs") + |> withLangVersion langVersion + |> withNoWarn 9 + |> compileExeAndRun + |> shouldSucceed + |> verifyIL [""" + .method public static !!T pinIt(class FixedBindings/RefField`1 thing) cil managed + { + .param type T + .custom instance void System.Runtime.CompilerServices.IsUnmanagedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 5 + .locals init (native int V_0, + !!T& pinned V_1) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_000e + + IL_0003: ldarg.0 + IL_0004: callvirt instance !0& class FixedBindings/RefField`1::GetPinnableReference() + IL_0009: stloc.1 + IL_000a: ldloc.1 + IL_000b: conv.i + IL_000c: br.s IL_000f + + IL_000e: ldarg.0 + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: ldc.i4.0 + IL_0012: conv.i + IL_0013: sizeof !!T + IL_0019: mul + IL_001a: add + IL_001b: ldobj !!T + IL_0020: ret + } """ ] [] let ``Pin null value of type with GetPinnableReference`` langVersion = diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithCSharpStyleExtensionGetPinnableReferenceReturningByref.fs similarity index 100% rename from tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithExtensionGetPinnableReferenceReturningByref.fs rename to tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithCSharpStyleExtensionGetPinnableReferenceReturningByref.fs diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithFSharpStyleExtensionGetPinnableReferenceReturningByref.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithFSharpStyleExtensionGetPinnableReferenceReturningByref.fs new file mode 100644 index 00000000000..b54bebeeef8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinTypeWithFSharpStyleExtensionGetPinnableReferenceReturningByref.fs @@ -0,0 +1,20 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop +open System.Runtime.CompilerServices + +type RefField<'T> = { mutable _value: 'T } +type RefField<'T> with + [] + member this.GetPinnableReference() : byref<'T> = &this._value + +let pinIt (thing: RefField<'T>) = + use ptr = fixed thing + NativePtr.get ptr 0 + +[] +let main _ = + let mutable x = 42 + let refToX = { _value = x } + let y = pinIt refToX + if y <> x then failwith "y did not equal x" + 0 \ No newline at end of file From 557ef00ff1119c1c7c97a7ef92cf3d913c85cfa8 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 10:28:54 -0600 Subject: [PATCH 47/51] Add some more fixed binding negative tests for sanity --- .../Language/FixedBindings/FixedBindings.fs | 52 +++++++++++++++++++ .../Language/FixedBindings/PinNakedDU.fs | 8 +++ .../FixedBindings/PinNakedStructDU.fs | 9 ++++ .../Language/FixedBindings/PinNakedTuple.fs | 6 +++ .../FixedBindings/PinNakedValueTuple.fs | 6 +++ 5 files changed, 81 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedDU.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedStructDU.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedTuple.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedValueTuple.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index 1104c9aa143..2d80d4f185a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -66,6 +66,58 @@ but given a The type 'char' does not match the type 'byte'""") ] + [] + [] + [] + let ``Pin naked Tuple -- illegal`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedTuple.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + [] + [] + [] + let ``Pin naked ValueTuple -- illegal`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedValueTuple.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 5, Col 9, Line 5, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 5, Col 9, Line 5, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + [] + [] + [] + let ``Pin naked discriminated union -- illegal`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedDU.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 7, Col 9, Line 7, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 7, Col 9, Line 7, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + + [] + [] + [] + let ``Pin naked struct discriminated union -- illegal`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinNakedStructDU.fs") + |> withLangVersion langVersion + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 9, Line 8, Col 9, Line 8, Col 12, """Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.""") + (Error 3207, Line 8, Col 9, Line 8, Col 12, """Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is one of the following: an array, the address of an array element, a string, a byref, an inref, or a type implementing GetPinnableReference()""") + ] + [] [] [] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedDU.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedDU.fs new file mode 100644 index 00000000000..3d6c8ed5e87 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedDU.fs @@ -0,0 +1,8 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +type Fruit = Apple | Banana + +let pinIt (x: Fruit) = + use ptr = fixed x + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedStructDU.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedStructDU.fs new file mode 100644 index 00000000000..81ea3e246e6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedStructDU.fs @@ -0,0 +1,9 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +[] +type Fruit = Apple | Banana + +let pinIt (x: Fruit) = + use ptr = fixed x + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedTuple.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedTuple.fs new file mode 100644 index 00000000000..9cc1cd49885 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedTuple.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (x: System.Tuple) = + use ptr = fixed x + NativePtr.get ptr 0 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedValueTuple.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedValueTuple.fs new file mode 100644 index 00000000000..88de978bd0b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinNakedValueTuple.fs @@ -0,0 +1,6 @@ +module FixedBindings +open Microsoft.FSharp.NativeInterop + +let pinIt (x: System.ValueTuple) = + use ptr = fixed x + NativePtr.get ptr 0 \ No newline at end of file From ef318f78cab5d6cd4f88d9e891dbfa16dd896703 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Thu, 10 Aug 2023 10:47:45 -0600 Subject: [PATCH 48/51] Apply fantomas --- src/Compiler/Facilities/DiagnosticsLogger.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fs b/src/Compiler/Facilities/DiagnosticsLogger.fs index e8d2cf724e3..374a8ddb8bd 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fs +++ b/src/Compiler/Facilities/DiagnosticsLogger.fs @@ -825,7 +825,7 @@ let internal languageFeatureError (langVersion: LanguageVersion) (langFeature: L let private tryLanguageFeatureErrorAux (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) = if not (langVersion.SupportsFeature langFeature) then - Some (languageFeatureError langVersion langFeature m) + Some(languageFeatureError langVersion langFeature m) else None From dbdc4595ead46a8205f610af275a50e160c77fe5 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Mon, 14 Aug 2023 15:37:47 -0500 Subject: [PATCH 49/51] Change an IL test to hopefully make it compile consistently in CI --- .../EmittedIL/FixedBindings/FixedBindings.fs | 46 +++++++------------ ...NullValueOfTypeWithGetPinnableReference.fs | 10 ++-- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs index edf188f4076..6c1737b9518 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/FixedBindings.fs @@ -709,37 +709,25 @@ module ExtendedFixedBindings = |> compileExeAndRun |> shouldSucceed |> verifyIL [""" - .method public static void pinIt(class FixedExpressions/RefField`1 thing) cil managed + .method public static bool pinIt(class FixedExpressions/RefField`1 thing) cil managed { .maxstack 4 - .locals init (native int V_0, - int32& pinned V_1) - IL_0000: ldarg.0 - IL_0001: brfalse.s IL_000e - - IL_0003: ldarg.0 - IL_0004: callvirt instance !0& class FixedExpressions/RefField`1::GetPinnableReference() - IL_0009: stloc.1 - IL_000a: ldloc.1 - IL_000b: conv.i - IL_000c: br.s IL_000f - - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldc.i8 0x0 - IL_0019: conv.i - IL_001a: ldloc.0 - IL_001b: bne.un.s IL_002e - - IL_001d: ldstr "Success - null guard worked" - IL_0022: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0027: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_002c: pop - IL_002d: ret - - IL_002e: ldstr "Test failed - null guard did not work" - IL_0033: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) - IL_0038: throw + .locals init (int32& pinned V_0) + IL_0000: ldc.i8 0x0 + IL_0009: conv.i + IL_000a: ldarg.0 + IL_000b: brfalse.s IL_0018 + + IL_000d: ldarg.0 + IL_000e: callvirt instance !0& class FixedExpressions/RefField`1::GetPinnableReference() + IL_0013: stloc.0 + IL_0014: ldloc.0 + IL_0015: conv.i + IL_0016: br.s IL_0019 + + IL_0018: ldarg.0 + IL_0019: ceq + IL_001b: ret } """] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNullValueOfTypeWithGetPinnableReference.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNullValueOfTypeWithGetPinnableReference.fs index c393306599f..d7c20ed43b0 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNullValueOfTypeWithGetPinnableReference.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/FixedBindings/PinNullValueOfTypeWithGetPinnableReference.fs @@ -11,12 +11,12 @@ type RefField<'T>(_value) = let pinIt (thing: RefField) = use ptr = fixed thing - if NativePtr.isNullPtr ptr then + NativePtr.isNullPtr ptr + +[] +let main _ = + if (pinIt Unchecked.defaultof>) then printfn "Success - null guard worked" else failwith "Test failed - null guard did not work" - -[] -let main _ = - pinIt Unchecked.defaultof> 0 \ No newline at end of file From 43d0d5f5182216b7451d4532418bb36ee3ff048f Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Mon, 14 Aug 2023 15:47:32 -0500 Subject: [PATCH 50/51] Change method name to try to appease CI --- .../Language/FixedBindings/FixedBindings.fs | 4 ++-- ...inTypeWithValidAndInvalidGetPinnableReferenceOverloads.fs} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/{PinTypeWIthValidGetPinnableReferenceAndSeveralInvalidOverloads.fs => PinTypeWithValidAndInvalidGetPinnableReferenceOverloads.fs} (100%) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index 2d80d4f185a..438dca1a69f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -384,8 +384,8 @@ The type 'char' does not match the type 'byte'""") [] [] - let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` langVersion = - FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithValidGetPinnableReferenceAndSeveralInvalidOverloads.fs") + let ``Pin type with valid and invalid GetPinnableReference overloads`` langVersion = + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithValidAndInvalidGetPinnableReferenceOverloads.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWIthValidGetPinnableReferenceAndSeveralInvalidOverloads.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithValidAndInvalidGetPinnableReferenceOverloads.fs similarity index 100% rename from tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWIthValidGetPinnableReferenceAndSeveralInvalidOverloads.fs rename to tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/PinTypeWithValidAndInvalidGetPinnableReferenceOverloads.fs From 597e29d58a0aa19ea4b4d5c494169715f82ad0e4 Mon Sep 17 00:00:00 2001 From: John Wostenberg Date: Mon, 14 Aug 2023 16:25:29 -0500 Subject: [PATCH 51/51] Fix test file name --- .../Language/FixedBindings/FixedBindings.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs index 438dca1a69f..86fb0c6c641 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/FixedBindings/FixedBindings.fs @@ -617,7 +617,7 @@ module ExtendedFixedBindings = [] [] let ``Pin type with a valid GetPinnableReference method and several invalid overloads`` langVersion = - FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithValidGetPinnableReferenceAndSeveralInvalidOverloads.fs") + FsFromPath (__SOURCE_DIRECTORY__ ++ "PinTypeWithValidAndInvalidGetPinnableReferenceOverloads.fs") |> withLangVersion langVersion |> ignoreWarnings |> compile