Skip to content

Commit f1d57c4

Browse files
committed
Predict self type instead of converting after the fact
1 parent 95d9171 commit f1d57c4

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
@@ -889,6 +889,16 @@ object Parsers {
889889
val next = in.lookahead.token
890890
next == LBRACKET || next == LPAREN
891891

892+
893+
def followingIsSelfType() =
894+
val lookahead = in.LookaheadScanner()
895+
lookahead.nextToken()
896+
lookahead.token == COLON
897+
&& {
898+
lookahead.nextToken()
899+
canStartTypeTokens(lookahead.token)
900+
}
901+
892902
/** Is current ident a `*`, and is it followed by a `)`, `, )`, `,EOF`? The latter two are not
893903
syntactically valid, but we need to include them here for error recovery. */
894904
def followingIsVararg(): Boolean =
@@ -3901,7 +3911,37 @@ object Parsers {
39013911
stats.toList
39023912
}
39033913

3904-
/** TemplateStatSeq ::= [id [`:' Type] `=>'] TemplateStat {semi TemplateStat}
3914+
/** SelfType ::= id [‘:’ InfixType] ‘=>’
3915+
* | ‘this’ ‘:’ InfixType ‘=>’
3916+
*/
3917+
def selfType(): ValDef =
3918+
if (in.isIdent || in.token == THIS)
3919+
&& (in.lookahead.token == COLON && followingIsSelfType()
3920+
|| in.lookahead.token == ARROW)
3921+
then
3922+
atSpan(in.offset) {
3923+
val selfName =
3924+
if in.token == THIS then
3925+
in.nextToken()
3926+
nme.WILDCARD
3927+
else ident()
3928+
val selfTpt =
3929+
if in.token == COLON then
3930+
in.nextToken()
3931+
infixType()
3932+
else
3933+
if selfName == nme.WILDCARD then accept(COLON)
3934+
TypeTree()
3935+
if in.token == ARROW then
3936+
in.token = SELFARROW // suppresses INDENT insertion after `=>`
3937+
in.nextToken()
3938+
else
3939+
syntaxError("`=>` expected after self type")
3940+
makeSelfDef(selfName, selfTpt)
3941+
}
3942+
else EmptyValDef
3943+
3944+
/** TemplateStatSeq ::= [SelfType] TemplateStat {semi TemplateStat}
39053945
* TemplateStat ::= Import
39063946
* | Export
39073947
* | Annotations Modifiers Def
@@ -3913,25 +3953,8 @@ object Parsers {
39133953
* | Annotations Modifiers EnumCase
39143954
*/
39153955
def templateStatSeq(): (ValDef, List[Tree]) = checkNoEscapingPlaceholders {
3916-
var self: ValDef = EmptyValDef
39173956
val stats = new ListBuffer[Tree]
3918-
if isExprIntro && !isDefIntro(modifierTokens) then
3919-
val first = expr1()
3920-
if in.token == ARROW then
3921-
first match {
3922-
case Typed(tree @ This(EmptyTypeIdent), tpt) =>
3923-
self = makeSelfDef(nme.WILDCARD, tpt).withSpan(first.span)
3924-
case _ =>
3925-
val ValDef(name, tpt, _) = convertToParam(first, EmptyModifiers, "self type clause")
3926-
if (name != nme.ERROR)
3927-
self = makeSelfDef(name, tpt).withSpan(first.span)
3928-
}
3929-
in.token = SELFARROW // suppresses INDENT insertion after `=>`
3930-
in.nextToken()
3931-
else
3932-
stats += first
3933-
statSepOrEnd(stats)
3934-
end if
3957+
val self = selfType()
39353958
while
39363959
var empty = false
39373960
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)