From e7b1e44f0aa28be24dd9f7d6c6cf6dab98b1fbbd Mon Sep 17 00:00:00 2001 From: Matt D'Souza Date: Tue, 31 Oct 2017 21:09:01 -0400 Subject: [PATCH 1/7] duplicateNamedTypeArgument new error message --- .../reporting/diagnostic/ErrorMessageID.java | 3 ++- .../dotc/reporting/diagnostic/messages.scala | 7 +++++++ .../dotty/tools/dotc/typer/TypeAssigner.scala | 2 +- .../dotc/reporting/ErrorMessagesTests.scala | 20 +++++++++++++++++++ scala-backend | 2 +- 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index 09ca64e7fa8e..5a16d227284e 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -107,7 +107,8 @@ public enum ErrorMessageID { TailrecNotApplicableID, FailureToEliminateExistentialID, OnlyFunctionsCanBeFollowedByUnderscoreID, - MissingEmptyArgumentListID + MissingEmptyArgumentListID, + DuplicateNamedTypeArgumentID ; public int errorNumber() { diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 74ace0a629f2..6be7dcdabbd3 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1865,4 +1865,11 @@ object messages { |Excluded from this rule are methods that are defined in Java or that override methods defined in Java.""" } } + + case class DuplicateNamedTypeArgument(name: Name)(implicit ctx: Context) + extends Message(DuplicateNamedTypeArgumentID) { + val kind = "Syntax" + val msg = hl"Type parameter $name was defined multiple times." + val explanation = "" + } } diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 45c8a422b855..4d736a8f5631 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -371,7 +371,7 @@ trait TypeAssigner { val namedArgMap = new mutable.HashMap[Name, Type] for (NamedArg(name, arg) <- args) if (namedArgMap.contains(name)) - ctx.error("duplicate name", arg.pos) + ctx.error(DuplicateNamedTypeArgument(name), arg.pos) else if (!paramNames.contains(name)) ctx.error(s"undefined parameter name, required: ${paramNames.mkString(" or ")}", arg.pos) else diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index ca3bc6b06585..f4a68b1a7d32 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1088,4 +1088,24 @@ class ErrorMessagesTests extends ErrorMessagesTest { val MissingEmptyArgumentList(method) :: Nil = messages assertEquals("method greet", method.show) } + + @Test def duplicateNamedTypeArgument = + checkMessagesAfter("frontend") { + """ + |object Test { + | def f[A, B]() = ??? + | f[A=Any, A=Any]() + | f[B=Any, B=Any]() + |} + | + """.stripMargin + } + .expect { (ictx, messages) => + implicit val ctx: Context = ictx + + assertMessageCount(2, messages) + val DuplicateNamedTypeArgument(n2) :: DuplicateNamedTypeArgument(n1) :: Nil = messages + assertEquals("A", n1.show) + assertEquals("B", n2.show) + } } diff --git a/scala-backend b/scala-backend index 9dfe905943d0..83b68e5a1fd8 160000 --- a/scala-backend +++ b/scala-backend @@ -1 +1 @@ -Subproject commit 9dfe905943d0fc946677f75caf38d10915c185ae +Subproject commit 83b68e5a1fd80afff7f628e813796f5d81a59cc3 From aa23a8e5d3fb6cc96f0021c101c1489e04d1dc6e Mon Sep 17 00:00:00 2001 From: Matt D'Souza Date: Tue, 31 Oct 2017 21:09:01 -0400 Subject: [PATCH 2/7] duplicateNamedTypeArgument new error message --- .../reporting/diagnostic/ErrorMessageID.java | 3 ++- .../dotc/reporting/diagnostic/messages.scala | 7 +++++++ .../dotty/tools/dotc/typer/TypeAssigner.scala | 2 +- .../dotc/reporting/ErrorMessagesTests.scala | 20 +++++++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index 09ca64e7fa8e..5a16d227284e 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -107,7 +107,8 @@ public enum ErrorMessageID { TailrecNotApplicableID, FailureToEliminateExistentialID, OnlyFunctionsCanBeFollowedByUnderscoreID, - MissingEmptyArgumentListID + MissingEmptyArgumentListID, + DuplicateNamedTypeArgumentID ; public int errorNumber() { diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 74ace0a629f2..6be7dcdabbd3 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1865,4 +1865,11 @@ object messages { |Excluded from this rule are methods that are defined in Java or that override methods defined in Java.""" } } + + case class DuplicateNamedTypeArgument(name: Name)(implicit ctx: Context) + extends Message(DuplicateNamedTypeArgumentID) { + val kind = "Syntax" + val msg = hl"Type parameter $name was defined multiple times." + val explanation = "" + } } diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 45c8a422b855..4d736a8f5631 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -371,7 +371,7 @@ trait TypeAssigner { val namedArgMap = new mutable.HashMap[Name, Type] for (NamedArg(name, arg) <- args) if (namedArgMap.contains(name)) - ctx.error("duplicate name", arg.pos) + ctx.error(DuplicateNamedTypeArgument(name), arg.pos) else if (!paramNames.contains(name)) ctx.error(s"undefined parameter name, required: ${paramNames.mkString(" or ")}", arg.pos) else diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index ca3bc6b06585..f4a68b1a7d32 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1088,4 +1088,24 @@ class ErrorMessagesTests extends ErrorMessagesTest { val MissingEmptyArgumentList(method) :: Nil = messages assertEquals("method greet", method.show) } + + @Test def duplicateNamedTypeArgument = + checkMessagesAfter("frontend") { + """ + |object Test { + | def f[A, B]() = ??? + | f[A=Any, A=Any]() + | f[B=Any, B=Any]() + |} + | + """.stripMargin + } + .expect { (ictx, messages) => + implicit val ctx: Context = ictx + + assertMessageCount(2, messages) + val DuplicateNamedTypeArgument(n2) :: DuplicateNamedTypeArgument(n1) :: Nil = messages + assertEquals("A", n1.show) + assertEquals("B", n2.show) + } } From dbe80de4f13e63aef0dbb79c356ab84817a81216 Mon Sep 17 00:00:00 2001 From: Matt D'Souza Date: Tue, 31 Oct 2017 21:17:19 -0400 Subject: [PATCH 3/7] fix scala-backend submodule --- scala-backend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scala-backend b/scala-backend index 83b68e5a1fd8..9dfe905943d0 160000 --- a/scala-backend +++ b/scala-backend @@ -1 +1 @@ -Subproject commit 83b68e5a1fd80afff7f628e813796f5d81a59cc3 +Subproject commit 9dfe905943d0fc946677f75caf38d10915c185ae From 615bf48b139dccc6b24097ec4b0db21f2782fef7 Mon Sep 17 00:00:00 2001 From: Matt D'Souza Date: Tue, 31 Oct 2017 21:33:27 -0400 Subject: [PATCH 4/7] undefinedNamedTypeArgument new error message --- .../reporting/diagnostic/ErrorMessageID.java | 3 ++- .../dotc/reporting/diagnostic/messages.scala | 7 ++++++ .../dotty/tools/dotc/typer/TypeAssigner.scala | 2 +- .../dotc/reporting/ErrorMessagesTests.scala | 23 +++++++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index 5a16d227284e..ac9bbf084c2f 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -108,7 +108,8 @@ public enum ErrorMessageID { FailureToEliminateExistentialID, OnlyFunctionsCanBeFollowedByUnderscoreID, MissingEmptyArgumentListID, - DuplicateNamedTypeArgumentID + DuplicateNamedTypeArgumentID, + UndefinedNamedTypeArgumentID ; public int errorNumber() { diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 6be7dcdabbd3..67ce85ba50e5 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1872,4 +1872,11 @@ object messages { val msg = hl"Type parameter $name was defined multiple times." val explanation = "" } + + case class UndefinedNamedTypeArgument(undefinedName: Name, definedNames: List[Name])(implicit ctx: Context) + extends Message(UndefinedNamedTypeArgumentID) { + val kind = "Syntax" + val msg = hl"The type parameter $undefinedName is undefined. Expected one of ${definedNames.mkString(",")}." + val explanation = "" + } } diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 4d736a8f5631..21893632bc53 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -373,7 +373,7 @@ trait TypeAssigner { if (namedArgMap.contains(name)) ctx.error(DuplicateNamedTypeArgument(name), arg.pos) else if (!paramNames.contains(name)) - ctx.error(s"undefined parameter name, required: ${paramNames.mkString(" or ")}", arg.pos) + ctx.error(UndefinedNamedTypeArgument(name, paramNames), arg.pos) else namedArgMap(name) = preCheckKind(arg, paramBoundsByName(name.asTypeName)).tpe diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index f4a68b1a7d32..5ad03577e78e 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1108,4 +1108,27 @@ class ErrorMessagesTests extends ErrorMessagesTest { assertEquals("A", n1.show) assertEquals("B", n2.show) } + + @Test def undefinedNamedTypeArgument = + checkMessagesAfter("frontend") { + """ + |object Test { + | def f[A, B]() = ??? + | f[A=Any, C=Any]() + | f[C=Any, B=Any]() + |} + | + """.stripMargin + } + .expect { (ictx, messages) => + implicit val ctx: Context = ictx + + assertMessageCount(2, messages) + val UndefinedNamedTypeArgument(n2, l2) :: UndefinedNamedTypeArgument(n1, l1) :: Nil = messages + assertEquals("C", n1.show) + assertEquals("A"::"B"::Nil, l1.map(_.show)) + assertEquals("C", n2.show) + assertEquals("A"::"B"::Nil, l2.map(_.show)) + + } } From 45db4b88ed3e570ed7b9f2bb411199568e8b58f0 Mon Sep 17 00:00:00 2001 From: Matt D'Souza Date: Tue, 31 Oct 2017 21:45:58 -0400 Subject: [PATCH 5/7] fix typo --- .../src/dotty/tools/dotc/reporting/diagnostic/messages.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 67ce85ba50e5..3b62e0755b5b 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1876,7 +1876,7 @@ object messages { case class UndefinedNamedTypeArgument(undefinedName: Name, definedNames: List[Name])(implicit ctx: Context) extends Message(UndefinedNamedTypeArgumentID) { val kind = "Syntax" - val msg = hl"The type parameter $undefinedName is undefined. Expected one of ${definedNames.mkString(",")}." + val msg = hl"The type parameter $undefinedName is undefined. Expected one of ${definedNames.mkString(", ")}." val explanation = "" } } From 3b48a3a1354c9e0a6331a0e75442d167c611e802 Mon Sep 17 00:00:00 2001 From: Matt D'Souza Date: Tue, 31 Oct 2017 21:48:46 -0400 Subject: [PATCH 6/7] make undefined message consistent with duplicate message --- .../src/dotty/tools/dotc/reporting/diagnostic/messages.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 3b62e0755b5b..ba64e2ecf5d9 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1876,7 +1876,7 @@ object messages { case class UndefinedNamedTypeArgument(undefinedName: Name, definedNames: List[Name])(implicit ctx: Context) extends Message(UndefinedNamedTypeArgumentID) { val kind = "Syntax" - val msg = hl"The type parameter $undefinedName is undefined. Expected one of ${definedNames.mkString(", ")}." + val msg = hl"Type parameter $undefinedName is undefined. Expected one of ${definedNames.mkString(", ")}." val explanation = "" } } From 439a331e32c83607a1cde0c7371836893f68adf5 Mon Sep 17 00:00:00 2001 From: Matt D'Souza Date: Wed, 1 Nov 2017 20:41:10 -0400 Subject: [PATCH 7/7] refactor based on review --- .../dotc/reporting/diagnostic/ErrorMessageID.java | 4 ++-- .../tools/dotc/reporting/diagnostic/messages.scala | 10 +++++----- .../src/dotty/tools/dotc/typer/TypeAssigner.scala | 4 ++-- .../tools/dotc/reporting/ErrorMessagesTests.scala | 13 +++++++------ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index ac9bbf084c2f..d4920b5665a8 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -108,8 +108,8 @@ public enum ErrorMessageID { FailureToEliminateExistentialID, OnlyFunctionsCanBeFollowedByUnderscoreID, MissingEmptyArgumentListID, - DuplicateNamedTypeArgumentID, - UndefinedNamedTypeArgumentID + DuplicateNamedTypeParameterID, + UndefinedNamedTypeParameterID ; public int errorNumber() { diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index ba64e2ecf5d9..4305f9594b68 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1866,17 +1866,17 @@ object messages { } } - case class DuplicateNamedTypeArgument(name: Name)(implicit ctx: Context) - extends Message(DuplicateNamedTypeArgumentID) { + case class DuplicateNamedTypeParameter(name: Name)(implicit ctx: Context) + extends Message(DuplicateNamedTypeParameterID) { val kind = "Syntax" val msg = hl"Type parameter $name was defined multiple times." val explanation = "" } - case class UndefinedNamedTypeArgument(undefinedName: Name, definedNames: List[Name])(implicit ctx: Context) - extends Message(UndefinedNamedTypeArgumentID) { + case class UndefinedNamedTypeParameter(undefinedName: Name, definedNames: List[Name])(implicit ctx: Context) + extends Message(UndefinedNamedTypeParameterID) { val kind = "Syntax" - val msg = hl"Type parameter $undefinedName is undefined. Expected one of ${definedNames.mkString(", ")}." + val msg = hl"Type parameter $undefinedName is undefined. Expected one of ${definedNames.map(_.show).mkString(", ")}." val explanation = "" } } diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 21893632bc53..338f0c2da0bf 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -371,9 +371,9 @@ trait TypeAssigner { val namedArgMap = new mutable.HashMap[Name, Type] for (NamedArg(name, arg) <- args) if (namedArgMap.contains(name)) - ctx.error(DuplicateNamedTypeArgument(name), arg.pos) + ctx.error(DuplicateNamedTypeParameter(name), arg.pos) else if (!paramNames.contains(name)) - ctx.error(UndefinedNamedTypeArgument(name, paramNames), arg.pos) + ctx.error(UndefinedNamedTypeParameter(name, paramNames), arg.pos) else namedArgMap(name) = preCheckKind(arg, paramBoundsByName(name.asTypeName)).tpe diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index 5ad03577e78e..1f8c65a874f7 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1089,7 +1089,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { assertEquals("method greet", method.show) } - @Test def duplicateNamedTypeArgument = + @Test def duplicateNamedTypeParameter = checkMessagesAfter("frontend") { """ |object Test { @@ -1104,12 +1104,12 @@ class ErrorMessagesTests extends ErrorMessagesTest { implicit val ctx: Context = ictx assertMessageCount(2, messages) - val DuplicateNamedTypeArgument(n2) :: DuplicateNamedTypeArgument(n1) :: Nil = messages + val DuplicateNamedTypeParameter(n2) :: DuplicateNamedTypeParameter(n1) :: Nil = messages assertEquals("A", n1.show) assertEquals("B", n2.show) } - @Test def undefinedNamedTypeArgument = + @Test def undefinedNamedTypeParameter = checkMessagesAfter("frontend") { """ |object Test { @@ -1124,11 +1124,12 @@ class ErrorMessagesTests extends ErrorMessagesTest { implicit val ctx: Context = ictx assertMessageCount(2, messages) - val UndefinedNamedTypeArgument(n2, l2) :: UndefinedNamedTypeArgument(n1, l1) :: Nil = messages + val UndefinedNamedTypeParameter(n2, l2) :: UndefinedNamedTypeParameter(n1, l1) :: Nil = messages + val tpParams = List("A", "B") assertEquals("C", n1.show) - assertEquals("A"::"B"::Nil, l1.map(_.show)) + assertEquals(tpParams, l1.map(_.show)) assertEquals("C", n2.show) - assertEquals("A"::"B"::Nil, l2.map(_.show)) + assertEquals(tpParams, l2.map(_.show)) } }