From 164720f287dc569c3e6604fbc8cf51bcc565561a Mon Sep 17 00:00:00 2001 From: Jan-Pieter van den Heuvel Date: Sun, 13 Apr 2025 18:11:39 +0200 Subject: [PATCH 1/2] Disallow context bounds in type lambdas (#22659) Fixes #22552 --------- Co-authored-by: Natsu Kagami --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 13 +++++++++++-- tests/neg/i22552.check | 8 ++++++++ tests/neg/i22552.scala | 5 +++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/neg/i22552.check create mode 100644 tests/neg/i22552.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 47389fbce054..e92ef2f7ce69 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1677,8 +1677,9 @@ object Parsers { val start = in.offset val tparams = typeParamClause(ParamOwner.TypeParam) if in.token == TLARROW then + // Filter illegal context bounds and report syntax error atSpan(start, in.skipToken()): - LambdaTypeTree(tparams, toplevelTyp()) + LambdaTypeTree(tparams.mapConserve(stripContextBounds("type lambdas")), toplevelTyp()) else if in.token == ARROW || isPureArrow(nme.PUREARROW) then val arrowOffset = in.skipToken() val body = toplevelTyp() @@ -1699,6 +1700,13 @@ object Parsers { typeRest(infixType()) end typ + /** Removes context bounds from TypeDefs and returns a syntax error. */ + private def stripContextBounds(in: String)(tparam: TypeDef) = tparam match + case TypeDef(name, rhs: ContextBounds) => + syntaxError(em"context bounds are not allowed in $in", rhs.span) + TypeDef(name, rhs.bounds) + case other => other + private def makeKindProjectorTypeDef(name: TypeName): TypeDef = { val isVarianceAnnotated = name.startsWith("+") || name.startsWith("-") // We remove the variance marker from the name without passing along the specified variance at all @@ -3267,7 +3275,8 @@ object Parsers { * TypTypeParam ::= {Annotation} id [HkTypePamClause] TypeBounds * * HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’ - * HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypePamClause] | ‘_’) TypeBounds + * HkTypeParam ::= {Annotation} [‘+’ | ‘-’] + * (id | ‘_’) [HkTypeParamClause] TypeBounds */ def typeParamClause(paramOwner: ParamOwner): List[TypeDef] = inBracketsWithCommas { diff --git a/tests/neg/i22552.check b/tests/neg/i22552.check new file mode 100644 index 000000000000..7a9b6c9800c7 --- /dev/null +++ b/tests/neg/i22552.check @@ -0,0 +1,8 @@ +-- [E040] Syntax Error: tests/neg/i22552.scala:3:10 -------------------------------------------------------------------- +3 | type A[X: TC] // error + | ^ + | ']' expected, but ':' found +-- Error: tests/neg/i22552.scala:4:15 ---------------------------------------------------------------------------------- +4 | type C = [X: TC] =>> List[X] // error + | ^^ + | context bounds are not allowed in type lambdas diff --git a/tests/neg/i22552.scala b/tests/neg/i22552.scala new file mode 100644 index 000000000000..5ac7840a3a96 --- /dev/null +++ b/tests/neg/i22552.scala @@ -0,0 +1,5 @@ +trait Foo: + type TC[T] + type A[X: TC] // error + type C = [X: TC] =>> List[X] // error + type D = [X: TC] => () => List[X] // allowed context bound From 3c8c16b7c17bda26de3b61a5c52d8cd65632b3da Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Mon, 28 Apr 2025 10:59:18 +0200 Subject: [PATCH 2/2] Disallow context bounds in type lambdas (#22659) Fixes #22552 --------- Co-authored-by: Natsu Kagami [Cherry-picked 5b4b5c21b791d592f4bd2218485a11c50a48e538][modified]