diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs
index ac0080ca82..21506cfaeb 100644
--- a/src/Compiler/Checking/CheckDeclarations.fs
+++ b/src/Compiler/Checking/CheckDeclarations.fs
@@ -385,7 +385,7 @@ let CheckNamespaceModuleOrTypeName (g: TcGlobals) (id: Ident) =
// type names '[]' etc. are used in fslib
if not g.compilingFSharpCore && id.idText.IndexOfAny IllegalCharactersInTypeAndNamespaceNames <> -1 then
errorR(Error(FSComp.SR.tcInvalidNamespaceModuleTypeUnionName(), id.idRange))
-
+
let CheckDuplicates (idf: _ -> Ident) k elems =
elems |> List.iteri (fun i uc1 ->
elems |> List.iteri (fun j uc2 ->
@@ -394,7 +394,22 @@ let CheckDuplicates (idf: _ -> Ident) k elems =
if j > i && id1.idText = id2.idText then
errorR (Duplicate(k, id1.idText, id1.idRange))))
elems
-
+
+let private CheckDuplicatesArgNames (synVal: SynValSig) m =
+ let argNames = synVal.SynInfo.ArgNames |> List.duplicates
+ for name in argNames do
+ errorR(Error((FSComp.SR.chkDuplicatedMethodParameter(name), m)))
+
+let private CheckDuplicatesAbstractMethodParmsSig (typeSpecs: SynTypeDefnSig list) =
+ for SynTypeDefnSig(typeRepr= trepr) in typeSpecs do
+ match trepr with
+ | SynTypeDefnSigRepr.ObjectModel(_, synMemberSigs, _) ->
+ for sms in synMemberSigs do
+ match sms with
+ | SynMemberSig.Member(synValSig, _, m) ->
+ CheckDuplicatesArgNames synValSig m
+ | _ -> ()
+ | _ -> ()
module TcRecdUnionAndEnumDeclarations =
@@ -3946,7 +3961,16 @@ module TcDeclarations =
| SynMemberDefn.NestedType (range=m) :: _ -> errorR(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), m))
| _ -> ()
| ds ->
- // Classic class construction
+
+ // Check for duplicated parameters in abstract methods
+ for slot in ds do
+ if isAbstractSlot slot then
+ match slot with
+ | SynMemberDefn.AbstractSlot (synVal, _, m) ->
+ CheckDuplicatesArgNames synVal m
+ | _ -> ()
+
+ // Classic class construction
let _, ds = List.takeUntil (allFalse [isMember;isAbstractSlot;isInterface;isInherit;isField;isTycon]) ds
match ds with
| SynMemberDefn.Member (range=m) :: _ -> errorR(InternalError("CheckMembersForm: List.takeUntil is wrong", m))
@@ -3960,7 +3984,6 @@ module TcDeclarations =
| SynMemberDefn.ValField (range=m) :: _
| SynMemberDefn.NestedType (range=m) :: _ -> errorR(InternalError("CheckMembersForm: List.takeUntil is wrong", m))
| _ -> ()
-
/// Separates the definition into core (shape) and body.
///
@@ -4351,7 +4374,8 @@ let rec TcSignatureElementNonMutRec (cenv: cenv) parent typeNames endm (env: TcE
let _, _, _, env = TcExceptionDeclarations.TcExnSignature cenv env parent emptyUnscopedTyparEnv (edef, scopem)
return env
- | SynModuleSigDecl.Types (typeSpecs, m) ->
+ | SynModuleSigDecl.Types (typeSpecs, m) ->
+ CheckDuplicatesAbstractMethodParmsSig typeSpecs
let scopem = unionRanges m endm
let mutRecDefns = typeSpecs |> List.map MutRecShape.Tycon
let env = TcDeclarations.TcMutRecSignatureDecls cenv env parent typeNames emptyUnscopedTyparEnv m scopem None mutRecDefns
@@ -4521,7 +4545,8 @@ and TcSignatureElementsMutRec cenv parent typeNames m mutRecNSInfo envInitial (d
let rec loop isNamespace moduleRange defs: MutRecSigsInitialData =
((true, true), defs) ||> List.collectFold (fun (openOk, moduleAbbrevOk) def ->
match def with
- | SynModuleSigDecl.Types (typeSpecs, _) ->
+ | SynModuleSigDecl.Types (typeSpecs, _) ->
+ CheckDuplicatesAbstractMethodParmsSig typeSpecs
let decls = typeSpecs |> List.map MutRecShape.Tycon
decls, (false, false)
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index 80c356d31d..0ee05fb9db 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -1656,3 +1656,5 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form"
3546,parsExpectingPatternInTuple,"Expecting pattern"
3547,parsExpectedPatternAfterToken,"Expected a pattern after this point"
3548,matchNotAllowedForUnionCaseWithNoData,"Pattern discard is not allowed for union case that takes no data."
+3549,chkDuplicatedMethodParameter,"Duplicate parameter. The parameter '%s' has been used more that once in this method."
+
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index 45710ab5cf..3696785eb8 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -12,6 +12,11 @@
Soubor {0} má nerozpoznanou příponu. Zdrojové soubory musí mít příponu .fs, .fsi, .fsx nebo .fsscript.
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.Funkce {0} není v jazyce F# {1} dostupná. Použijte prosím jazyk verze {2} nebo vyšší.
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index ba4333b678..2af4582a1e 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -12,6 +12,11 @@
Die Dateierweiterung von „{0}“ wurde nicht erkannt. Quelldateien müssen die Erweiterung .fs, .fsi, .fsx oder .fsscript haben
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.Das Feature "{0}" ist in F# {1} nicht verfügbar. Verwenden Sie Sprachversion {2} oder höher.
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index eecf6e2f3a..bc434a73f6 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -12,6 +12,11 @@
No se reconoce la extensión de archivo de '{0}'. Los archivos de código fuente deben tener las extensiones .fs, .fsi, .fsx o .fsscript
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.La característica "{0}" no está disponible en F# {1}. Use la versión {2} del lenguaje o una posterior.
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index f3a792d36a..97c6a16eee 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -12,6 +12,11 @@
L'extension de fichier de '{0}' n'est pas reconnue. Les fichiers sources doivent avoir l'extension .fs, .fsi, .fsx, ou .fsscript.
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.La fonctionnalité '{0}' n'est pas disponible en F# {1}. Utilisez la version de langage {2} ou une version ultérieure.
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index 39577ed46e..9757bbdfd0 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -12,6 +12,11 @@
Estensione di file di '{0}' non riconosciuta. I file di origine devono avere estensione .fs, .fsi, .fsx or .fsscript
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.La funzionalità '{0}' non è disponibile in F# {1}. Usare la versione {2} o versioni successive del linguaggio.
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index a851b0056b..394e511757 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -12,6 +12,11 @@
'{0}' のファイル拡張子は認識されません。ソース ファイルの拡張子は .fs、.fsi、.fsx、または .fsscript にする必要があります。
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.機能 '{0}' は F# {1} では使用できません。{2} 以上の言語バージョンをお使いください。
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index 72cf918ed2..e00f2307a0 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -12,6 +12,11 @@
'{0}'의 파일 확장명을 인식할 수 없습니다. 원본 파일의 확장명은 .fs, .fsi, .fsx 또는 .fsscript여야 합니다.
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.'{0}' 기능은 F# {1}에서 사용할 수 없습니다. {2} 이상의 언어 버전을 사용하세요.
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index 3abd172903..9e1f501321 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -12,6 +12,11 @@
Rozszerzenie pliku "{0}" nie zostało rozpoznane. Pliki źródłowe muszą mieć rozszerzenie .fs, .fsi, .fsx lub .fsscript
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.Funkcja „{0}” nie jest dostępna w języku F# {1}. Użyj języka w wersji {2} lub nowszej.
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index eb1c7e422f..71b6fd7066 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -12,6 +12,11 @@
A extensão do arquivo de '{0}' não foi reconhecida. Os arquivos de origem devem ter a extensão .fs, .fsi, .fsx or .fsscript
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.O recurso '{0}' não está disponível no F# {1}. Use a versão da linguagem {2} ou superior.
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index e2a701653f..0311d5e08b 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -12,6 +12,11 @@
Расширение файла "{0}" не распознано. Исходные файлы должны иметь расширения FS, FSI, FSX или FSSCRIPT
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.Компонент "{0}" недоступен в F# {1}. Используйте версию языка {2} или выше.
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index 23bf49a2a8..aaf54f8415 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -12,6 +12,11 @@
'{0}' kaynak dosyasının dosya uzantısı tanınmadı. Kaynak dosyaların uzantısı .fs, .fsi, .fsx veya .fsscript olmalıdır.
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.'{0}' özelliği F# {1} sürümünde kullanılamıyor. Lütfen {2} veya daha yüksek bir dil sürümünü kullanın.
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index cb4c2e34eb..8dde976c61 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -12,6 +12,11 @@
无法识别“{0}”的文件扩展名。源文件必须具有扩展名 .fs、.fsi、.fsx 或 .fsscript
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.功能“{0}”在 F# {1} 中不可用。请使用 {2} 或更高的语言版本。
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index 7e9a9048b4..f4bd497a98 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -12,6 +12,11 @@
無法辨識 '{0}' 的副檔名。來源檔案的副檔名必須是 .fs、.fsi、.fsx 或 .fsscript。
+
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+ Duplicate parameter. The parameter '{0}' has been used more that once in this method.
+
+ Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.F# {1} 中無法使用 '{0}' 功能。請使用語言版本 {2} 或更新的版本。
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_Abstract_ReusedParam.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_Abstract_ReusedParam.fs
new file mode 100644
index 0000000000..f5c1c9cec3
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_Abstract_ReusedParam.fs
@@ -0,0 +1,11 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+type I =
+ // Tupled.
+ abstract M : i:int * i:int -> int
+ // Curried.
+ abstract N : i:int -> i:int -> int
+ // More than two.
+ abstract O : i:int * i: int * i:int -> int
+ // Multiple distinct names repeated.
+ abstract P : i:int * j:int * i:int * j:int -> int
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs
index 363e045f26..a8a1471fa4 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs
@@ -413,5 +413,153 @@ module MethodsAndProperties =
compilation
|> verifyCompileAndRun
|> shouldSucceed
+
+ // SOURCE=E_Abstract_ReusedParam.fs # E_Abstract_ReusedParam.fs
+ []
+ let ``E_Abstract_Methods_ReusedParam_fs`` compilation =
+ compilation
+ |> verifyCompile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3549, Line 5, Col 5, Line 5, Col 38, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 7, Col 5, Line 7, Col 39, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 9, Col 5, Line 9, Col 47, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'j' has been used more that once in this method.")
+ ]
+
+ []
+ let ``Error in signature file with not implementation file with abstract methods when reusing parameters`` () =
+ let encodeFsi =
+ Fsi """
+namespace Foo
+type I =
+ // Tupled.
+ abstract M : i:int * i:int -> int
+ // Curried.
+ abstract N : i:int -> i:int -> int
+ // More than two.
+ abstract O : i:int * i: int * i:int -> int
+ // Multiple distinct names repeated.
+ abstract P : i:int * j:int * i:int * j:int -> int
+ """
+ encodeFsi
+ |> verifyCompile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3549, Line 5, Col 5, Line 5, Col 38, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 7, Col 5, Line 7, Col 39, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 9, Col 5, Line 9, Col 47, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'j' has been used more that once in this method.")
+ (Error 240, Line 2, Col 1, Line 11, Col 54, "The signature file 'Test' does not have a corresponding implementation file. If an implementation file exists then check the 'module' and 'namespace' declarations in the signature and implementation files match.")
+ ]
+
+ []
+ let ``Error in signature file with not implementation file with abstract methods when reusing parameters in recursive namespace`` () =
+ let encodeFsi =
+ Fsi """
+namespace rec Foo
+type I =
+ // Tupled.
+ abstract M : i:int * i:int -> int
+ // Curried.
+ abstract N : i:int -> i:int -> int
+ // More than two.
+ abstract O : i:int * i: int * i:int -> int
+ // Multiple distinct names repeated.
+ abstract P : i:int * j:int * i:int * j:int -> int
+ """
+ encodeFsi
+ |> verifyCompile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3549, Line 5, Col 5, Line 5, Col 38, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 7, Col 5, Line 7, Col 39, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 9, Col 5, Line 9, Col 47, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'j' has been used more that once in this method.")
+ (Error 240, Line 2, Col 1, Line 11, Col 54, "The signature file 'Test' does not have a corresponding implementation file. If an implementation file exists then check the 'module' and 'namespace' declarations in the signature and implementation files match.")
+ ]
+ []
+ let ``Errors in signature and implementation files with abstract methods when reusing parameters`` () =
+ let encodeFsi =
+ Fsi """
+namespace Foo
+type I =
+ // Tupled.
+ abstract M : i:int * i:int -> int
+ // Curried.
+ abstract N : i:int -> i:int -> int
+ // More than two.
+ abstract O : i:int * i: int * i:int -> int
+ // Multiple distinct names repeated.
+ abstract P : i:int * j:int * i:int * j:int -> int
+ """
+ let encodeFs =
+ FsSource """
+namespace Foo
+type I =
+ abstract M : i:int * i:int -> int
+ abstract N : i:int -> i:int -> int
+ abstract O : i:int * i: int * i:int -> int
+ abstract P : i:int * j:int * i:int * j:int -> int
+ """
+ encodeFsi
+ |> withAdditionalSourceFile encodeFs
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3549, Line 5, Col 5, Line 5, Col 38, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 7, Col 5, Line 7, Col 39, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 9, Col 5, Line 9, Col 47, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'j' has been used more that once in this method.")
+ (Error 3549, Line 4, Col 5, Line 4, Col 38, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 5, Col 5, Line 5, Col 39, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 6, Col 5, Line 6, Col 47, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 7, Col 5, Line 7, Col 54, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 7, Col 5, Line 7, Col 54, "Duplicate parameter. The parameter 'j' has been used more that once in this method.")
+ ]
+ []
+ let ``Errors in signature and implementation files with abstract methods when reusing parameters in recursive namespaces`` () =
+ let encodeFsi =
+ Fsi """
+namespace rec Foo
+type I =
+ // Tupled.
+ abstract M : i:int * i:int -> int
+ // Curried.
+ abstract N : i:int -> i:int -> int
+ // More than two.
+ abstract O : i:int * i: int * i:int -> int
+ // Multiple distinct names repeated.
+ abstract P : i:int * j:int * i:int * j:int -> int
+ """
+ let encodeFs =
+ FsSource """
+namespace rec Foo
+type I =
+ abstract M : i:int * i:int -> int
+ abstract N : i:int -> i:int -> int
+ abstract O : i:int * i: int * i:int -> int
+ abstract P : i:int * j:int * i:int * j:int -> int
+ """
+ encodeFsi
+ |> withAdditionalSourceFile encodeFs
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3549, Line 5, Col 5, Line 5, Col 38, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 7, Col 5, Line 7, Col 39, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 9, Col 5, Line 9, Col 47, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 11, Col 5, Line 11, Col 54, "Duplicate parameter. The parameter 'j' has been used more that once in this method.")
+ (Error 3549, Line 4, Col 5, Line 4, Col 38, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 5, Col 5, Line 5, Col 39, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 6, Col 5, Line 6, Col 47, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 7, Col 5, Line 7, Col 54, "Duplicate parameter. The parameter 'i' has been used more that once in this method.")
+ (Error 3549, Line 7, Col 5, Line 7, Col 54, "Duplicate parameter. The parameter 'j' has been used more that once in this method.")
+ ]