Skip to content

Commit c291f1e

Browse files
authored
Fix: generate fixups for static abstracts (#16195)
* Generate fixups for static abstracts
1 parent f10beba commit c291f1e

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

src/Compiler/CodeGen/IlxGen.fs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9212,7 +9212,13 @@ and GenMethodForBinding
92129212
if not memberInfo.MemberFlags.IsOverrideOrExplicitImpl then
92139213
mkILStaticMethod (ilMethTypars, mspec.Name, access, ilParams, ilReturn, ilMethodBody)
92149214
else // We want to get potential fixups and hidebysig for abstract statics:
9215-
let flagFixups = [ fixupStaticAbstractSlotFlags ]
9215+
let flagFixups =
9216+
[
9217+
fixupStaticAbstractSlotFlags
9218+
match ComputeMethodImplNameFixupForMemberBinding cenv v with
9219+
| Some nm -> renameMethodDef nm
9220+
| None -> ()
9221+
]
92169222

92179223
let mdef =
92189224
mkILStaticMethod (ilMethTypars, mspec.Name, access, ilParams, ilReturn, ilMethodBody)

tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,3 +831,94 @@ let main _ =
831831
|> compile
832832
|> shouldFail
833833
|> withErrorMessage $"The type 'float<potato>' is not compatible with the type '{potatoType}'"
834+
835+
[<FactForNETCOREAPP>]
836+
let ``Interface A with static abstracts can be inherited in interface B and then implemented in type C which inherits B in lang version70`` () =
837+
Fsx """
838+
type IParseable<'T when 'T :> IParseable<'T>> =
839+
static abstract member Parse : string -> 'T
840+
841+
type IAction<'T when 'T :> IAction<'T>> =
842+
inherit IParseable<'T>
843+
844+
type SomeAction = A | B with
845+
interface IAction<SomeAction> with
846+
static member Parse (s: string) : SomeAction =
847+
match s with
848+
| "A" -> A
849+
| "B" -> B
850+
| _ -> failwith "can't parse"
851+
852+
let parse<'T when 'T :> IParseable<'T>> (x: string) : 'T = 'T.Parse x
853+
854+
if parse<SomeAction> "A" <> A then
855+
failwith "failed"
856+
"""
857+
|> withNoWarn 3535
858+
|> withLangVersion70
859+
|> compile
860+
|> shouldSucceed
861+
862+
[<FactForNETCOREAPP>]
863+
let ``Static abstracts can be inherited through multiple levels in lang version70`` () =
864+
Fsx """
865+
type IParseable<'T when 'T :> IParseable<'T>> =
866+
static abstract member Parse : string -> 'T
867+
868+
type IAction1<'T when 'T :> IAction1<'T>> =
869+
inherit IParseable<'T>
870+
871+
type IAction2<'T when 'T :> IAction2<'T>> =
872+
inherit IAction1<'T>
873+
static abstract member AltParse : string -> 'T
874+
875+
type IAction3<'T when 'T :> IAction3<'T>> =
876+
inherit IAction2<'T>
877+
878+
type SomeAction = A | B with
879+
interface IAction3<SomeAction> with
880+
static member AltParse (s: string) : SomeAction = A
881+
static member Parse (s: string) : SomeAction =
882+
match s with
883+
| "A" -> A
884+
| "B" -> B
885+
| _ -> failwith "can't parse"
886+
887+
let parse<'T when 'T :> IParseable<'T>> (x: string) : 'T = 'T.Parse x
888+
let altParse<'T when 'T :> IAction3<'T>> (x: string) : 'T = 'T.AltParse x
889+
890+
let x: SomeAction = parse "A"
891+
let y: SomeAction = altParse "A"
892+
893+
if x <> A || y <> A then
894+
failwith "failed"
895+
"""
896+
|> withNoWarn 3535
897+
|> withLangVersion70
898+
|> compile
899+
|> shouldSucceed
900+
901+
[<FactForNETCOREAPP>]
902+
let ``Static abstracts from BCL can be inherited through multiple levels in lang version70`` () =
903+
Fsx """
904+
open System
905+
open System.Globalization
906+
907+
type Person = Person with
908+
interface ISpanParsable<Person> with
909+
static member Parse(_x: string, _provider: IFormatProvider) = Person
910+
static member TryParse(_x: string, _provider: IFormatProvider, _result: byref<Person>) = true
911+
912+
static member Parse(_x: ReadOnlySpan<char>, _provider: IFormatProvider) = Person
913+
static member TryParse(_x: ReadOnlySpan<char>, _provider: IFormatProvider, _result: byref<Person>) = true
914+
915+
let parse<'T when 'T :> IParsable<'T>> (x: string) : 'T = 'T.Parse (x, CultureInfo.InvariantCulture)
916+
917+
let x: Person = parse "Something"
918+
if x <> Person then
919+
failwith "failed"
920+
"""
921+
|> withNoWarn 3535
922+
|> withLangVersion70
923+
|> compile
924+
|> shouldSucceed

0 commit comments

Comments
 (0)