From 55b36ea99beeadc4ccbcb86217582abd7de9c385 Mon Sep 17 00:00:00 2001 From: Jan-Pieter van den Heuvel Date: Mon, 24 Feb 2025 18:44:57 +0100 Subject: [PATCH] Disallow context bounds in type lambdas --- .../dotty/tools/dotc/parsing/Parsers.scala | 20 ++++++++++++++++--- tests/neg/i22552.check | 8 ++++++++ tests/neg/i22552.scala | 5 +++++ 3 files changed, 30 insertions(+), 3 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 cfb132dd95ce..5ec2e2da3053 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1798,8 +1798,22 @@ object Parsers { val start = in.offset val tparams = typeParamClause(ParamOwner.Type) if in.token == TLARROW then - atSpan(start, in.skipToken()): - LambdaTypeTree(tparams, toplevelTyp()) + val hasContextBounds = tparams.exists(_.rhs match { + case x: ContextBounds => true + case _ => false + }) + if hasContextBounds then + // Filter illegal context bounds and report syntax error + atSpan(start, in.skipToken()): + LambdaTypeTree(tparams.map { + case TypeDef(name, rhs: ContextBounds) => + syntaxError(em"context bounds are not allowed in type lambdas", rhs.span) + TypeDef(name, TypeBoundsTree(EmptyTree, EmptyTree)) + case other => other + }, toplevelTyp()) + else + atSpan(start, in.skipToken()): + LambdaTypeTree(tparams, toplevelTyp()) else if in.token == ARROW || isPureArrow(nme.PUREARROW) then val arrowOffset = in.skipToken() val body = toplevelTyp(nestedIntoOK(in.token)) @@ -3475,7 +3489,7 @@ object Parsers { * * HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’ * HkTypeParam ::= {Annotation} [‘+’ | ‘-’] - * (id | ‘_’) [HkTypePamClause] TypeBounds + * (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