未验证 提交 e2f3a3e0 编写于 作者: E Edgar Gonzalez 提交者: GitHub

No errors for non-virtual members overrides (#14263)

* No errors for non virtual members overrides

* Check for isFSharpObjModelTy as we are interested on csharp virtual methods

* More testing

* Add a feature lang preview

* More testing

* Fix PR comment
上级 b9d1bc3a
......@@ -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)
......
......@@ -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."
......
......@@ -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 =
......
......@@ -46,6 +46,7 @@ type LanguageFeature =
| SelfTypeConstraints
| MatchNotAllowedForUnionCaseWithNoData
| CSharpExtensionAttributeNotRequired
| ErrorForNonVirtualMembersOverrides
/// LanguageVersion management
type LanguageVersion =
......
......@@ -177,6 +177,11 @@
<target state="translated">literál float32 bez tečky</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">chyba při zastaralém přístupu konstruktoru s atributem RequireQualifiedAccess</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">punktloses float32-Literal</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">Beim veralteten Zugriff auf das Konstrukt mit dem RequireQualifiedAccess-Attribut wird ein Fehler ausgegeben.</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">literal float32 sin punto</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">error en el acceso en desuso de la construcción con el atributo RequireQualifiedAccess</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">littéral float32 sans point</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">donner une erreur sur l’accès déconseillé de la construction avec l’attribut RequireQualifiedAccess</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">valore letterale float32 senza punti</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">errore durante l'accesso deprecato del costrutto con l'attributo RequireQualifiedAccess</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">ドットなしの float32 リテラル</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">RequireQualifiedAccess 属性を持つコンストラクトの非推奨アクセスでエラーが発生しました</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">점이 없는 float32 리터럴</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">RequireQualifiedAccess 특성을 사용하여 사용되지 않는 구문 액세스에 대한 오류 제공</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">bezkropkowy literał float32</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">wskazywanie błędu w przypadku przestarzałego dostępu do konstrukcji z atrybutem RequireQualifiedAccess</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">literal float32 sem ponto</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">fornecer erro no acesso preterido do constructo com o atributo RequireQualifiedAccess</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">литерал float32 без точки</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">выдать ошибку при устаревшем доступе к конструкции с атрибутом RequireQualifiedAccess</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">noktasız float32 sabit değeri</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">RequireQualifiedAccess özniteliğine sahip yapının kullanım dışı erişiminde hata</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">无点 float32 文本</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">对具有 RequireQualifiedAccess 属性的构造进行弃用的访问时出错</target>
......
......@@ -177,6 +177,11 @@
<target state="translated">無點號的 float32 常值</target>
<note />
</trans-unit>
<trans-unit id="featureErrorForNonVirtualMembersOverrides">
<source>Raises errors for non-virtual members overrides</source>
<target state="new">Raises errors for non-virtual members overrides</target>
<note />
</trans-unit>
<trans-unit id="featureErrorOnDeprecatedRequireQualifiedAccess">
<source>give error on deprecated access of construct with RequireQualifiedAccess attribute</source>
<target state="translated">對具有 RequireQualifiedAccess 屬性的建構的已取代存取發出錯誤</target>
......
......@@ -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.")
]
[<Fact>]
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")
]
[<Fact>]
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")
]
[<Fact>]
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
[<Fact>]
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
[<Fact>]
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")
]
[<Fact>]
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")
]
[<Fact>]
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")
]
[<Fact>]
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
[<Fact>]
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")
]
[<Fact>]
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
[<Fact>]
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")
]
[<Fact>]
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册