Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC FS-1124 - Interfaces with static abstract methods #13119

Merged
merged 126 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
3814613
WIP: Support implementing statics in interfaces
vzarytovskii May 9, 2022
ff0deda
Cleanup (#13113)
dsyme May 9, 2022
7ce8b63
Revert "Cleanup (#13113)"
vzarytovskii May 10, 2022
adade8a
Merge remote-tracking branch 'upstream/main' into statics-in-interfac…
vzarytovskii May 10, 2022
baef7c4
WIP
vzarytovskii May 11, 2022
a84bd24
Merge 'main'
vzarytovskii May 13, 2022
44ae728
Removed double check for non-abstract interface
vzarytovskii May 16, 2022
f2c2e48
Merge remote-tracking branch 'upstream/main' into statics-in-interfac…
vzarytovskii May 18, 2022
1d9c753
Merge remote-tracking branch 'upstream/main' into statics-in-interfac…
vzarytovskii May 18, 2022
f2d160a
Merge remote-tracking branch 'upstream/main' into statics-in-interfac…
vzarytovskii May 18, 2022
e91659d
Merge remote-tracking branch 'upstream/main' into statics-in-interfac…
vzarytovskii May 19, 2022
b36215a
Merge remote-tracking branch 'upstream/main' into statics-in-interfac…
vzarytovskii May 20, 2022
ebe1050
WIP
vzarytovskii May 20, 2022
5cf713c
Merge remote-tracking branch 'upstream/main' into statics-in-interfac…
vzarytovskii May 25, 2022
c200abd
WIP
vzarytovskii May 25, 2022
6762674
Merge remote-tracking branch 'upstream/main' into statics-in-interfac…
vzarytovskii May 27, 2022
2168e1e
WIP
vzarytovskii May 30, 2022
c91c73f
WIP
vzarytovskii Jun 3, 2022
747e8f1
Merge remote-tracking branch 'origin/main' into statics-in-interfaces-2
vzarytovskii Jun 13, 2022
8b31c82
WIP: Fixed method codegen
vzarytovskii Jun 13, 2022
470952e
Merge branch 'main' into statics-in-interfaces-2
vzarytovskii Jun 13, 2022
40916ee
Fixes to style + indent
vzarytovskii Jun 13, 2022
92fdf2a
After merge fixes
vzarytovskii Jun 13, 2022
f74ecf2
WIP: add language and runtime feature
vzarytovskii Jun 14, 2022
018bfd0
Fixed feature guard
vzarytovskii Jun 16, 2022
810a51f
Fixed the immediate members filter
vzarytovskii Jun 17, 2022
15178c8
Merge branch 'main' into statics-in-interfaces-2
vzarytovskii Jun 20, 2022
9e86055
Fix tests baselines
vzarytovskii Jun 20, 2022
d2e96c7
Fix tests baselines
vzarytovskii Jun 20, 2022
c0aac06
fix for list pattern syntax
vzarytovskii Jun 20, 2022
82a079e
Added operators tests
vzarytovskii Jun 20, 2022
e6ad912
allow authoring and fix abstract slot inference
dsyme Jun 22, 2022
be1909c
add tests
dsyme Jun 23, 2022
7546888
Merge pull request #2 from dsyme/statics-in-interfaces-2
vzarytovskii Jun 23, 2022
7262f1f
fix build
dsyme Jun 23, 2022
9b00827
Merge branch 'statics-in-interfaces-2' of https://github.com/vzarytov…
dsyme Jun 23, 2022
aa03f82
Update surface area tests
vzarytovskii Jun 24, 2022
a6b7118
Merge branch 'main' of https://github.com/dotnet/fsharp into statics-…
dsyme Jun 24, 2022
6122923
Apply fantomas
vzarytovskii Jun 24, 2022
b512c93
add call syntax and emit constrained prefix
dsyme Jun 24, 2022
d4504db
Merge pull request #3 from dsyme/statics-in-interfaces-2
vzarytovskii Jun 27, 2022
3355110
fix parsing problems, allow invocation and support name resolution of…
dsyme Jun 28, 2022
8520647
merge main
dsyme Jun 28, 2022
cc574a8
merge main
dsyme Jun 28, 2022
aeade7a
fix from-end-slicing
dsyme Jun 28, 2022
85e3997
Self constraints; Disallow ^T; Full test matrix for propery SRTP cons…
dsyme Jun 29, 2022
c038f9c
update samples
dsyme Jun 29, 2022
74a996d
Merge branch 'main' of https://github.com/dotnet/fsharp into statics-…
dsyme Jun 30, 2022
7dcd465
fix tests
dsyme Jun 30, 2022
273e206
git first execution test working
dsyme Jun 30, 2022
b2f8c28
Merge branch 'main' of https://github.com/dotnet/fsharp into statics-…
dsyme Jun 30, 2022
13fa09b
Merge branch 'main' of https://github.com/dotnet/fsharp into statics-…
dsyme Jul 1, 2022
555fbbe
update formating
dsyme Jul 1, 2022
1fe8d22
merge and fix test
dsyme Jul 3, 2022
4b983f0
merge main
dsyme Jul 4, 2022
3874fa5
fix tests
dsyme Jul 4, 2022
28bea4a
fix tests
dsyme Jul 4, 2022
3432f30
allow IWSAM constraints to solve SRTP traits
dsyme Jul 4, 2022
ce57d10
fix to signature compat
dsyme Jul 4, 2022
a864274
Merge branch 'main' of https://github.com/dotnet/fsharp into statics-…
dsyme Jul 4, 2022
fb8b75c
format code
dsyme Jul 4, 2022
b33b80b
fix task tests
dsyme Jul 5, 2022
de6ec1a
Merge branch 'main' of https://github.com/dotnet/fsharp into statics-…
dsyme Jul 5, 2022
243c207
fix test
dsyme Jul 5, 2022
09f7f17
fix up tests
dsyme Jul 6, 2022
4200b5e
fix test
dsyme Jul 6, 2022
13b97fc
add warnings to match RFC
dsyme Jul 6, 2022
7eeae6d
update messages and protect changes
dsyme Jul 6, 2022
7f6a46d
clear static req for inference variables
dsyme Jul 6, 2022
01f6ec4
clear static req for inference variables
dsyme Jul 6, 2022
9f9c49a
fix another case of generalization
dsyme Jul 6, 2022
d0544e4
fix build
dsyme Jul 6, 2022
8438abd
fix formatting
dsyme Jul 6, 2022
1b71be2
Merge branch 'main' of https://github.com/dotnet/fsharp into statics-…
dsyme Jul 6, 2022
aa5820a
fix tests
dsyme Jul 6, 2022
87e1304
fix tests
dsyme Jul 7, 2022
03f7bef
add tests and improve diagnostics
dsyme Jul 7, 2022
7ee7e07
format code
dsyme Jul 7, 2022
ab95b72
fix tests
dsyme Jul 7, 2022
a254a88
add more quickinfo etc tests
dsyme Jul 7, 2022
19a4934
clean up tests
dsyme Jul 8, 2022
d6da718
Merge branch 'main' into statics-in-interfaces-2
dsyme Jul 11, 2022
79ae597
merge main
dsyme Jul 11, 2022
c9e6284
format code
dsyme Jul 11, 2022
6df8a34
fix build
dsyme Jul 11, 2022
a5d56a3
merge main
dsyme Jul 11, 2022
9d33a53
Update LanguageFeatures.fs
dsyme Jul 11, 2022
e36b205
merge main
dsyme Jul 11, 2022
fb50126
merge main
dsyme Jul 11, 2022
5aaa9a1
fix build
dsyme Jul 11, 2022
6c783a7
Moved tests/adhoc to ComponentTests
0101 Jul 13, 2022
cb21cef
Updated new syntax test
0101 Jul 14, 2022
aaf86b7
Updated new syntax test
0101 Jul 14, 2022
ef8fecf
Disabling failing tests for now
0101 Jul 14, 2022
218f9ee
Fix new SRTP instance method invocation
0101 Jul 14, 2022
1ac2e27
Func conversion tests, renaming
0101 Jul 15, 2022
22aa7d5
Verify IL for IWSAM test
0101 Jul 15, 2022
c464aef
Byref tests
0101 Jul 15, 2022
aa8b80a
Test creating delegates to IWSAM-constrained target methods
0101 Jul 18, 2022
6145058
Tests for implicit conversion and nominal type in constraint selector
0101 Jul 19, 2022
1a3bb71
IWSAM active patterns tests
0101 Jul 27, 2022
9e760a6
Test for C# using IWSAM defined in F#
0101 Jul 27, 2022
ce3aa0d
Release IL in test
0101 Jul 27, 2022
6681e16
Merge branch 'main' into statics-in-interfaces-2
0101 Jul 27, 2022
8b8427a
Fix test
0101 Jul 27, 2022
bc8d9b8
Skip IWSAM tests on NET FW
0101 Jul 28, 2022
86d3552
merge main
dsyme Aug 1, 2022
ed56f7e
fix build
dsyme Aug 1, 2022
143045d
fix build
dsyme Aug 1, 2022
881d431
fix test
dsyme Aug 1, 2022
2ae12a5
fix inference tests
dsyme Aug 1, 2022
4605e77
Updated type inference tests
0101 Aug 1, 2022
5b2c6e2
Merge branch 'statics-in-interfaces-2' of github.com:vzarytovskii/fsh…
0101 Aug 1, 2022
7b96494
Fix compiler generated attribute for setters
0101 Aug 1, 2022
23f0c61
Prepared System.Numerics suppression test
0101 Aug 1, 2022
5c404c0
Sample project for .NET 7
0101 Aug 1, 2022
ef3ae6c
fix byref arguments to trait calls
dsyme Aug 1, 2022
c700443
fix byref arguments to trait calls
dsyme Aug 1, 2022
80f1833
Added more samples, fixed compiler paths for VS
vzarytovskii Aug 2, 2022
c59553a
DirectoryAttribute puts each test into its own directory
0101 Aug 2, 2022
713416a
Merge branch 'statics-in-interfaces-2' of github.com:vzarytovskii/fsh…
0101 Aug 2, 2022
540ba37
Only add extra dir for test if there multiple tests processed by Dire…
0101 Aug 2, 2022
3fbcb5d
Moved adhoc byref tests to actual tests
0101 Aug 2, 2022
a76d013
Tests update
0101 Aug 2, 2022
3a847d8
Merge branch 'main' into statics-in-interfaces-2
0101 Aug 3, 2022
5629ef4
Merge branch 'main' into statics-in-interfaces-2
vzarytovskii Aug 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 39 additions & 9 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1314,13 +1314,16 @@ let MakeMemberDataAndMangledNameForMemberVal(g, tcref, isExtrinsic, attrs, implS

let isInstance = MemberIsCompiledAsInstance g tcref isExtrinsic memberInfo attrs

if (memberFlags.IsDispatchSlot || not (isNil intfSlotTys)) then
if not isInstance then
errorR(VirtualAugmentationOnNullValuedType(id.idRange))
let hasUseNullAsTrueAttr = TyconHasUseNullAsTrueValueAttribute g tcref.Deref

elif not memberFlags.IsOverrideOrExplicitImpl && memberFlags.IsInstance then
if not isExtrinsic && not isInstance then
warning(NonVirtualAugmentationOnNullValuedType(id.idRange))
if hasUseNullAsTrueAttr then
if (memberFlags.IsDispatchSlot || not (isNil intfSlotTys)) then
if not isInstance then
errorR(VirtualAugmentationOnNullValuedType(id.idRange))

elif not memberFlags.IsOverrideOrExplicitImpl && memberFlags.IsInstance then
if not isExtrinsic && not isInstance then
warning(NonVirtualAugmentationOnNullValuedType(id.idRange))

let compiledName =
if isExtrinsic then
Expand Down Expand Up @@ -10909,7 +10912,7 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (bindingTy, m, syn
match memberFlags.MemberKind with
| SynMemberKind.Member ->
let dispatchSlots, dispatchSlotsArityMatch =
GetAbstractMethInfosForSynMethodDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers, valSynData)
GetAbstractMethInfosForSynMethodDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers, valSynData, memberFlags)

let uniqueAbstractMethSigs =
match dispatchSlots with
Expand Down Expand Up @@ -11051,14 +11054,15 @@ and AnalyzeRecursiveStaticMemberOrValDecl
envinner: TcEnv,
tpenv,
declKind,
synTyparDecls,
newslotsOK,
overridesOK,
tcrefContainerInfo,
vis1,
id: Ident,
vis2,
declaredTypars,
memberFlagsOpt,
memberFlagsOpt: SynMemberFlags option,
thisIdOpt,
bindingAttribs,
valSynInfo,
Expand All @@ -11074,6 +11078,32 @@ and AnalyzeRecursiveStaticMemberOrValDecl
// name for the member and the information about which type it is augmenting

match tcrefContainerInfo, memberFlagsOpt with
| Some(MemberOrValContainerInfo(tcref, intfSlotTyOpt, _, _, declaredTyconTypars)), Some memberFlags
when memberFlags.MemberKind = SynMemberKind.Member &&
memberFlags.IsInstance = false &&
memberFlags.IsOverrideOrExplicitImpl = true ->

CheckMemberFlags intfSlotTyOpt newslotsOK overridesOK memberFlags id.idRange
CheckForNonAbstractInterface declKind tcref memberFlags id.idRange

let isExtrinsic = (declKind = ExtrinsicExtensionBinding)
let tcrefObjTy, enclosingDeclaredTypars, renaming, objTy, _ = FreshenObjectArgType cenv mBinding TyparRigidity.WillBeRigid tcref isExtrinsic declaredTyconTypars
let envinner = AddDeclaredTypars CheckForDuplicateTypars enclosingDeclaredTypars envinner
let envinner = MakeInnerEnvForTyconRef envinner tcref isExtrinsic

let (ExplicitTyparInfo(_, declaredTypars, infer)) = explicitTyparInfo

let domainTy = NewInferenceType g

let optInferredImplSlotTys, declaredTypars =
ApplyAbstractSlotInference cenv envinner (domainTy, mBinding, synTyparDecls, declaredTypars, id, tcrefObjTy, renaming, objTy, intfSlotTyOpt, valSynInfo, memberFlags, bindingAttribs)

let explicitTyparInfo = ExplicitTyparInfo(declaredTypars, declaredTypars, infer)

let memberInfo = MakeMemberDataAndMangledNameForMemberVal(g, tcref, isExtrinsic, bindingAttribs, optInferredImplSlotTys, memberFlags, valSynInfo, id, false)

envinner, tpenv, id, None, Some memberInfo, vis, vis2, None, enclosingDeclaredTypars, None, explicitTyparInfo, bindingRhs, declaredTypars

| Some(MemberOrValContainerInfo(tcref, intfSlotTyOpt, baseValOpt, _safeInitInfo, declaredTyconTypars)), Some memberFlags ->
assert (Option.isNone intfSlotTyOpt)

Expand Down Expand Up @@ -11260,7 +11290,7 @@ and AnalyzeRecursiveDecl

| SynPat.Named (SynIdent(id,_), _, vis2, _) ->
AnalyzeRecursiveStaticMemberOrValDecl
(cenv, envinner, tpenv, declKind,
(cenv, envinner, tpenv, declKind, synTyparDecls,
newslotsOK, overridesOK, tcrefContainerInfo,
vis1, id, vis2, declaredTypars,
memberFlagsOpt, thisIdOpt, bindingAttribs,
Expand Down
18 changes: 13 additions & 5 deletions src/Compiler/Checking/MethodOverrides.fs
Original file line number Diff line number Diff line change
Expand Up @@ -767,9 +767,10 @@ module DispatchSlotChecking =
// Find the methods relevant to implementing the abstract slots listed under the reqdType being checked.
let allImmediateMembersThatMightImplementDispatchSlots =
allImmediateMembers |> List.filter (fun overrideBy ->
overrideBy.IsInstanceMember && // exclude static
overrideBy.IsVirtualMember && // exclude non virtual (e.g. keep override/default). [4469]
not overrideBy.IsDispatchSlotMember)
(overrideBy.IsInstanceMember // Not static OR
|| ((not overrideBy.IsInstanceMember) && overrideBy.IsOverrideOrExplicitImpl) // Static in the interface
&& overrideBy.IsVirtualMember // exclude non virtual (e.g. keep override/default). [4469]
&& not overrideBy.IsDispatchSlotMember))

let mustOverrideSomething reqdTy (overrideBy: ValRef) =
let memberInfo = overrideBy.MemberInfo.Value
Expand Down Expand Up @@ -919,7 +920,7 @@ let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader: InfoReader, nenv

/// Get the methods relevant to determining if a uniquely-identified-override exists based on the syntactic information
/// at the member signature prior to type inference. This is used to pre-assign type information if it does
let GetAbstractMethInfosForSynMethodDecl(infoReader: InfoReader, ad, memberName: Ident, bindm, typToSearchForAbstractMembers, valSynData) =
let GetAbstractMethInfosForSynMethodDecl(infoReader: InfoReader, ad, memberName: Ident, bindm, typToSearchForAbstractMembers, valSynData, memberFlags: SynMemberFlags) =
let minfos =
match typToSearchForAbstractMembers with
| _, Some(SlotImplSet(_, dispatchSlotsKeyed, _, _)) ->
Expand All @@ -928,7 +929,14 @@ let GetAbstractMethInfosForSynMethodDecl(infoReader: InfoReader, ad, memberName:
GetIntrinsicMethInfosOfType infoReader (Some memberName.idText) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides bindm ty
let dispatchSlots = minfos |> List.filter (fun minfo -> minfo.IsDispatchSlot)
let topValSynArities = SynInfo.AritiesOfArgs valSynData
let topValSynArities = if List.isEmpty topValSynArities then topValSynArities else topValSynArities.Tail

// We only return everything if it's empty or if it's a non-instance member.
// If it's an instance member, we are getting rid of `this` (by only taking tail).
let topValSynArities =
if List.isEmpty topValSynArities || (not memberFlags.IsInstance) then
topValSynArities
else
topValSynArities.Tail
let dispatchSlotsArityMatch = dispatchSlots |> List.filter (fun minfo -> minfo.NumArgs = topValSynArities)
dispatchSlots, dispatchSlotsArityMatch

Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/Checking/MethodOverrides.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ val GetAbstractMethInfosForSynMethodDecl:
memberName: Ident *
bindm: range *
typToSearchForAbstractMembers: (TType * SlotImplSet option) *
valSynData: SynValInfo ->
valSynData: SynValInfo *
memberFlags: SynMemberFlags ->
MethInfo list * MethInfo list

/// Get the properties relevant to determining if a uniquely-identified-override exists based on the syntactic information
Expand Down
64 changes: 52 additions & 12 deletions src/Compiler/CodeGen/IlxGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4644,11 +4644,17 @@ and GenFormalSlotsig m cenv eenv slotsig =
let ilRet = GenFormalReturnType m cenv eenvForSlotSig returnTy
ilTy, ilParams, ilRet

and GenOverridesSpec cenv eenv slotsig m =
and GenOverridesSpec cenv eenv slotsig m isInstance =
let (TSlotSig(nameOfOverridenMethod, _, _, methodTypars, _, _)) = slotsig
let ilOverrideTy, ilOverrideParams, ilOverrideRet = GenFormalSlotsig m cenv eenv slotsig
let ilOverrideTyRef = ilOverrideTy.TypeRef
let ilOverrideMethRef = mkILMethRef(ilOverrideTyRef, ILCallingConv.Instance, nameOfOverridenMethod, List.length (DropErasedTypars methodTypars), typesOfILParams ilOverrideParams, ilOverrideRet.Type)
let callingConv =
if isInstance then
ILCallingConv.Instance
else
ILCallingConv.Static

let ilOverrideMethRef = mkILMethRef(ilOverrideTyRef, callingConv, nameOfOverridenMethod, List.length (DropErasedTypars methodTypars), typesOfILParams ilOverrideParams, ilOverrideRet.Type)
OverridesSpec(ilOverrideMethRef, ilOverrideTy)

and GenFormalReturnType m cenv eenvFormal returnTy : ILReturn =
Expand Down Expand Up @@ -4686,8 +4692,8 @@ and GenNameOfOverridingMethod cenv (useMethodImpl, slotsig) =
else
nameOfOverridenMethod

and GenMethodImpl cenv eenv (useMethodImpl, slotsig) m =
let ilOverridesSpec = GenOverridesSpec cenv eenv slotsig m
and GenMethodImpl cenv eenv (useMethodImpl, slotsig) m isInstance =
let ilOverridesSpec = GenOverridesSpec cenv eenv slotsig m isInstance

let nameOfOverridingMethod = GenNameOfOverridingMethod cenv (useMethodImpl, slotsig)
nameOfOverridingMethod,
Expand All @@ -4696,7 +4702,12 @@ and GenMethodImpl cenv eenv (useMethodImpl, slotsig) m =
let ilParamsOfOverridingMethod, ilReturnOfOverridingMethod = GenActualSlotsig m cenv eenvForOverrideBy slotsig methTyparsOfOverridingMethod []
let ilOverrideMethGenericParams = GenGenericParams cenv eenvForOverrideBy methTyparsOfOverridingMethod
let ilOverrideMethGenericArgs = mkILFormalGenericArgs 0 ilOverrideMethGenericParams
let ilOverrideBy = mkILInstanceMethSpecInTy(ilTyForOverriding, nameOfOverridingMethod, typesOfILParams ilParamsOfOverridingMethod, ilReturnOfOverridingMethod.Type, ilOverrideMethGenericArgs)
let ilOverrideBy =
if isInstance then
mkILInstanceMethSpecInTy(ilTyForOverriding, nameOfOverridingMethod, typesOfILParams ilParamsOfOverridingMethod, ilReturnOfOverridingMethod.Type, ilOverrideMethGenericArgs)
else
mkILStaticMethSpecInTy(ilTyForOverriding, nameOfOverridingMethod, typesOfILParams ilParamsOfOverridingMethod, ilReturnOfOverridingMethod.Type, ilOverrideMethGenericArgs)

{ Overrides = ilOverridesSpec
OverrideBy = ilOverrideBy })

Expand All @@ -4714,6 +4725,9 @@ and renameMethodDef nameOfOverridingMethod (mdef: ILMethodDef) =
and fixupMethodImplFlags (mdef: ILMethodDef) =
mdef.WithAccess(ILMemberAccess.Private).WithHideBySig().WithFinal(true).WithNewSlot

and fixupStaticAbstractSlotFlags (mdef: ILMethodDef) =
mdef.WithHideBySig(true)

and GenObjectMethod cenv eenvinner (cgbuf: CodeGenBuffer) useMethodImpl tmethod =
let g = cenv.g

Expand Down Expand Up @@ -4745,7 +4759,7 @@ and GenObjectMethod cenv eenvinner (cgbuf: CodeGenBuffer) useMethodImpl tmethod

let ilMethodBody = CodeGenMethodForExpr cenv cgbuf.mgbuf ([], nameOfOverridenMethod, eenvForMeth, 0, selfArgOpt, methBodyExpr, sequel)

let nameOfOverridingMethod, methodImplGenerator = GenMethodImpl cenv eenvinner (useMethodImpl, slotsig) methBodyExpr.Range
let nameOfOverridingMethod, methodImplGenerator = GenMethodImpl cenv eenvinner (useMethodImpl, slotsig) methBodyExpr.Range true

let mdef =
mkILGenericVirtualMethod
Expand Down Expand Up @@ -4868,7 +4882,7 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel
| _ -> error(InternalError(sprintf "expected method %s not found" imethName, m))

let slotsig = implementedMeth.GetSlotSig(amap, m)
let ilOverridesSpec = GenOverridesSpec cenv eenvinner slotsig m
let ilOverridesSpec = GenOverridesSpec cenv eenvinner slotsig m mdef.CallingConv.IsInstance
let ilOverrideBy = mkILInstanceMethSpecInTy(ilCloTy, imethName, mdef.ParameterTypes, mdef.Return.Type, [])
{ Overrides = ilOverridesSpec
OverrideBy = ilOverrideBy } ]
Expand Down Expand Up @@ -6632,6 +6646,22 @@ and ComputeFlagFixupsForMemberBinding cenv (v: Val) =
| Some nm -> renameMethodDef nm
| None -> () ]

and ComputeMethodImplNameFixupForStaticMemberBinding cenv (v: Val) =
if isNil v.ImplementedSlotSigs then
None
else
let slotsig = v.ImplementedSlotSigs |> List.last
let nameOfOverridingMethod = GenNameOfOverridingMethod cenv (false, slotsig)
Some nameOfOverridingMethod

and ComputeFlagFixupsForStaticMemberBinding cenv (v: Val) =
[
fixupStaticAbstractSlotFlags
match ComputeMethodImplNameFixupForStaticMemberBinding cenv v with
| Some nm -> renameMethodDef nm
| None -> ()
]

and ComputeMethodImplAttribs cenv (_v: Val) attrs =
let g = cenv.g
let implflags =
Expand Down Expand Up @@ -6864,8 +6894,16 @@ and GenMethodForBinding
else
let mdef =
if not compileAsInstance then
mkILStaticMethod (ilMethTypars, mspec.Name, access, ilParams, ilReturn, ilMethodBody)

if not memberInfo.MemberFlags.IsOverrideOrExplicitImpl then
mkILStaticMethod (ilMethTypars, mspec.Name, access, ilParams, ilReturn, ilMethodBody)
else // We want to get potential fixups and hidebysig for abstract statics:
let flagFixups = ComputeFlagFixupsForStaticMemberBinding cenv v
let mdef = mkILStaticMethod (ilMethTypars, mspec.Name, access, ilParams, ilReturn, ilMethodBody)
let mdef = List.fold (fun mdef f -> f mdef) mdef flagFixups

// fixup can potentially change name of reflected definition that was already recorded - patch it if necessary
mgbuf.ReplaceNameOfReflectedDefinition(v, mdef.Name)
mdef
elif (memberInfo.MemberFlags.IsDispatchSlot && memberInfo.IsImplemented) ||
memberInfo.MemberFlags.IsOverrideOrExplicitImpl then

Expand Down Expand Up @@ -7934,10 +7972,12 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
| Some(_, memberParentTypars, memberMethodTypars, _, _) -> memberParentTypars, memberMethodTypars
| None -> [], []

let useMethodImpl = true
// Don't use method impl for static abstract implementation (IsInstance <> true && IsOverrideOrExplicitImpl = true):
let isStaticAbstractImpl = (not memberInfo.MemberFlags.IsInstance) && memberInfo.MemberFlags.IsOverrideOrExplicitImpl
let useMethodImpl = not isStaticAbstractImpl
let eenvUnderTypars = EnvForTypars memberParentTypars eenv
let _, methodImplGenerator = GenMethodImpl cenv eenvUnderTypars (useMethodImpl, slotsig) m
if useMethodImpl then
let _, methodImplGenerator = GenMethodImpl cenv eenvUnderTypars (useMethodImpl, slotsig) m memberInfo.MemberFlags.IsInstance
if useMethodImpl || isStaticAbstractImpl then
yield methodImplGenerator (ilThisTy, memberMethodTypars)

| _ -> () ]
Expand Down
8 changes: 8 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,14 @@ let StaticMemberFlags trivia k : SynMemberFlags =
IsFinal=false
Trivia=trivia }

let ImplementStaticMemberFlags trivia k : SynMemberFlags =
{ MemberKind=k
IsInstance=false
IsDispatchSlot=false
IsOverrideOrExplicitImpl=true
IsFinal=false
Trivia=trivia }

let MemberSynMemberFlagsTrivia (mMember: range) : SynMemberFlagsTrivia =
{ MemberRange = Some mMember
OverrideRange = None
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ val AbstractMemberFlags: trivia: SynMemberFlagsTrivia -> k: SynMemberKind -> Syn

val StaticMemberFlags: trivia: SynMemberFlagsTrivia -> k: SynMemberKind -> SynMemberFlags

val ImplementStaticMemberFlags: SynMemberFlagsTrivia -> k: SynMemberKind -> SynMemberFlags

val MemberSynMemberFlagsTrivia: mMember: range -> SynMemberFlagsTrivia

val OverrideSynMemberFlagsTrivia: mOverride: range -> SynMemberFlagsTrivia
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/TypedTree/TypedTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ type TyparFlags(flags: int32) =
TyparFlags((if isFromError then 0b00000000000000010 else 0) |||
(if isCompGen then 0b00000000000000100 else 0) |||
(match staticReq with
| TyparStaticReq.None -> 0b00000000000000000
| TyparStaticReq.HeadType -> 0b00000000000001000) |||
| TyparStaticReq.None -> 0b00000000000000000
| TyparStaticReq.HeadType -> 0b00000000000001000) |||
(match rigidity with
| TyparRigidity.Rigid -> 0b00000000000000000
| TyparRigidity.WillBeRigid -> 0b00000000000100000
Expand Down
4 changes: 3 additions & 1 deletion src/Compiler/TypedTree/TypedTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8841,7 +8841,9 @@ let CompileAsEvent g attrs = HasFSharpAttribute g g.attrib_CLIEventAttribute att
let MemberIsCompiledAsInstance g parent isExtensionMember (membInfo: ValMemberInfo) attrs =
// All extension members are compiled as static members
if isExtensionMember then false
// Anything implementing a dispatch slot is compiled as an instance member
// Members implementing a dispatch slot is compiled as an instance member
// Exception is static interface members:
elif not membInfo.MemberFlags.IsInstance && membInfo.MemberFlags.IsOverrideOrExplicitImpl then false
elif membInfo.MemberFlags.IsOverrideOrExplicitImpl then true
elif not (isNil membInfo.ImplementedSlotSigs) then true
else
Expand Down
20 changes: 12 additions & 8 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -2325,28 +2325,32 @@ objectImplementationMembers:

/* One member in an object expression or interface implementation */
objectImplementationMember:
| opt_attributes memberOrOverride memberCore opt_ODECLEND
| opt_attributes staticMemberOrMemberOrOverride memberCore opt_ODECLEND
{ let rangeStart = rhs parseState 1
$3 None (OverrideMemberFlags $2) $1 rangeStart }
$3 None $2 $1 rangeStart }

| opt_attributes memberOrOverride autoPropsDefnDecl opt_ODECLEND
| opt_attributes staticMemberOrMemberOrOverride autoPropsDefnDecl opt_ODECLEND
{ let rangeStart = rhs parseState 1
$3 $1 false (OverrideMemberFlags $2) rangeStart }
$3 $1 false $2 rangeStart }

| opt_attributes memberOrOverride error
| opt_attributes staticMemberOrMemberOrOverride error
{ [] }

| opt_attributes error memberCore opt_ODECLEND
{ [] }


memberOrOverride:
staticMemberOrMemberOrOverride:
| STATIC MEMBER
{ let mStatic = rhs parseState 1
let mMember = rhs parseState 2
ImplementStaticMemberFlags(StaticMemberSynMemberFlagsTrivia mStatic mMember) }
| MEMBER
{ let mMember = rhs parseState 1
MemberSynMemberFlagsTrivia mMember }
OverrideMemberFlags(MemberSynMemberFlagsTrivia mMember) }
| OVERRIDE
{ let mOverride = rhs parseState 1
OverrideSynMemberFlagsTrivia mOverride }
OverrideMemberFlags(OverrideSynMemberFlagsTrivia mOverride) }


/* The core of the right-hand-side of a simple type definition */
Expand Down
Loading