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
+
+ 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
+
+ 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
+
+ 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
+
+ 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
+
+ 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
+
+ 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
+
+ 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
+
+ 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
+
+ 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
+
+ выдать ошибку при устаревшем доступе к конструкции с атрибутом 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
+
+ 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
+
+ 对具有 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
+
+ 對具有 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