Skip to content

Commit c123c20

Browse files
committed
Align Parser with syntax
- Change doc comments to match described syntax - Refactor `typ` method to make it clear it matches the syntax [Cherry-picked 6a9bea8][modified]
1 parent 91f0501 commit c123c20

File tree

3 files changed

+91
-98
lines changed

3 files changed

+91
-98
lines changed

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

Lines changed: 87 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,13 +1521,15 @@ object Parsers {
15211521
* PolyFunType ::= HKTypeParamClause '=>' Type
15221522
* | HKTypeParamClause ‘->’ [CaptureSet] Type -- under pureFunctions
15231523
* FunTypeArgs ::= InfixType
1524-
* | `(' [ [ ‘['erased'] FunArgType {`,' FunArgType } ] `)'
1525-
* | '(' [ ‘['erased'] TypedFunParam {',' TypedFunParam } ')'
1524+
* | `(' [ FunArgType {`,' FunArgType } ] `)'
1525+
* | '(' [ TypedFunParam {',' TypedFunParam } ')'
1526+
* MatchType ::= InfixType `match` <<< TypeCaseClauses >>>
15261527
*/
15271528
def typ(): Tree =
15281529
val start = in.offset
15291530
var imods = Modifiers()
15301531
var erasedArgs: ListBuffer[Boolean] = ListBuffer()
1532+
15311533
def functionRest(params: List[Tree]): Tree =
15321534
val paramSpan = Span(start, in.lastOffset)
15331535
atSpan(start, in.offset) {
@@ -1556,7 +1558,8 @@ object Parsers {
15561558
else
15571559
accept(ARROW)
15581560

1559-
val resultType = if isPure then capturesAndResult(typ) else typ()
1561+
val resultType =
1562+
if isPure then capturesAndResult(typ) else typ()
15601563
if token == TLARROW then
15611564
for case ValDef(_, tpt, _) <- params do
15621565
if isByNameType(tpt) then
@@ -1573,99 +1576,94 @@ object Parsers {
15731576
Function(params, resultType)
15741577
}
15751578

1576-
var isValParamList = false
1579+
def typeRest(t: Tree) = in.token match
1580+
case ARROW | CTXARROW =>
1581+
erasedArgs.addOne(false)
1582+
functionRest(t :: Nil)
1583+
case MATCH =>
1584+
matchType(t)
1585+
case FORSOME =>
1586+
syntaxError(ExistentialTypesNoLongerSupported())
1587+
t
1588+
case _ if isPureArrow =>
1589+
erasedArgs.addOne(false)
1590+
functionRest(t :: Nil)
1591+
case _ =>
1592+
if erasedArgs.contains(true) && !t.isInstanceOf[FunctionWithMods] then
1593+
syntaxError(ErasedTypesCanOnlyBeFunctionTypes(), implicitKwPos(start))
1594+
t
15771595

1578-
val t =
1579-
if (in.token == LPAREN) {
1596+
var isValParamList = false
1597+
if in.token == LPAREN then
1598+
in.nextToken()
1599+
if in.token == RPAREN then
15801600
in.nextToken()
1581-
if (in.token == RPAREN) {
1582-
in.nextToken()
1583-
functionRest(Nil)
1584-
}
1585-
else {
1586-
val paramStart = in.offset
1587-
def addErased() =
1588-
erasedArgs.addOne(isErasedKw)
1589-
if isErasedKw then { in.skipToken(); }
1590-
addErased()
1591-
val ts = in.currentRegion.withCommasExpected {
1601+
functionRest(Nil)
1602+
else
1603+
val paramStart = in.offset
1604+
def addErased() =
1605+
erasedArgs.addOne(isErasedKw)
1606+
if isErasedKw then in.skipToken()
1607+
addErased()
1608+
val args =
1609+
in.currentRegion.withCommasExpected:
15921610
funArgType() match
15931611
case Ident(name) if name != tpnme.WILDCARD && in.isColon =>
15941612
isValParamList = true
1595-
def funParam(start: Offset, mods: Modifiers) = {
1596-
atSpan(start) {
1613+
def funParam(start: Offset, mods: Modifiers) =
1614+
atSpan(start):
15971615
addErased()
15981616
typedFunParam(in.offset, ident(), imods)
1599-
}
1600-
}
16011617
commaSeparatedRest(
16021618
typedFunParam(paramStart, name.toTermName, imods),
16031619
() => funParam(in.offset, imods))
16041620
case t =>
1605-
def funParam() = {
1606-
addErased()
1607-
funArgType()
1608-
}
1609-
commaSeparatedRest(t, funParam)
1610-
}
1611-
accept(RPAREN)
1612-
if isValParamList || in.isArrow || isPureArrow then
1613-
functionRest(ts)
1614-
else {
1615-
val ts1 = ts.mapConserve { t =>
1616-
if isByNameType(t) then
1617-
syntaxError(ByNameParameterNotSupported(t), t.span)
1618-
stripByNameType(t)
1619-
else
1620-
t
1621-
}
1622-
val tuple = atSpan(start) { makeTupleOrParens(ts1) }
1623-
infixTypeRest(
1624-
refinedTypeRest(
1625-
withTypeRest(
1626-
annotTypeRest(
1627-
simpleTypeRest(tuple)))))
1628-
}
1629-
}
1630-
}
1631-
else if (in.token == LBRACKET) {
1632-
val start = in.offset
1633-
val tparams = typeParamClause(ParamOwner.TypeParam)
1634-
if (in.token == TLARROW)
1635-
atSpan(start, in.skipToken())(LambdaTypeTree(tparams, toplevelTyp()))
1636-
else if (in.token == ARROW || isPureArrow(nme.PUREARROW)) {
1637-
val arrowOffset = in.skipToken()
1638-
val body = toplevelTyp()
1639-
atSpan(start, arrowOffset) {
1640-
getFunction(body) match {
1641-
case Some(f) =>
1642-
checkFunctionNotErased(f, "poly function")
1643-
PolyFunction(tparams, body)
1644-
case None =>
1645-
syntaxError(em"Implementation restriction: polymorphic function types must have a value parameter", arrowOffset)
1646-
Ident(nme.ERROR.toTypeName)
1647-
}
1648-
}
1649-
}
1650-
else { accept(TLARROW); typ() }
1651-
}
1652-
else if (in.token == INDENT) enclosed(INDENT, typ())
1653-
else infixType()
1654-
1655-
in.token match
1656-
case ARROW | CTXARROW =>
1657-
erasedArgs.addOne(false)
1658-
functionRest(t :: Nil)
1659-
case MATCH => matchType(t)
1660-
case FORSOME => syntaxError(ExistentialTypesNoLongerSupported()); t
1661-
case _ =>
1662-
if isPureArrow then
1663-
erasedArgs.addOne(false)
1664-
functionRest(t :: Nil)
1621+
def funArg() =
1622+
addErased()
1623+
funArgType()
1624+
commaSeparatedRest(t, funArg)
1625+
accept(RPAREN)
1626+
if isValParamList || in.isArrow || isPureArrow then
1627+
functionRest(args)
16651628
else
1666-
if (erasedArgs.contains(true) && !t.isInstanceOf[FunctionWithMods])
1667-
syntaxError(ErasedTypesCanOnlyBeFunctionTypes(), implicitKwPos(start))
1668-
t
1629+
val args1 = args.mapConserve: t =>
1630+
if isByNameType(t) then
1631+
syntaxError(ByNameParameterNotSupported(t), t.span)
1632+
stripByNameType(t)
1633+
else
1634+
t
1635+
val tuple = atSpan(start):
1636+
makeTupleOrParens(args1)
1637+
typeRest:
1638+
infixTypeRest:
1639+
refinedTypeRest:
1640+
withTypeRest:
1641+
annotTypeRest:
1642+
simpleTypeRest(tuple)
1643+
else if in.token == LBRACKET then
1644+
val start = in.offset
1645+
val tparams = typeParamClause(ParamOwner.TypeParam)
1646+
if in.token == TLARROW then
1647+
atSpan(start, in.skipToken()):
1648+
LambdaTypeTree(tparams, toplevelTyp())
1649+
else if in.token == ARROW || isPureArrow(nme.PUREARROW) then
1650+
val arrowOffset = in.skipToken()
1651+
val body = toplevelTyp()
1652+
atSpan(start, arrowOffset):
1653+
getFunction(body) match
1654+
case Some(f) =>
1655+
checkFunctionNotErased(f, "poly function")
1656+
PolyFunction(tparams, body)
1657+
case None =>
1658+
syntaxError(em"Implementation restriction: polymorphic function types must have a value parameter", arrowOffset)
1659+
Ident(nme.ERROR.toTypeName)
1660+
else
1661+
accept(TLARROW)
1662+
typ()
1663+
else if in.token == INDENT then
1664+
enclosed(INDENT, typ())
1665+
else
1666+
typeRest(infixType())
16691667
end typ
16701668

16711669
private def makeKindProjectorTypeDef(name: TypeName): TypeDef = {
@@ -1702,7 +1700,7 @@ object Parsers {
17021700
private def implicitKwPos(start: Int): Span =
17031701
Span(start, start + nme.IMPLICITkw.asSimpleName.length)
17041702

1705-
/** TypedFunParam ::= id ':' Type */
1703+
/** TypedFunParam ::= [`erased`] id ':' Type */
17061704
def typedFunParam(start: Offset, name: TermName, mods: Modifiers = EmptyModifiers): ValDef =
17071705
atSpan(start) {
17081706
acceptColon()
@@ -2016,7 +2014,7 @@ object Parsers {
20162014
*/
20172015
def paramType(): Tree = paramTypeOf(paramValueType)
20182016

2019-
/** ParamValueType ::= [`into`] Type [`*']
2017+
/** ParamValueType ::= Type [`*']
20202018
*/
20212019
def paramValueType(): Tree = {
20222020
val t = maybeInto(toplevelTyp)
@@ -2374,7 +2372,7 @@ object Parsers {
23742372
Match(t, inBracesOrIndented(caseClauses(() => caseClause())))
23752373
}
23762374

2377-
/** `match' `{' TypeCaseClauses `}'
2375+
/** `match' <<< TypeCaseClauses >>>
23782376
*/
23792377
def matchType(t: Tree): MatchTypeTree =
23802378
atSpan(startOffset(t), accept(MATCH)) {
@@ -2384,7 +2382,7 @@ object Parsers {
23842382
/** FunParams ::= Bindings
23852383
* | id
23862384
* | `_'
2387-
* Bindings ::= `(' [[‘erased’] Binding {`,' Binding}] `)'
2385+
* Bindings ::= `(' [Binding {`,' Binding}] `)'
23882386
*/
23892387
def funParams(mods: Modifiers, location: Location): List[Tree] =
23902388
if in.token == LPAREN then
@@ -3126,7 +3124,7 @@ object Parsers {
31263124
* | AccessModifier
31273125
* | override
31283126
* | opaque
3129-
* LocalModifier ::= abstract | final | sealed | open | implicit | lazy | erased | inline | transparent
3127+
* LocalModifier ::= abstract | final | sealed | open | implicit | lazy | inline | transparent | infix | erased
31303128
*/
31313129
def modifiers(allowed: BitSet = modifierTokens, start: Modifiers = Modifiers()): Modifiers = {
31323130
@tailrec

compiler/src/dotty/tools/dotc/transform/Recheck.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@ import ast.*
99
import Names.Name
1010
import Phases.Phase
1111
import DenotTransformers.{DenotTransformer, IdentityDenotTransformer, SymTransformer}
12-
import NamerOps.{methodType, linkConstructorParams}
12+
import NamerOps.linkConstructorParams
1313
import NullOpsDecorator.stripNull
1414
import typer.ErrorReporting.err
1515
import typer.ProtoTypes.*
1616
import typer.TypeAssigner.seqLitType
1717
import typer.ConstFold
18-
import NamerOps.methodType
1918
import config.Printers.recheckr
2019
import util.Property
2120
import StdNames.nme

docs/_docs/internals/syntax.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ FunTypeArgs ::= InfixType
186186
| ‘(’ [ FunArgTypes ] ‘)’
187187
| FunParamClause
188188
FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’
189-
TypedFunParam ::= [`erased`] id ‘:’ IntoType
189+
TypedFunParam ::= [`erased`] id ‘:’ Type
190190
MatchType ::= InfixType `match` <<< TypeCaseClauses >>>
191191
InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2)
192192
RefinedType ::= AnnotType {[nl] Refinement} RefinedTypeTree(t, ds)
@@ -206,15 +206,11 @@ SimpleType1 ::= id
206206
Singleton ::= SimpleRef
207207
| SimpleLiteral
208208
| Singleton ‘.’ id
209-
FunArgType ::= IntoType
210-
| ‘=>’ IntoType PrefixOp(=>, t)
209+
FunArgType ::= Type
210+
| ‘=>’ Type PrefixOp(=>, t)
211211
FunArgTypes ::= FunArgType { ‘,’ FunArgType }
212212
ParamType ::= [‘=>’] ParamValueType
213213
ParamValueType ::= IntoType [‘*’] PostfixOp(t, "*")
214-
IntoType ::= [‘into’] IntoTargetType Into(t)
215-
| ‘(’ ‘into’ IntoTargetType ‘)’
216-
IntoTargetType ::= Type
217-
| FunTypeArgs (‘=>’ | ‘?=>’) IntoType
218214
TypeArgs ::= ‘[’ Types ‘]’ ts
219215
Refinement ::= :<<< [RefineDef] {semi [RefineDcl]} >>> ds
220216
TypeBounds ::= [‘>:’ Type] [‘<:’ Type] TypeBoundsTree(lo, hi)

0 commit comments

Comments
 (0)