未验证 提交 d911dcb4 编写于 作者: G Gustavo Leon 提交者: GitHub

Allow interfaces to be declared and implemented within intrinsics (#11170)

* Changing warning to implementing interfaces within intrisincs
* In case of recursive namespaces and modules, warning is not generated
* Adding tests for combinations of rec and non-rec modules/namespaces/nested namespaces
上级 f3a9937d
......@@ -1636,7 +1636,7 @@ module MutRecBindingChecking =
defnsEs, envMutRec
/// Check and generalize the interface implementations, members, 'let' definitions in a mutually recursive group of definitions.
let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (envMutRec: TcEnv) (mutRecDefns: MutRecDefnsPhase2Data) =
let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (envMutRec: TcEnv) (mutRecDefns: MutRecDefnsPhase2Data) isMutRec =
let g = cenv.g
let interfacesFromTypeDefn envForTycon tyconMembersData =
let (MutRecDefnsPhase2DataForTycon(_, _, declKind, tcref, _, _, declaredTyconTypars, members, _, _, _)) = tyconMembersData
......@@ -1665,11 +1665,13 @@ let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (env
(generatedHashAndEqualsWithComparerValues && typeEquiv g intfTyR (mkAppTy g.system_GenericIEquatable_tcref [ty])) ||
(generatedHashAndEqualsWithComparerValues && typeEquiv g intfTyR g.mk_IStructuralEquatable_ty) then
errorR(Error(FSComp.SR.tcDefaultImplementationForInterfaceHasAlreadyBeenAdded(), intfTy.Range))
if overridesOK = WarnOnOverrides then
warning(IntfImplInIntrinsicAugmentation(intfTy.Range))
if overridesOK = ErrorOnOverrides then
errorR(IntfImplInExtrinsicAugmentation(intfTy.Range))
match isMutRec, overridesOK with
| _, OverridesOK -> () // No warning/error if overrides are allowed
| true, WarnOnOverrides -> () // If we are in a recursive module/namespace, overrides of interface implementations are allowed and not considered a warning
| false, WarnOnOverrides -> warning(IntfImplInIntrinsicAugmentation(intfTy.Range))
| _, ErrorOnOverrides -> errorR(IntfImplInExtrinsicAugmentation(intfTy.Range))
match defnOpt with
| Some defn -> [ (intfTyR, defn, m) ]
| _-> []
......@@ -2270,7 +2272,7 @@ module TcExceptionDeclarations =
let envMutRec = AddLocalExnDefnAndReport cenv.tcSink scopem (AddLocalTycons g cenv.amap scopem [exnc] envInitial) exnc
let defns = [MutRecShape.Tycon(MutRecDefnsPhase2DataForTycon(Some exnc, parent, ModuleOrMemberBinding, mkLocalEntityRef exnc, None, NoSafeInitInfo, [], aug, m, NoNewSlots, (fun () -> ())))]
let binds2, envFinal = TcMutRecDefns_Phase2 cenv envInitial m scopem None envMutRec defns
let binds2, envFinal = TcMutRecDefns_Phase2 cenv envInitial m scopem None envMutRec defns true
let binds2flat = binds2 |> MutRecShapes.collectTycons |> List.collect snd
// Augment types with references to values that implement the pre-baked semantics of the type
let binds3 = AddAugmentationDeclarations.AddGenericEqualityBindings cenv envFinal exnc
......@@ -4162,7 +4164,7 @@ module TcDeclarations =
//-------------------------------------------------------------------------
/// Bind a collection of mutually recursive definitions in an implementation file
let TcMutRecDefinitions (cenv: cenv) envInitial parent typeNames tpenv m scopem mutRecNSInfo (mutRecDefns: MutRecDefnsInitialData) =
let TcMutRecDefinitions (cenv: cenv) envInitial parent typeNames tpenv m scopem mutRecNSInfo (mutRecDefns: MutRecDefnsInitialData) isMutRec =
let g = cenv.g
......@@ -4216,7 +4218,7 @@ module TcDeclarations =
cenv true scopem m
// Check the members and decide on representations for types with implicit constructors.
let withBindings, envFinal = TcMutRecDefns_Phase2 cenv envInitial m scopem mutRecNSInfo envMutRecPrelimWithReprs withEnvs
let withBindings, envFinal = TcMutRecDefns_Phase2 cenv envInitial m scopem mutRecNSInfo envMutRecPrelimWithReprs withEnvs isMutRec
// Generate the hash/compare/equality bindings for all tycons.
//
......@@ -4674,7 +4676,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem
| SynModuleDecl.Types (typeDefs, m) ->
let scopem = unionRanges m scopem
let mutRecDefns = typeDefs |> List.map MutRecShape.Tycon
let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv env parent typeNames tpenv m scopem None mutRecDefns
let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv env parent typeNames tpenv m scopem None mutRecDefns false
// Check the non-escaping condition as we build the expression on the way back up
let defn = TcMutRecDefsFinish cenv mutRecDefnsChecked m
let escapeCheck () =
......@@ -4725,7 +4727,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem
// Treat 'module rec M = ...' as a single mutually recursive definition group 'module M = ...'
if isRec then
assert (not isContinuingModule)
let modDecl = SynModuleDecl.NestedModule(compInfo, false, moduleDefs, isContinuingModule, m, trivia)
let modDecl = SynModuleDecl.NestedModule(compInfo, false, moduleDefs, isContinuingModule, m, trivia)
return! TcModuleOrNamespaceElementsMutRec cenv parent typeNames m env None [modDecl]
else
let (SynComponentInfo(Attributes attribs, _, _, longPath, xml, _, vis, im)) = compInfo
......@@ -4927,7 +4929,7 @@ and TcModuleOrNamespaceElementsMutRec (cenv: cenv) parent typeNames m envInitial
loop (match parent with ParentNone -> true | Parent _ -> false) m [] defs
let tpenv = emptyUnscopedTyparEnv
let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo mutRecDefns
let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo mutRecDefns true
// Check the assembly attributes
let attrs, _ = TcAttributesWithPossibleTargets false cenv envAfter AttributeTargets.Top synAttrs
......
......@@ -1054,7 +1054,7 @@
<value>Override implementations should be given as part of the initial declaration of a type.</value>
</data>
<data name="IntfImplInIntrinsicAugmentation" xml:space="preserve">
<value>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</value>
<value>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</value>
</data>
<data name="IntfImplInExtrinsicAugmentation" xml:space="preserve">
<value>Interface implementations should be given on the initial declaration of a type.</value>
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">Implementace rozhraní v rozšířeních jsou už zastaralé. Implementace rozhraní by se měly provádět při počáteční deklaraci typu.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">Implementace rozhraní v rozšířeních jsou už zastaralé. Implementace rozhraní by se měly provádět při počáteční deklaraci typu.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">Schnittstellenimplementierungen in Augmentationen sind jetzt veraltet. Schnittstellenimplementierungen sollten in der ersten Deklaration eines Typs angegeben werden.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">Schnittstellenimplementierungen in Augmentationen sind jetzt veraltet. Schnittstellenimplementierungen sollten in der ersten Deklaration eines Typs angegeben werden.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">Las implementaciones de interfaz en aumentos están en desuso. Las implementaciones de interfaz deben proporcionarse en la declaración inicial de un tipo.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">Las implementaciones de interfaz en aumentos están en desuso. Las implementaciones de interfaz deben proporcionarse en la declaración inicial de un tipo.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">Les implémentations d'interfaces dans les augmentations sont désormais déconseillées. Les implémentations d'interfaces doivent être fournies dans la déclaration initiale d'un type.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">Les implémentations d'interfaces dans les augmentations sont désormais déconseillées. Les implémentations d'interfaces doivent être fournies dans la déclaration initiale d'un type.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">Le implementazioni di interfaccia negli aumenti sono ora deprecate. Le implementazioni di interfaccia devono essere specificate nella dichiarazione iniziale di un tipo.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">Le implementazioni di interfaccia negli aumenti sono ora deprecate. Le implementazioni di interfaccia devono essere specificate nella dichiarazione iniziale di un tipo.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">拡張内のインターフェイスの実装は使用されなくなりました。インターフェイスの実装は、型の最初の宣言で指定してください。</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">拡張内のインターフェイスの実装は使用されなくなりました。インターフェイスの実装は、型の最初の宣言で指定してください。</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">확대의 인터페이스 구현은 이제 사용되지 않습니다. 인터페이스 구현은 초기 형식 선언 시 지정해야 합니다.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">확대의 인터페이스 구현은 이제 사용되지 않습니다. 인터페이스 구현은 초기 형식 선언 시 지정해야 합니다.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">Implementacje interfejsów w powiększeniach są teraz przestarzałe. Implementacje interfejsów powinny występować w początkowej deklaracji typu.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">Implementacje interfejsów w powiększeniach są teraz przestarzałe. Implementacje interfejsów powinny występować w początkowej deklaracji typu.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">Implementações de interface em aumentos agora são preteridas. Implementações de interface devem ser dadas nas declarações de tipo iniciais.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">Implementações de interface em aumentos agora são preteridas. Implementações de interface devem ser dadas nas declarações de tipo iniciais.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">Реализации интерфейсов в приращениях теперь являются не рекомендуемыми к использованию. Реализации интерфейсов должны быть даны при первичном объявлении типа.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">Реализации интерфейсов в приращениях теперь являются не рекомендуемыми к использованию. Реализации интерфейсов должны быть даны при первичном объявлении типа.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">Genişletmelerdeki arabirim uygulamaları artık kullanım dışı bırakıldı. Arabirim uygulamaları bir türün ilk bildiriminde verilmelidir.</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">Genişletmelerdeki arabirim uygulamaları artık kullanım dışı bırakıldı. Arabirim uygulamaları bir türün ilk bildiriminde verilmelidir.</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">扩大中的接口实现现已弃用。应在类型的初始声明中提供接口实现。</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">扩大中的接口实现现已弃用。应在类型的初始声明中提供接口实现。</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -1558,8 +1558,8 @@
<note />
</trans-unit>
<trans-unit id="IntfImplInIntrinsicAugmentation">
<source>Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.</source>
<target state="translated">增強指定中的介面實作現在已被取代。應該在類型的初始宣告上指定介面實作。</target>
<source>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</source>
<target state="needs-review-translation">增強指定中的介面實作現在已被取代。應該在類型的初始宣告上指定介面實作。</target>
<note />
</trans-unit>
<trans-unit id="IntfImplInExtrinsicAugmentation">
......
......@@ -6,7 +6,7 @@
#nowarn "52" // The value has been copied to ensure the original is not mutated by this operation
#nowarn "60" // Override implementations in augmentations are now deprecated. Override implementations should be given as part of the initial declaration of a type.
#nowarn "61" // The containing type can use 'null' as a representation value for its nullary union case. This member will be compiled as a static member.
#nowarn "69" // Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration...
#nowarn "69" // Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.
#nowarn "77" // Member constraints with the name 'Exp' are given special status by the F# compiler...
#nowarn "3218" // mismatch of parameter name for 'fst' and 'snd'
......
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.ComponentTests.ErrorMessages
open Xunit
open FSharp.Test.Compiler
module InterfaceImplAugmentation =
[<Fact>]
let ``Type in non-recursive namespace gives a warning when augmented externally``() =
FSharp """
namespace AugmentationsTest
type MyCustomType<'T> =
| Data of string
interface System.IDisposable
type MyCustomType<'T> with
interface System.IDisposable with
member x.Dispose() = printfn "Finish" """
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Warning 69, Line 8, Col 15, Line 8, Col 33,
"""Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.""")
[<Fact>]
let ``Exception type in non-recursive namespace gives a warning when augmented externally``() =
FSharp """
namespace AugmentationsTest
type MyCustomExcType<'T>() =
inherit System.Exception()
interface System.IDisposable
type MyCustomExcType<'T> with
interface System.IDisposable with
member x.Dispose() = printfn "Finish" """
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Warning 69, Line 8, Col 15, Line 8, Col 33,
"""Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.""")
[<Fact>]
let ``Type in a recursive namespace can be augmented without warning``() =
FSharp """
namespace rec AugmentationsTest
type MyCustomType<'T> =
| Data of string
interface System.IDisposable
type MyCustomType<'T> with
interface System.IDisposable with
member x.Dispose() = printfn "Finish" """
|> typecheck
|> shouldSucceed
|> withWarnings []
[<Fact>]
let ``Exception in a recursive namespace can be augmented without warning``() =
FSharp """
namespace rec AugmentationsTest
type MyCustomExcType<'T>() =
inherit System.Exception()
interface System.IDisposable
type MyCustomExcType<'T> with
interface System.IDisposable with
member x.Dispose() = printfn "Finish" """
|> typecheck
|> shouldSucceed
|> withWarnings []
[<Fact>]
let ``Type in a recursive module and in a non-recursive namespace can be augmented without warning``() =
FSharp """
namespace MyNonRecursiveNs
module rec RecursiveModule =
type MyCustomType<'T> =
| Data of string
interface System.IDisposable
type MyCustomType<'T> with
interface System.IDisposable with
member x.Dispose() = printfn "Finish" """
|> typecheck
|> shouldSucceed
|> withWarnings []
[<Fact>]
let ``Type in a nonrecursive module but in a recursive namespace can be augmented without warning``() =
FSharp """
namespace rec AugmentationsTest
module InnerNonRecursiveModule =
type MyCustomType<'T> =
| Data of string
interface System.IDisposable
type MyCustomType<'T> with
interface System.IDisposable with
member x.Dispose() = printfn "Finish" """
|> typecheck
|> shouldSucceed
|> withWarnings []
[<Fact>]
let ``Type in non-recursive namespace nested in a bigger recursive namespace shows warning``() =
FSharp """
namespace rec OuuterRec
namespace OuuterRec.InnerNonRec
type MyCustomType<'T> =
| Data of string
interface System.IDisposable
type MyCustomType<'T> with
interface System.IDisposable with
member x.Dispose() = printfn "Finish" """
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Warning 69, Line 9, Col 19, Line 9, Col 37,
"""Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.""")
[<Fact>]
let ``Type in non-rec ns show give a warning when augmented externally even when the same file has a recursive (but different) ns``() =
FSharp """
namespace rec OuuterRec
module Stuff =
let x = 5
namespace TotallyDifferentNs.InnerNonRec
type MyCustomType<'T> =
| Data of string
interface System.IDisposable
type MyCustomType<'T> with
interface System.IDisposable with
member x.Dispose() = printfn "Finish" """
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Warning 69, Line 11, Col 19, Line 11, Col 37,
"""Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.""")
[<Fact>]
let ``Adding an interface to a previously defined type should still be just an 909 error and nothing else``() =
FSharp """
type System.Random with
interface System.IComparable
static member Factory() = 1 """
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Error 909, Line 3, Col 15, Line 3, Col 33,
"""All implemented interfaces should be declared on the initial declaration of the type""")
\ No newline at end of file
......@@ -134,7 +134,7 @@
<Compile Include="EmittedIL\Structure\Structure.fs" />
<Compile Include="EmittedIL\TestFunctions\TestFunctions.fs" />
<Compile Include="EmittedIL\Tuples\Tuples.fs" />
<Compile Include="EmittedIL\StructDefensiveCopy\StructDefensiveCopy.fs" />
<Compile Include="EmittedIL\StructDefensiveCopy\StructDefensiveCopy.fs" />
<Compile Include="ErrorMessages\UnsupportedAttributes.fs" />
<Compile Include="ErrorMessages\TypeEqualsMissingTests.fs" />
<Compile Include="ErrorMessages\AccessOfTypeAbbreviationTests.fs" />
......@@ -159,9 +159,10 @@
<Compile Include="ErrorMessages\FS0988AtEndOfFile.fs" />
<Compile Include="ErrorMessages\Repro1548.fs" />
<Compile Include="ErrorMessages\WarnIfDiscardedInList.fs" />
<Compile Include="ErrorMessages\UnionCasePatternMatchingErrors.fs"/>
<Compile Include="ErrorMessages\UnionCasePatternMatchingErrors.fs"/>
<Compile Include="ErrorMessages\InterfaceImplInAugmentationsTests.fs"/>
<Compile Include="Language\IndexerSetterParamArray.fs" />
<Compile Include="Language\MultiDimensionalArrayTests.fs" />
<Compile Include="Language\MultiDimensionalArrayTests.fs" />
<Compile Include="Language\RegressionTests.fs" />
<Compile Include="Language\AttributeCheckingTests.fs" />
<Compile Include="Language\ObsoleteAttributeCheckingTests.fs" />
......@@ -181,8 +182,8 @@
<Link>%(RelativeDir)\TestSource\%(Filename)%(Extension)</Link>
</None>
<Compile Include="Interop\SimpleInteropTests.fs" />
<Compile Include="Interop\RequiredAndInitOnlyProperties.fs" />
<Compile Include="Interop\StaticsInInterfaces.fs" />
<Compile Include="Interop\RequiredAndInitOnlyProperties.fs" />
<Compile Include="Interop\StaticsInInterfaces.fs" />
<Compile Include="Interop\VisibilityTests.fs" />
<Compile Include="Scripting\Interactive.fs" />
<Compile Include="TypeChecks\CheckDeclarationsTests.fs" />
......
......@@ -29,7 +29,7 @@ neg10.fs(25,16,25,53): typecheck error FS0001: This type parameter cannot be ins
neg10.fs(54,17,54,20): typecheck error FS0060: Override implementations in augmentations are now deprecated. Override implementations should be given as part of the initial declaration of a type.
neg10.fs(66,19,66,21): typecheck error FS0069: Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
neg10.fs(66,19,66,21): typecheck error FS0069: Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.
neg10.fs(77,13,77,34): typecheck error FS0896: Enumerations cannot have members
......
......@@ -37,4 +37,4 @@ neg46.fs(64,8,64,26): typecheck error FS0912: This declaration element is not pe
neg46.fs(68,18,68,36): typecheck error FS0909: All implemented interfaces should be declared on the initial declaration of the type
neg46.fs(73,18,73,36): typecheck error FS0909: All implemented interfaces should be declared on the initial declaration of the type
neg46.fs(73,18,73,36): typecheck error FS0909: All implemented interfaces should be declared on the initial declaration of the type
\ No newline at end of file
......@@ -2,5 +2,4 @@
SOURCE="lib002.fs E_typeext_int002.fs" SCFLAGS="--test:ErrorRanges" # E_typeext_int002.fs
SOURCE="lib003.fs typeext_int003.fs" # typeext_int003.fs
SOURCE="lib004.fs typeext_int004.fs" # typeext_int004fs
SOURCE="lib005.fs typeext_int005.fs" # typeext_int005fs
SOURCE="lib006.fs typeext_int006.fs" SCFLAGS="--test:ErrorRanges" # typeext_int006.fs
SOURCE="lib005.fs typeext_int005.fs" # typeext_int005fs
\ No newline at end of file
// #Regression #Conformance #ObjectOrientedTypes #TypeExtensions
//<Expects id="FS0909" span="(7,17-7,19)" status="error">All implemented interfaces should be declared on the initial declaration of the type</Expects>
namespace NS
type IM =
interface
abstract M : int -> int
end
type Lib() =
class
member x.Prop = 1
end
// #Conformance #ObjectOrientedTypes #TypeExtensions
// verify that implementing an interface is not allowed
namespace NS
module M =
type Lib with
interface IM
with member x.M i = i
module F = exit 0
// #Conformance #ObjectOrientedTypes #TypeExtensions #Regression
// Regression for 909525, previously there was no error here
// <Expects status="error" id="FS0909" span="(5,15-5,33)">All implemented interfaces should be declared on the initial declaration of the type</Expects>
type System.Random with
interface System.IComparable
static member Factory() = 1
exit 1
......@@ -3,7 +3,6 @@
SOURCE="lib003.fs" SCFLAGS="-a" # lib003.fs
SOURCE="lib004.fs" SCFLAGS="-a" # lib004.fs
SOURCE="lib005.fs" SCFLAGS="-a" # lib005.fs
SOURCE="lib006.fs" SCFLAGS="-a" # lib006.fs
SOURCE="E_NotInModule.fs" SCFLAGS="-r:lib000.dll --test:ErrorRanges" # E_NotInModule.fs
SOURCE="ShortNamesAllowed.fs" SCFLAGS="-r:lib000.dll" # ShortNamesAllowed.fs
SOURCE="E_ModuleNotOpen.fs" SCFLAGS="-r:lib000.dll --test:ErrorRanges" # E_ModuleNotOpen.fs
......@@ -13,8 +12,6 @@
SOURCE="typeext_opt004.fs" SCFLAGS="-r:lib004.dll" # typeext_opt004.fs
SOURCE="typeext_opt005.fs" SCFLAGS="-r:lib005.dll" # typeext_opt005.fs
SOURCE="E_typeext_opt005.fs" SCFLAGS="-r:lib005.dll --test:ErrorRanges" # E_typeext_opt005.fs
SOURCE="typeext_opt006.fs" SCFLAGS="-r:lib006.dll --test:ErrorRanges" # typeext_opt006.fs
SOURCE="typeext_opt007.fs" SCFLAGS="-r:lib001.dll" # typeext_opt007.fs
SOURCE="typeext_opt008.fs" SCFLAGS="-r:lib001.dll --test:ErrorRanges" # typeext_opt008.fs
SOURCE=E_TypeExtensionWithInterface01.fs SCFLAGS="--test:ErrorRanges" # E_TypeExtensionWithInterface01.fs
SOURCE=E_CrossModule01.fs SCFLAGS="--test:ErrorRanges" # E_CrossModule01.fs
// #Conformance #ObjectOrientedTypes #TypeExtensions
#light
namespace NS
type IM =
interface
abstract M : int -> int
end
type Lib() =
class
member x.Prop = 1
end
// #Regression #Conformance #ObjectOrientedTypes #TypeExtensions
//<Expects id="FS0909" span="(7,17-7,19)" status="error">All implemented interfaces should be declared on the initial declaration of the type</Expects>
namespace NS
module M =
type Lib with
interface IM
with member x.M i = i
module F = exit 0
// #Regression #Diagnostics
// Regression test for FSHARP1.0:1273
// Give warning on use of interface and/or override implementations in augmentations
//
//<Expects id="FS0069" span="(18,23-18,24)" status="warning"></Expects>
type I = interface
abstract M : int
end
type T2b2 = class
interface I
end
type T2b2 with
interface I with
member a.M = 3
end
end
// #Regression #Diagnostics
// Regression test for FSHARP1.0:1273
// Give warning on use of interface and/or override implementations in augmentations
//<Expects id="FS0069" span="(26,23-26,25)" status="warning">Interface implementations in augmentations are now deprecated\. Interface implementations should be given on the initial declaration of a type\.$</Expects>
type I = interface
abstract M : int
end
type I2 = interface
inherit I
end
type I3 = interface
inherit I2
end
type I4 = interface
inherit I3
end
type T2b2 = class
interface I4
end
type T2b2 with
interface I4 with
member a.M = 3
end
end
// #Regression #Diagnostics
// Regression test for FSHARP1.0:1273
// Give warning on use of interface and/or override implementations in augmentations
//<Expects id="FS0069" span="(27,23-27,25)" status="warning">Interface implementations in augmentations are now deprecated\. Interface implementations should be given on the initial declaration of a type\.$</Expects>
type I = interface
end
type I2 = interface
inherit I
end
type I3 = interface
inherit I2
end
type I4 = interface
inherit I3
abstract M : int
end
type T2b2 = class
interface I4
end
type T2b2 with
interface I4 with
member a.M = 3
end
end
// #Regression #Diagnostics
// Regression test for FSHARP1.0:1273
// Give warning on use of interface and/or override implementations in augmentations
//
//<Expects id="FS0060" span="(13,21-13,24)" status="warning"></Expects>
module M
type T2b = class
abstract M : int
//default a.M = 3
end
type T2b with
default x.M = 0 // warning FS0060: Override implementations should be given as part of the initial declaration of a type. While the current language specification allows overrides implementations in augmentations, this is likely to be deprecated in a future revision of the language
end
// #Regression #Diagnostics
// Regression test for FSHARP1.0:1273
// Give warning on use of interface and/or override implementations in augmentations
//
//<Expects id="FS0060" span="(13,22-13,25)" status="warning"></Expects>
//<Expects id="FS0001" span="(13,28-13,31)" status="error"></Expects>
type T2 = class
abstract M : int
//default a.M = 3
end
type T2 with
override x.M = 0.0 // warning + error
end
......@@ -93,12 +93,7 @@ NoMT SOURCE=E_MissingSourceFile04.fs SCFLAGS="--exec doesnotexist.fs" FSIMODE=PI
SOURCE=E_StructMustHaveAtLeastOneField.fs SCFLAGS="--test:ErrorRanges" # E_StructMustHaveAtLeastOneField.fs
SOURCE=E_UnexpectedSymbol01.fs SCFLAGS="--test:ErrorRanges" # E_UnexpectedSymbol01.fs
SOURCE=W_InterfaceImplementationInAugmentation01a.fs SCFLAGS="--test:ErrorRanges" # W_InterfaceImplementationInAugmentation01a.fs
SOURCE=W_InterfaceImplementationInAugmentation01b.fs SCFLAGS="--test:ErrorRanges" # W_InterfaceImplementationInAugmentation01b.fs
SOURCE=W_InterfaceImplementationInAugmentation02a.fs SCFLAGS="--test:ErrorRanges" # W_InterfaceImplementationInAugmentation02a.fs
SOURCE=W_OverrideImplementationInAugmentation01a.fs SCFLAGS="--test:ErrorRanges -a" # W_OverrideImplementationInAugmentation01a.fs
SOURCE=W_OverrideImplementationInAugmentation01b.fs SCFLAGS="--test:ErrorRanges -a" # W_OverrideImplementationInAugmentation01b.fs
SOURCE=W_OverrideImplementationInAugmentation02a.fs SCFLAGS="--test:ErrorRanges" # W_OverrideImplementationInAugmentation02a.fs
SOURCE=W_OverrideImplementationInAugmentation02b.fs SCFLAGS="--test:ErrorRanges" # W_OverrideImplementationInAugmentation02b.fs
SOURCE=W_OverrideImplementationInAugmentation03a.fs SCFLAGS="--test:ErrorRanges -a" # W_OverrideImplementationInAugmentation03a.fs
SOURCE=W_OverrideImplementationInAugmentation03b.fs SCFLAGS="--test:ErrorRanges -a" # W_OverrideImplementationInAugmentation03b.fs
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册