Skip to content

Commit

Permalink
Emitting IsReadOnly/In attributes on abstract properties (#10542)
Browse files Browse the repository at this point in the history
  • Loading branch information
TIHan committed Nov 25, 2020
1 parent 86c4beb commit a20b124
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 5 deletions.
19 changes: 14 additions & 5 deletions src/fsharp/IlxGen.fs
Expand Up @@ -7129,14 +7129,22 @@ and GenAbstractBinding cenv eenv tref (vref: ValRef) =
let memberInfo = Option.get vref.MemberInfo
let attribs = vref.Attribs
let hasPreserveSigImplFlag, hasSynchronizedImplFlag, hasNoInliningFlag, hasAggressiveInliningImplFlag, attribs = ComputeMethodImplAttribs cenv vref.Deref attribs
if memberInfo.MemberFlags.IsDispatchSlot && not memberInfo.IsImplemented then
let ilAttrs =
[ yield! GenAttrs cenv eenv attribs
yield! GenCompilationArgumentCountsAttr cenv vref.Deref ]

if memberInfo.MemberFlags.IsDispatchSlot && not memberInfo.IsImplemented then
let mspec, _mspecW, ctps, mtps, _curriedArgInfos, argInfos, retInfo, witnessInfos, methArgTys, returnTy =
GetMethodSpecForMemberVal cenv.amap cenv.g memberInfo vref

let ilAttrs =
[ yield! GenAttrs cenv eenv attribs
yield! GenCompilationArgumentCountsAttr cenv vref.Deref

match vref.MemberInfo, returnTy with
| Some memberInfo, Some returnTy when
memberInfo.MemberFlags.MemberKind = MemberKind.PropertyGet ||
memberInfo.MemberFlags.MemberKind = MemberKind.PropertySet ||
memberInfo.MemberFlags.MemberKind = MemberKind.PropertyGetSet ->
match GenReadOnlyAttributeIfNecessary g returnTy with Some ilAttr -> ilAttr | _ -> ()
| _ -> () ]

assert witnessInfos.IsEmpty

let eenvForMeth = EnvForTypars (ctps@mtps) eenv
Expand Down Expand Up @@ -7175,6 +7183,7 @@ and GenAbstractBinding cenv eenv tref (vref: ValRef) =
else
let ilPropDef =
let ilPropTy = GenType cenv.amap m eenvForMeth.tyenv vtyp
let ilPropTy = GenReadOnlyModReqIfNecessary g vtyp ilPropTy
let ilArgTys = v |> ArgInfosOfPropertyVal g |> List.map fst |> GenTypes cenv.amap m eenvForMeth.tyenv
GenPropertyForMethodDef compileAsInstance tref mdef v memberInfo ilArgTys ilPropTy (mkILCustomAttrs ilAttrs) None
let mdef = mdef.WithSpecialName
Expand Down
29 changes: 29 additions & 0 deletions tests/fsharp/Compiler/Language/ByrefTests.fs
Expand Up @@ -341,4 +341,33 @@ type C<'T>() =
FSharp src
|> compile
|> verifyIL [verifyMethod]
|> ignore

[<Test>]
let ``Returning an 'inref<_>' from an abstract property should emit System.Runtime.CompilerServices.IsReadOnlyAttribute on the return type of the signature`` () =
let src =
"""
module Test
type C =
abstract X: inref<int>
"""

let verifyProperty = """.property instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute)
X()
{
.custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )
.get instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) Test/C::get_X()
}"""

let verifyMethod = """.method public hidebysig specialname abstract virtual
instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute)
get_X() cil managed
{
.param [0]
.custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )"""

FSharp src
|> compile
|> verifyIL [verifyProperty;verifyMethod]
|> ignore

0 comments on commit a20b124

Please sign in to comment.