Skip to content

Commit

Permalink
Allow vals in using clauses of givens
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky committed May 7, 2024
1 parent 34f17b7 commit 31c9e8a
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ object Parsers {
case ExtensionFollow // extension clause, following extension parameter

def isClass = // owner is a class
this == Class || this == CaseClass
this == Class || this == CaseClass || this == Given
def takesOnlyUsingClauses = // only using clauses allowed for this owner
this == Given || this == ExtensionFollow
def acceptsVariance =
Expand Down Expand Up @@ -3372,7 +3372,7 @@ object Parsers {
val isAbstractOwner = paramOwner == ParamOwner.Type || paramOwner == ParamOwner.TypeParam
val start = in.offset
var mods = annotsAsMods() | Param
if paramOwner == ParamOwner.Class || paramOwner == ParamOwner.CaseClass then
if paramOwner.isClass then
mods |= PrivateLocal
if isIdent(nme.raw.PLUS) && checkVarianceOK() then
mods |= Covariant
Expand Down Expand Up @@ -4100,6 +4100,14 @@ object Parsers {
val nameStart = in.offset
val name = if isIdent && followingIsGivenSig() then ident() else EmptyTermName

// TODO Change syntax description
def adjustDefParams(paramss: List[ParamClause]): List[ParamClause] =
paramss.nestedMap: param =>
if !param.mods.isAllOf(PrivateLocal) then
syntaxError(em"method parameter ${param.name} may not be `a val`", param.span)
param.withMods(param.mods &~ (AccessFlags | ParamAccessor | Mutable) | Param)
.asInstanceOf[List[ParamClause]]

val gdef =
val tparams = typeParamClauseOpt(ParamOwner.Given)
newLineOpt()
Expand All @@ -4121,16 +4129,17 @@ object Parsers {
mods1 |= Lazy
ValDef(name, parents.head, subExpr())
else
DefDef(name, joinParams(tparams, vparamss), parents.head, subExpr())
DefDef(name, adjustDefParams(joinParams(tparams, vparamss)), parents.head, subExpr())
else if (isStatSep || isStatSeqEnd) && parentsIsType then
if name.isEmpty then
syntaxError(em"anonymous given cannot be abstract")
DefDef(name, joinParams(tparams, vparamss), parents.head, EmptyTree)
DefDef(name, adjustDefParams(joinParams(tparams, vparamss)), parents.head, EmptyTree)
else
val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal))
val vparamss1 = vparamss.map(_.map(vparam =>
vparam.withMods(vparam.mods &~ Param | ParamAccessor | Protected)))
val constr = makeConstructor(tparams1, vparamss1)
val vparamss1 = vparamss.nestedMap: vparam =>
if vparam.mods.is(Private)
then vparam.withMods(vparam.mods &~ PrivateLocal | Protected)
else vparam
val constr = makeConstructor(tparams, vparamss1)
val templ =
if isStatSep || isStatSeqEnd then Template(constr, parents, Nil, EmptyValDef, Nil)
else withTemplate(constr, parents)
Expand Down

0 comments on commit 31c9e8a

Please sign in to comment.