From 7294607fed48226f1237ad1db53d8dd9cab16921 Mon Sep 17 00:00:00 2001 From: Hamza Remmal Date: Mon, 19 May 2025 18:00:54 +0200 Subject: [PATCH] chore: have a better error message when context bounds are not allowed Co-authored-by: ajafri2001 Co-authored-by: jan-pieter --- .../src/dotty/tools/dotc/parsing/Parsers.scala | 14 ++++++++------ .../tools/dotc/reporting/ErrorMessageID.scala | 1 + .../src/dotty/tools/dotc/reporting/messages.scala | 8 ++++++++ tests/neg/i22552.check | 6 +++--- tests/neg/i22660.check | 4 ++++ tests/neg/i22660.scala | 2 ++ 6 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 tests/neg/i22660.check create mode 100644 tests/neg/i22660.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 9c081c8d21af..3185fcb4de16 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -68,8 +68,8 @@ object Parsers { this == Given || this == ExtensionFollow def acceptsVariance = this == Class || this == CaseClass || this == Hk - def acceptsCtxBounds = - !(this == Type || this == Hk) + def acceptsCtxBounds(using Context) = + !(this == Type || this == Hk) || (sourceVersion.enablesNewGivens && this == Type) def acceptsWildcard = this == Type || this == Hk @@ -3549,10 +3549,12 @@ object Parsers { else ident().toTypeName val isCap = gobbleHat() val hkparams = typeParamClauseOpt(ParamOwner.Hk) - val bounds = - if paramOwner.acceptsCtxBounds then typeAndCtxBounds(name) - else if sourceVersion.enablesNewGivens && paramOwner == ParamOwner.Type then typeAndCtxBounds(name) - else typeBounds() + val bounds = typeAndCtxBounds(name) match + case bounds: TypeBoundsTree => bounds + case bounds: ContextBounds if paramOwner.acceptsCtxBounds => bounds + case ContextBounds(bounds, cxBounds) => + for cbound <- cxBounds do report.error(IllegalContextBounds(), cbound.srcPos) + bounds val res = TypeDef(name, lambdaAbstract(hkparams, bounds)).withMods(mods) if isCap then res.pushAttachment(CaptureVar, ()) diff --git a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala index 3f95789789bd..035f1fa1ab48 100644 --- a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala +++ b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala @@ -227,6 +227,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe case MatchIsNotPartialFunctionID // errorNumber: 211 case OnlyFullyDependentAppliedConstructorTypeID // errorNumber: 212 case PointlessAppliedConstructorTypeID // errorNumber: 213 + case IllegalContextBoundsID // errorNumber: 214 def errorNumber = ordinal - 1 diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 4446c38d29cc..d1516a5df52a 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -3510,3 +3510,11 @@ final class OnlyFullyDependentAppliedConstructorType()(using Context) i"Applied constructor type can only be used with classes where all parameters in the first parameter list are tracked" override protected def explain(using Context): String = "" + +final class IllegalContextBounds(using Context) extends SyntaxMsg(IllegalContextBoundsID): + override protected def msg(using Context): String = + i"Context bounds are not allowed in this position" + + override protected def explain(using Context): String = "" + +end IllegalContextBounds \ No newline at end of file diff --git a/tests/neg/i22552.check b/tests/neg/i22552.check index 7a9b6c9800c7..fe4f36aa2caf 100644 --- a/tests/neg/i22552.check +++ b/tests/neg/i22552.check @@ -1,7 +1,7 @@ --- [E040] Syntax Error: tests/neg/i22552.scala:3:10 -------------------------------------------------------------------- +-- [E214] Syntax Error: tests/neg/i22552.scala:3:14 -------------------------------------------------------------------- 3 | type A[X: TC] // error - | ^ - | ']' expected, but ':' found + | ^^ + | Context bounds are not allowed in this position -- Error: tests/neg/i22552.scala:4:15 ---------------------------------------------------------------------------------- 4 | type C = [X: TC] =>> List[X] // error | ^^ diff --git a/tests/neg/i22660.check b/tests/neg/i22660.check new file mode 100644 index 000000000000..309979bf1147 --- /dev/null +++ b/tests/neg/i22660.check @@ -0,0 +1,4 @@ +-- [E214] Syntax Error: tests/neg/i22660.scala:2:21 -------------------------------------------------------------------- +2 |type Foo[T: Equatable] // error + | ^^^^^^^^^ + | Context bounds are not allowed in this position diff --git a/tests/neg/i22660.scala b/tests/neg/i22660.scala new file mode 100644 index 000000000000..650ceac4f48c --- /dev/null +++ b/tests/neg/i22660.scala @@ -0,0 +1,2 @@ +trait Equatable[T] +type Foo[T: Equatable] // error