Skip to content

Commit 54d05be

Browse files
[release/dev17.8] Ad-hoc fix for ref readonly parameters (#16252)
* Test should fail * Threat ref readonly as inref * Fixed condition in test * Bump version --------- Co-authored-by: Vlad Zarytovskii <vzaritovsky@hotmail.com>
1 parent f41fe15 commit 54d05be

5 files changed

Lines changed: 71 additions & 9 deletions

File tree

eng/Versions.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<!-- F# Version components -->
1616
<FSMajorVersion>8</FSMajorVersion>
1717
<FSMinorVersion>0</FSMinorVersion>
18-
<FSBuildVersion>100</FSBuildVersion>
18+
<FSBuildVersion>101</FSBuildVersion>
1919
<FSRevisionVersion>0</FSRevisionVersion>
2020
<!-- -->
2121
<!-- F# Language version -->

src/Compiler/Checking/TypeHierarchy.fs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,13 @@ let ImportILTypeFromMetadata amap m scoref tinst minst ilTy =
355355
/// Read an Abstract IL type from metadata, including any attributes that may affect the type itself, and convert to an F# type.
356356
let ImportILTypeFromMetadataWithAttributes amap m scoref tinst minst ilTy getCattrs =
357357
let ty = RescopeAndImportILType scoref amap m (tinst@minst) ilTy
358-
// If the type is a byref and one of attributes from a return or parameter has IsReadOnly, then it's a inref.
359-
if isByrefTy amap.g ty && TryFindILAttribute amap.g.attrib_IsReadOnlyAttribute (getCattrs ()) then
358+
// If the type is a byref and one of attributes from a return or parameter has
359+
// - a `IsReadOnlyAttribute` - it's an inref
360+
// - a `RequiresLocationAttribute` (in which case it's a `ref readonly`) which we treat as inref,
361+
// latter is an ad-hoc fix for https://github.com/dotnet/runtime/issues/94317.
362+
if isByrefTy amap.g ty
363+
&& (TryFindILAttribute amap.g.attrib_IsReadOnlyAttribute (getCattrs ())
364+
|| TryFindILAttribute amap.g.attrib_RequiresLocationAttribute (getCattrs ())) then
360365
mkInByrefTy amap.g (destByrefTy amap.g ty)
361366
else
362367
ty
@@ -428,4 +433,3 @@ let FixupNewTypars m (formalEnclosingTypars: Typars) (tinst: TType list) (tpsori
428433
let tprefInst = mkTyparInst formalEnclosingTypars tinst @ renaming
429434
(tpsorig, tps) ||> List.iter2 (fun tporig tp -> tp.SetConstraints (CopyTyparConstraints m tprefInst tporig))
430435
renaming, tptys
431-

src/Compiler/TypedTree/TcGlobals.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,7 @@ type TcGlobals(
14231423
member val attrib_ParamArrayAttribute = findSysAttrib "System.ParamArrayAttribute"
14241424
member val attrib_IDispatchConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IDispatchConstantAttribute"
14251425
member val attrib_IUnknownConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IUnknownConstantAttribute"
1426+
member val attrib_RequiresLocationAttribute = findSysAttrib "System.Runtime.CompilerServices.RequiresLocationAttribute"
14261427

14271428
// We use 'findSysAttrib' here because lookup on attribute is done by name comparison, and can proceed
14281429
// even if the type is not found in a system assembly.

tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<ItemGroup>
3030
<Compile Include="..\service\FsUnit.fs">
3131
<Link>FsUnit.fs</Link>
32-
</Compile>
32+
</Compile>
3333
<Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\Basic\Basic.fs" />
3434
<Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\OnOverridesAndIFaceImpl\OnOverridesAndIFaceImpl.fs" />
3535
<Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\OnTypeMembers\OnTypeMembers.fs" />
@@ -112,7 +112,7 @@
112112
<Compile Include="Conformance\Types\RecordTypes\AnonymousRecords.fs" />
113113
<Compile Include="Conformance\Types\RecordTypes\RecordTypes.fs" />
114114
<Compile Include="Conformance\Types\StructTypes\StructTypes.fs" />
115-
<Compile Include="Conformance\Types\StructTypes\StructActivePatterns.fs" />
115+
<Compile Include="Conformance\Types\StructTypes\StructActivePatterns.fs" />
116116
<Compile Include="Conformance\Types\TypeConstraints\CheckingSyntacticTypes\CheckingSyntacticTypes.fs" />
117117
<Compile Include="Conformance\Types\TypeConstraints\LogicalPropertiesOfTypes\LogicalPropertiesOfTypes.fs" />
118118
<Compile Include="Conformance\Types\TypeConstraints\IWSAMsAndSRTPs\IWSAMsAndSRTPsTests.fs" />
@@ -175,7 +175,7 @@
175175
<Compile Include="ErrorMessages\DontSuggestTests.fs" />
176176
<Compile Include="ErrorMessages\ElseBranchHasWrongTypeTests.fs" />
177177
<Compile Include="ErrorMessages\InvalidLiteralTests.fs" />
178-
<Compile Include="ErrorMessages\InvalidNumericLiteralTests.fs" />
178+
<Compile Include="ErrorMessages\InvalidNumericLiteralTests.fs" />
179179
<Compile Include="ErrorMessages\MissingElseBranch.fs" />
180180
<Compile Include="ErrorMessages\MissingExpressionTests.fs" />
181181
<Compile Include="ErrorMessages\ModuleTests.fs" />
@@ -191,7 +191,7 @@
191191
<Compile Include="ErrorMessages\Repro1548.fs" />
192192
<Compile Include="ErrorMessages\WarnIfDiscardedInList.fs" />
193193
<Compile Include="ErrorMessages\UnionCasePatternMatchingErrors.fs" />
194-
<Compile Include="ErrorMessages\InterfaceImplInAugmentationsTests.fs" />
194+
<Compile Include="ErrorMessages\InterfaceImplInAugmentationsTests.fs" />
195195
<Compile Include="ErrorMessages\ExtendedDiagnosticDataTests.fs" />
196196
<Compile Include="Language\IndexerSetterParamArray.fs" />
197197
<Compile Include="Language\MultiDimensionalArrayTests.fs" />
@@ -225,6 +225,7 @@
225225
<Compile Include="Interop\RequiredAndInitOnlyProperties.fs" />
226226
<Compile Include="Interop\StaticsInInterfaces.fs" />
227227
<Compile Include="Interop\VisibilityTests.fs" />
228+
<Compile Include="Interop\ByrefTests.fs" />
228229
<Compile Include="Scripting\Interactive.fs" />
229230
<Compile Include="TypeChecks\CheckDeclarationsTests.fs" />
230231
<Compile Include="TypeChecks\Graph\Utils.fs" />
@@ -322,5 +323,5 @@
322323
<ItemGroup Condition="'$(FSHARPCORE_USE_PACKAGE)' == 'true'">
323324
<PackageReference Include="FSharp.Core" Version="$(FSharpCoreShippedPackageVersionValue)" />
324325
</ItemGroup>
325-
326+
326327
</Project>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace Interop
4+
5+
open FSharp.Test
6+
open FSharp.Test.Compiler
7+
8+
module ``Byref interop verification tests`` =
9+
10+
[<FactForNETCOREAPP>]
11+
let ``Test that ref readonly is treated as inref`` () =
12+
13+
FSharp """
14+
module ByrefTest
15+
open System.Runtime.CompilerServices
16+
type MyRecord = { Value : int } with
17+
member this.SetValue(v: int) = (Unsafe.AsRef<int> &this.Value) <- v
18+
19+
let check mr =
20+
if mr.Value <> 1 then
21+
failwith "Value should be 1"
22+
23+
mr.SetValue(42)
24+
25+
if mr.Value <> 42 then
26+
failwith $"Value should be 42, but is {mr.Value}"
27+
0
28+
29+
[<EntryPoint>]
30+
let main _ =
31+
let mr = { Value = 1 }
32+
check mr
33+
"""
34+
|> asExe
35+
|> compileAndRun
36+
|> shouldSucceed
37+
38+
[<FactForNETCOREAPP>]
39+
let ``Test that ref readonly is treated as inref for ROS .ctor`` () =
40+
FSharp """
41+
module Foo
42+
open System
43+
44+
45+
[<EntryPoint>]
46+
let main _ =
47+
let mutable bt: int = 42
48+
let ros = ReadOnlySpan<int>(&bt)
49+
50+
if ros.Length <> 1 || ros[0] <> 42 then
51+
failwith "Unexpected result"
52+
0
53+
"""
54+
|> asExe
55+
|> compileAndRun
56+
|> shouldSucceed

0 commit comments

Comments
 (0)