Skip to content

Commit af66de4

Browse files
committed
Fix #7078: Allow <: T in given alias definitions
1 parent 19b4216 commit af66de4

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ object Parsers {
907907
lookahead.nextToken()
908908
while lookahead.token == LPAREN || lookahead.token == LBRACKET do
909909
lookahead.skipParens()
910-
lookahead.token == COLON
910+
lookahead.token == COLON || lookahead.token == SUBTYPE
911911

912912
/* --------- OPERAND/OPERATOR STACK --------------------------------------- */
913913

@@ -3232,7 +3232,7 @@ object Parsers {
32323232
case ENUM =>
32333233
enumDef(start, posMods(start, mods | Enum))
32343234
case GIVEN =>
3235-
instanceDef(start, mods, atSpan(in.skipToken()) { Mod.Given() })
3235+
givenDef(start, mods, atSpan(in.skipToken()) { Mod.Given() })
32363236
case _ =>
32373237
syntaxErrorOrIncomplete(ExpectedStartOfTopLevelDefinition())
32383238
EmptyTree
@@ -3336,19 +3336,13 @@ object Parsers {
33363336
syntaxError(em"extension clause must start with a single regular parameter", start)
33373337

33383338

3339-
/** OLD:
3340-
* GivenDef ::= [id] [DefTypeParamClause] GivenBody
3341-
* GivenBody ::= [‘as ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody]
3342-
* | ‘as’ Type {GivenParamClause} ‘=’ Expr
3343-
* | ‘(’ DefParam ‘)’ TemplateBody
3344-
* NEW:
3345-
* GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
3339+
/** GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
33463340
* | [GivenSig ‘:’] [ConstrApp {‘,’ ConstrApp }] [TemplateBody]
33473341
* | [id ‘:’] [ExtParamClause] TemplateBody
33483342
* GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause}
33493343
* ExtParamClause ::= [DefTypeParamClause] DefParamClause {GivenParamClause}
33503344
*/
3351-
def instanceDef(start: Offset, mods: Modifiers, instanceMod: Mod) = atSpan(start, nameStart) {
3345+
def givenDef(start: Offset, mods: Modifiers, instanceMod: Mod) = atSpan(start, nameStart) {
33523346
var mods1 = addMod(mods, instanceMod)
33533347
val hasGivenSig = followingIsGivenSig()
33543348
val name = if isIdent && hasGivenSig then ident() else EmptyTermName
@@ -3382,6 +3376,11 @@ object Parsers {
33823376
Nil
33833377
else
33843378
tokenSeparated(COMMA, constrApp)
3379+
else if in.token == SUBTYPE then
3380+
if !mods.is(Inline) then
3381+
syntaxError("`<:' is only allowed for given with `inline' modifier")
3382+
in.nextToken()
3383+
TypeBoundsTree(EmptyTree, toplevelTyp()) :: Nil
33853384
else if name.isEmpty && in.token != LBRACE then
33863385
tokenSeparated(COMMA, constrApp)
33873386
else Nil
@@ -3392,7 +3391,9 @@ object Parsers {
33923391
mods1 |= Final
33933392
DefDef(name, tparams, vparamss, parents.head, subExpr())
33943393
else
3395-
//println(i"given $name $hasExtensionParams $hasGivenSig")
3394+
parents match
3395+
case TypeBoundsTree(_, _) :: _ => syntaxError("`=' expected")
3396+
case _ =>
33963397
possibleTemplateStart()
33973398
if !hasExtensionParams then
33983399
tparams = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal))

tests/neg/i7078.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
trait A
2+
class B extends A
3+
4+
given g1 <: A = B() // error: `<:' is only allowed for given with `inline' modifier // error
5+
6+
inline given g2 <: A // error: <: A is not a class type
7+
def foo = 2 // error: `=' expected
8+

tests/pos/i7078.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
trait A
2+
class B extends A
3+
4+
inline given tc <: A = B()
5+
6+
val x: B = summon[A]
7+

0 commit comments

Comments
 (0)