From 7862b2b1628492d94cd77ff0f5e5bcdca9b8b7e4 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 10 Nov 2023 12:07:41 +0000 Subject: [PATCH 1/5] Fix internal error when implements IWSAM in object expression --- src/Compiler/Checking/CheckExpressions.fs | 2 +- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 302a338ccdf..f53d19f1d91 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -6804,7 +6804,7 @@ and TcObjectExprBinding (cenv: cenv) (env: TcEnv) implTy tpenv (absSlotInfo, bin let rec lookPat p = match p, memberFlagsOpt with | SynPat.FromParseError(pat, _), _ -> lookPat pat - | SynPat.Named (SynIdent(id,_), _, _, _), None -> + | SynPat.Named (SynIdent(id,_), _, _, _), _ -> let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar (ident (CompilerGeneratedName "this", id.idRange))) bindingRhs let logicalMethId = id let memberFlags = OverrideMemberFlags SynMemberKind.Member 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 3363bbfb961..60c17598e47 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1101,6 +1101,28 @@ module StaticAbstractBug = (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 ``Produce an error when one leaves keyword "static" when implementing IWSAM in an object expression`` () = + Fsx """ +type IOperation = + static abstract member Execute: unit -> unit + abstract member Execute2: unit -> unit + +let _ = + { new IOperation with + static member Execute() = () + member _.Execute2() = () + } + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> withLangVersion80 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 17, Line 8, Col 23, Line 8, Col 30, "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 7, Col 11, Line 7, Col 21, "At least one override did not correctly implement its corresponding abstract member") + ] [] let ``Produces errors when includes keyword "static" when implementing a generic interface in a type`` () = From b5c215866a7e5dc6696ccace7ac14c3bd1b8eda8 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 10 Nov 2023 23:47:16 +0000 Subject: [PATCH 2/5] Add new error and add more tests --- src/Compiler/Checking/CheckExpressions.fs | 16 ++++-- src/Compiler/Checking/MethodOverrides.fs | 45 +++++++++------- src/Compiler/Checking/MethodOverrides.fsi | 1 + src/Compiler/Driver/CompilerDiagnostics.fs | 2 +- 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 ++ .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 51 ++++++++++++++++++- 19 files changed, 155 insertions(+), 26 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index f53d19f1d91..9781ad97a3a 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -6804,11 +6804,17 @@ and TcObjectExprBinding (cenv: cenv) (env: TcEnv) implTy tpenv (absSlotInfo, bin let rec lookPat p = match p, memberFlagsOpt with | SynPat.FromParseError(pat, _), _ -> lookPat pat - | SynPat.Named (SynIdent(id,_), _, _, _), _ -> + | SynPat.Named (SynIdent(id,_), _, _, _), None -> let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar (ident (CompilerGeneratedName "this", id.idRange))) bindingRhs let logicalMethId = id let memberFlags = OverrideMemberFlags SynMemberKind.Member bindingRhs, logicalMethId, memberFlags + + | SynPat.Named (SynIdent(id,_), _, _, _), Some memberFlags -> + CheckMemberFlags None NewSlotsOK OverridesOK memberFlags mBinding + let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar (ident (CompilerGeneratedName "this", id.idRange))) bindingRhs + let logicalMethId = id + bindingRhs, logicalMethId, memberFlags | SynPat.InstanceMember(thisId, memberId, _, _, _), Some memberFlags -> CheckMemberFlags None NewSlotsOK OverridesOK memberFlags mBinding @@ -7014,7 +7020,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, true, implTy, dispatchSlots, availPriorOverrides, overrideSpecs) |> ignore) // 3. create the specs of overrides let allTypeImpls = @@ -7022,9 +7028,9 @@ 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, _, isInstance)) = overrideInfo - if not isFakeEventProperty then + if not isFakeEventProperty && isInstance then let searchForOverride = dispatchSlotsKeyed |> NameMultiMap.find id.idText @@ -11245,7 +11251,7 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (_: Val option) (a if instanceExpected then errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) else - errorR (Error(FSComp.SR.tcNoStaticMemberFoundForOverride (), memberId.idRange)) + 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 080e790374e..c7f62e040e2 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -324,6 +324,7 @@ module DispatchSlotChecking = let CheckDispatchSlotsAreImplemented (denv, infoReader: InfoReader, m, nenv, sink: TcResultsSink, isOverallTyAbstract, + isObjExpr: bool, reqdTy, dispatchSlots: RequiredSlot list, availPriorOverrides: OverrideInfo list, @@ -331,7 +332,7 @@ module DispatchSlotChecking = let g = infoReader.g let amap = infoReader.amap - let isReqdTyInterface = isInterfaceTy g reqdTy + let isReqdTyInterface = isInterfaceTy g reqdTy let showMissingMethodsAndRaiseErrors = (isReqdTyInterface || not isOverallTyAbstract) let mutable res = true @@ -392,7 +393,7 @@ module DispatchSlotChecking = noimpl() | [ overrideBy ] -> - let (Override(_, _, _, methTypars, _, argTys, _, _, _, _)) = overrideBy + let (Override(_, _, _, methTypars, _, argTys, _, _, _, isInstance)) = overrideBy let moreThanOnePossibleDispatchSlot = dispatchSlots @@ -402,17 +403,18 @@ module DispatchSlotChecking = let (CompiledSig (vargTys, _, fvmethTypars, _)) = compiledSig - if moreThanOnePossibleDispatchSlot then - noimpl() - - elif argTys.Length <> vargTys.Length then - fail(Error(FSComp.SR.typrelMemberDoesNotHaveCorrectNumberOfArguments(FormatOverride denv overrideBy, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) - elif methTypars.Length <> fvmethTypars.Length then - fail(Error(FSComp.SR.typrelMemberDoesNotHaveCorrectNumberOfTypeParameters(FormatOverride denv overrideBy, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) - elif not (IsTyparKindMatch compiledSig overrideBy) then - fail(Error(FSComp.SR.typrelMemberDoesNotHaveCorrectKindsOfGenericParameters(FormatOverride denv overrideBy, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) - else - fail(Error(FSComp.SR.typrelMemberCannotImplement(FormatOverride denv overrideBy, NicePrint.stringOfMethInfo infoReader m denv dispatchSlot, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) + if (not isObjExpr && not isInstance) then + if moreThanOnePossibleDispatchSlot then + noimpl() + + elif (argTys.Length <> vargTys.Length) then + fail(Error(FSComp.SR.typrelMemberDoesNotHaveCorrectNumberOfArguments(FormatOverride denv overrideBy, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) + elif methTypars.Length <> fvmethTypars.Length then + fail(Error(FSComp.SR.typrelMemberDoesNotHaveCorrectNumberOfTypeParameters(FormatOverride denv overrideBy, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) + elif not (IsTyparKindMatch compiledSig overrideBy) then + fail(Error(FSComp.SR.typrelMemberDoesNotHaveCorrectKindsOfGenericParameters(FormatOverride denv overrideBy, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) + else + fail(Error(FSComp.SR.typrelMemberCannotImplement(FormatOverride denv overrideBy, NicePrint.stringOfMethInfo infoReader m denv dispatchSlot, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) | overrideBy :: _ -> errorR(Error(FSComp.SR.typrelOverloadNotFound(FormatMethInfoSig g amap m denv dispatchSlot, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) @@ -599,11 +601,18 @@ module DispatchSlotChecking = match relevantVirts |> List.filter (fun dispatchSlot -> IsPartialMatch g dispatchSlot (CompiledSigOfMeth g amap m dispatchSlot) overrideBy) with | [dispatchSlot] -> errorR(OverrideDoesntOverride(denv, overrideBy, Some dispatchSlot, g, amap, m)) - | _ -> + | _ -> match relevantVirts |> List.filter (fun dispatchSlot -> IsNameMatch dispatchSlot overrideBy) with - | [] -> errorR(OverrideDoesntOverride(denv, overrideBy, None, g, amap, m)) - | [dispatchSlot] -> - errorR(OverrideDoesntOverride(denv, overrideBy, Some dispatchSlot, g, amap, m)) + | [] -> + if isObjExpr && not overrideBy.IsInstance then + errorR(Error(FSComp.SR.chkStaticMembersOnObjectExpressions(), overrideBy.Range)) + else + errorR(OverrideDoesntOverride(denv, overrideBy, None, g, amap, m)) + | [dispatchSlot] -> + if isObjExpr && not overrideBy.IsInstance then + errorR(Error(FSComp.SR.chkStaticMembersOnObjectExpressions(), overrideBy.Range)) + else + errorR(OverrideDoesntOverride(denv, overrideBy, Some dispatchSlot, g, amap, m)) | possibleDispatchSlots -> let details = possibleDispatchSlots @@ -820,7 +829,7 @@ module DispatchSlotChecking = 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 allCorrect = CheckDispatchSlotsAreImplemented (denv, infoReader, m, nenv, sink, tcaug.tcaug_abstract, false, 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 6468c03e8b1..b06fb16e499 100644 --- a/src/Compiler/Checking/MethodOverrides.fsi +++ b/src/Compiler/Checking/MethodOverrides.fsi @@ -113,6 +113,7 @@ module DispatchSlotChecking = nenv: NameResolutionEnv * sink: TcResultsSink * isOverallTyAbstract: bool * + isObjExpr: bool * reqdTy: TType * dispatchSlots: RequiredSlot list * availPriorOverrides: OverrideInfo list * diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 34fd76eb1ba..ca66fa31d0b 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -1551,7 +1551,7 @@ type Exception with // 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. + // Required slot is instance, meaning implementation is static, tell user that we expect instance. if minfoVirt.IsInstance then os.AppendString(OverrideShouldBeStatic().Format) else diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 8c732b6edbb..c334ea814c1 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1731,3 +1731,4 @@ featureUnmanagedConstraintCsharpInterop,"Interop between C#'s and F#'s unmanaged 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" +3860,chkStaticMembersOnObjectExpressions,"Static members are not allowed in object expressions." \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index e3ab47ab86e..c1b382568d3 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -122,6 +122,11 @@ Člen nebo funkce „{0}“ má atribut „TailCallAttribute“, ale nepoužívá se koncovým (tail) rekurzivním způsobem. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. Atribut AssemblyKeyNameAttribute je zastaralý. Použijte místo něj AssemblyKeyFileAttribute. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 74eb118d29c..7a612d411b9 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -122,6 +122,11 @@ Der Member oder die Funktion "{0}" weist das Attribut "TailCallAttribute" auf, wird jedoch nicht endrekursiv verwendet. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. "AssemblyKeyNameAttribute" gilt als veraltet. Verwenden Sie stattdessen "AssemblyKeyFileAttribute". diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index e9cac9515a3..a6748ddb014 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -122,6 +122,11 @@ El miembro o la función “{0}” tiene el atributo “TailCallAttribute”, pero no se usa de forma de recursión de cola. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. El elemento "AssemblyKeyNameAttribute" está en desuso. Use "AssemblyKeyFileAttribute" en su lugar. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index d4f47923abb..9fde6696b9b 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -122,6 +122,11 @@ Le membre ou la fonction « {0} » possède l'attribut « TailCallAttribute », mais n'est pas utilisé de manière récursive. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. 'AssemblyKeyNameAttribute' a été déprécié. Utilisez 'AssemblyKeyFileAttribute' à la place. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 7c45b565dc4..400fae5c8af 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -122,6 +122,11 @@ Il membro o la funzione "{0}" ha l'attributo "TailCallAttribute", ma non è in uso in modo ricorsivo finale. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. L'attributo 'AssemblyKeyNameAttribute' è deprecato. In alternativa, usare 'AssemblyKeyFileAttribute'. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 0e707fca19d..7be02f43a00 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -122,6 +122,11 @@ メンバーまたは関数 '{0}' には 'TailCallAttribute' 属性がありますが、末尾の再帰的な方法では使用されていません。 + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. 'AssemblyKeyNameAttribute' は非推奨になりました。代わりに 'AssemblyKeyFileAttribute' を使用してください。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 2c8b3a8d206..1f1edeebe4a 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -122,6 +122,11 @@ 멤버 또는 함수 '{0}'에 'TailCallAttribute' 특성이 있지만 비상 재귀적인 방식으로 사용되고 있지 않습니다. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. 'AssemblyKeyNameAttribute'는 사용되지 않습니다. 대신 'AssemblyKeyFileAttribute'를 사용하세요. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 30cea28b6bb..f43ad6e3967 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -122,6 +122,11 @@ Składowa lub funkcja „{0}” ma atrybut „TailCallAttribute”, ale nie jest używana w sposób cykliczny końca. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. Element „AssemblyKeyNameAttribute” jest przestarzały. Zamiast niego użyj elementu „AssemblyKeyFileAttribute”. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index a4654f80c85..9bcf102c412 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -122,6 +122,11 @@ O membro ou a função "{0}" tem o atributo "TailCallAttribute", mas não está sendo usado de maneira recursiva em cauda. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. O 'AssemblyKeyNameAttribute' foi preterido. Use o 'AssemblyKeyFileAttribute'. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index cf3004de36a..8ff9eedfae5 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -122,6 +122,11 @@ Элемент или функция "{0}" содержит атрибут "TailCallAttribute", но не используется в рекурсивном хвостовом режиме. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. Атрибут "AssemblyKeyNameAttribute" является устаревшим. Используйте вместо него атрибут "AssemblyKeyFileAttribute". diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index db76b1a5de8..3d07bc6424d 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -122,6 +122,11 @@ Üye veya '{0}' işlevi, 'TailCallAttribute' özniteliğine sahip ancak kuyruk özyinelemeli bir şekilde kullanılmıyor. + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. 'AssemblyKeyNameAttribute' kullanım dışı bırakıldı. Bunun yerine 'AssemblyKeyFileAttribute' kullanın. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 241ffe580d4..e708d5fc46b 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -122,6 +122,11 @@ 成员或函数“{0}”具有 "TailCallAttribute" 属性,但未以尾递归方式使用。 + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. "AssemblyKeyNameAttribute" 已被弃用。请改为使用 "AssemblyKeyFileAttribute"。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 4d5140432b0..dc2ed0a09a9 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -122,6 +122,11 @@ 成員或函式 '{0}' 具有 'TailCallAttribute' 屬性,但未以尾遞迴方式使用。 + + Static members are not allowed in object expressions. + Static members are not allowed in object expressions. + + The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. 'AssemblyKeyNameAttribute' 已淘汰。請改用 'AssemblyKeyFileAttribute'。 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 60c17598e47..b503cd6018a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1120,8 +1120,55 @@ let _ = |> typecheck |> shouldFail |> withDiagnostics [ - (Error 17, Line 8, Col 23, Line 8, Col 30, "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 7, Col 11, Line 7, Col 21, "At least one override did not correctly implement its corresponding abstract member") + (Error 3860, Line 8, Col 23, Line 8, Col 30, "Static members are not allowed in object expressions.") + ] + + [] + let ``Produce an error when one leaves keyword "static" when implementing multiple IWSAM in an object expression`` () = + Fsx """ +type IOperation = + static abstract member Execute: unit -> unit + static abstract member Execute2: unit -> unit + +let _ = + { new IOperation with + static member Execute() = () + static member Execute2() = () + } + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> withLangVersion80 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3860, Line 8, Col 23, Line 8, Col 30, "Static members are not allowed in object expressions."); + (Error 3860, Line 9, Col 23, Line 9, Col 31, "Static members are not allowed in object expressions.") + ] + + [] + let ``Produce an error when one leaves keyword "static" when implementing static and not static members in an object expression`` () = + Fsx """ +type IOperation = + static abstract member Execute: unit -> unit + abstract member Execute1: unit -> unit + static abstract member Execute2: unit -> unit + abstract member Execute3: bool + +let _ = + { new IOperation with + static member Execute() = () + member this.Execute1() = () + static member Execute2() = () + member this.Execute3 = true + } + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> withLangVersion80 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3860, Line 10, Col 23, Line 10, Col 30, "Static members are not allowed in object expressions."); + (Error 3860, Line 12, Col 23, Line 12, Col 31, "Static members are not allowed in object expressions."); ] [] From 23290672cfd66eef5675284ab9eb0027a6bb351f Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sat, 11 Nov 2023 16:10:28 +0000 Subject: [PATCH 3/5] Fix test --- src/Compiler/Checking/MethodOverrides.fs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/MethodOverrides.fs b/src/Compiler/Checking/MethodOverrides.fs index c7f62e040e2..f467dc8db25 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -402,8 +402,10 @@ module DispatchSlotChecking = |> not let (CompiledSig (vargTys, _, fvmethTypars, _)) = compiledSig - - if (not isObjExpr && not isInstance) then + + // Object expressions can only implement instance members + let isObjExprWithInstanceMembers = (isObjExpr && isInstance) + if isObjExprWithInstanceMembers || isInstance then if moreThanOnePossibleDispatchSlot then noimpl() From 6499462e7cbf892a3530d09a43d790edff932cb6 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sat, 11 Nov 2023 20:58:35 +0000 Subject: [PATCH 4/5] One more test --- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 23 +++++++++++++++++++ 1 file changed, 23 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 b503cd6018a..3f952c1655d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1171,6 +1171,29 @@ let _ = (Error 3860, Line 12, Col 23, Line 12, Col 31, "Static members are not allowed in object expressions."); ] + [] + let ``Produces an error when implementing only instance members from from a IWSAM in an object expression`` () = + Fsx """ +type ILogger = + abstract member Log: string -> unit + static abstract member Execute: string -> unit + +let consoleLogger = + { new ILogger with + member this.Log(message: string) = + printfn "%s" message + } + +consoleLogger.Log("Hello World") + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> withLangVersion80 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 366, Line 7, Col 5, Line 10, Col 6, "No implementation was given for 'static abstract ILogger.Execute: string -> unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + ] + [] let ``Produces errors when includes keyword "static" when implementing a generic interface in a type`` () = Fsx """ From 8c4d29580554efc3e4ceba0c5b375e8d36032758 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sun, 12 Nov 2023 07:28:02 +0000 Subject: [PATCH 5/5] more tests --- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 46 ++++++++++++++++++- 1 file changed, 45 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 3f952c1655d..0685988d23c 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1172,7 +1172,7 @@ let _ = ] [] - let ``Produces an error when implementing only instance members from from a IWSAM in an object expression`` () = + let ``Produces an error when implementing only instance members from IWSAM in an object expression`` () = Fsx """ type ILogger = abstract member Log: string -> unit @@ -1193,6 +1193,50 @@ consoleLogger.Log("Hello World") |> withDiagnostics [ (Error 366, Line 7, Col 5, Line 10, Col 6, "No implementation was given for 'static abstract ILogger.Execute: string -> unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") ] + + [] + let ``Produces an error when implementing only instance members from IWSAM(Interface attribute) in an object expression`` () = + Fsx """ +[] +type ILogger = + abstract member Log: string -> unit + static abstract member Execute: string -> unit + +let consoleLogger = + { new ILogger with + member this.Log(message: string) = + printfn "%s" message + } + +consoleLogger.Log("Hello World") + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> withLangVersion80 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 366, Line 8, Col 5, Line 11, Col 6, "No implementation was given for 'static abstract ILogger.Execute: string -> unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + ] + + [] + let ``No error when implementing only instance members from a type(Interface attribute) in an object expression`` () = + Fsx """ +[] +type ILogger = + abstract member Log: string -> unit + static member Execute x = x + +let consoleLogger = + { new ILogger with + member this.Log(message: string) = + printf "%A" message + } + +consoleLogger.Log("Hello World") + """ + |> withLangVersion80 + |> compile + |> shouldSucceed [] let ``Produces errors when includes keyword "static" when implementing a generic interface in a type`` () =