Skip to content

Commit 0b10433

Browse files
authored
Merge pull request #7334 from dotty-staging/fix-#7078
Fix #7078: Allow <: T in given alias definitions
2 parents c1ba7e7 + af66de4 commit 0b10433

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

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

+12-11
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ object Parsers {
903903
lookahead.nextToken()
904904
while lookahead.token == LPAREN || lookahead.token == LBRACKET do
905905
lookahead.skipParens()
906-
lookahead.token == COLON
906+
lookahead.token == COLON || lookahead.token == SUBTYPE
907907

908908
/* --------- OPERAND/OPERATOR STACK --------------------------------------- */
909909

@@ -3238,7 +3238,7 @@ object Parsers {
32383238
case ENUM =>
32393239
enumDef(start, posMods(start, mods | Enum))
32403240
case GIVEN =>
3241-
instanceDef(start, mods, atSpan(in.skipToken()) { Mod.Given() })
3241+
givenDef(start, mods, atSpan(in.skipToken()) { Mod.Given() })
32423242
case _ =>
32433243
syntaxErrorOrIncomplete(ExpectedStartOfTopLevelDefinition())
32443244
EmptyTree
@@ -3342,19 +3342,13 @@ object Parsers {
33423342
syntaxError(em"extension clause must start with a single regular parameter", start)
33433343

33443344

3345-
/** OLD:
3346-
* GivenDef ::= [id] [DefTypeParamClause] GivenBody
3347-
* GivenBody ::= [‘as ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody]
3348-
* | ‘as’ Type {GivenParamClause} ‘=’ Expr
3349-
* | ‘(’ DefParam ‘)’ TemplateBody
3350-
* NEW:
3351-
* GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
3345+
/** GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
33523346
* | [GivenSig ‘:’] [ConstrApp {‘,’ ConstrApp }] [TemplateBody]
33533347
* | [id ‘:’] [ExtParamClause] TemplateBody
33543348
* GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause}
33553349
* ExtParamClause ::= [DefTypeParamClause] DefParamClause {GivenParamClause}
33563350
*/
3357-
def instanceDef(start: Offset, mods: Modifiers, instanceMod: Mod) = atSpan(start, nameStart) {
3351+
def givenDef(start: Offset, mods: Modifiers, instanceMod: Mod) = atSpan(start, nameStart) {
33583352
var mods1 = addMod(mods, instanceMod)
33593353
val hasGivenSig = followingIsGivenSig()
33603354
val name = if isIdent && hasGivenSig then ident() else EmptyTermName
@@ -3388,6 +3382,11 @@ object Parsers {
33883382
Nil
33893383
else
33903384
tokenSeparated(COMMA, constrApp)
3385+
else if in.token == SUBTYPE then
3386+
if !mods.is(Inline) then
3387+
syntaxError("`<:' is only allowed for given with `inline' modifier")
3388+
in.nextToken()
3389+
TypeBoundsTree(EmptyTree, toplevelTyp()) :: Nil
33913390
else if name.isEmpty && in.token != LBRACE then
33923391
tokenSeparated(COMMA, constrApp)
33933392
else Nil
@@ -3398,7 +3397,9 @@ object Parsers {
33983397
mods1 |= Final
33993398
DefDef(name, tparams, vparamss, parents.head, subExpr())
34003399
else
3401-
//println(i"given $name $hasExtensionParams $hasGivenSig")
3400+
parents match
3401+
case TypeBoundsTree(_, _) :: _ => syntaxError("`=' expected")
3402+
case _ =>
34023403
possibleTemplateStart()
34033404
if !hasExtensionParams then
34043405
tparams = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal))

tests/neg/i7078.scala

+8
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

+7
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)