From bd51817a33c4ecc966e11b8e1d712debb2c47b15 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 24 Oct 2023 23:02:46 +0100 Subject: [PATCH 01/20] Produce an error when one leaves out keyword static in an implementation of IWSAM --- src/Compiler/Checking/CheckDeclarations.fs | 38 ++++++++++++++++ .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 44 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 5db81b47a56..f463c15fae5 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -4457,6 +4457,44 @@ module TcDeclarations = if not (List.isEmpty attributes) && (declKind = ExtrinsicExtensionBinding || declKind = IntrinsicExtensionBinding) then let attributeRange = (List.head attributes).Range error(Error(FSComp.SR.tcAugmentationsCannotHaveAttributes(), attributeRange)) + + let staticAbstractMembers = + tcref.ImmediateInterfaceTypesOfFSharpTycon + |> List.choose( + fun ttype -> + match stripTyEqnsAndMeasureEqns g ttype with + | TType_app(tyconRef = tcref) -> + let staticAbstractMembers = + tcref.MembersOfFSharpTyconSorted + |> List.filter(fun x -> not x.IsInstanceMember) + Some staticAbstractMembers + | _ -> None + ) + |> List.concat + + let implMembers = + members + |> List.choose( + fun synMemberDef -> + match synMemberDef with + | SynMemberDefn.Interface(members= Some(synMemberDefns)) -> + let members = + synMemberDefns + |> List.choose( + fun synMemberDefn -> + match synMemberDefn with + | SynMemberDefn.Member(memberDefn = SynBinding(headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ _; ident])))) -> Some ident + | _ -> None + ) + Some members + | _ -> None + ) + |> List.concat + + for memberId in implMembers do + if staticAbstractMembers |> List.exists(fun x -> x.Id.idText = memberId.idText) then + // TODO : Should we reuse FS855 or create a new error with a better message + errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) MutRecDefnsPhase2DataForTycon(tyconOpt, innerParent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, members, tyDeclRange, newslotsOK, fixupFinalAttrs)) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 77787d5a256..f730c5445b7 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -922,3 +922,47 @@ let main _ = |> withLangVersion70 |> compile |> shouldSucceed + + + [] + let ``Produce an error when one leaves out keyword "static" in an implementation of IWSAM`` () = + Fsx """ +module StaticAbstractBug = + type IOperation = + static abstract member Execute: unit -> unit + abstract member Execute2: unit -> unit + + type FaultyOperation() = + interface IOperation with + member _.Execute() = () + member _.Execute2() = () + """ + |> withOptions [ "--nowarn:3535" ] + |> withLangVersion80 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 9, Col 22, Line 9, Col 29, "No abstract or interface member was found that corresponds to this override") + ] + + [] + let ``Produce an error for interface with static abstract member that is implemented as instance member`` () = + Fsx """ +module StaticAbstractBug = + type IFoo<'T> = + abstract DoIt: unit -> string + static abstract Other : int -> int + type MyFoo = { + Value : int + } with + interface IFoo with + member me.DoIt() = string me.Value + member _.Other(value) = value + 1 + """ + |> withOptions [ "--nowarn:3535" ] + |> withLangVersion80 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 11, Col 18, Line 11, Col 23, "No abstract or interface member was found that corresponds to this override") + ] From a3dd7cdab5d55aa7c9542509c3c1906bdde2f89c Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 25 Oct 2023 00:41:18 +0100 Subject: [PATCH 02/20] Extract logic --- src/Compiler/Checking/CheckDeclarations.fs | 66 ++++++++++------------ 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index f463c15fae5..61a1c7fa942 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -4418,6 +4418,33 @@ module TcDeclarations = let isAtOriginalTyconDefn = true let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, SynTypeDefnSimpleRepr.Exception r, implements1, false, false, isAtOriginalTyconDefn) core, extra_vals_Inherits_Abstractslots @ extraMembers + + let private CheckStaticAbstractSlots g (tcref: EntityRef) members = + let staticMembers = + [ for ttype in tcref.ImmediateInterfaceTypesOfFSharpTycon do + match stripTyEqnsAndMeasureEqns g ttype with + | TType_app(tyconRef = tcref) -> + tcref.MembersOfFSharpTyconSorted + |> List.filter(fun x -> not x.IsInstanceMember) + |> List.map(fun x -> x.DisplayNameCore) + | _ -> () ] + |> List.concat + + let implMembers = + [ for synMemberDef in members do + match synMemberDef with + | SynMemberDefn.Interface(members= Some(synMemberDefns)) -> + [ for synMemberDefn in synMemberDefns do + match synMemberDefn with + | SynMemberDefn.Member(memberDefn = SynBinding(headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ _; ident])))) -> ident + | _ -> () ] + | _ -> () + ]|> List.concat + + for memberId in implMembers do + if staticMembers |> List.exists(fun name -> name = memberId.idText) then + // TODO : Should we reuse FS855 or create a new error with a better message + errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) //------------------------------------------------------------------------- @@ -4458,43 +4485,8 @@ module TcDeclarations = let attributeRange = (List.head attributes).Range error(Error(FSComp.SR.tcAugmentationsCannotHaveAttributes(), attributeRange)) - let staticAbstractMembers = - tcref.ImmediateInterfaceTypesOfFSharpTycon - |> List.choose( - fun ttype -> - match stripTyEqnsAndMeasureEqns g ttype with - | TType_app(tyconRef = tcref) -> - let staticAbstractMembers = - tcref.MembersOfFSharpTyconSorted - |> List.filter(fun x -> not x.IsInstanceMember) - Some staticAbstractMembers - | _ -> None - ) - |> List.concat - - let implMembers = - members - |> List.choose( - fun synMemberDef -> - match synMemberDef with - | SynMemberDefn.Interface(members= Some(synMemberDefns)) -> - let members = - synMemberDefns - |> List.choose( - fun synMemberDefn -> - match synMemberDefn with - | SynMemberDefn.Member(memberDefn = SynBinding(headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ _; ident])))) -> Some ident - | _ -> None - ) - Some members - | _ -> None - ) - |> List.concat - - for memberId in implMembers do - if staticAbstractMembers |> List.exists(fun x -> x.Id.idText = memberId.idText) then - // TODO : Should we reuse FS855 or create a new error with a better message - errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) + if not members.IsEmpty then + CheckStaticAbstractSlots g tcref members MutRecDefnsPhase2DataForTycon(tyconOpt, innerParent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, members, tyDeclRange, newslotsOK, fixupFinalAttrs)) From f45c3ce0d0f77d189da8799d4a2bd78223f6a5e3 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 25 Oct 2023 00:41:26 +0100 Subject: [PATCH 03/20] More tests --- .../TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index f730c5445b7..6b99280f8b7 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -931,18 +931,23 @@ module StaticAbstractBug = type IOperation = static abstract member Execute: unit -> unit abstract member Execute2: unit -> unit + static abstract member Property: int + abstract member Property2: int type FaultyOperation() = interface IOperation with member _.Execute() = () member _.Execute2() = () + member this.Property = 0 + member this.Property2 = 0 """ |> withOptions [ "--nowarn:3535" ] |> withLangVersion80 |> compile |> shouldFail |> withDiagnostics [ - (Error 855, Line 9, Col 22, Line 9, Col 29, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 11, Col 22, Line 11, Col 29, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 13, Col 25, Line 13, Col 33, "No abstract or interface member was found that corresponds to this override") ] [] From a4b7ac171c7c26875499f98bcb6221e6bd638352 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 25 Oct 2023 08:05:07 +0100 Subject: [PATCH 04/20] more tests --- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 6b99280f8b7..c9beb0a61a1 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -933,6 +933,7 @@ module StaticAbstractBug = abstract member Execute2: unit -> unit static abstract member Property: int abstract member Property2: int + static abstract Property3 : int with get, set type FaultyOperation() = interface IOperation with @@ -940,14 +941,16 @@ module StaticAbstractBug = member _.Execute2() = () member this.Property = 0 member this.Property2 = 0 + member this.Property3 set value = () """ |> withOptions [ "--nowarn:3535" ] |> withLangVersion80 |> compile |> shouldFail |> withDiagnostics [ - (Error 855, Line 11, Col 22, Line 11, Col 29, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 13, Col 25, Line 13, Col 33, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 12, Col 22, Line 12, Col 29, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 14, Col 25, Line 14, Col 33, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 16, Col 25, Line 16, Col 34, "No abstract or interface member was found that corresponds to this override") ] [] @@ -957,17 +960,25 @@ module StaticAbstractBug = type IFoo<'T> = abstract DoIt: unit -> string static abstract Other : int -> int + static abstract member Property: int + abstract member Property2: int + static abstract Property3 : int with get, set type MyFoo = { Value : int } with interface IFoo with member me.DoIt() = string me.Value member _.Other(value) = value + 1 + member this.Property = 0 + member this.Property2 = 0 + member this.Property3 set value = () """ |> withOptions [ "--nowarn:3535" ] |> withLangVersion80 |> compile |> shouldFail |> withDiagnostics [ - (Error 855, Line 11, Col 18, Line 11, Col 23, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 14, Col 18, Line 14, Col 23, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 15, Col 21, Line 15, Col 29, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 17, Col 21, Line 17, Col 30, "No abstract or interface member was found that corresponds to this override") ] From c61627427db65431894b485406950d9be55a9c49 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 25 Oct 2023 10:00:52 +0100 Subject: [PATCH 05/20] more tests --- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index c9beb0a61a1..ce9e5bb42ed 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -923,7 +923,6 @@ let main _ = |> compile |> shouldSucceed - [] let ``Produce an error when one leaves out keyword "static" in an implementation of IWSAM`` () = Fsx """ @@ -982,3 +981,53 @@ module StaticAbstractBug = (Error 855, Line 15, Col 21, Line 15, Col 29, "No abstract or interface member was found that corresponds to this override") (Error 855, Line 17, Col 21, Line 17, Col 30, "No abstract or interface member was found that corresponds to this override") ] + + [] + let ``Produce an error when one leaves out keyword "static" in multiple IWSAM implementations`` () = + Fsx """ +module StaticAbstractBug = + type IOperation = + static abstract member Execute: unit -> int + abstract member Execute2: unit -> unit + + type IOperation2 = + static abstract member Execute: unit -> int + abstract member Execute2: unit -> unit + + type FaultyOperation() = + interface IOperation with + member this.Execute() = 0 + member _.Execute2() = () + + interface IOperation2 with + member this.Execute() = 0 + member this.Execute2() = () + """ + |> withOptions [ "--nowarn:3535" ] + |> withLangVersion80 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 13, Col 25, Line 13, Col 32, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 17, Col 25, Line 17, Col 32, "No abstract or interface member was found that corresponds to this override") + ] + + [] + let ``IWSAM not supported in object expressions`` () = + Fsx """ +module StaticAbstractBug = + type IOperation = + static abstract member Execute: unit -> unit + abstract member Execute2: unit -> unit + + let objExpr = + { new IOperation with + member this.Execute() = () + member _.Execute2() = () } + """ + |> withOptions [ "--nowarn:3535" ] + |> withLangVersion80 + |> typecheck + |> shouldFail + |> withWarningCode 3536 + |> withDiagnosticMessage """'IOperation' is normally used as a type constraint in generic code, e.g. "'T when ISomeInterface<'T>" or "let f (x: #ISomeInterface<_>)". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn "3536"' or '--nowarn:3536'.""" \ No newline at end of file From 5ad9c1a9090ea65298e99a128b2aad59212a0f9c Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 30 Oct 2023 15:34:08 +0000 Subject: [PATCH 06/20] Move the chekc to a more appropiate place --- src/Compiler/Checking/CheckDeclarations.fs | 30 ------------------- src/Compiler/Checking/MethodOverrides.fs | 12 ++++++-- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 15 ++++------ 3 files changed, 16 insertions(+), 41 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 61a1c7fa942..bd4b64bf29c 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -4419,33 +4419,6 @@ module TcDeclarations = let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, SynTypeDefnSimpleRepr.Exception r, implements1, false, false, isAtOriginalTyconDefn) core, extra_vals_Inherits_Abstractslots @ extraMembers - let private CheckStaticAbstractSlots g (tcref: EntityRef) members = - let staticMembers = - [ for ttype in tcref.ImmediateInterfaceTypesOfFSharpTycon do - match stripTyEqnsAndMeasureEqns g ttype with - | TType_app(tyconRef = tcref) -> - tcref.MembersOfFSharpTyconSorted - |> List.filter(fun x -> not x.IsInstanceMember) - |> List.map(fun x -> x.DisplayNameCore) - | _ -> () ] - |> List.concat - - let implMembers = - [ for synMemberDef in members do - match synMemberDef with - | SynMemberDefn.Interface(members= Some(synMemberDefns)) -> - [ for synMemberDefn in synMemberDefns do - match synMemberDefn with - | SynMemberDefn.Member(memberDefn = SynBinding(headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ _; ident])))) -> ident - | _ -> () ] - | _ -> () - ]|> List.concat - - for memberId in implMembers do - if staticMembers |> List.exists(fun name -> name = memberId.idText) then - // TODO : Should we reuse FS855 or create a new error with a better message - errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) - //------------------------------------------------------------------------- /// Bind a collection of mutually recursive definitions in an implementation file @@ -4484,9 +4457,6 @@ module TcDeclarations = if not (List.isEmpty attributes) && (declKind = ExtrinsicExtensionBinding || declKind = IntrinsicExtensionBinding) then let attributeRange = (List.head attributes).Range error(Error(FSComp.SR.tcAugmentationsCannotHaveAttributes(), attributeRange)) - - if not members.IsEmpty then - CheckStaticAbstractSlots g tcref members MutRecDefnsPhase2DataForTycon(tyconOpt, innerParent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, members, tyDeclRange, newslotsOK, fixupFinalAttrs)) diff --git a/src/Compiler/Checking/MethodOverrides.fs b/src/Compiler/Checking/MethodOverrides.fs index bfa11de4c02..9938f220670 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -61,6 +61,10 @@ type OverrideInfo = member x.ReturnType = let (Override(returnType=b)) = x in b member x.IsCompilerGenerated = let (Override(isCompilerGenerated=b)) = x in b + + member x.IsInstance = + x.BoundingTyconRef.MembersOfFSharpTyconSorted + |> List.exists (fun y -> y.LogicalName = x.LogicalName && y.IsInstanceMember) type RequiredSlot = | RequiredSlot of methodInfo: MethInfo * isOptional: bool @@ -353,8 +357,12 @@ module DispatchSlotChecking = |> List.filter (OverrideImplementsDispatchSlot g amap m dispatchSlot) match maybeResolvedSlot with - | [ovd] -> - if not ovd.IsCompilerGenerated then + | [ovd] -> + if not ovd.IsCompilerGenerated then + let hasSameName = IsNameMatch dispatchSlot ovd + let hasSameSig = IsSigExactMatch g amap m dispatchSlot ovd && ovd.IsInstance = dispatchSlot.IsInstance + if hasSameName && not hasSameSig then + errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), ovd.Range)) let item = Item.MethodGroup(ovd.LogicalName, [dispatchSlot],None) CallNameResolutionSink sink (ovd.Range, nenv, item, dispatchSlot.FormalMethodTyparInst, ItemOccurence.Implemented, AccessorDomain.AccessibleFromSomewhere) | [] -> diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index ce9e5bb42ed..011c19625b9 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -940,16 +940,18 @@ module StaticAbstractBug = member _.Execute2() = () member this.Property = 0 member this.Property2 = 0 - member this.Property3 set value = () + member this.Property3 = 0 + member this.Property3 with set value = () """ |> withOptions [ "--nowarn:3535" ] |> withLangVersion80 |> compile |> shouldFail |> withDiagnostics [ - (Error 855, Line 12, Col 22, Line 12, Col 29, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 14, Col 25, Line 14, Col 33, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 16, Col 25, Line 16, Col 34, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 12, Col 22, Line 12, Col 29, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 14, Col 25, Line 14, Col 33, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 16, Col 25, Line 16, Col 34, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 17, Col 25, Line 17, Col 34, "No abstract or interface member was found that corresponds to this override") ] [] @@ -977,9 +979,6 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 855, Line 14, Col 18, Line 14, Col 23, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 15, Col 21, Line 15, Col 29, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 17, Col 21, Line 17, Col 30, "No abstract or interface member was found that corresponds to this override") ] [] @@ -1008,8 +1007,6 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 855, Line 13, Col 25, Line 13, Col 32, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 17, Col 25, Line 17, Col 32, "No abstract or interface member was found that corresponds to this override") ] [] From 006b35c1666bb4d709f7df69f00e10fa10b06357 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 30 Oct 2023 15:44:51 +0000 Subject: [PATCH 07/20] More tests --- .../Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 011c19625b9..1225230594f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1007,6 +1007,8 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ + (Error 855, Line 17, Col 25, Line 17, Col 32, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 13, Col 25, Line 13, Col 32, "No abstract or interface member was found that corresponds to this override") ] [] From ae4caab484c0f26e71c5f762a5505c65c8f49ec9 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 30 Oct 2023 16:36:35 +0000 Subject: [PATCH 08/20] more tests --- src/Compiler/Checking/CheckExpressions.fs | 2 +- src/Compiler/Checking/MethodOverrides.fs | 46 +++++++++++++------ src/Compiler/Checking/MethodOverrides.fsi | 10 +++- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 7 ++- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index d232a04e65b..31395dec984 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -7004,7 +7004,7 @@ and TcObjectExpr (cenv: cenv) env tpenv (objTy, realObjTy, argopt, binds, extraI DispatchSlotChecking.CheckOverridesAreAllUsedOnce (env.DisplayEnv, g, cenv.infoReader, true, implTy, dispatchSlotsKeyed, availPriorOverrides, overrideSpecs) - DispatchSlotChecking.CheckDispatchSlotsAreImplemented (env.DisplayEnv, cenv.infoReader, m, env.NameEnv, cenv.tcSink, false, implTy, dispatchSlots, availPriorOverrides, overrideSpecs) |> ignore) + DispatchSlotChecking.CheckDispatchSlotsAreImplemented (env.DisplayEnv, cenv.infoReader, m, env.NameEnv, cenv.tcSink, false, implTy, dispatchSlots, availPriorOverrides, OverrideInfoKind.OverrideInfo(overrideSpecs)) |> ignore) // 3. create the specs of overrides let allTypeImpls = diff --git a/src/Compiler/Checking/MethodOverrides.fs b/src/Compiler/Checking/MethodOverrides.fs index 9938f220670..a2c634320d7 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -62,9 +62,21 @@ type OverrideInfo = member x.IsCompilerGenerated = let (Override(isCompilerGenerated=b)) = x in b - member x.IsInstance = - x.BoundingTyconRef.MembersOfFSharpTyconSorted - |> List.exists (fun y -> y.LogicalName = x.LogicalName && y.IsInstanceMember) +type OverrideInfoKind = + | OverrideInfo of overrideInfo: OverrideInfo list + | OverrideInfoWithValRef of (ValRef option * OverrideInfo) list + + member x.OverrideInfoValRef = + match x with + | OverrideInfo(overrideInfo) -> [ for ovd in overrideInfo -> (None, ovd) ] + | OverrideInfoWithValRef(overrideInfo) -> overrideInfo + + member x.OverrideInfos = + match x with + | OverrideInfo ovd -> ovd + | OverrideInfoWithValRef ovd -> ovd |> List.map snd + + type RequiredSlot = | RequiredSlot of methodInfo: MethInfo * isOptional: bool @@ -325,7 +337,7 @@ module DispatchSlotChecking = reqdTy, dispatchSlots: RequiredSlot list, availPriorOverrides: OverrideInfo list, - overrides: OverrideInfo list) = + overrides: OverrideInfoKind) = let g = infoReader.g let amap = infoReader.amap @@ -340,7 +352,7 @@ module DispatchSlotChecking = // Index the availPriorOverrides and overrides by name let availPriorOverridesKeyed = availPriorOverrides |> NameMultiMap.initBy (fun ov -> ov.LogicalName) - let overridesKeyed = overrides |> NameMultiMap.initBy (fun ov -> ov.LogicalName) + let overridesKeyed = overrides.OverrideInfoValRef |> NameMultiMap.initBy (fun (_, ov) -> ov.LogicalName) // we accumulate those to compose a more complete error message, see noimpl() bellow. let missingOverloadImplementation = ResizeArray() @@ -354,15 +366,18 @@ module DispatchSlotChecking = let maybeResolvedSlot = NameMultiMap.find dispatchSlot.LogicalName overridesKeyed - |> List.filter (OverrideImplementsDispatchSlot g amap m dispatchSlot) + |> List.filter (fun (_, x) -> OverrideImplementsDispatchSlot g amap m dispatchSlot x) match maybeResolvedSlot with - | [ovd] -> + | [(valRef, ovd)] -> if not ovd.IsCompilerGenerated then - let hasSameName = IsNameMatch dispatchSlot ovd - let hasSameSig = IsSigExactMatch g amap m dispatchSlot ovd && ovd.IsInstance = dispatchSlot.IsInstance - if hasSameName && not hasSameSig then - errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), ovd.Range)) + match valRef with + | Some valRef -> + let hasSameName = IsNameMatch dispatchSlot ovd + let hasSameSig = IsSigExactMatch g amap m dispatchSlot ovd && valRef.IsInstanceMember = dispatchSlot.IsInstance + if hasSameName && not hasSameSig then + errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), ovd.Range)) + | _ -> () let item = Item.MethodGroup(ovd.LogicalName, [dispatchSlot],None) CallNameResolutionSink sink (ovd.Range, nenv, item, dispatchSlot.FormalMethodTyparInst, ItemOccurence.Implemented, AccessorDomain.AccessibleFromSomewhere) | [] -> @@ -383,10 +398,10 @@ module DispatchSlotChecking = let noimpl() = missingOverloadImplementation.Add((isReqdTyInterface, lazy NicePrint.stringOfMethInfo infoReader m denv dispatchSlot)) - match overrides |> List.filter (IsPartialMatch g dispatchSlot compiledSig) with + match overrides.OverrideInfos |> List.filter (IsPartialMatch g dispatchSlot compiledSig) with | [] -> let possibleOverrides = - overrides + overrides.OverrideInfos |> List.filter (fun overrideBy -> IsNameMatch dispatchSlot overrideBy && IsImplMatch g dispatchSlot overrideBy) match possibleOverrides with @@ -820,8 +835,9 @@ module DispatchSlotChecking = // We don't give missing method errors for abstract classes if isImplementation && not (isInterfaceTy g overallTy) then - let overrides = allImmediateMembersThatMightImplementDispatchSlots |> List.map snd - let allCorrect = CheckDispatchSlotsAreImplemented (denv, infoReader, m, nenv, sink, tcaug.tcaug_abstract, reqdTy, dispatchSlots, availPriorOverrides, overrides) + let overrides = allImmediateMembersThatMightImplementDispatchSlots + let overrides = overrides |> List.map (fun (overrideBy, overrideByInfo) -> Some overrideBy, overrideByInfo) + let allCorrect = CheckDispatchSlotsAreImplemented (denv, infoReader, m, nenv, sink, tcaug.tcaug_abstract, reqdTy, dispatchSlots, availPriorOverrides, OverrideInfoKind.OverrideInfoWithValRef(overrides)) // Tell the user to mark the thing abstract if it was missing implementations if not allCorrect && not tcaug.tcaug_abstract && not (isInterfaceTy g reqdTy) then diff --git a/src/Compiler/Checking/MethodOverrides.fsi b/src/Compiler/Checking/MethodOverrides.fsi index d18a8cdc6f1..000551e7a92 100644 --- a/src/Compiler/Checking/MethodOverrides.fsi +++ b/src/Compiler/Checking/MethodOverrides.fsi @@ -78,6 +78,14 @@ exception TypeIsImplicitlyAbstract of range exception OverrideDoesntOverride of DisplayEnv * OverrideInfo * MethInfo option * TcGlobals * ImportMap * range +type OverrideInfoKind = + | OverrideInfo of overrideInfo: OverrideInfo list + | OverrideInfoWithValRef of (ValRef option * OverrideInfo) list + + member OverrideInfoValRef: (ValRef option * OverrideInfo) list + + member OverrideInfos: OverrideInfo list + module DispatchSlotChecking = /// Format the signature of an override as a string as part of an error message val FormatOverride: denv: DisplayEnv -> d: OverrideInfo -> string @@ -113,7 +121,7 @@ module DispatchSlotChecking = reqdTy: TType * dispatchSlots: RequiredSlot list * availPriorOverrides: OverrideInfo list * - overrides: OverrideInfo list -> + overrides: OverrideInfoKind -> bool /// Check all implementations implement some dispatch slot. diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 1225230594f..ac28a372473 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -972,13 +972,18 @@ module StaticAbstractBug = member _.Other(value) = value + 1 member this.Property = 0 member this.Property2 = 0 - member this.Property3 set value = () + member this.Property3 = 0 + member this.Property3 with set value = () """ |> withOptions [ "--nowarn:3535" ] |> withLangVersion80 |> compile |> shouldFail |> withDiagnostics [ + (Error 855, Line 14, Col 18, Line 14, Col 23, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 15, Col 21, Line 15, Col 29, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 17, Col 21, Line 17, Col 30, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 18, Col 21, Line 18, Col 30, "No abstract or interface member was found that corresponds to this override") ] [] From f6ef8299479a2e8962a83c7eeddd4ecf9e51b5dd Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 31 Oct 2023 14:11:55 +0000 Subject: [PATCH 09/20] fantomas --- src/Compiler/Checking/MethodOverrides.fsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/MethodOverrides.fsi b/src/Compiler/Checking/MethodOverrides.fsi index 000551e7a92..2cb484b4a3b 100644 --- a/src/Compiler/Checking/MethodOverrides.fsi +++ b/src/Compiler/Checking/MethodOverrides.fsi @@ -81,9 +81,9 @@ exception OverrideDoesntOverride of DisplayEnv * OverrideInfo * MethInfo option type OverrideInfoKind = | OverrideInfo of overrideInfo: OverrideInfo list | OverrideInfoWithValRef of (ValRef option * OverrideInfo) list - + member OverrideInfoValRef: (ValRef option * OverrideInfo) list - + member OverrideInfos: OverrideInfo list module DispatchSlotChecking = From dd01d771b1173559c7aee3b7192ea7d13ba5947a Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 31 Oct 2023 15:57:00 +0000 Subject: [PATCH 10/20] Trying Vlad's version --- src/Compiler/Checking/CheckExpressions.fs | 4 +- src/Compiler/Checking/MethodOverrides.fs | 60 ++++------ src/Compiler/Checking/MethodOverrides.fsi | 15 +-- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 104 +++++++++++++++--- 4 files changed, 117 insertions(+), 66 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 31395dec984..11162f71c24 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -7004,7 +7004,7 @@ and TcObjectExpr (cenv: cenv) env tpenv (objTy, realObjTy, argopt, binds, extraI DispatchSlotChecking.CheckOverridesAreAllUsedOnce (env.DisplayEnv, g, cenv.infoReader, true, implTy, dispatchSlotsKeyed, availPriorOverrides, overrideSpecs) - DispatchSlotChecking.CheckDispatchSlotsAreImplemented (env.DisplayEnv, cenv.infoReader, m, env.NameEnv, cenv.tcSink, false, implTy, dispatchSlots, availPriorOverrides, OverrideInfoKind.OverrideInfo(overrideSpecs)) |> ignore) + DispatchSlotChecking.CheckDispatchSlotsAreImplemented (env.DisplayEnv, cenv.infoReader, m, env.NameEnv, cenv.tcSink, false, implTy, dispatchSlots, availPriorOverrides, overrideSpecs) |> ignore) // 3. create the specs of overrides let allTypeImpls = @@ -7012,7 +7012,7 @@ and TcObjectExpr (cenv: cenv) env tpenv (objTy, realObjTy, argopt, binds, extraI let overrides' = [ for overrideMeth in overrides do let overrideInfo, (_, thisVal, methodVars, bindingAttribs, bindingBody) = overrideMeth - let (Override(_, _, id, mtps, _, _, _, isFakeEventProperty, _)) = overrideInfo + let (Override(_, _, id, mtps, _, _, _, isFakeEventProperty, _, _)) = overrideInfo if not isFakeEventProperty then let searchForOverride = diff --git a/src/Compiler/Checking/MethodOverrides.fs b/src/Compiler/Checking/MethodOverrides.fs index a2c634320d7..7fe0ae24f12 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -44,7 +44,9 @@ type OverrideInfo = argTypes: TType list list * returnType: TType option * isFakeEventProperty: bool * - isCompilerGenerated: bool + isCompilerGenerated: bool * + isInstance: bool + member x.CanImplement = let (Override(canImplement=a)) = x in a @@ -62,20 +64,7 @@ type OverrideInfo = member x.IsCompilerGenerated = let (Override(isCompilerGenerated=b)) = x in b -type OverrideInfoKind = - | OverrideInfo of overrideInfo: OverrideInfo list - | OverrideInfoWithValRef of (ValRef option * OverrideInfo) list - - member x.OverrideInfoValRef = - match x with - | OverrideInfo(overrideInfo) -> [ for ovd in overrideInfo -> (None, ovd) ] - | OverrideInfoWithValRef(overrideInfo) -> overrideInfo - - member x.OverrideInfos = - match x with - | OverrideInfo ovd -> ovd - | OverrideInfoWithValRef ovd -> ovd |> List.map snd - + member x.IsInstance = let (Override(isInstance=b)) = x in b type RequiredSlot = @@ -120,7 +109,7 @@ exception OverrideDoesntOverride of DisplayEnv * OverrideInfo * MethInfo option module DispatchSlotChecking = /// Print the signature of an override to a buffer as part of an error message - let PrintOverrideToBuffer denv os (Override(_, _, id, methTypars, memberToParentInst, argTys, retTy, _, _)) = + let PrintOverrideToBuffer denv os (Override(_, _, id, methTypars, memberToParentInst, argTys, retTy, _, _, _)) = let denv = { denv with showTyparBinding = true } let retTy = (retTy |> GetFSharpViewOfReturnType denv.g) let argInfos = @@ -152,7 +141,7 @@ module DispatchSlotChecking = let (CompiledSig (argTys, retTy, fmethTypars, ttpinst)) = CompiledSigOfMeth g amap m minfo let isFakeEventProperty = minfo.IsFSharpEventPropertyMethod - Override(parentType, minfo.ApparentEnclosingTyconRef, mkSynId m nm, fmethTypars, ttpinst, argTys, retTy, isFakeEventProperty, false) + Override(parentType, minfo.ApparentEnclosingTyconRef, mkSynId m nm, fmethTypars, ttpinst, argTys, retTy, isFakeEventProperty, false, minfo.IsInstance) /// Get the override info for a value being used to implement a dispatch slot. let GetTypeMemberOverrideInfo g reqdTy (overrideBy: ValRef) = @@ -191,7 +180,7 @@ module DispatchSlotChecking = //CanImplementAnySlot <<----- Change to this to enable implicit interface implementation let isFakeEventProperty = overrideBy.IsFSharpEventProperty(g) - Override(implKind, overrideBy.MemberApparentEntity, mkSynId overrideBy.Range nm, memberMethodTypars, memberToParentInst, argTys, retTy, isFakeEventProperty, overrideBy.IsCompilerGenerated) + Override(implKind, overrideBy.MemberApparentEntity, mkSynId overrideBy.Range nm, memberMethodTypars, memberToParentInst, argTys, retTy, isFakeEventProperty, overrideBy.IsCompilerGenerated, overrideBy.IsInstanceMember) /// Get the override information for an object expression method being used to implement dispatch slots let GetObjectExprOverrideInfo g amap (implTy, id: Ident, memberFlags, ty, arityInfo, bindingAttribs, rhsExpr) = @@ -216,7 +205,7 @@ module DispatchSlotChecking = CanImplementAnyClassHierarchySlot //CanImplementAnySlot <<----- Change to this to enable implicit interface implementation let isFakeEventProperty = CompileAsEvent g bindingAttribs - let overrideByInfo = Override(implKind, tcrefOfAppTy g implTy, id, tps, [], argTys, retTy, isFakeEventProperty, false) + let overrideByInfo = Override(implKind, tcrefOfAppTy g implTy, id, tps, [], argTys, retTy, isFakeEventProperty, false, memberFlags.IsInstance) overrideByInfo, (baseValOpt, thisv, vs, bindingAttribs, rhsExpr) | _ -> error(InternalError("Unexpected shape for object expression override", id.idRange)) @@ -243,7 +232,7 @@ module DispatchSlotChecking = /// Check if an override is a partial match for the requirements for a dispatch slot except for the name. let IsSigPartialMatch g (dispatchSlot: MethInfo) compiledSig overrideBy = - let (Override(_, _, _, methTypars, _, argTys, _retTy, _, _)) = overrideBy + let (Override(_, _, _, methTypars, _, argTys, _retTy, _, _, _)) = overrideBy let (CompiledSig (vargTys, _, fvmethTypars, _)) = compiledSig methTypars.Length = fvmethTypars.Length && IsTyparKindMatch compiledSig overrideBy && @@ -265,7 +254,7 @@ module DispatchSlotChecking = /// Check if an override exactly matches the requirements for a dispatch slot except for the name. let IsSigExactMatch g amap m dispatchSlot overrideBy = - let (Override(_, _, _, methTypars, memberToParentInst, argTys, retTy, _, _)) = overrideBy + let (Override(_, _, _, methTypars, memberToParentInst, argTys, retTy, _, _, _)) = overrideBy let compiledSig = CompiledSigOfMeth g amap m dispatchSlot IsSigPartialMatch g dispatchSlot compiledSig overrideBy && let (CompiledSig (vargTys, vrty, fvmethTypars, ttpinst)) = compiledSig @@ -316,7 +305,8 @@ module DispatchSlotChecking = /// Check if an override exactly matches the requirements for a dispatch slot. let IsExactMatch g amap m dispatchSlot overrideBy = IsNameMatch dispatchSlot overrideBy && - IsSigExactMatch g amap m dispatchSlot overrideBy + IsSigExactMatch g amap m dispatchSlot overrideBy && + dispatchSlot.IsInstance = overrideBy.IsInstance /// Check if an override implements a dispatch slot let OverrideImplementsDispatchSlot g amap m dispatchSlot availPriorOverride = @@ -337,7 +327,7 @@ module DispatchSlotChecking = reqdTy, dispatchSlots: RequiredSlot list, availPriorOverrides: OverrideInfo list, - overrides: OverrideInfoKind) = + overrides: OverrideInfo list) = let g = infoReader.g let amap = infoReader.amap @@ -352,7 +342,7 @@ module DispatchSlotChecking = // Index the availPriorOverrides and overrides by name let availPriorOverridesKeyed = availPriorOverrides |> NameMultiMap.initBy (fun ov -> ov.LogicalName) - let overridesKeyed = overrides.OverrideInfoValRef |> NameMultiMap.initBy (fun (_, ov) -> ov.LogicalName) + let overridesKeyed = overrides |> NameMultiMap.initBy (fun ov -> ov.LogicalName) // we accumulate those to compose a more complete error message, see noimpl() bellow. let missingOverloadImplementation = ResizeArray() @@ -366,18 +356,11 @@ module DispatchSlotChecking = let maybeResolvedSlot = NameMultiMap.find dispatchSlot.LogicalName overridesKeyed - |> List.filter (fun (_, x) -> OverrideImplementsDispatchSlot g amap m dispatchSlot x) + |> List.filter (OverrideImplementsDispatchSlot g amap m dispatchSlot) match maybeResolvedSlot with - | [(valRef, ovd)] -> + | [ovd] -> if not ovd.IsCompilerGenerated then - match valRef with - | Some valRef -> - let hasSameName = IsNameMatch dispatchSlot ovd - let hasSameSig = IsSigExactMatch g amap m dispatchSlot ovd && valRef.IsInstanceMember = dispatchSlot.IsInstance - if hasSameName && not hasSameSig then - errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), ovd.Range)) - | _ -> () let item = Item.MethodGroup(ovd.LogicalName, [dispatchSlot],None) CallNameResolutionSink sink (ovd.Range, nenv, item, dispatchSlot.FormalMethodTyparInst, ItemOccurence.Implemented, AccessorDomain.AccessibleFromSomewhere) | [] -> @@ -398,10 +381,10 @@ module DispatchSlotChecking = let noimpl() = missingOverloadImplementation.Add((isReqdTyInterface, lazy NicePrint.stringOfMethInfo infoReader m denv dispatchSlot)) - match overrides.OverrideInfos |> List.filter (IsPartialMatch g dispatchSlot compiledSig) with + match overrides |> List.filter (IsPartialMatch g dispatchSlot compiledSig) with | [] -> let possibleOverrides = - overrides.OverrideInfos + overrides |> List.filter (fun overrideBy -> IsNameMatch dispatchSlot overrideBy && IsImplMatch g dispatchSlot overrideBy) match possibleOverrides with @@ -409,7 +392,7 @@ module DispatchSlotChecking = noimpl() | [ overrideBy ] -> - let (Override(_, _, _, methTypars, _, argTys, _, _, _)) = overrideBy + let (Override(_, _, _, methTypars, _, argTys, _, _, _, _)) = overrideBy let moreThanOnePossibleDispatchSlot = dispatchSlots @@ -835,9 +818,8 @@ module DispatchSlotChecking = // We don't give missing method errors for abstract classes if isImplementation && not (isInterfaceTy g overallTy) then - let overrides = allImmediateMembersThatMightImplementDispatchSlots - let overrides = overrides |> List.map (fun (overrideBy, overrideByInfo) -> Some overrideBy, overrideByInfo) - let allCorrect = CheckDispatchSlotsAreImplemented (denv, infoReader, m, nenv, sink, tcaug.tcaug_abstract, reqdTy, dispatchSlots, availPriorOverrides, OverrideInfoKind.OverrideInfoWithValRef(overrides)) + let overrides = allImmediateMembersThatMightImplementDispatchSlots |> List.map snd + let allCorrect = CheckDispatchSlotsAreImplemented (denv, infoReader, m, nenv, sink, tcaug.tcaug_abstract, reqdTy, dispatchSlots, availPriorOverrides, overrides) // Tell the user to mark the thing abstract if it was missing implementations if not allCorrect && not tcaug.tcaug_abstract && not (isInterfaceTy g reqdTy) then diff --git a/src/Compiler/Checking/MethodOverrides.fsi b/src/Compiler/Checking/MethodOverrides.fsi index 2cb484b4a3b..1e56272bc25 100644 --- a/src/Compiler/Checking/MethodOverrides.fsi +++ b/src/Compiler/Checking/MethodOverrides.fsi @@ -32,7 +32,8 @@ type OverrideInfo = argTypes: TType list list * returnType: TType option * isFakeEventProperty: bool * - isCompilerGenerated: bool + isCompilerGenerated: bool * + isInstance: bool member ArgTypes: TType list list @@ -42,6 +43,8 @@ type OverrideInfo = member IsCompilerGenerated: bool + member IsInstance: bool + member IsFakeEventProperty: bool member LogicalName: string @@ -78,14 +81,6 @@ exception TypeIsImplicitlyAbstract of range exception OverrideDoesntOverride of DisplayEnv * OverrideInfo * MethInfo option * TcGlobals * ImportMap * range -type OverrideInfoKind = - | OverrideInfo of overrideInfo: OverrideInfo list - | OverrideInfoWithValRef of (ValRef option * OverrideInfo) list - - member OverrideInfoValRef: (ValRef option * OverrideInfo) list - - member OverrideInfos: OverrideInfo list - module DispatchSlotChecking = /// Format the signature of an override as a string as part of an error message val FormatOverride: denv: DisplayEnv -> d: OverrideInfo -> string @@ -121,7 +116,7 @@ module DispatchSlotChecking = reqdTy: TType * dispatchSlots: RequiredSlot list * availPriorOverrides: OverrideInfo list * - overrides: OverrideInfoKind -> + overrides: OverrideInfo list -> bool /// Check all implementations implement some dispatch slot. diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index ac28a372473..ec3f6bb8ac6 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -948,10 +948,44 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 855, Line 12, Col 22, Line 12, Col 29, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 14, Col 25, Line 14, Col 33, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 16, Col 25, Line 16, Col 34, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 17, Col 25, Line 17, Col 34, "No abstract or interface member was found that corresponds to this override") + (Error 17, Line 12, Col 22, Line 12, Col 29, "The member 'Execute: unit -> unit' does not have the correct type to override the corresponding abstract method.") + (Error 17, Line 14, Col 25, Line 14, Col 33, "The member 'get_Property: unit -> int' does not have the correct type to override the corresponding abstract method.") + (Error 17, Line 16, Col 25, Line 16, Col 34, "The member 'get_Property3: unit -> int' does not have the correct type to override the corresponding abstract method.") + (Error 17, Line 17, Col 25, Line 17, Col 34, "The member 'set_Property3: int -> unit' does not have the correct type to override the corresponding abstract method.") + ] + + [] + let ``Produce an error when one leaves out keyword "static" in an implementation of IWSAM with multiple overloads`` () = + Fsx """ +module StaticAbstractBug = + type IOperation = + static abstract member Execute: unit -> unit + abstract member Execute: unit -> bool + static abstract member Property: int + abstract member Property: int + + type FaultyOperation() = + interface IOperation with + member _.Execute() = () + member _.Execute() = false + member this.Property = 0 + member this.Property = false + """ + |> withOptions [ "--nowarn:3535" ] + |> withLangVersion80 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 358, Line 10, Col 19, Line 10, Col 29, "The override for 'Execute: unit -> unit' was ambiguous") + (Error 358, Line 10, Col 19, Line 10, Col 29, "The override for 'get_Property: unit -> int' was ambiguous") + (Error 3213, Line 11, Col 22, Line 11, Col 29, "The member 'Execute: unit -> unit' matches multiple overloads of the same method. +Please restrict it to one of the following: + Execute: unit -> bool + Execute: unit -> unit."); + (Error 3213, Line 14, Col 25, Line 14, Col 33, "The member 'get_Property: unit -> bool' matches multiple overloads of the same method. +Please restrict it to one of the following: + get_Property: unit -> int + get_Property: unit -> int.") ] [] @@ -980,10 +1014,47 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 855, Line 14, Col 18, Line 14, Col 23, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 15, Col 21, Line 15, Col 29, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 17, Col 21, Line 17, Col 30, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 18, Col 21, Line 18, Col 30, "No abstract or interface member was found that corresponds to this override") + (Error 17, Line 14, Col 18, Line 14, Col 23, "The member 'Other: int -> int' does not have the correct type to override the corresponding abstract method.") + (Error 17, Line 15, Col 21, Line 15, Col 29, "The member 'get_Property: unit -> int' does not have the correct type to override the corresponding abstract method.") + (Error 17, Line 17, Col 21, Line 17, Col 30, "The member 'get_Property3: unit -> int' does not have the correct type to override the corresponding abstract method.") + (Error 17, Line 18, Col 21, Line 18, Col 30, "The member 'set_Property3: int -> unit' does not have the correct type to override the corresponding abstract method.") + ] + + [] + let ``Produce an error for interface with static abstract member that is implemented as instance member with multiple overloads`` () = + Fsx """ +module StaticAbstractBug = + type IFoo<'T> = + abstract DoIt: unit -> string + static abstract Other : int -> int + abstract Other : int -> bool + static abstract member Property: int + abstract member Property: bool + type MyFoo = { + Value : int + } with + interface IFoo with + member me.DoIt() = string me.Value + member _.Other(value) = value + 1 + member _.Other(value) = value = 1 + member this.Property = 0 + member this.Property = false + """ + |> withOptions [ "--nowarn:3535" ] + |> withLangVersion80 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 358, Line 12, Col 17, Line 12, Col 28, "The override for 'Other: int -> int' was ambiguous") + (Error 358, Line 12, Col 17, Line 12, Col 28, "The override for 'get_Property: unit -> int' was ambiguous") + (Error 3213, Line 14, Col 18, Line 14, Col 23, "The member 'Other: int -> int' matches multiple overloads of the same method. +Please restrict it to one of the following: + Other: int -> bool + Other: int -> int.") + (Error 3213, Line 16, Col 21, Line 16, Col 29, "The member 'get_Property: unit -> int' matches multiple overloads of the same method. +Please restrict it to one of the following: + get_Property: unit -> bool + get_Property: unit -> int.") ] [] @@ -1012,12 +1083,12 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 855, Line 17, Col 25, Line 17, Col 32, "No abstract or interface member was found that corresponds to this override") - (Error 855, Line 13, Col 25, Line 13, Col 32, "No abstract or interface member was found that corresponds to this override") + (Error 17, Line 17, Col 25, Line 17, Col 32, "The member 'Execute: unit -> int' does not have the correct type to override the corresponding abstract method.") + (Error 17, Line 13, Col 25, Line 13, Col 32, "The member 'Execute: unit -> int' does not have the correct type to override the corresponding abstract method.") ] [] - let ``IWSAM not supported in object expressions`` () = + let ``Produce an error when one leaves out keyword "static" when implementing IWSAM in an object expression`` () = Fsx """ module StaticAbstractBug = type IOperation = @@ -1026,12 +1097,15 @@ module StaticAbstractBug = let objExpr = { new IOperation with - member this.Execute() = () + member Execute() = () member _.Execute2() = () } """ - |> withOptions [ "--nowarn:3535" ] + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] |> withLangVersion80 |> typecheck |> shouldFail - |> withWarningCode 3536 - |> withDiagnosticMessage """'IOperation' is normally used as a type constraint in generic code, e.g. "'T when ISomeInterface<'T>" or "let f (x: #ISomeInterface<_>)". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn "3536"' or '--nowarn:3536'.""" \ No newline at end of file + |> withDiagnostics [ + (Error 673, Line 9, Col 20, Line 9, Col 27, "This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args) = ...'.") + (Error 17, Line 9, Col 20, Line 9, Col 27, "The member 'Execute: unit -> unit' does not have the correct type to override the corresponding abstract method.") + (Error 783, Line 8, Col 15, Line 8, Col 25, "At least one override did not correctly implement its corresponding abstract member") + ] \ No newline at end of file From 8a00e060d24992a596f6e62fed3688f14b398d54 Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Wed, 1 Nov 2023 16:15:51 +0100 Subject: [PATCH 11/20] WIP --- .vscode/launch.json | 4 ++-- .vscode/tasks.json | 21 +++++++++++++++++---- src/Compiler/Checking/CheckExpressions.fs | 6 +++++- src/Compiler/Checking/MethodOverrides.fs | 6 +++--- src/Compiler/Driver/CompilerDiagnostics.fs | 10 ++++++++++ src/Compiler/FSComp.txt | 1 + src/Compiler/FSStrings.resx | 6 ++++++ 7 files changed, 44 insertions(+), 10 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 8853be0a138..965a1b47fc3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -21,7 +21,7 @@ "type": "coreclr", "request": "launch", // TODO: Shall we assume that it's already been built, or build it every time we debug? - // "preLaunchTask": "Build (Debug)", + "preLaunchTask": "Build (Debug)", // If you have changed target frameworks, make sure to update the program p "program": "${workspaceFolder}/artifacts/bin/fsi/Debug/net8.0/fsi.dll", "args": [ @@ -50,7 +50,7 @@ "type": "coreclr", "request": "launch", // TODO: Shall we assume that it's already been built, or build it every time we debug? - // "preLaunchTask": "Build (Debug)", + "preLaunchTask": "Build (Debug)", // If you have changed target frameworks, make sure to update the program path. "program": "${workspaceFolder}/artifacts/bin/fsc/Debug/net8.0/fsc.dll", "args": [ diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 7ec6813a99c..1728f4efc97 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -31,10 +31,18 @@ "-c", "Debug", "FSharp.Compiler.Service.sln" - ], + ] + }, + "options": { + "env": { + "UpdateXlfOnBuild": "true" + } }, "problemMatcher": "$msCompile", - "group": "build", + "group": { + "kind": "build", + "isDefault": true + } }, { "label": "Build (Release)", @@ -53,10 +61,15 @@ "-c", "Release", "FSharp.Compiler.Service.sln" - ], + ] + }, + "options": { + "env": { + "UpdateXlfOnBuild": "true" + } }, "problemMatcher": "$msCompile", - "group": "build", + "group": "build" }, { "label": "Update xlf files", diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 11162f71c24..3815f553e29 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -11234,7 +11234,11 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (_: Val option) (a let uniqueAbstractMethSigs = match dispatchSlots with | [] -> - errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) + let instanceExpected = memberFlags.IsInstance + if instanceExpected then + errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) + else + errorR (Error(FSComp.SR.tcNoStaticMemberFoundForOverride (), memberId.idRange)) [] | slot :: _ as slots -> diff --git a/src/Compiler/Checking/MethodOverrides.fs b/src/Compiler/Checking/MethodOverrides.fs index 7fe0ae24f12..85f8901eb12 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -618,7 +618,8 @@ module DispatchSlotChecking = if dispatchSlot.IsFinal && (isObjExpr || not (typeEquiv g reqdTy dispatchSlot.ApparentEnclosingType)) then errorR(Error(FSComp.SR.typrelMethodIsSealed(NicePrint.stringOfMethInfo infoReader m denv dispatchSlot), m)) | dispatchSlots -> - match dispatchSlots |> List.filter (fun dispatchSlot -> + match dispatchSlots |> List.filter (fun dispatchSlot -> + (dispatchSlot.IsInstance = overrideBy.IsInstance) && isInterfaceTy g dispatchSlot.ApparentEnclosingType || not (DispatchSlotIsAlreadyImplemented g amap m availPriorOverridesKeyed dispatchSlot)) with | h1 :: h2 :: _ -> @@ -946,7 +947,7 @@ let GetAbstractMethInfosForSynMethodDecl(infoReader: InfoReader, ad, memberName: NameMultiMap.find memberName.idText dispatchSlotsKeyed |> List.map (fun reqdSlot -> reqdSlot.MethodInfo) | ty, None -> GetIntrinsicMethInfosOfType infoReader (Some memberName.idText) ad AllowMultiIntfInstantiations.Yes findFlag bindm ty - let dispatchSlots = minfos |> List.filter (fun minfo -> minfo.IsDispatchSlot) + let dispatchSlots = minfos |> List.filter (fun minfo -> minfo.IsDispatchSlot && minfo.IsInstance = memberFlags.IsInstance) let valReprSynArities = SynInfo.AritiesOfArgs valSynData // We only return everything if it's empty or if it's a non-instance member. @@ -971,4 +972,3 @@ let GetAbstractPropInfosForSynPropertyDecl(infoReader: InfoReader, ad, memberNam let dispatchSlots = pinfos |> List.filter (fun pinfo -> pinfo.IsVirtualProperty) dispatchSlots - diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 842044aab14..34fd76eb1ba 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -532,6 +532,8 @@ module OldStyleMessages = let OverrideDoesntOverride2E () = Message("OverrideDoesntOverride2", "%s") let OverrideDoesntOverride3E () = Message("OverrideDoesntOverride3", "%s") let OverrideDoesntOverride4E () = Message("OverrideDoesntOverride4", "%s") + let OverrideShouldBeStatic () = Message("OverrideShouldBeStatic", "") + let OverrideShouldBeInstance () = Message("OverrideShouldBeInstance", "") let UnionCaseWrongArgumentsE () = Message("UnionCaseWrongArguments", "%d%d") let UnionPatternsBindDifferentNamesE () = Message("UnionPatternsBindDifferentNames", "") let RequiredButNotSpecifiedE () = Message("RequiredButNotSpecified", "%s%s%s") @@ -1547,6 +1549,14 @@ type Exception with if sig1 <> sig2 then os.AppendString(OverrideDoesntOverride3E().Format sig2) + // If implementation and required slot doesn't have same "instance-ness", then tell user that. + if impl.IsInstance <> minfoVirt.IsInstance then + // Requried slot is instance, meaning implementation is static, tell user that we expect instance. + if minfoVirt.IsInstance then + os.AppendString(OverrideShouldBeStatic().Format) + else + os.AppendString(OverrideShouldBeInstance().Format) + | UnionCaseWrongArguments (_, n1, n2, _) -> os.AppendString(UnionCaseWrongArgumentsE().Format n2 n1) | UnionPatternsBindDifferentNames _ -> os.AppendString(UnionPatternsBindDifferentNamesE().Format) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index c6baff5fc2d..4769a972acd 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1725,3 +1725,4 @@ featureUnmanagedConstraintCsharpInterop,"Interop between C#'s and F#'s unmanaged 3579,alwaysUseTypedStringInterpolation,"Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended." 3580,tcUnexpectedFunTypeInUnionCaseField,"Unexpected function type in union case field definition. If you intend the field to be a function, consider wrapping the function signature with parens, e.g. | Case of a -> b into | Case of (a -> b)." 3582,tcInfoIfFunctionShadowsUnionCase,"This is a function definition that shadows a union case. If this is what you want, ignore or suppress this warning. If you want it to be a union case deconstruction, add parentheses." +3855,tcNoStaticMemberFoundForOverride,"No static abstract member was found that corresponds to this override" \ No newline at end of file diff --git a/src/Compiler/FSStrings.resx b/src/Compiler/FSStrings.resx index 04946671a84..251f626c63e 100644 --- a/src/Compiler/FSStrings.resx +++ b/src/Compiler/FSStrings.resx @@ -882,6 +882,12 @@ The member '{0}' is specialized with 'unit' but 'unit' can't be used as return type of an abstract method parameterized on return type. + + Static member is expected. + + + Non-static member is expected. + This constructor is applied to {0} argument(s) but expects {1} From 774e34f3c8a2b3288a66a9d38da0ad5df615c886 Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Wed, 1 Nov 2023 17:11:58 +0100 Subject: [PATCH 12/20] tests --- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 41 +++++-------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index ec3f6bb8ac6..0f3652fae92 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -948,10 +948,7 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 17, Line 12, Col 22, Line 12, Col 29, "The member 'Execute: unit -> unit' does not have the correct type to override the corresponding abstract method.") - (Error 17, Line 14, Col 25, Line 14, Col 33, "The member 'get_Property: unit -> int' does not have the correct type to override the corresponding abstract method.") - (Error 17, Line 16, Col 25, Line 16, Col 34, "The member 'get_Property3: unit -> int' does not have the correct type to override the corresponding abstract method.") - (Error 17, Line 17, Col 25, Line 17, Col 34, "The member 'set_Property3: int -> unit' does not have the correct type to override the corresponding abstract method.") + (Error 855, Line 12, Col 22, Line 12, Col 29, "No abstract or interface member was found that corresponds to this override") ] [] @@ -976,16 +973,10 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 358, Line 10, Col 19, Line 10, Col 29, "The override for 'Execute: unit -> unit' was ambiguous") - (Error 358, Line 10, Col 19, Line 10, Col 29, "The override for 'get_Property: unit -> int' was ambiguous") - (Error 3213, Line 11, Col 22, Line 11, Col 29, "The member 'Execute: unit -> unit' matches multiple overloads of the same method. -Please restrict it to one of the following: - Execute: unit -> bool - Execute: unit -> unit."); - (Error 3213, Line 14, Col 25, Line 14, Col 33, "The member 'get_Property: unit -> bool' matches multiple overloads of the same method. -Please restrict it to one of the following: - get_Property: unit -> int - get_Property: unit -> int.") + (Error 1, Line 11, Col 34, Line 11, Col 36, "This expression was expected to have type + 'bool' +but here has type + 'unit' ") ] [] @@ -1014,10 +1005,7 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 17, Line 14, Col 18, Line 14, Col 23, "The member 'Other: int -> int' does not have the correct type to override the corresponding abstract method.") - (Error 17, Line 15, Col 21, Line 15, Col 29, "The member 'get_Property: unit -> int' does not have the correct type to override the corresponding abstract method.") - (Error 17, Line 17, Col 21, Line 17, Col 30, "The member 'get_Property3: unit -> int' does not have the correct type to override the corresponding abstract method.") - (Error 17, Line 18, Col 21, Line 18, Col 30, "The member 'set_Property3: int -> unit' does not have the correct type to override the corresponding abstract method.") + (Error 855, Line 14, Col 18, Line 14, Col 23, "No abstract or interface member was found that corresponds to this override") ] [] @@ -1045,16 +1033,7 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 358, Line 12, Col 17, Line 12, Col 28, "The override for 'Other: int -> int' was ambiguous") - (Error 358, Line 12, Col 17, Line 12, Col 28, "The override for 'get_Property: unit -> int' was ambiguous") - (Error 3213, Line 14, Col 18, Line 14, Col 23, "The member 'Other: int -> int' matches multiple overloads of the same method. -Please restrict it to one of the following: - Other: int -> bool - Other: int -> int.") - (Error 3213, Line 16, Col 21, Line 16, Col 29, "The member 'get_Property: unit -> int' matches multiple overloads of the same method. -Please restrict it to one of the following: - get_Property: unit -> bool - get_Property: unit -> int.") + (Error 1, Line 14, Col 41, Line 14, Col 42, "The type 'bool' does not match the type 'int'") ] [] @@ -1083,8 +1062,8 @@ module StaticAbstractBug = |> compile |> shouldFail |> withDiagnostics [ - (Error 17, Line 17, Col 25, Line 17, Col 32, "The member 'Execute: unit -> int' does not have the correct type to override the corresponding abstract method.") - (Error 17, Line 13, Col 25, Line 13, Col 32, "The member 'Execute: unit -> int' does not have the correct type to override the corresponding abstract method.") + (Error 855, Line 13, Col 25, Line 13, Col 32, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 17, Col 25, Line 17, Col 32, "No abstract or interface member was found that corresponds to this override") ] [] @@ -1106,6 +1085,6 @@ module StaticAbstractBug = |> shouldFail |> withDiagnostics [ (Error 673, Line 9, Col 20, Line 9, Col 27, "This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args) = ...'.") - (Error 17, Line 9, Col 20, Line 9, Col 27, "The member 'Execute: unit -> unit' does not have the correct type to override the corresponding abstract method.") + (Error 17, Line 9, Col 20, Line 9, Col 27, "The member 'Execute: unit -> unit' does not have the correct type to override the corresponding abstract method. Non-static member is expected.") (Error 783, Line 8, Col 15, Line 8, Col 25, "At least one override did not correctly implement its corresponding abstract member") ] \ No newline at end of file From b834bb4bd10f8a08af9e5510e287799f8ff66999 Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Wed, 1 Nov 2023 17:28:15 +0100 Subject: [PATCH 13/20] xlf --- 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 +++++ src/Compiler/xlf/FSStrings.cs.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.de.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.es.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.fr.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.it.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.ja.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.ko.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.pl.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.pt-BR.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.ru.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.tr.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.zh-Hans.xlf | 10 ++++++++++ src/Compiler/xlf/FSStrings.zh-Hant.xlf | 10 ++++++++++ 26 files changed, 195 insertions(+) diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 0de0dda3fcb..e1416d0d84b 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1252,6 +1252,11 @@ Použití metod s atributem NoEagerConstraintApplicationAttribute vyžaduje /langversion:6.0 nebo novější. + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Tento výraz podporuje indexování, třeba expr.[index]. Syntaxe expr[index] vyžaduje /langversion:preview. Více informací: https://aka.ms/fsharp-index-notation diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index ace9ad92933..e34fe6a410f 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1252,6 +1252,11 @@ Die Verwendung von Methoden mit "NoEagerConstraintApplicationAttribute" erfordert /langversion:6.0 oder höher. + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Dieser Ausdruck unterstützt die Indizierung, z. B. "expr.[index]". Die Syntax "expr[index]" erfordert /langversion:preview. Siehe https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 286598c9988..7c8b4c74a06 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1252,6 +1252,11 @@ El uso de métodos con "NoEagerConstraintApplicationAttribute" requiere /langversion:6.0 o posteriores + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Esta expresión admite indexación, por ejemplo "expr.[index]". La sintaxis "expr[index]" requiere /langversion:preview. Ver https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index e3f9f534475..a763dc6a825 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1252,6 +1252,11 @@ L’utilisation de méthodes avec « NoEagerConstraintApplicationAttribute » requiert/langversion:6.0 ou ultérieur + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Cette expression prend en charge l’indexation, par exemple « expr.[index] ». La syntaxe « expr[index] » requiert /langversion:preview. Voir https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index fefdc56090c..ee1a3203918 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1252,6 +1252,11 @@ L'utilizzo di metodi con 'NoEagerConstraintApplicationAttribute' richiede /langversion: 6.0 o versione successiva + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Questa espressione supporta l'indicizzazione, ad esempio 'expr.[index]'. La sintassi 'expr[index]' richiede/langversion:preview. Vedere https://aka.ms/fsharp-index-notation.. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 547baf049f7..9e6319e0bae 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1252,6 +1252,11 @@ 'NoEagerConstraintApplicationAttribute' を指定してメソッドを使用するには、/langversion:6.0 以降が必要です + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. この式は、'expr. [index]' などのインデックスをサポートしています。構文 'expr[index]' には /langversion:preview が必要です。https://aka.ms/fsharp-index-notation を参照してください。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 51ed5cd562a..6107fffa639 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1252,6 +1252,11 @@ 'NoEagerConstraintApplicationAttribute'와 함께 메서드를 사용하려면 /langversion:6.0 이상이 필요합니다. + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. 이 식은 인덱싱을 지원합니다. 'expr.[index]'. 'expr[index]' 구문에는 /langversion:preview가 필요합니다. https://aka.ms/fsharp-index-notation을 참조하세요. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 4fe31c3a96b..85b46c32002 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1252,6 +1252,11 @@ Używanie metod z atrybutem "NoEagerConstraintApplicationAttribute" wymaga parametru /langversion:6.0 lub nowszego + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. To wyrażenie obsługuje indeksowanie, np. „expr.[index]”. Składnia wyrażenia „expr[index]” wymaga parametru /langversion:preview. Zobacz: https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index b80b7cb1665..538af997412 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1252,6 +1252,11 @@ Usar métodos com 'NoEagerConstraintApplicationAttribute' requer /langversion:6.0 ou posterior + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Essa expressão oferece suporte à indexação, por exemplo, 'expr. [index]'. A sintaxe 'expr[index]' requer /langversion:preview. Consulte https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index a70e6137577..5387a872edf 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1252,6 +1252,11 @@ Для использования методов с "NoEagerConstraintApplicationAttribute" требуется /langversion:6.0 или более поздняя версия + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Это выражение поддерживает индексирование, например, "expr. [index]". Для синтаксиса "expr[index]" требуется /langversion:preview. См. https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index b5588a963ff..6c725a85f8f 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1252,6 +1252,11 @@ 'NoEagerConstraintApplicationAttribute' içeren yöntemlerin kullanılması /langversion:6.0 veya üstünü gerektiriyor + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Bu ifade dizin oluşturmayı destekler, örn. “expr.[index]”. Söz dizimi “expr.[index]” /langversion:preview gerektirir. https://aka.ms/fsharp-index-notation'a bakın. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 804aefd5e43..dc6440223a3 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1252,6 +1252,11 @@ 将方法与 “NoEagerConstraintApplicationAttribute” 配合使用需要 /langversion:6.0 或更高版本 + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. 此表达式支持索引,例如“expr.[index]”。语法“expr[index]”需要 /langversion:preview。请参阅 https://aka.ms/fsharp-index-notation。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 3e5f30fb7a6..667288b6258 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1252,6 +1252,11 @@ 使用具有 'NoEagerConstraintApplicationAttribute' 的方法需要 /langversion:6.0 或更新版本 + + No static abstract member was found that corresponds to this override + No static abstract member was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. 此運算式支援編製索引,例如 'expr.[index]'。語法 'expr[index]' 需要 /langversion:preview。請參閱 https://aka.ms/fsharp-index-notation。 diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf index 7fb003f52d8..318ea1464ff 100644 --- a/src/Compiler/xlf/FSStrings.cs.xlf +++ b/src/Compiler/xlf/FSStrings.cs.xlf @@ -22,6 +22,16 @@ Případy sjednocení s malými písmeny jsou povolené jenom při použití atributu RequireQualifiedAccess. + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' symbol ..^ diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf index 91366947a2a..430b308631e 100644 --- a/src/Compiler/xlf/FSStrings.de.xlf +++ b/src/Compiler/xlf/FSStrings.de.xlf @@ -22,6 +22,16 @@ Diskriminierte Union-Fälle in Kleinbuchstaben sind nur zulässig, wenn das RequireQualifiedAccess-Attribut verwendet wird. + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' Symbol "..^" diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf index 12117838fdf..9a94fe0bfca 100644 --- a/src/Compiler/xlf/FSStrings.es.xlf +++ b/src/Compiler/xlf/FSStrings.es.xlf @@ -22,6 +22,16 @@ Los casos de unión discriminada en minúsculas solo se permiten cuando se usa el atributo RequireQualifiedAccess + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' símbolo "..^" diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf index 555adcfef64..0d5bfd687ae 100644 --- a/src/Compiler/xlf/FSStrings.fr.xlf +++ b/src/Compiler/xlf/FSStrings.fr.xlf @@ -22,6 +22,16 @@ Les cas d’union discriminée en minuscules sont uniquement autorisés lors de l’utilisation de l’attribut RequireQualifiedAccess. + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' symbole '..^' diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf index 54a69b1b768..465456a085d 100644 --- a/src/Compiler/xlf/FSStrings.it.xlf +++ b/src/Compiler/xlf/FSStrings.it.xlf @@ -22,6 +22,16 @@ I casi di unione discriminati minuscoli sono consentiti solo quando si usa l'attributo RequireQualifiedAccess + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' simbolo '..^' diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf index cf0302da1c2..c895e7a6a1e 100644 --- a/src/Compiler/xlf/FSStrings.ja.xlf +++ b/src/Compiler/xlf/FSStrings.ja.xlf @@ -22,6 +22,16 @@ 小文字で区別される和集合のケースは、RequireQualifiedAccess 属性を使用する場合にのみ許可されます + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' シンボル '..^' diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf index b43d666d0b6..82dbc42e072 100644 --- a/src/Compiler/xlf/FSStrings.ko.xlf +++ b/src/Compiler/xlf/FSStrings.ko.xlf @@ -22,6 +22,16 @@ 소문자로 구분된 공용 구조체 케이스는 RequireQualifiedAccess 특성을 사용하는 경우에만 허용됩니다. + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' 기호 '..^' diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf index 0040f91cbcf..e2bc31e3fb9 100644 --- a/src/Compiler/xlf/FSStrings.pl.xlf +++ b/src/Compiler/xlf/FSStrings.pl.xlf @@ -22,6 +22,16 @@ Przypadki unii z dyskryminatorem z małymi literami są dozwolone tylko w przypadku używania atrybutu RequireQualifiedAccess + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' symbol „..^” diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf index 4c01cb03d6e..b4d1f7ba70d 100644 --- a/src/Compiler/xlf/FSStrings.pt-BR.xlf +++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf @@ -22,6 +22,16 @@ Os casos de união discriminados em letras minúsculas só são permitidos ao usar o atributo RequireQualifiedAccess + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' símbolo '..^' diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf index 1f43d4d03f8..5149ef4d9f0 100644 --- a/src/Compiler/xlf/FSStrings.ru.xlf +++ b/src/Compiler/xlf/FSStrings.ru.xlf @@ -22,6 +22,16 @@ Размеченные в нижнем регистре случаи объединения разрешены только при использовании атрибута RequireQualifiedAccess + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' символ "..^" diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf index 96203f5ae96..dde4f9ee022 100644 --- a/src/Compiler/xlf/FSStrings.tr.xlf +++ b/src/Compiler/xlf/FSStrings.tr.xlf @@ -22,6 +22,16 @@ Küçük harf ayrımlı birleşim durumlarına yalnızca RequireQualifiedAccess özniteliği kullanılırken izin verilir + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' '..^' sembolü diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf index 6b0e8f8a303..89e54bb26c5 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf @@ -22,6 +22,16 @@ 仅当使用 RequireQualifiedAccess 属性时才允许区分小写的联合事例 + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' 符号 "..^" diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf index 721818d7dd5..71c045b02fa 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf @@ -22,6 +22,16 @@ 只有在使用 RequireQualifiedAccess 屬性時,才允許小寫區分聯結案例 + + Non-static member is expected. + Non-static member is expected. + + + + Static member is expected. + Static member is expected. + + symbol '..^' 符號 '..^' From d219fc30d2c1eb7115baa3cd326631b24ce1343e Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Wed, 1 Nov 2023 18:14:46 +0100 Subject: [PATCH 14/20] Fix test (new error message) --- .../LegacyLanguageService/Tests.LanguageService.ErrorList.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ErrorList.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ErrorList.fs index b62f508c919..3c3c452b0c3 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ErrorList.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ErrorList.fs @@ -377,7 +377,7 @@ type staticInInterface = CheckErrorList fileContent (function | err1 :: _ -> - Assert.IsTrue(err1.Message.Contains("No abstract or interface member was found that corresponds to this override")) + Assert.IsTrue(err1.Message.Contains("No static abstract member was found that corresponds to this override")) | x -> Assert.Fail(sprintf "Unexpected errors: %A" x)) From 81726185ce718ec4870c7e6bc781b47cc5009cc9 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 2 Nov 2023 09:53:13 +0000 Subject: [PATCH 15/20] Fix test --- tests/fsharp/typecheck/sigs/neg02.vsbsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fsharp/typecheck/sigs/neg02.vsbsl b/tests/fsharp/typecheck/sigs/neg02.vsbsl index 46e4ce5cb46..b979ec4b36b 100644 --- a/tests/fsharp/typecheck/sigs/neg02.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg02.vsbsl @@ -7,4 +7,4 @@ neg02.fs(17,21,17,26): typecheck error FS3351: Feature 'static abstract interfac neg02.fs(17,21,17,26): typecheck error FS3350: Feature 'static abstract interface members' is not available in F# 6.0. Please use language version 7.0 or greater. -neg02.fs(17,21,17,24): typecheck error FS0855: No abstract or interface member was found that corresponds to this override +neg02.fs(17,21,17,24): typecheck error FS3855: No static abstract member was found that corresponds to this override From d2e7548588b1fdb74beebd3dd910398432b6c833 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 2 Nov 2023 11:20:18 +0000 Subject: [PATCH 16/20] More testing --- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 74 ++++++++++++++++--- 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 0f3652fae92..9e4ea53f005 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -947,9 +947,8 @@ module StaticAbstractBug = |> withLangVersion80 |> compile |> shouldFail - |> withDiagnostics [ - (Error 855, Line 12, Col 22, Line 12, Col 29, "No abstract or interface member was found that corresponds to this override") - ] + |> withSingleDiagnostic (Error 855, Line 12, Col 22, Line 12, Col 29, "No abstract or interface member was found that corresponds to this override") + [] let ``Produce an error when one leaves out keyword "static" in an implementation of IWSAM with multiple overloads`` () = @@ -972,12 +971,11 @@ module StaticAbstractBug = |> withLangVersion80 |> compile |> shouldFail - |> withDiagnostics [ + |> withSingleDiagnostic (Error 1, Line 11, Col 34, Line 11, Col 36, "This expression was expected to have type 'bool' but here has type 'unit' ") - ] [] let ``Produce an error for interface with static abstract member that is implemented as instance member`` () = @@ -1004,9 +1002,7 @@ module StaticAbstractBug = |> withLangVersion80 |> compile |> shouldFail - |> withDiagnostics [ - (Error 855, Line 14, Col 18, Line 14, Col 23, "No abstract or interface member was found that corresponds to this override") - ] + |> withSingleDiagnostic (Error 855, Line 14, Col 18, Line 14, Col 23, "No abstract or interface member was found that corresponds to this override") [] let ``Produce an error for interface with static abstract member that is implemented as instance member with multiple overloads`` () = @@ -1032,9 +1028,7 @@ module StaticAbstractBug = |> withLangVersion80 |> compile |> shouldFail - |> withDiagnostics [ - (Error 1, Line 14, Col 41, Line 14, Col 42, "The type 'bool' does not match the type 'int'") - ] + |> withSingleDiagnostic (Error 1, Line 14, Col 41, Line 14, Col 42, "The type 'bool' does not match the type 'int'") [] let ``Produce an error when one leaves out keyword "static" in multiple IWSAM implementations`` () = @@ -1087,4 +1081,62 @@ module StaticAbstractBug = (Error 673, Line 9, Col 20, Line 9, Col 27, "This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args) = ...'.") (Error 17, Line 9, Col 20, Line 9, Col 27, "The member 'Execute: unit -> unit' does not have the correct type to override the corresponding abstract method. Non-static member is expected.") (Error 783, Line 8, Col 15, Line 8, Col 25, "At least one override did not correctly implement its corresponding abstract member") + ] + + [] + let ``Produces errors when includes keyword "static" when implementing a non generic interface in a type`` () = + Fsx """ +module StaticAbstractBug = + type IFoo<'T> = + abstract DoIt: unit -> string + abstract Other : int -> int + abstract member Property: int + abstract member Property2: int + abstract Property3 : int with get, set + type MyFoo = { + Value : int + } with + interface IFoo with + static member DoIt() = "" + static member Other(value) = value + 1 + static member Property = 0 + static member Property2 = 0 + static member Property3 = 0 + static member Property3 with set value = () + """ + |> withLangVersion80 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3855, Line 13, Col 23, Line 13, Col 27, "No static abstract member was found that corresponds to this override"); + (Error 3855, Line 14, Col 23, Line 14, Col 28, "No static abstract member was found that corresponds to this override") + ] + + [] + let ``Produces errors when includes keyword "static" when implementing an interface in a type`` () = + Fsx """ +module StaticAbstractBug = + type IOperation = + abstract member Execute: unit -> unit + abstract member Execute: unit -> bool + abstract member Property: int + abstract member Property: int + + type FaultyOperation() = + interface IOperation with + static member Execute() = () + static member Execute() = false + static member Property = 0 + static member Property = false + """ + |> withLangVersion80 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3855, Line 11, Col 27, Line 11, Col 34, "No static abstract member was found that corresponds to this override") + (Error 3855, Line 12, Col 27, Line 12, Col 34, "No static abstract member was found that corresponds to this override") + (Error 1, Line 14, Col 38, Line 14, Col 43, "This expression was expected to have type + 'int' +but here has type + 'bool' ") ] \ No newline at end of file From feed043b2503370fefdba657e1539d1fc4a19bc2 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 2 Nov 2023 12:10:11 +0000 Subject: [PATCH 17/20] update tests --- .../Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 9e4ea53f005..7197edd7568 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1104,6 +1104,7 @@ module StaticAbstractBug = static member Property3 = 0 static member Property3 with set value = () """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] |> withLangVersion80 |> typecheck |> shouldFail @@ -1129,6 +1130,7 @@ module StaticAbstractBug = static member Property = 0 static member Property = false """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] |> withLangVersion80 |> typecheck |> shouldFail From 80c5c1f1ec61d596311b792e6c369eed3ada574e Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 2 Nov 2023 16:04:25 +0000 Subject: [PATCH 18/20] [] --- .../TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 7197edd7568..f402b05dfe2 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -923,7 +923,7 @@ let main _ = |> compile |> shouldSucceed - [] + [] let ``Produce an error when one leaves out keyword "static" in an implementation of IWSAM`` () = Fsx """ module StaticAbstractBug = @@ -1083,7 +1083,7 @@ module StaticAbstractBug = (Error 783, Line 8, Col 15, Line 8, Col 25, "At least one override did not correctly implement its corresponding abstract member") ] - [] + [] let ``Produces errors when includes keyword "static" when implementing a non generic interface in a type`` () = Fsx """ module StaticAbstractBug = @@ -1113,7 +1113,7 @@ module StaticAbstractBug = (Error 3855, Line 14, Col 23, Line 14, Col 28, "No static abstract member was found that corresponds to this override") ] - [] + [] let ``Produces errors when includes keyword "static" when implementing an interface in a type`` () = Fsx """ module StaticAbstractBug = From 0ab3139b74ab1f4177cca8e24bb7205dd55224b9 Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Thu, 9 Nov 2023 14:58:32 +0100 Subject: [PATCH 19/20] Check properties --- src/Compiler/Checking/CheckExpressions.fs | 8 ++++++-- src/Compiler/Checking/MethodOverrides.fs | 4 ++-- src/Compiler/Checking/MethodOverrides.fsi | 3 ++- src/Compiler/FSComp.txt | 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 +++++ 17 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index ba07adf9ddf..302a338ccdf 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -11304,7 +11304,7 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (_: Val option) (a | SynMemberKind.PropertyGet | SynMemberKind.PropertySet as k -> - let dispatchSlots = GetAbstractPropInfosForSynPropertyDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers) + let dispatchSlots = GetAbstractPropInfosForSynPropertyDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers, memberFlags) // Only consider those abstract slots where the get/set flags match the value we're defining let dispatchSlots = @@ -11317,7 +11317,11 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (_: Val option) (a let uniqueAbstractPropSigs = match dispatchSlots with | [] when not (CompileAsEvent g attribs) -> - errorR(Error(FSComp.SR.tcNoPropertyFoundForOverride(), memberId.idRange)) + let instanceExpected = memberFlags.IsInstance + if instanceExpected then + errorR(Error(FSComp.SR.tcNoPropertyFoundForOverride(), memberId.idRange)) + else + errorR (Error(FSComp.SR.tcNoStaticPropertyFoundForOverride (), memberId.idRange)) [] | [uniqueAbstractProp] -> [uniqueAbstractProp] | _ -> diff --git a/src/Compiler/Checking/MethodOverrides.fs b/src/Compiler/Checking/MethodOverrides.fs index 85f8901eb12..080e790374e 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -962,7 +962,7 @@ let GetAbstractMethInfosForSynMethodDecl(infoReader: InfoReader, ad, memberName: /// Get the properties 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 GetAbstractPropInfosForSynPropertyDecl(infoReader: InfoReader, ad, memberName: Ident, bindm, typToSearchForAbstractMembers) = +let GetAbstractPropInfosForSynPropertyDecl(infoReader: InfoReader, ad, memberName: Ident, bindm, typToSearchForAbstractMembers, memberFlags: SynMemberFlags) = let pinfos = match typToSearchForAbstractMembers with | _, Some(SlotImplSet(_, _, _, reqdProps)) -> @@ -970,5 +970,5 @@ let GetAbstractPropInfosForSynPropertyDecl(infoReader: InfoReader, ad, memberNam | ty, None -> GetIntrinsicPropInfosOfType infoReader (Some memberName.idText) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides bindm ty - let dispatchSlots = pinfos |> List.filter (fun pinfo -> pinfo.IsVirtualProperty) + let dispatchSlots = pinfos |> List.filter (fun pinfo -> pinfo.IsVirtualProperty && (not pinfo.IsStatic) = memberFlags.IsInstance) dispatchSlots diff --git a/src/Compiler/Checking/MethodOverrides.fsi b/src/Compiler/Checking/MethodOverrides.fsi index 1e56272bc25..6468c03e8b1 100644 --- a/src/Compiler/Checking/MethodOverrides.fsi +++ b/src/Compiler/Checking/MethodOverrides.fsi @@ -170,5 +170,6 @@ val GetAbstractPropInfosForSynPropertyDecl: ad: AccessorDomain * memberName: Ident * bindm: range * - typToSearchForAbstractMembers: (TType * SlotImplSet option) -> + typToSearchForAbstractMembers: (TType * SlotImplSet option) * + memberFlags: SynMemberFlags -> PropInfo list diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 13e281a8f0b..8c732b6edbb 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1730,3 +1730,4 @@ featureUnmanagedConstraintCsharpInterop,"Interop between C#'s and F#'s unmanaged 3583,unnecessaryParentheses,"Parentheses can be removed." 3584,tcDotLambdaAtNotSupportedExpression,"Shorthand lambda syntax is only supported for atomic expressions, such as method, property, field or indexer on the implied '_' argument. For example: 'let f = _.Length'." 3855,tcNoStaticMemberFoundForOverride,"No static abstract member was found that corresponds to this override" +3859,tcNoStaticPropertyFoundForOverride,"No static abstract property was found that corresponds to this override" diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 60d902e01df..e3ab47ab86e 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Tento výraz podporuje indexování, třeba expr.[index]. Syntaxe expr[index] vyžaduje /langversion:preview. Více informací: https://aka.ms/fsharp-index-notation diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index ae5473df071..74eb118d29c 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Dieser Ausdruck unterstützt die Indizierung, z. B. "expr.[index]". Die Syntax "expr[index]" erfordert /langversion:preview. Siehe https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 7158758445b..e9cac9515a3 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Esta expresión admite indexación, por ejemplo "expr.[index]". La sintaxis "expr[index]" requiere /langversion:preview. Ver https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 566f44e62e2..d4f47923abb 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Cette expression prend en charge l’indexation, par exemple « expr.[index] ». La syntaxe « expr[index] » requiert /langversion:preview. Voir https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 6e7306ba2f6..7c45b565dc4 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Questa espressione supporta l'indicizzazione, ad esempio 'expr.[index]'. La sintassi 'expr[index]' richiede/langversion:preview. Vedere https://aka.ms/fsharp-index-notation.. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index cf7904d10eb..0e707fca19d 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. この式は、'expr. [index]' などのインデックスをサポートしています。構文 'expr[index]' には /langversion:preview が必要です。https://aka.ms/fsharp-index-notation を参照してください。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index f5e410ea130..2c8b3a8d206 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. 이 식은 인덱싱을 지원합니다. 'expr.[index]'. 'expr[index]' 구문에는 /langversion:preview가 필요합니다. https://aka.ms/fsharp-index-notation을 참조하세요. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 37edc96565a..30cea28b6bb 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. To wyrażenie obsługuje indeksowanie, np. „expr.[index]”. Składnia wyrażenia „expr[index]” wymaga parametru /langversion:preview. Zobacz: https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 8fda9dd740b..a4654f80c85 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Essa expressão oferece suporte à indexação, por exemplo, 'expr. [index]'. A sintaxe 'expr[index]' requer /langversion:preview. Consulte https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index a3c1c06a7b7..cf3004de36a 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Это выражение поддерживает индексирование, например, "expr. [index]". Для синтаксиса "expr[index]" требуется /langversion:preview. См. https://aka.ms/fsharp-index-notation. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index dfded995c0a..db76b1a5de8 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. Bu ifade dizin oluşturmayı destekler, örn. “expr.[index]”. Söz dizimi “expr.[index]” /langversion:preview gerektirir. https://aka.ms/fsharp-index-notation'a bakın. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index feb55324887..241ffe580d4 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. 此表达式支持索引,例如“expr.[index]”。语法“expr[index]”需要 /langversion:preview。请参阅 https://aka.ms/fsharp-index-notation。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 53d31914d3c..4d5140432b0 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1267,6 +1267,11 @@ No static abstract member was found that corresponds to this override + + No static abstract property was found that corresponds to this override + No static abstract property was found that corresponds to this override + + This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. 此運算式支援編製索引,例如 'expr.[index]'。語法 'expr[index]' 需要 /langversion:preview。請參閱 https://aka.ms/fsharp-index-notation。 From 2fd89bca9d32fb64996430d0adfc86b25580444b Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 9 Nov 2023 20:28:34 +0000 Subject: [PATCH 20/20] Update tests --- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 55 +++++++++++++------ 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index f402b05dfe2..3363bbfb961 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -947,8 +947,12 @@ module StaticAbstractBug = |> withLangVersion80 |> compile |> shouldFail - |> withSingleDiagnostic (Error 855, Line 12, Col 22, Line 12, Col 29, "No abstract or interface member was found that corresponds to this override") - + |> withDiagnostics [ + (Error 855, Line 12, Col 22, Line 12, Col 29, "No abstract or interface member was found that corresponds to this override") + (Error 859, Line 14, Col 25, Line 14, Col 33, "No abstract property was found that corresponds to this override") + (Error 859, Line 16, Col 25, Line 16, Col 34, "No abstract property was found that corresponds to this override") + (Error 859, Line 17, Col 25, Line 17, Col 34, "No abstract property was found that corresponds to this override") + ] [] let ``Produce an error when one leaves out keyword "static" in an implementation of IWSAM with multiple overloads`` () = @@ -971,11 +975,16 @@ module StaticAbstractBug = |> withLangVersion80 |> compile |> shouldFail - |> withSingleDiagnostic - (Error 1, Line 11, Col 34, Line 11, Col 36, "This expression was expected to have type + |> withDiagnostics [ + (Error 1, Line 11, Col 34, Line 11, Col 36, "This expression was expected to have type 'bool' but here has type 'unit' ") + (Error 1, Line 14, Col 36, Line 14, Col 41, "This expression was expected to have type + 'int' +but here has type + 'bool' ") + ] [] let ``Produce an error for interface with static abstract member that is implemented as instance member`` () = @@ -1002,8 +1011,13 @@ module StaticAbstractBug = |> withLangVersion80 |> compile |> shouldFail - |> withSingleDiagnostic (Error 855, Line 14, Col 18, Line 14, Col 23, "No abstract or interface member was found that corresponds to this override") - + |> withDiagnostics [ + (Error 855, Line 14, Col 18, Line 14, Col 23, "No abstract or interface member was found that corresponds to this override"); + (Error 859, Line 15, Col 21, Line 15, Col 29, "No abstract property was found that corresponds to this override"); + (Error 859, Line 17, Col 21, Line 17, Col 30, "No abstract property was found that corresponds to this override"); + (Error 859, Line 18, Col 21, Line 18, Col 30, "No abstract property was found that corresponds to this override") + ] + [] let ``Produce an error for interface with static abstract member that is implemented as instance member with multiple overloads`` () = Fsx """ @@ -1028,7 +1042,13 @@ module StaticAbstractBug = |> withLangVersion80 |> compile |> shouldFail - |> withSingleDiagnostic (Error 1, Line 14, Col 41, Line 14, Col 42, "The type 'bool' does not match the type 'int'") + |> withDiagnostics [ + (Error 1, Line 14, Col 41, Line 14, Col 42, "The type 'bool' does not match the type 'int'") + (Error 1, Line 16, Col 32, Line 16, Col 33, "This expression was expected to have type + 'bool' +but here has type + 'int' ") + ] [] let ``Produce an error when one leaves out keyword "static" in multiple IWSAM implementations`` () = @@ -1070,7 +1090,7 @@ module StaticAbstractBug = let objExpr = { new IOperation with - member Execute() = () + member _.Execute() = () member _.Execute2() = () } """ |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] @@ -1078,13 +1098,12 @@ module StaticAbstractBug = |> typecheck |> shouldFail |> withDiagnostics [ - (Error 673, Line 9, Col 20, Line 9, Col 27, "This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args) = ...'.") - (Error 17, Line 9, Col 20, Line 9, Col 27, "The member 'Execute: unit -> unit' does not have the correct type to override the corresponding abstract method. Non-static member is expected.") + (Error 17, Line 9, Col 22, Line 9, Col 29, "The member 'Execute: unit -> unit' does not have the correct type to override the corresponding abstract method. Non-static member is expected.") (Error 783, Line 8, Col 15, Line 8, Col 25, "At least one override did not correctly implement its corresponding abstract member") ] [] - let ``Produces errors when includes keyword "static" when implementing a non generic interface in a type`` () = + let ``Produces errors when includes keyword "static" when implementing a generic interface in a type`` () = Fsx """ module StaticAbstractBug = type IFoo<'T> = @@ -1109,8 +1128,12 @@ module StaticAbstractBug = |> typecheck |> shouldFail |> withDiagnostics [ - (Error 3855, Line 13, Col 23, Line 13, Col 27, "No static abstract member was found that corresponds to this override"); - (Error 3855, Line 14, Col 23, Line 14, Col 28, "No static abstract member was found that corresponds to this override") + (Error 3855, Line 13, Col 23, Line 13, Col 27, "No static abstract member was found that corresponds to this override") + (Error 3855, Line 14, Col 23, Line 14, Col 28, "No static abstract member was found that corresponds to this override") + (Error 3859, Line 15, Col 23, Line 15, Col 31, "No static abstract property was found that corresponds to this override") + (Error 3859, Line 16, Col 23, Line 16, Col 32, "No static abstract property was found that corresponds to this override") + (Error 3859, Line 17, Col 23, Line 17, Col 32, "No static abstract property was found that corresponds to this override") + (Error 3859, Line 18, Col 23, Line 18, Col 32, "No static abstract property was found that corresponds to this override") ] [] @@ -1137,8 +1160,6 @@ module StaticAbstractBug = |> withDiagnostics [ (Error 3855, Line 11, Col 27, Line 11, Col 34, "No static abstract member was found that corresponds to this override") (Error 3855, Line 12, Col 27, Line 12, Col 34, "No static abstract member was found that corresponds to this override") - (Error 1, Line 14, Col 38, Line 14, Col 43, "This expression was expected to have type - 'int' -but here has type - 'bool' ") + (Error 3859, Line 13, Col 27, Line 13, Col 35, "No static abstract property was found that corresponds to this override") + (Error 3859, Line 14, Col 27, Line 14, Col 35, "No static abstract property was found that corresponds to this override") ] \ No newline at end of file