Skip to content

Commit 5851c62

Browse files
committed
Predict self type instead of converting after the fact
1 parent 6aa65cf commit 5851c62

File tree

6 files changed

+46
-24
lines changed

6 files changed

+46
-24
lines changed

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

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,16 @@ object Parsers {
891891
val next = in.lookahead.token
892892
next == LBRACKET || next == LPAREN
893893

894+
895+
def followingIsSelfType() =
896+
val lookahead = in.LookaheadScanner()
897+
lookahead.nextToken()
898+
lookahead.token == COLON
899+
&& {
900+
lookahead.nextToken()
901+
canStartTypeTokens(lookahead.token)
902+
}
903+
894904
/** Is current ident a `*`, and is it followed by a `)`, `, )`, `,EOF`? The latter two are not
895905
syntactically valid, but we need to include them here for error recovery. */
896906
def followingIsVararg(): Boolean =
@@ -3892,7 +3902,37 @@ object Parsers {
38923902
stats.toList
38933903
}
38943904

3895-
/** TemplateStatSeq ::= [id [`:' Type] `=>'] TemplateStat {semi TemplateStat}
3905+
/** SelfType ::= id [‘:’ InfixType] ‘=>’
3906+
* | ‘this’ ‘:’ InfixType ‘=>’
3907+
*/
3908+
def selfType(): ValDef =
3909+
if (in.isIdent || in.token == THIS)
3910+
&& (in.lookahead.token == COLON && followingIsSelfType()
3911+
|| in.lookahead.token == ARROW)
3912+
then
3913+
atSpan(in.offset) {
3914+
val selfName =
3915+
if in.token == THIS then
3916+
in.nextToken()
3917+
nme.WILDCARD
3918+
else ident()
3919+
val selfTpt =
3920+
if in.token == COLON then
3921+
in.nextToken()
3922+
infixType()
3923+
else
3924+
if selfName == nme.WILDCARD then accept(COLON)
3925+
TypeTree()
3926+
if in.token == ARROW then
3927+
in.token = SELFARROW // suppresses INDENT insertion after `=>`
3928+
in.nextToken()
3929+
else
3930+
syntaxError("`=>` expected after self type")
3931+
makeSelfDef(selfName, selfTpt)
3932+
}
3933+
else EmptyValDef
3934+
3935+
/** TemplateStatSeq ::= [SelfType] TemplateStat {semi TemplateStat}
38963936
* TemplateStat ::= Import
38973937
* | Export
38983938
* | Annotations Modifiers Def
@@ -3904,25 +3944,8 @@ object Parsers {
39043944
* | Annotations Modifiers EnumCase
39053945
*/
39063946
def templateStatSeq(): (ValDef, List[Tree]) = checkNoEscapingPlaceholders {
3907-
var self: ValDef = EmptyValDef
39083947
val stats = new ListBuffer[Tree]
3909-
if isExprIntro && !isDefIntro(modifierTokens) then
3910-
val first = expr1()
3911-
if in.token == ARROW then
3912-
first match {
3913-
case Typed(tree @ This(EmptyTypeIdent), tpt) =>
3914-
self = makeSelfDef(nme.WILDCARD, tpt).withSpan(first.span)
3915-
case _ =>
3916-
val ValDef(name, tpt, _) = convertToParam(first, EmptyModifiers, "self type clause")
3917-
if (name != nme.ERROR)
3918-
self = makeSelfDef(name, tpt).withSpan(first.span)
3919-
}
3920-
in.token = SELFARROW // suppresses INDENT insertion after `=>`
3921-
in.nextToken()
3922-
else
3923-
stats += first
3924-
statSepOrEnd(stats)
3925-
end if
3948+
val self = selfType()
39263949
while
39273950
var empty = false
39283951
if (in.token == IMPORT)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ object Tokens extends TokensCommon {
233233
final val canStartExprTokens2: TokenSet = canStartExprTokens3 | BitSet(DO)
234234

235235
final val canStartTypeTokens: TokenSet = literalTokens | identifierTokens | BitSet(
236-
THIS, SUPER, USCORE, LPAREN, AT)
236+
THIS, SUPER, USCORE, LPAREN, LBRACE, AT)
237237

238238
final val templateIntroTokens: TokenSet = BitSet(CLASS, TRAIT, OBJECT, ENUM, CASECLASS, CASEOBJECT)
239239

tests/neg/cycles.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ class T2 {
3838
type U = X | Int
3939
}
4040
object T12 {
41-
??? : (T1 {})#U // old-error: conflicting bounds
41+
val _ : (T1 {})#U = ??? // old-error: conflicting bounds
4242
??? : (T2 {})#U // old-error: conflicting bounds
4343
}

tests/neg/i4373b.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// ==> 05bef7805687ba94da37177f7568e3ba7da1f91c.scala <==
22
class x0 {
3-
x1: // error
3+
x1:
44
x0 | _ // error
55
// error

tests/neg/parser-stability-16.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@ class x0[x0] {
33
}
44
trait x3 extends x0 { // error
55
x1 = 0 object // error // error
6-
// error

tests/neg/parser-stability-5.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
trait x0 {
2-
x1 : { // error
2+
x1 : {
33
var x2
44
// error

0 commit comments

Comments
 (0)