diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index ef97720368ce..5e892eac8a93 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -60,6 +60,7 @@ public enum ErrorMessageID { MethodDoesNotTakeParametersId, AmbiguousOverloadID, ReassignmentToValID, + TypeDoesNotTakeParametersID, ; 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 f46030965681..5d16406ef4a8 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -19,6 +19,7 @@ import printing.Highlighting._ import printing.Formatting import ErrorMessageID._ import Denotations.SingleDenotation +import dotty.tools.dotc.ast.Trees import dotty.tools.dotc.core.SymDenotations.SymDenotation object messages { @@ -1277,7 +1278,7 @@ object messages { |$noParameters""".stripMargin } - + case class AmbiguousOverload(tree: tpd.Tree, alts: List[SingleDenotation], pt: Type)( err: typer.ErrorReporting.Errors)( implicit ctx: Context) @@ -1296,7 +1297,7 @@ object messages { |- adding a type ascription as in `${"instance.myMethod: String => Int"}` |""" } - + case class ReassignmentToVal(name: Names.Name)(implicit ctx: Context) extends Message(ReassignmentToValID) { val kind = "Reference" @@ -1310,4 +1311,19 @@ object messages { | ${"var"} $name ${"="} ... |""".stripMargin } + + case class TypeDoesNotTakeParameters(tpe: Types.Type, params: List[Trees.Tree[Trees.Untyped]])(implicit ctx: Context) + extends Message(TypeDoesNotTakeParametersID) { + val kind = "Reference" + val msg = hl"$tpe does not take type parameters" + + private val ps = + if (params.size == 1) hl"a type parameter ${params.head}" + else hl"type parameters ${params.map(_.show).mkString(", ")}" + + val explanation = + i"""You specified $ps for ${hl"$tpe"}, which is not + |declared to take any. + |""" + } } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 69140fcd0204..b1b39606c693 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1052,7 +1052,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val tpt1 = typed(tree.tpt, AnyTypeConstructorProto)(ctx.retractMode(Mode.Pattern)) val tparams = tpt1.tpe.typeParams if (tparams.isEmpty) { - ctx.error(ex"${tpt1.tpe} does not take type parameters", tree.pos) + ctx.error(TypeDoesNotTakeParameters(tpt1.tpe, tree.args), tree.pos) tpt1 } else { diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index cc0c53aad017..586450cf2eb5 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -399,7 +399,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { assertEquals("Scope.foo(1)", tree.show) assertEquals("((a: Int)Unit)(Scope.foo)", methodPart.show) } - + @Test def ambiugousOverloadWithWildcard = checkMessagesAfter("frontend") { """object Context { @@ -440,4 +440,21 @@ class ErrorMessagesTests extends ErrorMessagesTest { val ReassignmentToVal(name) :: Nil = messages assertEquals("value", name.show) } + + @Test def typeDoesNotTakeParameters = + checkMessagesAfter("frontend") { + """ + |trait WithOutParams + |class Extending extends WithOutParams[String] + """.stripMargin + } + .expect { (ictx, messages) => + implicit val ctx: Context = ictx + val defn = ictx.definitions + + assertMessageCount(1, messages) + val TypeDoesNotTakeParameters(tpe, params) :: Nil = messages + assertEquals("WithOutParams", tpe.show) + } + }