Skip to content

Commit 6a9bea8

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
1 parent e06b831 commit 6a9bea8

File tree

3 files changed

+90
-97
lines changed

3 files changed

+90
-97
lines changed

Diff for: compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+86-88
Original file line numberDiff line numberDiff line change
@@ -1532,13 +1532,15 @@ object Parsers {
15321532
* PolyFunType ::= HKTypeParamClause '=>' Type
15331533
* | HKTypeParamClause ‘->’ [CaptureSet] Type -- under pureFunctions
15341534
* FunTypeArgs ::= InfixType
1535-
* | `(' [ [ ‘['erased'] FunArgType {`,' FunArgType } ] `)'
1536-
* | '(' [ ‘['erased'] TypedFunParam {',' TypedFunParam } ')'
1535+
* | `(' [ FunArgType {`,' FunArgType } ] `)'
1536+
* | '(' [ TypedFunParam {',' TypedFunParam } ')'
1537+
* MatchType ::= InfixType `match` <<< TypeCaseClauses >>>
15371538
*/
15381539
def typ(): Tree =
15391540
val start = in.offset
15401541
var imods = Modifiers()
15411542
var erasedArgs: ListBuffer[Boolean] = ListBuffer()
1543+
15421544
def functionRest(params: List[Tree]): Tree =
15431545
val paramSpan = Span(start, in.lastOffset)
15441546
atSpan(start, in.offset) {
@@ -1567,7 +1569,8 @@ object Parsers {
15671569
else
15681570
accept(ARROW)
15691571

1570-
val resultType = if isPure then capturesAndResult(typ) else typ()
1572+
val resultType =
1573+
if isPure then capturesAndResult(typ) else typ()
15711574
if token == TLARROW then
15721575
for case ValDef(_, tpt, _) <- params do
15731576
if isByNameType(tpt) then
@@ -1585,98 +1588,93 @@ object Parsers {
15851588
Function(params, resultType)
15861589
}
15871590

1588-
var isValParamList = false
1591+
def typeRest(t: Tree) = in.token match
1592+
case ARROW | CTXARROW =>
1593+
erasedArgs.addOne(false)
1594+
functionRest(t :: Nil)
1595+
case MATCH =>
1596+
matchType(t)
1597+
case FORSOME =>
1598+
syntaxError(ExistentialTypesNoLongerSupported())
1599+
t
1600+
case _ if isPureArrow =>
1601+
erasedArgs.addOne(false)
1602+
functionRest(t :: Nil)
1603+
case _ =>
1604+
if erasedArgs.contains(true) && !t.isInstanceOf[FunctionWithMods] then
1605+
syntaxError(ErasedTypesCanOnlyBeFunctionTypes(), implicitKwPos(start))
1606+
t
15891607

1590-
val t =
1591-
if (in.token == LPAREN) {
1608+
var isValParamList = false
1609+
if in.token == LPAREN then
1610+
in.nextToken()
1611+
if in.token == RPAREN then
15921612
in.nextToken()
1593-
if (in.token == RPAREN) {
1594-
in.nextToken()
1595-
functionRest(Nil)
1596-
}
1597-
else {
1598-
val paramStart = in.offset
1599-
def addErased() =
1600-
erasedArgs.addOne(isErasedKw)
1601-
if isErasedKw then { in.skipToken(); }
1602-
addErased()
1603-
val ts = in.currentRegion.withCommasExpected {
1613+
functionRest(Nil)
1614+
else
1615+
val paramStart = in.offset
1616+
def addErased() =
1617+
erasedArgs.addOne(isErasedKw)
1618+
if isErasedKw then in.skipToken()
1619+
addErased()
1620+
val args =
1621+
in.currentRegion.withCommasExpected:
16041622
funArgType() match
16051623
case Ident(name) if name != tpnme.WILDCARD && in.isColon =>
16061624
isValParamList = true
1607-
def funParam(start: Offset, mods: Modifiers) = {
1608-
atSpan(start) {
1625+
def funParam(start: Offset, mods: Modifiers) =
1626+
atSpan(start):
16091627
addErased()
16101628
typedFunParam(in.offset, ident(), imods)
1611-
}
1612-
}
16131629
commaSeparatedRest(
16141630
typedFunParam(paramStart, name.toTermName, imods),
16151631
() => funParam(in.offset, imods))
16161632
case t =>
1617-
def funParam() = {
1618-
addErased()
1619-
funArgType()
1620-
}
1621-
commaSeparatedRest(t, funParam)
1622-
}
1623-
accept(RPAREN)
1624-
if isValParamList || in.isArrow || isPureArrow then
1625-
functionRest(ts)
1626-
else {
1627-
val ts1 = ts.mapConserve { t =>
1628-
if isByNameType(t) then
1629-
syntaxError(ByNameParameterNotSupported(t), t.span)
1630-
stripByNameType(t)
1631-
else
1632-
t
1633-
}
1634-
val tuple = atSpan(start) { makeTupleOrParens(ts1) }
1635-
infixTypeRest(
1636-
refinedTypeRest(
1637-
withTypeRest(
1638-
annotTypeRest(
1639-
simpleTypeRest(tuple)))))
1640-
}
1641-
}
1642-
}
1643-
else if (in.token == LBRACKET) {
1644-
val start = in.offset
1645-
val tparams = typeParamClause(ParamOwner.TypeParam)
1646-
if (in.token == TLARROW)
1647-
atSpan(start, in.skipToken())(LambdaTypeTree(tparams, toplevelTyp()))
1648-
else if (in.token == ARROW || isPureArrow(nme.PUREARROW)) {
1649-
val arrowOffset = in.skipToken()
1650-
val body = toplevelTyp()
1651-
atSpan(start, arrowOffset) {
1652-
getFunction(body) match {
1653-
case Some(f) =>
1654-
PolyFunction(tparams, body)
1655-
case None =>
1656-
syntaxError(em"Implementation restriction: polymorphic function types must have a value parameter", arrowOffset)
1657-
Ident(nme.ERROR.toTypeName)
1658-
}
1659-
}
1660-
}
1661-
else { accept(TLARROW); typ() }
1662-
}
1663-
else if (in.token == INDENT) enclosed(INDENT, typ())
1664-
else infixType()
1665-
1666-
in.token match
1667-
case ARROW | CTXARROW =>
1668-
erasedArgs.addOne(false)
1669-
functionRest(t :: Nil)
1670-
case MATCH => matchType(t)
1671-
case FORSOME => syntaxError(ExistentialTypesNoLongerSupported()); t
1672-
case _ =>
1673-
if isPureArrow then
1674-
erasedArgs.addOne(false)
1675-
functionRest(t :: Nil)
1633+
def funArg() =
1634+
addErased()
1635+
funArgType()
1636+
commaSeparatedRest(t, funArg)
1637+
accept(RPAREN)
1638+
if isValParamList || in.isArrow || isPureArrow then
1639+
functionRest(args)
16761640
else
1677-
if (erasedArgs.contains(true) && !t.isInstanceOf[FunctionWithMods])
1678-
syntaxError(ErasedTypesCanOnlyBeFunctionTypes(), implicitKwPos(start))
1679-
t
1641+
val args1 = args.mapConserve: t =>
1642+
if isByNameType(t) then
1643+
syntaxError(ByNameParameterNotSupported(t), t.span)
1644+
stripByNameType(t)
1645+
else
1646+
t
1647+
val tuple = atSpan(start):
1648+
makeTupleOrParens(args1)
1649+
typeRest:
1650+
infixTypeRest:
1651+
refinedTypeRest:
1652+
withTypeRest:
1653+
annotTypeRest:
1654+
simpleTypeRest(tuple)
1655+
else if in.token == LBRACKET then
1656+
val start = in.offset
1657+
val tparams = typeParamClause(ParamOwner.TypeParam)
1658+
if in.token == TLARROW then
1659+
atSpan(start, in.skipToken()):
1660+
LambdaTypeTree(tparams, toplevelTyp())
1661+
else if in.token == ARROW || isPureArrow(nme.PUREARROW) then
1662+
val arrowOffset = in.skipToken()
1663+
val body = toplevelTyp()
1664+
atSpan(start, arrowOffset):
1665+
getFunction(body) match
1666+
case Some(f) =>
1667+
PolyFunction(tparams, body)
1668+
case None =>
1669+
syntaxError(em"Implementation restriction: polymorphic function types must have a value parameter", arrowOffset)
1670+
Ident(nme.ERROR.toTypeName)
1671+
else
1672+
accept(TLARROW)
1673+
typ()
1674+
else if in.token == INDENT then
1675+
enclosed(INDENT, typ())
1676+
else
1677+
typeRest(infixType())
16801678
end typ
16811679

16821680
private def makeKindProjectorTypeDef(name: TypeName): TypeDef = {
@@ -1713,7 +1711,7 @@ object Parsers {
17131711
private def implicitKwPos(start: Int): Span =
17141712
Span(start, start + nme.IMPLICITkw.asSimpleName.length)
17151713

1716-
/** TypedFunParam ::= id ':' Type */
1714+
/** TypedFunParam ::= [`erased`] id ':' Type */
17171715
def typedFunParam(start: Offset, name: TermName, mods: Modifiers = EmptyModifiers): ValDef =
17181716
atSpan(start) {
17191717
acceptColon()
@@ -2068,7 +2066,7 @@ object Parsers {
20682066
*/
20692067
def paramType(): Tree = paramTypeOf(paramValueType)
20702068

2071-
/** ParamValueType ::= [`into`] Type [`*']
2069+
/** ParamValueType ::= Type [`*']
20722070
*/
20732071
def paramValueType(): Tree = {
20742072
val t = maybeInto(toplevelTyp)
@@ -2425,7 +2423,7 @@ object Parsers {
24252423
Match(t, inBracesOrIndented(caseClauses(() => caseClause())))
24262424
}
24272425

2428-
/** `match' `{' TypeCaseClauses `}'
2426+
/** `match' <<< TypeCaseClauses >>>
24292427
*/
24302428
def matchType(t: Tree): MatchTypeTree =
24312429
atSpan(startOffset(t), accept(MATCH)) {
@@ -2435,7 +2433,7 @@ object Parsers {
24352433
/** FunParams ::= Bindings
24362434
* | id
24372435
* | `_'
2438-
* Bindings ::= `(' [[‘erased’] Binding {`,' Binding}] `)'
2436+
* Bindings ::= `(' [Binding {`,' Binding}] `)'
24392437
*/
24402438
def funParams(mods: Modifiers, location: Location): List[Tree] =
24412439
if in.token == LPAREN then
@@ -3173,7 +3171,7 @@ object Parsers {
31733171
* | AccessModifier
31743172
* | override
31753173
* | opaque
3176-
* LocalModifier ::= abstract | final | sealed | open | implicit | lazy | erased | inline | transparent
3174+
* LocalModifier ::= abstract | final | sealed | open | implicit | lazy | inline | transparent | infix | erased
31773175
*/
31783176
def modifiers(allowed: BitSet = modifierTokens, start: Modifiers = Modifiers()): Modifiers = {
31793177
@tailrec

Diff for: compiler/src/dotty/tools/dotc/transform/Recheck.scala

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ 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
1818
import typer.ErrorReporting.{Addenda, NothingToAdd}
19-
import NamerOps.methodType
2019
import config.Printers.recheckr
2120
import util.Property
2221
import StdNames.nme

Diff for: docs/_docs/internals/syntax.md

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