From c83adaeb86b800f9b9cad672ece0308aaf4b9eac Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 17 May 2024 13:28:19 +0100 Subject: [PATCH 1/3] Error for partial implementation of interface with static and non static abstract members (#17160) --- .../.FSharp.Compiler.Service/8.0.400.md | 1 + src/Compiler/Checking/CheckExpressions.fs | 4 +- src/Compiler/Checking/MethodOverrides.fs | 12 +- src/Compiler/Checking/MethodOverrides.fsi | 1 - .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 130 ++++++++++++++++++ 5 files changed, 138 insertions(+), 10 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md index 4b1ccda719e..7765f188e0e 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md @@ -1,5 +1,6 @@ ### Fixed +* Error for partial implementation of interface with static and non-static abstract members. ([Issue #17138](https://github.com/dotnet/fsharp/issues/17138), [PR #17160](https://github.com/dotnet/fsharp/pull/17160)) * Optimize simple mappings with preludes in computed collections. ([PR #17067](https://github.com/dotnet/fsharp/pull/17067)) * Improve error reporting for abstract members when used in classes. ([PR #17063](https://github.com/dotnet/fsharp/pull/17063)) * Improve error reporting when property has same name as DU case. ([Issue #16646](https://github.com/dotnet/fsharp/issues/16646), [PR #17088](https://github.com/dotnet/fsharp/pull/17088)) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 871f36dd454..4aa56135baf 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -7189,7 +7189,9 @@ 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, true, implTy, dispatchSlots, availPriorOverrides, overrideSpecs) |> ignore) + if not hasStaticMembers then + 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 = diff --git a/src/Compiler/Checking/MethodOverrides.fs b/src/Compiler/Checking/MethodOverrides.fs index a426e0b166c..7e36d12ed9c 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -324,7 +324,6 @@ module DispatchSlotChecking = let CheckDispatchSlotsAreImplemented (denv, infoReader: InfoReader, m, nenv, sink: TcResultsSink, isOverallTyAbstract, - isObjExpr: bool, reqdTy, dispatchSlots: RequiredSlot list, availPriorOverrides: OverrideInfo list, @@ -380,8 +379,7 @@ module DispatchSlotChecking = let compiledSig = CompiledSigOfMeth g amap m dispatchSlot let noimpl() = - if dispatchSlot.IsInstance then - missingOverloadImplementation.Add((isReqdTyInterface, lazy NicePrint.stringOfMethInfo infoReader m denv dispatchSlot)) + missingOverloadImplementation.Add((isReqdTyInterface, lazy NicePrint.stringOfMethInfo infoReader m denv dispatchSlot)) match overrides |> List.filter (IsPartialMatch g dispatchSlot compiledSig) with | [] -> @@ -404,10 +402,8 @@ module DispatchSlotChecking = let (CompiledSig (vargTys, _, fvmethTypars, _)) = compiledSig - // Object expressions can only implement instance members - let isObjExprWithInstanceMembers = (isObjExpr && isInstance) - if isObjExprWithInstanceMembers || isInstance then - if moreThanOnePossibleDispatchSlot then + if isInstance then + if moreThanOnePossibleDispatchSlot then noimpl() elif (argTys.Length <> vargTys.Length) then @@ -828,7 +824,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, false, reqdTy, dispatchSlots, availPriorOverrides, overrides) + 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 && (isClassTy g reqdTy) then diff --git a/src/Compiler/Checking/MethodOverrides.fsi b/src/Compiler/Checking/MethodOverrides.fsi index b06fb16e499..6468c03e8b1 100644 --- a/src/Compiler/Checking/MethodOverrides.fsi +++ b/src/Compiler/Checking/MethodOverrides.fsi @@ -113,7 +113,6 @@ module DispatchSlotChecking = nenv: NameResolutionEnv * sink: TcResultsSink * isOverallTyAbstract: bool * - isObjExpr: bool * reqdTy: TType * dispatchSlots: RequiredSlot list * availPriorOverrides: OverrideInfo list * 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 3e971a054b0..aa959306198 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1269,3 +1269,133 @@ type A () = |> withDiagnostics [ (Error 3867, Line 3, Col 21, Line 3, Col 22, "Classes cannot contain static abstract members.") ] + + [] + let ``Error for partial implementation of interface with static abstract members`` () = + Fsx """ +type IFace = + static abstract P1 : int + static abstract P2 : int + +type T = + interface IFace with + static member P1 = 1 + + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 366, Line 7, Col 15, Line 7, Col 20, "No implementation was given for 'static abstract IFace.P2: int'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + ] + + [] + let ``Error for no implementation of interface with static abstract members`` () = + Fsx """ +type IFace = + static abstract P1 : int + static abstract P2 : int + +type T = + interface IFace with + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 366, Line 7, Col 15, Line 7, Col 20, "No implementation was given for those members: + 'static abstract IFace.P1: int' + 'static abstract IFace.P2: int' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + ] + + [] + let ``Error for partial implementation of interface with static and non static abstract members`` () = + Fsx """ +type IFace = + static abstract P1 : int + static abstract P2 : int + abstract member P3 : int + abstract member P4 : int + +type T = + interface IFace with + static member P1 = 1 + member this.P3 = 3 + + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 366, Line 9, Col 15, Line 9, Col 20, "No implementation was given for those members: + 'static abstract IFace.P2: int' + 'abstract IFace.P4: int' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + ] + + [] + let ``Error for no implementation of interface with static and non static abstract members`` () = + Fsx """ +type IFace = + static abstract P1 : int + static abstract P2 : int + abstract member P3 : int + abstract member P4 : int + +type T = + interface IFace with + + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 366, Line 9, Col 15, Line 9, Col 20, "No implementation was given for those members: + 'static abstract IFace.P1: int' + 'static abstract IFace.P2: int' + 'abstract IFace.P3: int' + 'abstract IFace.P4: int' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + ] + + [] + let ``Error for partial implementation of interface with non static abstract members`` () = + Fsx """ +type IFace = + abstract member P3 : int + abstract member P4 : int + +type T = + interface IFace with + member this.P3 = 3 + + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 366, Line 7, Col 15, Line 7, Col 20, "No implementation was given for 'abstract IFace.P4: int'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + ] + + [] + let ``Error for no implementation of interface with non static abstract members`` () = + Fsx """ +type IFace = + abstract member P3 : int + abstract member P4 : int + +type T = + interface IFace with + + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 366, Line 7, Col 15, Line 7, Col 20, "No implementation was given for those members: + 'abstract IFace.P3: int' + 'abstract IFace.P4: int' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + ] + From 997f9ee9fb7699c5fbed2656846b8b91663ea354 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 17 May 2024 14:44:04 -0700 Subject: [PATCH 2/3] Update dependencies from https://github.com/dotnet/arcade build 20240516.3 (#17169) Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.24264.1 -> To Version 8.0.0-beta.24266.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- global.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2b222d96471..2431687e789 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -30,9 +30,9 @@ - + https://github.com/dotnet/arcade - 1814df258a66473d388b8884ac95bd1c8a2585a9 + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac diff --git a/global.json b/global.json index bf0bb4364d7..20baab986d0 100644 --- a/global.json +++ b/global.json @@ -17,7 +17,7 @@ "perl": "5.38.2.2" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24264.1", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24266.3", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } From 817ee1e4730c97c7084ae90d36c97ac30915bbed Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 20 May 2024 08:15:11 +0000 Subject: [PATCH 3/3] trimmed size --- tests/AheadOfTime/Trimming/check.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/AheadOfTime/Trimming/check.ps1 b/tests/AheadOfTime/Trimming/check.ps1 index 4c0f2fbe6cb..ce8db8c7665 100644 --- a/tests/AheadOfTime/Trimming/check.ps1 +++ b/tests/AheadOfTime/Trimming/check.ps1 @@ -45,4 +45,4 @@ function CheckTrim($root, $tfm, $outputfile, $expected_len) { CheckTrim -root "SelfContained_Trimming_Test" -tfm "net8.0" -outputfile "FSharp.Core.dll" -expected_len 285184 # Check net8.0 trimmed assemblies -CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net8.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 8818176 +CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net8.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 8819200