diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 48fee010206..043502372c2 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10950,7 +10950,7 @@ and ComputeIsComplete enclosingDeclaredTypars declaredTypars ty = /// Determine if a uniquely-identified-abstract-slot exists for an override member (or interface member implementation) based on the information available /// at the syntactic definition of the member (i.e. prior to type inference). If so, we know the expected signature of the override, and the full slotsig /// it implements. Apply the inferred slotsig. -and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (argsAndRetTy, m, synTyparDecls, declaredTypars, memberId, tcrefObjTy, renaming, _objTy, intfSlotTyOpt, valSynData, memberFlags: SynMemberFlags, attribs) = +and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (baseValOpt: Val option) (argsAndRetTy, m, synTyparDecls, declaredTypars, memberId, tcrefObjTy, renaming, intfSlotTyOpt, valSynData, memberFlags: SynMemberFlags, attribs) = let g = cenv.g let ad = envinner.eAccessRights @@ -10997,7 +10997,21 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (argsAndRetTy, m, | _ -> [] // check that method to override is sealed is located at CheckOverridesAreAllUsedOnce (typrelns.fs) // We hit this case when it is ambiguous which abstract method is being implemented. - + if g.langVersion.SupportsFeature(LanguageFeature.ErrorForNonVirtualMembersOverrides) then + // Checks if the declaring type inherits from a base class and is not FSharpObjModelTy + // Raises an error if we try to override an non virtual member with the same name in both + match baseValOpt with + | Some ttype when not(isFSharpObjModelTy g ttype.Type) -> + match stripTyEqns g ttype.Type with + | TType_app(tyconRef, _, _) -> + let ilMethods = tyconRef.ILTyconRawMetadata.Methods.AsList() + let nameOpt = ilMethods |> List.tryFind(fun id -> id.Name = memberId.idText) + match nameOpt with + | Some name when not name.IsVirtual -> + errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) + | _ -> () + | _ -> () + | _ -> () // If we determined a unique member then utilize the type information from the slotsig let declaredTypars = @@ -11159,14 +11173,14 @@ and AnalyzeRecursiveStaticMemberOrValDecl CheckForNonAbstractInterface declKind tcref memberFlags id.idRange let isExtrinsic = (declKind = ExtrinsicExtensionBinding) - let tcrefObjTy, enclosingDeclaredTypars, renaming, objTy, _ = FreshenObjectArgType cenv mBinding TyparRigidity.WillBeRigid tcref isExtrinsic declaredTyconTypars + let tcrefObjTy, enclosingDeclaredTypars, renaming, _, _ = FreshenObjectArgType cenv mBinding TyparRigidity.WillBeRigid tcref isExtrinsic declaredTyconTypars let envinner = AddDeclaredTypars CheckForDuplicateTypars enclosingDeclaredTypars envinner let envinner = MakeInnerEnvForTyconRef envinner tcref isExtrinsic let (ExplicitTyparInfo(_, declaredTypars, infer)) = explicitTyparInfo let optInferredImplSlotTys, declaredTypars = - ApplyAbstractSlotInference cenv envinner (ty, mBinding, synTyparDecls, declaredTypars, id, tcrefObjTy, renaming, objTy, intfSlotTyOpt, valSynInfo, memberFlags, bindingAttribs) + ApplyAbstractSlotInference cenv envinner None (ty, mBinding, synTyparDecls, declaredTypars, id, tcrefObjTy, renaming, intfSlotTyOpt, valSynInfo, memberFlags, bindingAttribs) let explicitTyparInfo = ExplicitTyparInfo(declaredTypars, declaredTypars, infer) @@ -11231,7 +11245,6 @@ and AnalyzeRecursiveStaticMemberOrValDecl | _ -> envinner, tpenv, id, None, None, vis, vis2, None, [], None, explicitTyparInfo, bindingRhs, declaredTypars - and AnalyzeRecursiveInstanceMemberDecl (cenv: cenv, envinner: TcEnv, @@ -11290,7 +11303,7 @@ and AnalyzeRecursiveInstanceMemberDecl // at the member signature. If so, we know the type of this member, and the full slotsig // it implements. Apply the inferred slotsig. let optInferredImplSlotTys, declaredTypars = - ApplyAbstractSlotInference cenv envinner (argsAndRetTy, mBinding, synTyparDecls, declaredTypars, memberId, tcrefObjTy, renaming, objTy, intfSlotTyOpt, valSynInfo, memberFlags, bindingAttribs) + ApplyAbstractSlotInference cenv envinner baseValOpt (argsAndRetTy, mBinding, synTyparDecls, declaredTypars, memberId, tcrefObjTy, renaming, intfSlotTyOpt, valSynInfo, memberFlags, bindingAttribs) // Update the ExplicitTyparInfo to reflect the declaredTypars inferred from the abstract slot let explicitTyparInfo = ExplicitTyparInfo(declaredTypars, declaredTypars, infer) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 9c9da192081..53cfa341667 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1561,6 +1561,7 @@ featureInitProperties,"support for consuming init properties" featureLowercaseDUWhenRequireQualifiedAccess,"Allow lowercase DU when RequireQualifiedAccess attribute" featureMatchNotAllowedForUnionCaseWithNoData,"Pattern match discard is not allowed for union case that takes no data." featureCSharpExtensionAttributeNotRequired,"Allow implicit Extension attribute on declaring types, modules" +featureErrorForNonVirtualMembersOverrides,"Raises errors for non-virtual members overrides" 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 00ddd74b6c5..14302b05132 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -56,6 +56,7 @@ type LanguageFeature = | SelfTypeConstraints | MatchNotAllowedForUnionCaseWithNoData | CSharpExtensionAttributeNotRequired + | ErrorForNonVirtualMembersOverrides /// LanguageVersion management type LanguageVersion(versionText) = @@ -128,6 +129,7 @@ type LanguageVersion(versionText) = LanguageFeature.FromEndSlicing, previewVersion LanguageFeature.MatchNotAllowedForUnionCaseWithNoData, previewVersion LanguageFeature.CSharpExtensionAttributeNotRequired, previewVersion + LanguageFeature.ErrorForNonVirtualMembersOverrides, previewVersion ] @@ -237,6 +239,7 @@ type LanguageVersion(versionText) = | LanguageFeature.SelfTypeConstraints -> FSComp.SR.featureSelfTypeConstraints () | LanguageFeature.MatchNotAllowedForUnionCaseWithNoData -> FSComp.SR.featureMatchNotAllowedForUnionCaseWithNoData () | LanguageFeature.CSharpExtensionAttributeNotRequired -> FSComp.SR.featureCSharpExtensionAttributeNotRequired () + | LanguageFeature.ErrorForNonVirtualMembersOverrides -> FSComp.SR.featureErrorForNonVirtualMembersOverrides () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index 1b3d68e8f2a..f471f371b95 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -46,6 +46,7 @@ type LanguageFeature = | SelfTypeConstraints | MatchNotAllowedForUnionCaseWithNoData | CSharpExtensionAttributeNotRequired + | ErrorForNonVirtualMembersOverrides /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 8c4a1300a7f..2afccb1fd40 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -177,6 +177,11 @@ literál float32 bez tečky + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute chyba při zastaralém přístupu konstruktoru s atributem RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 688592092e3..b0eec3044bc 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -177,6 +177,11 @@ punktloses float32-Literal + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute Beim veralteten Zugriff auf das Konstrukt mit dem RequireQualifiedAccess-Attribut wird ein Fehler ausgegeben. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index a06daa1f7f1..89d57eacb65 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -177,6 +177,11 @@ literal float32 sin punto + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute error en el acceso en desuso de la construcción con el atributo RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index f8a89904bfa..2db2d58f88f 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -177,6 +177,11 @@ littéral float32 sans point + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute donner une erreur sur l’accès déconseillé de la construction avec l’attribut RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 37d11b74636..66011450a6b 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -177,6 +177,11 @@ valore letterale float32 senza punti + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute errore durante l'accesso deprecato del costrutto con l'attributo RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index c42700c1d18..0ba2173b8fc 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -177,6 +177,11 @@ ドットなしの float32 リテラル + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute RequireQualifiedAccess 属性を持つコンストラクトの非推奨アクセスでエラーが発生しました diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 39e9a33001e..e97d0cf2eb2 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -177,6 +177,11 @@ 점이 없는 float32 리터럴 + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute RequireQualifiedAccess 특성을 사용하여 사용되지 않는 구문 액세스에 대한 오류 제공 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index e3a61d7dd58..d39b72ca26f 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -177,6 +177,11 @@ bezkropkowy literał float32 + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute wskazywanie błędu w przypadku przestarzałego dostępu do konstrukcji z atrybutem RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 78742938012..09d70721f8a 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -177,6 +177,11 @@ literal float32 sem ponto + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute fornecer erro no acesso preterido do constructo com o atributo RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 837271832bf..01249439e53 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -177,6 +177,11 @@ литерал float32 без точки + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute выдать ошибку при устаревшем доступе к конструкции с атрибутом RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 59d04a3fe94..113d6a42396 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -177,6 +177,11 @@ noktasız float32 sabit değeri + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute RequireQualifiedAccess özniteliğine sahip yapının kullanım dışı erişiminde hata diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index ebcafbf1852..b6a766f9cd5 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -177,6 +177,11 @@ 无点 float32 文本 + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute 对具有 RequireQualifiedAccess 属性的构造进行弃用的访问时出错 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 0606b9b48c4..f404d766e1c 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -177,6 +177,11 @@ 無點號的 float32 常值 + + Raises errors for non-virtual members overrides + Raises errors for non-virtual members overrides + + give error on deprecated access of construct with RequireQualifiedAccess attribute 對具有 RequireQualifiedAccess 屬性的建構的已取代存取發出錯誤 diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs index 621307f4e66..eeb3ab1d371 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs @@ -120,4 +120,426 @@ type X() = |> withDiagnostics [ (Error 531, Line 4, Col 5, Line 4, Col 12, "Accessibility modifiers should come immediately prior to the identifier naming a construct") (Error 512, Line 4, Col 13, Line 4, Col 18, "Accessibility modifiers are not permitted on 'do' bindings, but 'Private' was given.") - (Error 222, Line 2, Col 1, Line 3, Col 1, "Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration.")] + (Error 222, Line 2, Col 1, Line 3, Col 1, "Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration.") + ] + + [] + let ``No abstract or interface member was found that corresponds to this override with lang preview``() = + Fsx """ +type A = + abstract member M1: unit -> unit + abstract member M2: unit -> unit + abstract member M3: unit -> unit + abstract member M4: unit -> unit + +type B() = + interface A with + override this.M1() = () + override this.M2() = () // error is expected + override this.M3() = () // error is expected + override this.M4() = () + +type C() = + inherit B() + override this.M1() = () + override this.M2() = () + override this.M3() = () + override this.M4() = () + member this.M5() = () + """ + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 17, Col 19, Line 17, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 18, Col 19, Line 18, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 19, Col 19, Line 19, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 20, Col 19, Line 20, Col 21, "No abstract or interface member was found that corresponds to this override") + ] + + [] + let ``No abstract or interface member was found that corresponds to this override with lang version70``() = + Fsx """ +type A = + abstract member M1: unit -> unit + abstract member M2: unit -> unit + abstract member M3: unit -> unit + abstract member M4: unit -> unit + +type B() = + interface A with + override this.M1() = () + override this.M2() = () // error is expected + override this.M3() = () // error is expected + override this.M4() = () + +type C() = + inherit B() + override this.M1() = () + override this.M2() = () + override this.M3() = () + override this.M4() = () + member this.M5() = () + """ + |> withLangVersion70 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 17, Col 19, Line 17, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 18, Col 19, Line 18, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 19, Col 19, Line 19, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 20, Col 19, Line 20, Col 21, "No abstract or interface member was found that corresponds to this override") + ] + + [] + let ``Virtual member was found that corresponds to this override with lang version70`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public virtual void M2() { } + public virtual void M3() { } + public virtual void M4() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type B() = + inherit A() + override this.M1() = () + override this.M2() = () + override this.M3() = () + override this.M4() = () + member this.M5() = () + """ |> withReferences [CSLib] + app + |> withLangVersion70 + |> compile + |> shouldSucceed + + [] + let ``Virtual member was found that corresponds to this override with lang preview`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public virtual void M2() { } + public virtual void M3() { } + public virtual void M4() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type B() = + inherit A() + override this.M1() = () + override this.M2() = () + override this.M3() = () + override this.M4() = () + member this.M5() = () + """ |> withReferences [CSLib] + app + |> withLangVersionPreview + |> compile + |> shouldSucceed + + + [] + let ``Virtual member was not found that corresponds to this override simple base class with lang version preview`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public void M2() { } + public virtual void M3() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type B() = + inherit A() + + override this.M1() = () + override this.M2() = () // error expected + override this.M3() = () + member this.M4() = () + """ |> withReferences [CSLib] + app + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 7, Col 19, Line 7, Col 21, "No abstract or interface member was found that corresponds to this override") + ] + + [] + let ``Virtual member was not found that corresponds to this override simple base class with lang version70`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public void M2() { } + public virtual void M3() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type B() = + inherit A() + + override this.M1() = () + override this.M2() = () + override this.M3() = () + member this.M4() = () + """ |> withReferences [CSLib] + app + |> withLangVersion70 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 7, Col 19, Line 7, Col 21, "No abstract or interface member was found that corresponds to this override") + ] + + [] + let ``Virtual member was not found that corresponds to this override nested base class with lang version preview`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public virtual void M2() { } + public virtual void M3() { } + public virtual void M4() { } +} + +public class B : A +{ + public override void M1() { } + public void M2() { } + public new void M3() { } + public new virtual void M4() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type C() = + inherit B() + + override this.M1() = () + override this.M2() = () // error expected + override this.M3() = () // error expected + override this.M4() = () + member this.M5() = () + """ |> withReferences [CSLib] + app + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 7, Col 19, Line 7, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 8, Col 19, Line 8, Col 21, "No abstract or interface member was found that corresponds to this override") + ] + + [] + let ``Virtual member was not found that corresponds to this override nested base class with lang version70`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public virtual void M2() { } + public virtual void M3() { } + public virtual void M4() { } +} + +public class B : A +{ + public override void M1() { } + public void M2() { } + public new void M3() { } + public new virtual void M4() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type C() = + inherit B() + + override this.M1() = () + override this.M2() = () // error expected + override this.M3() = () // error expected + override this.M4() = () + member this.M5() = () + """ |> withReferences [CSLib] + app + |> withLangVersion70 + |> compile + |> shouldSucceed + + [] + let ``Virtual member was not found that corresponds to this override nested 2 base class with lang preview`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public virtual void M2() { } + public virtual void M3() { } + public virtual void M4() { } +} + +public class B : A +{ + public void M2() { } + public new void M3() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type C() = + inherit B() + + override this.M1() = () + override this.M2() = () // error is expected + override this.M3() = () // error is expected + override this.M4() = () + member this.M5() = () + """ |> withReferences [CSLib] + app + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 7, Col 19, Line 7, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 8, Col 19, Line 8, Col 21, "No abstract or interface member was found that corresponds to this override") + ] + + [] + let ``Virtual member was not found that corresponds to this override nested 2 base classes with lang version70`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public virtual void M2() { } + public virtual void M3() { } + public virtual void M4() { } +} + +public class B : A +{ + public void M2() { } + public new void M3() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type C() = + inherit B() + + override this.M1() = () + override this.M2() = () // error is expected + override this.M3() = () // error is expected + override this.M4() = () + member this.M5() = () + """ |> withReferences [CSLib] + app + |> withLangVersion70 + |> compile + |> shouldSucceed + + [] + let ``Virtual member was not found that corresponds to this override nested 2 base classes and mixed methods with lang preview`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public void M2() { } +} + +public class B : A +{ + public virtual void M3() { } + public new void M4() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type C() = + inherit B() + + override this.M1() = () + override this.M2() = () // error is expected + override this.M3() = () + override this.M4() = () // error is expected + member this.M5() = () + """ |> withReferences [CSLib] + app + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 7, Col 19, Line 7, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 9, Col 19, Line 9, Col 21, "No abstract or interface member was found that corresponds to this override") + ] + + [] + let ``Virtual member was not found that corresponds to this override nested 2 base classes and mixed methods with lang version70`` () = + let CSLib = + CSharp """ +public class A +{ + public virtual void M1() { } + public void M2() { } +} + +public class B : A +{ + public virtual void M3() { } + public new void M4() { } +} + """ |> withName "CSLib" + + let app = + FSharp """ +module ClassTests +type C() = + inherit B() + + override this.M1() = () + override this.M2() = () // error is expected + override this.M3() = () + override this.M4() = () // error is expected + member this.M5() = () + """ |> withReferences [CSLib] + app + |> withLangVersion70 + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 855, Line 7, Col 19, Line 7, Col 21, "No abstract or interface member was found that corresponds to this override") + (Error 855, Line 9, Col 19, Line 9, Col 21, "No abstract or interface member was found that corresponds to this override") + ] \ No newline at end of file