diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs
index 36f49053ad8..c4c2798a2df 100644
--- a/src/Compiler/Checking/CheckDeclarations.fs
+++ b/src/Compiler/Checking/CheckDeclarations.fs
@@ -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
diff --git a/src/Compiler/FSStrings.resx b/src/Compiler/FSStrings.resx
index 51f172fbbea..a6953680006 100644
--- a/src/Compiler/FSStrings.resx
+++ b/src/Compiler/FSStrings.resx
@@ -1054,7 +1054,7 @@
Override implementations should be given as part of the initial declaration of a type.
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
+ 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.Interface implementations should be given on the initial declaration of a type.
diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf
index f80da09f758..828b90669df 100644
--- a/src/Compiler/xlf/FSStrings.cs.xlf
+++ b/src/Compiler/xlf/FSStrings.cs.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- 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.
+ 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.
+ 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.
diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf
index 8978b176751..9c6e11f305c 100644
--- a/src/Compiler/xlf/FSStrings.de.xlf
+++ b/src/Compiler/xlf/FSStrings.de.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- Schnittstellenimplementierungen in Augmentationen sind jetzt veraltet. Schnittstellenimplementierungen sollten in der ersten Deklaration eines Typs angegeben werden.
+ 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.
+ Schnittstellenimplementierungen in Augmentationen sind jetzt veraltet. Schnittstellenimplementierungen sollten in der ersten Deklaration eines Typs angegeben werden.
diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf
index bc0ce4ad5a8..74d41dad785 100644
--- a/src/Compiler/xlf/FSStrings.es.xlf
+++ b/src/Compiler/xlf/FSStrings.es.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- Las implementaciones de interfaz en aumentos están en desuso. Las implementaciones de interfaz deben proporcionarse en la declaración inicial de un tipo.
+ 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.
+ Las implementaciones de interfaz en aumentos están en desuso. Las implementaciones de interfaz deben proporcionarse en la declaración inicial de un tipo.
diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf
index f88d8e7182b..6039490dc6d 100644
--- a/src/Compiler/xlf/FSStrings.fr.xlf
+++ b/src/Compiler/xlf/FSStrings.fr.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- 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.
+ 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.
+ 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.
diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf
index 90d7b1611ff..eda88c84995 100644
--- a/src/Compiler/xlf/FSStrings.it.xlf
+++ b/src/Compiler/xlf/FSStrings.it.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- Le implementazioni di interfaccia negli aumenti sono ora deprecate. Le implementazioni di interfaccia devono essere specificate nella dichiarazione iniziale di un tipo.
+ 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.
+ Le implementazioni di interfaccia negli aumenti sono ora deprecate. Le implementazioni di interfaccia devono essere specificate nella dichiarazione iniziale di un tipo.
diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf
index b0a149427b1..d62c37b5fe7 100644
--- a/src/Compiler/xlf/FSStrings.ja.xlf
+++ b/src/Compiler/xlf/FSStrings.ja.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- 拡張内のインターフェイスの実装は使用されなくなりました。インターフェイスの実装は、型の最初の宣言で指定してください。
+ 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.
+ 拡張内のインターフェイスの実装は使用されなくなりました。インターフェイスの実装は、型の最初の宣言で指定してください。
diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf
index 95015040f09..6332a9dcbb2 100644
--- a/src/Compiler/xlf/FSStrings.ko.xlf
+++ b/src/Compiler/xlf/FSStrings.ko.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- 확대의 인터페이스 구현은 이제 사용되지 않습니다. 인터페이스 구현은 초기 형식 선언 시 지정해야 합니다.
+ 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.
+ 확대의 인터페이스 구현은 이제 사용되지 않습니다. 인터페이스 구현은 초기 형식 선언 시 지정해야 합니다.
diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf
index 48a2f8adedc..a09fa340ac5 100644
--- a/src/Compiler/xlf/FSStrings.pl.xlf
+++ b/src/Compiler/xlf/FSStrings.pl.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- Implementacje interfejsów w powiększeniach są teraz przestarzałe. Implementacje interfejsów powinny występować w początkowej deklaracji typu.
+ 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.
+ Implementacje interfejsów w powiększeniach są teraz przestarzałe. Implementacje interfejsów powinny występować w początkowej deklaracji typu.
diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf
index 1929c486cda..c98c991ca2f 100644
--- a/src/Compiler/xlf/FSStrings.pt-BR.xlf
+++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- Implementações de interface em aumentos agora são preteridas. Implementações de interface devem ser dadas nas declarações de tipo iniciais.
+ 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.
+ Implementações de interface em aumentos agora são preteridas. Implementações de interface devem ser dadas nas declarações de tipo iniciais.
diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf
index 1e91c13cd4c..53c522f0096 100644
--- a/src/Compiler/xlf/FSStrings.ru.xlf
+++ b/src/Compiler/xlf/FSStrings.ru.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- Реализации интерфейсов в приращениях теперь являются не рекомендуемыми к использованию. Реализации интерфейсов должны быть даны при первичном объявлении типа.
+ 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.
+ Реализации интерфейсов в приращениях теперь являются не рекомендуемыми к использованию. Реализации интерфейсов должны быть даны при первичном объявлении типа.
diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf
index 31b4cad81af..cd29eea14d1 100644
--- a/src/Compiler/xlf/FSStrings.tr.xlf
+++ b/src/Compiler/xlf/FSStrings.tr.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- Genişletmelerdeki arabirim uygulamaları artık kullanım dışı bırakıldı. Arabirim uygulamaları bir türün ilk bildiriminde verilmelidir.
+ 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.
+ Genişletmelerdeki arabirim uygulamaları artık kullanım dışı bırakıldı. Arabirim uygulamaları bir türün ilk bildiriminde verilmelidir.
diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf
index be3604df4bf..21b470ea885 100644
--- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- 扩大中的接口实现现已弃用。应在类型的初始声明中提供接口实现。
+ 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.
+ 扩大中的接口实现现已弃用。应在类型的初始声明中提供接口实现。
diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf
index 67e6c25370e..eb2c82827bc 100644
--- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf
@@ -1558,8 +1558,8 @@
- Interface implementations in augmentations are now deprecated. Interface implementations should be given on the initial declaration of a type.
- 增強指定中的介面實作現在已被取代。應該在類型的初始宣告上指定介面實作。
+ 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.
+ 增強指定中的介面實作現在已被取代。應該在類型的初始宣告上指定介面實作。
diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs
index 85befedcb4b..a3019b1ec84 100644
--- a/src/FSharp.Core/prim-types.fs
+++ b/src/FSharp.Core/prim-types.fs
@@ -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'
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InterfaceImplInAugmentationsTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InterfaceImplInAugmentationsTests.fs
new file mode 100644
index 00000000000..828775a958f
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InterfaceImplInAugmentationsTests.fs
@@ -0,0 +1,154 @@
+// 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 =
+ []
+ 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.""")
+
+ []
+ 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.""")
+
+
+ []
+ 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 []
+
+ []
+ 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 []
+
+ []
+ 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 []
+
+ []
+ 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 []
+
+ []
+ 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.""")
+
+
+
+ []
+ 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.""")
+
+ []
+ 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
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index 6203b71fd6f..9312c28403c 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -134,7 +134,7 @@
-
+
@@ -159,9 +159,10 @@
-
+
+
-
+
@@ -181,8 +182,8 @@
%(RelativeDir)\TestSource\%(Filename)%(Extension)
-
-
+
+
diff --git a/tests/fsharp/typecheck/sigs/neg10.bsl b/tests/fsharp/typecheck/sigs/neg10.bsl
index ca47dbf94d0..50dadab0ddd 100644
--- a/tests/fsharp/typecheck/sigs/neg10.bsl
+++ b/tests/fsharp/typecheck/sigs/neg10.bsl
@@ -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
diff --git a/tests/fsharp/typecheck/sigs/neg46.bsl b/tests/fsharp/typecheck/sigs/neg46.bsl
index 1bdf9fbc95b..bb3cafeccb3 100644
--- a/tests/fsharp/typecheck/sigs/neg46.bsl
+++ b/tests/fsharp/typecheck/sigs/neg46.bsl
@@ -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
diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/env.lst
index cb4bf2101d8..1f10ac869db 100644
--- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/env.lst
+++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/env.lst
@@ -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
diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/lib006.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/lib006.fs
deleted file mode 100644
index 52ea4d77c14..00000000000
--- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/lib006.fs
+++ /dev/null
@@ -1,14 +0,0 @@
-// #Regression #Conformance #ObjectOrientedTypes #TypeExtensions
-//All implemented interfaces should be declared on the initial declaration of the type
-
-namespace NS
- type IM =
- interface
- abstract M : int -> int
- end
-
- type Lib() =
- class
- member x.Prop = 1
- end
-
diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/typeext_int006.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/typeext_int006.fs
deleted file mode 100644
index c5bfd677714..00000000000
--- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/intrinsic/typeext_int006.fs
+++ /dev/null
@@ -1,14 +0,0 @@
-// #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
-
-
-
diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/E_TypeExtensionWithInterface01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/E_TypeExtensionWithInterface01.fs
deleted file mode 100644
index c33ef60b389..00000000000
--- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/E_TypeExtensionWithInterface01.fs
+++ /dev/null
@@ -1,8 +0,0 @@
-// #Conformance #ObjectOrientedTypes #TypeExtensions #Regression
-// Regression for 909525, previously there was no error here
-// All implemented interfaces should be declared on the initial declaration of the type
-type System.Random with
- interface System.IComparable
- static member Factory() = 1
-
-exit 1
diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/env.lst
index bef08d26615..6cf885da545 100644
--- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/env.lst
+++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/env.lst
@@ -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
diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/lib006.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/lib006.fs
deleted file mode 100644
index b36e866272e..00000000000
--- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/lib006.fs
+++ /dev/null
@@ -1,13 +0,0 @@
-// #Conformance #ObjectOrientedTypes #TypeExtensions
-#light
-namespace NS
- type IM =
- interface
- abstract M : int -> int
- end
-
- type Lib() =
- class
- member x.Prop = 1
- end
-
diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/typeext_opt006.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/typeext_opt006.fs
deleted file mode 100644
index 4335bc703a7..00000000000
--- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/typeext_opt006.fs
+++ /dev/null
@@ -1,13 +0,0 @@
-// #Regression #Conformance #ObjectOrientedTypes #TypeExtensions
-//All implemented interfaces should be declared on the initial declaration of the type
-
-namespace NS
- module M =
- type Lib with
- interface IM
- with member x.M i = i
-
- module F = exit 0
-
-
-
diff --git a/tests/fsharpqa/Source/Diagnostics/General/W_InterfaceImplementationInAugmentation01a.fs b/tests/fsharpqa/Source/Diagnostics/General/W_InterfaceImplementationInAugmentation01a.fs
deleted file mode 100644
index 0e1afb421cd..00000000000
--- a/tests/fsharpqa/Source/Diagnostics/General/W_InterfaceImplementationInAugmentation01a.fs
+++ /dev/null
@@ -1,22 +0,0 @@
-// #Regression #Diagnostics
-// Regression test for FSHARP1.0:1273
-// Give warning on use of interface and/or override implementations in augmentations
-//
-//
-
-
-
-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
-
diff --git a/tests/fsharpqa/Source/Diagnostics/General/W_InterfaceImplementationInAugmentation01b.fs b/tests/fsharpqa/Source/Diagnostics/General/W_InterfaceImplementationInAugmentation01b.fs
deleted file mode 100644
index 2002b516ab4..00000000000
--- a/tests/fsharpqa/Source/Diagnostics/General/W_InterfaceImplementationInAugmentation01b.fs
+++ /dev/null
@@ -1,31 +0,0 @@
-// #Regression #Diagnostics
-// Regression test for FSHARP1.0:1273
-// Give warning on use of interface and/or override implementations in augmentations
-//Interface implementations in augmentations are now deprecated\. Interface implementations should be given on the initial declaration of a type\.$
-
-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
-
-
diff --git a/tests/fsharpqa/Source/Diagnostics/General/W_InterfaceImplementationInAugmentation02a.fs b/tests/fsharpqa/Source/Diagnostics/General/W_InterfaceImplementationInAugmentation02a.fs
deleted file mode 100644
index a9bce5df4a8..00000000000
--- a/tests/fsharpqa/Source/Diagnostics/General/W_InterfaceImplementationInAugmentation02a.fs
+++ /dev/null
@@ -1,30 +0,0 @@
-// #Regression #Diagnostics
-// Regression test for FSHARP1.0:1273
-// Give warning on use of interface and/or override implementations in augmentations
-//Interface implementations in augmentations are now deprecated\. Interface implementations should be given on the initial declaration of a type\.$
-
-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
diff --git a/tests/fsharpqa/Source/Diagnostics/General/W_OverrideImplementationInAugmentation01b.fs b/tests/fsharpqa/Source/Diagnostics/General/W_OverrideImplementationInAugmentation01b.fs
deleted file mode 100644
index 32742489d9d..00000000000
--- a/tests/fsharpqa/Source/Diagnostics/General/W_OverrideImplementationInAugmentation01b.fs
+++ /dev/null
@@ -1,14 +0,0 @@
-// #Regression #Diagnostics
-// Regression test for FSHARP1.0:1273
-// Give warning on use of interface and/or override implementations in augmentations
-//
-//
-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
diff --git a/tests/fsharpqa/Source/Diagnostics/General/W_OverrideImplementationInAugmentation02a.fs b/tests/fsharpqa/Source/Diagnostics/General/W_OverrideImplementationInAugmentation02a.fs
deleted file mode 100644
index 70c842c270a..00000000000
--- a/tests/fsharpqa/Source/Diagnostics/General/W_OverrideImplementationInAugmentation02a.fs
+++ /dev/null
@@ -1,14 +0,0 @@
-// #Regression #Diagnostics
-// Regression test for FSHARP1.0:1273
-// Give warning on use of interface and/or override implementations in augmentations
-//
-//
-//
-
-type T2 = class
- abstract M : int
- //default a.M = 3
- end
-type T2 with
- override x.M = 0.0 // warning + error
- end
diff --git a/tests/fsharpqa/Source/Diagnostics/General/env.lst b/tests/fsharpqa/Source/Diagnostics/General/env.lst
index d77d0099a55..99a0383442b 100644
--- a/tests/fsharpqa/Source/Diagnostics/General/env.lst
+++ b/tests/fsharpqa/Source/Diagnostics/General/env.lst
@@ -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