Skip to content

Commit 0581219

Browse files
committed
Bring back InlineIf
- Revert: Drop InlineIf and InlineMatch (reverted from commit 8ae9d6a) - Modify trees to not use a kind field in Match
1 parent 19181ce commit 0581219

File tree

11 files changed

+118
-82
lines changed

11 files changed

+118
-82
lines changed

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,12 @@ object Trees {
495495
case class If[-T >: Untyped] private[ast] (cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
496496
extends TermTree[T] {
497497
type ThisTree[-T >: Untyped] = If[T]
498+
def isInline = false
499+
}
500+
class InlineIf[T >: Untyped] private[ast] (cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
501+
extends If(cond, thenp, elsep) {
502+
override def isInline = true
503+
override def toString = s"InlineIf($cond, $thenp, $elsep)"
498504
}
499505

500506
/** A closure with an environment and a reference to a method.
@@ -512,16 +518,15 @@ object Trees {
512518
}
513519

514520
/** selector match { cases } */
515-
case class Match[-T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])(val kind: MatchKind)
521+
case class Match[-T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])
516522
extends TermTree[T] {
517523
type ThisTree[-T >: Untyped] = Match[T]
524+
def isInline = false
518525
}
519-
520-
type MatchKind = Int
521-
object MatchKind {
522-
val Regular = 0
523-
val Inline = 1
524-
val Implicit = 2
526+
class InlineMatch[T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])
527+
extends Match(selector, cases) {
528+
override def isInline = true
529+
override def toString = s"InlineMatch($selector, $cases)"
525530
}
526531

527532
/** case pat if guard => body; only appears as child of a Match */
@@ -908,8 +913,10 @@ object Trees {
908913
type Assign = Trees.Assign[T]
909914
type Block = Trees.Block[T]
910915
type If = Trees.If[T]
916+
type InlineIf = Trees.InlineIf[T]
911917
type Closure = Trees.Closure[T]
912918
type Match = Trees.Match[T]
919+
type InlineMatch = Trees.InlineMatch[T]
913920
type CaseDef = Trees.CaseDef[T]
914921
type Labeled = Trees.Labeled[T]
915922
type Return = Trees.Return[T]
@@ -1037,16 +1044,16 @@ object Trees {
10371044
}
10381045
def If(tree: Tree)(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = tree match {
10391046
case tree: If if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree
1047+
case tree: InlineIf => finalize(tree, untpd.InlineIf(cond, thenp, elsep))
10401048
case _ => finalize(tree, untpd.If(cond, thenp, elsep))
10411049
}
10421050
def Closure(tree: Tree)(env: List[Tree], meth: Tree, tpt: Tree)(implicit ctx: Context): Closure = tree match {
10431051
case tree: Closure if (env eq tree.env) && (meth eq tree.meth) && (tpt eq tree.tpt) => tree
10441052
case _ => finalize(tree, untpd.Closure(env, meth, tpt))
10451053
}
10461054
def Match(tree: Tree)(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = tree match {
1047-
case tree: Match =>
1048-
if ((selector eq tree.selector) && (cases eq tree.cases)) tree
1049-
else finalize(tree, untpd.Match(selector, cases, tree.kind))
1055+
case tree: Match if (selector eq tree.selector) && (cases eq tree.cases) => tree
1056+
case tree: InlineMatch => finalize(tree, untpd.InlineMatch(selector, cases))
10501057
case _ => finalize(tree, untpd.Match(selector, cases))
10511058
}
10521059
def CaseDef(tree: Tree)(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef = tree match {

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
8585
def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
8686
ta.assignType(untpd.If(cond, thenp, elsep), thenp, elsep)
8787

88+
def InlineIf(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
89+
ta.assignType(untpd.InlineIf(cond, thenp, elsep), thenp, elsep)
90+
8891
def Closure(env: List[Tree], meth: Tree, tpt: Tree)(implicit ctx: Context): Closure =
8992
ta.assignType(untpd.Closure(env, meth, tpt), meth, tpt)
9093

@@ -118,9 +121,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
118121
def CaseDef(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef =
119122
ta.assignType(untpd.CaseDef(pat, guard, body), pat, body)
120123

121-
def Match(selector: Tree, cases: List[CaseDef], kind: MatchKind = MatchKind.Regular)(implicit ctx: Context): Match =
124+
def Match(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match =
122125
ta.assignType(untpd.Match(selector, cases), selector, cases)
123126

127+
def InlineMatch(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match =
128+
ta.assignType(untpd.InlineMatch(selector, cases), selector, cases)
129+
124130
def Labeled(bind: Bind, expr: Tree)(implicit ctx: Context): Labeled =
125131
ta.assignType(untpd.Labeled(bind, expr))
126132

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
271271
def Assign(lhs: Tree, rhs: Tree): Assign = new Assign(lhs, rhs)
272272
def Block(stats: List[Tree], expr: Tree): Block = new Block(stats, expr)
273273
def If(cond: Tree, thenp: Tree, elsep: Tree): If = new If(cond, thenp, elsep)
274+
def InlineIf(cond: Tree, thenp: Tree, elsep: Tree): If = new InlineIf(cond, thenp, elsep)
274275
def Closure(env: List[Tree], meth: Tree, tpt: Tree): Closure = new Closure(env, meth, tpt)
275-
def Match(selector: Tree, cases: List[CaseDef], kind: MatchKind = MatchKind.Regular): Match = new Match(selector, cases)(kind)
276+
def Match(selector: Tree, cases: List[CaseDef]): Match = new Match(selector, cases)
277+
def InlineMatch(selector: Tree, cases: List[CaseDef]): Match = new InlineMatch(selector, cases)
276278
def CaseDef(pat: Tree, guard: Tree, body: Tree): CaseDef = new CaseDef(pat, guard, body)
277279
def Labeled(bind: Bind, expr: Tree): Labeled = new Labeled(bind, expr)
278280
def Return(expr: Tree, from: Tree): Return = new Return(expr, from)

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1301,5 +1301,4 @@ class Definitions {
13011301
isInitialized = true
13021302
}
13031303
}
1304-
13051304
}

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,8 @@ Standard-Section: "ASTs" TopLevelStat*
8888
BLOCK Length expr_Term Stat*
8989
INLINED Length expr_Term call_Term? ValOrDefDef*
9090
LAMBDA Length meth_Term target_Type?
91-
IF Length cond_Term then_Term else_Term
92-
MATCH Length sel_Term CaseDef*
93-
INLINEMATCH Length (sel_Term | IMPLICIT) CaseDef*
91+
IF Length [INLINE] cond_Term then_Term else_Term
92+
MATCH Length (IMPLICIT | [INLINE] sel_Term) CaseDef*
9493
TRY Length expr_Term CaseDef* finalizer_Term?
9594
RETURN Length meth_ASTRef expr_Term?
9695
WHILE Length cond_Term body_Term
@@ -237,7 +236,7 @@ Standard Section: "Comments" Comment*
237236
object TastyFormat {
238237

239238
final val header: Array[Int] = Array(0x5C, 0xA1, 0xAB, 0x1F)
240-
val MajorVersion: Int = 13
239+
val MajorVersion: Int = 11
241240
val MinorVersion: Int = 0
242241

243242
/** Tags used to serialize names */
@@ -381,41 +380,39 @@ object TastyFormat {
381380
final val IF = 141
382381
final val LAMBDA = 142
383382
final val MATCH = 143
384-
final val INLINEMATCH = 144
385-
386-
final val RETURN = 146
387-
final val WHILE = 147
388-
final val TRY = 148
389-
final val INLINED = 149
390-
final val SELECTouter = 150
391-
final val REPEATED = 151
392-
final val BIND = 152
393-
final val ALTERNATIVE = 153
394-
final val UNAPPLY = 154
395-
final val ANNOTATEDtype = 155
396-
final val ANNOTATEDtpt = 156
397-
final val CASEDEF = 157
398-
final val TEMPLATE = 158
399-
final val SUPER = 159
400-
final val SUPERtype = 160
401-
final val REFINEDtype = 161
402-
final val REFINEDtpt = 162
403-
final val APPLIEDtype = 163
404-
final val APPLIEDtpt = 164
405-
final val TYPEBOUNDS = 165
406-
final val TYPEBOUNDStpt = 166
407-
final val ANDtype = 167
408-
final val ANDtpt = 168
409-
final val ORtype = 169
410-
final val ORtpt = 170
411-
final val POLYtype = 171
412-
final val TYPELAMBDAtype = 172
413-
final val LAMBDAtpt = 173
414-
final val PARAMtype = 174
415-
final val ANNOTATION = 175
416-
final val TERMREFin = 176
417-
final val TYPEREFin = 177
418-
final val OBJECTDEF = 178
383+
final val RETURN = 144
384+
final val WHILE = 145
385+
final val TRY = 146
386+
final val INLINED = 147
387+
final val SELECTouter = 148
388+
final val REPEATED = 149
389+
final val BIND = 150
390+
final val ALTERNATIVE = 151
391+
final val UNAPPLY = 152
392+
final val ANNOTATEDtype = 153
393+
final val ANNOTATEDtpt = 154
394+
final val CASEDEF = 155
395+
final val TEMPLATE = 156
396+
final val SUPER = 157
397+
final val SUPERtype = 158
398+
final val REFINEDtype = 159
399+
final val REFINEDtpt = 160
400+
final val APPLIEDtype = 161
401+
final val APPLIEDtpt = 162
402+
final val TYPEBOUNDS = 163
403+
final val TYPEBOUNDStpt = 164
404+
final val ANDtype = 165
405+
final val ANDtpt = 166
406+
final val ORtype = 167
407+
final val ORtpt = 168
408+
final val POLYtype = 169
409+
final val TYPELAMBDAtype = 170
410+
final val LAMBDAtpt = 171
411+
final val PARAMtype = 172
412+
final val ANNOTATION = 173
413+
final val TERMREFin = 174
414+
final val TYPEREFin = 175
415+
final val OBJECTDEF = 176
419416

420417
// In binary: 101101EI
421418
// I = implicit method type
@@ -590,7 +587,6 @@ object TastyFormat {
590587
case IF => "IF"
591588
case LAMBDA => "LAMBDA"
592589
case MATCH => "MATCH"
593-
case INLINEMATCH => "INLINEMATCH"
594590
case RETURN => "RETURN"
595591
case WHILE => "WHILE"
596592
case INLINED => "INLINED"

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -414,22 +414,30 @@ class TreePickler(pickler: TastyPickler) {
414414
writeByte(BLOCK)
415415
stats.foreach(preRegister)
416416
withLength { pickleTree(expr); stats.foreach(pickleTree) }
417-
case If(cond, thenp, elsep) =>
417+
case tree @ If(cond, thenp, elsep) =>
418418
writeByte(IF)
419-
withLength { pickleTree(cond); pickleTree(thenp); pickleTree(elsep) }
419+
withLength {
420+
if (tree.isInline) writeByte(INLINE)
421+
pickleTree(cond)
422+
pickleTree(thenp)
423+
pickleTree(elsep)
424+
}
420425
case Closure(env, meth, tpt) =>
421426
writeByte(LAMBDA)
422427
assert(env.isEmpty)
423428
withLength {
424429
pickleTree(meth)
425430
if (tpt.tpe.exists) pickleTpt(tpt)
426431
}
427-
case mtch @ Match(selector, cases) =>
428-
writeByte(if (mtch.kind == MatchKind.Regular) MATCH else INLINEMATCH)
432+
case tree @ Match(selector, cases) =>
433+
writeByte(MATCH)
429434
withLength {
430-
if (mtch.kind == MatchKind.Implicit) writeByte(IMPLICIT)
435+
if (tree.isInline) {
436+
if (selector.isEmpty) writeByte(IMPLICIT)
437+
else { writeByte(INLINE); pickleTree(selector) }
438+
}
431439
else pickleTree(selector)
432-
cases.foreach(pickleTree)
440+
tree.cases.foreach(pickleTree)
433441
}
434442
case CaseDef(pat, guard, rhs) =>
435443
writeByte(CASEDEF)

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,19 +1081,26 @@ class TreeUnpickler(reader: TastyReader,
10811081
val expansion = exprReader.readTerm() // need bindings in scope, so needs to be read before
10821082
Inlined(call, bindings, expansion)
10831083
case IF =>
1084-
If(readTerm(), readTerm(), readTerm())
1084+
if (nextByte == INLINE) {
1085+
readByte()
1086+
InlineIf(readTerm(), readTerm(), readTerm())
1087+
}
1088+
else
1089+
If(readTerm(), readTerm(), readTerm())
10851090
case LAMBDA =>
10861091
val meth = readTerm()
10871092
val tpt = ifBefore(end)(readTpt(), EmptyTree)
10881093
Closure(Nil, meth, tpt)
10891094
case MATCH =>
1090-
Match(readTerm(), readCases(end))
1091-
case INLINEMATCH =>
10921095
if (nextByte == IMPLICIT) {
10931096
readByte()
1094-
Match(EmptyTree, readCases(end), MatchKind.Implicit)
1097+
InlineMatch(EmptyTree, readCases(end))
1098+
}
1099+
else if (nextByte == INLINE) {
1100+
readByte()
1101+
InlineMatch(readTerm(), readCases(end))
10951102
}
1096-
else Match(readTerm(), readCases(end), MatchKind.Inline)
1103+
else Match(readTerm(), readCases(end))
10971104
case RETURN =>
10981105
val from = readSymRef()
10991106
val expr = ifBefore(end)(readTerm(), EmptyTree)

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

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,8 +1099,8 @@ object Parsers {
10991099
* | Expr
11001100
* BlockResult ::= [FunArgMods] FunParams =>' Block
11011101
* | Expr1
1102-
* Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] else Expr]
1103-
* | `if' Expr `then' Expr [[semi] else Expr]
1102+
* Expr1 ::= [‘inline’] `if' `(' Expr `)' {nl} Expr [[semi] else Expr]
1103+
* | [‘inline’] `if' Expr `then' Expr [[semi] else Expr]
11041104
* | `while' `(' Expr `)' {nl} Expr
11051105
* | `while' Expr `do' Expr
11061106
* | `do' Expr [semi] `while' Expr
@@ -1211,11 +1211,16 @@ object Parsers {
12111211
case _ =>
12121212
if (isIdent(nme.INLINEkw)) {
12131213
val start = in.skipToken()
1214-
val t = postfixExpr()
1215-
if (in.token == MATCH) matchExpr(t, start, MatchKind.Inline)
1216-
else {
1217-
syntaxErrorOrIncomplete(i"`match` expected but ${in.token} found")
1218-
t
1214+
in.token match {
1215+
case IF =>
1216+
ifExpr(start, InlineIf)
1217+
case _ =>
1218+
val t = postfixExpr()
1219+
if (in.token == MATCH) matchExpr(t, start, InlineMatch)
1220+
else {
1221+
syntaxErrorOrIncomplete(i"`match` or `if` expected but ${in.token} found")
1222+
t
1223+
}
12191224
}
12201225
}
12211226
else expr1Rest(postfixExpr(), location)
@@ -1232,7 +1237,7 @@ object Parsers {
12321237
case COLON =>
12331238
ascription(t, location)
12341239
case MATCH =>
1235-
matchExpr(t, startOffset(t), MatchKind.Regular)
1240+
matchExpr(t, startOffset(t), Match)
12361241
case _ =>
12371242
t
12381243
}
@@ -1278,9 +1283,9 @@ object Parsers {
12781283

12791284
/** `match' { CaseClauses }
12801285
*/
1281-
def matchExpr(t: Tree, start: Offset, kind: MatchKind): Match =
1286+
def matchExpr(t: Tree, start: Offset, mkMatch: (Tree, List[CaseDef]) => Match) =
12821287
atPos(start, in.skipToken()) {
1283-
inBraces(Match(t, caseClauses(caseClause), kind))
1288+
inBraces(mkMatch(t, caseClauses(caseClause)))
12841289
}
12851290

12861291
/** `match' { ImplicitCaseClauses }
@@ -1294,7 +1299,8 @@ object Parsers {
12941299
case Mod.Implicit() :: mods => markFirstIllegal(mods)
12951300
case mods => markFirstIllegal(mods)
12961301
}
1297-
val result @ Match(t, cases) = matchExpr(EmptyTree, start, MatchKind.Implicit)
1302+
val result @ Match(t, cases) =
1303+
matchExpr(EmptyTree, start, InlineMatch)
12981304
for (CaseDef(pat, _, _) <- cases) {
12991305
def isImplicitPattern(pat: Tree) = pat match {
13001306
case Typed(pat1, _) => isVarPattern(pat1)

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
674674
*/
675675
def reduceInlineMatch(mtch: untpd.Match, scrutinee: Tree, scrutType: Type, typer: Typer)(implicit ctx: Context): MatchRedux = {
676676

677-
val isImplicit = mtch.kind == MatchKind.Implicit
677+
val isImplicit = mtch.selector.isEmpty
678678
val gadtSyms = typer.gadtSyms(scrutType)
679679

680680
/** Try to match pattern `pat` against scrutinee reference `scrut`. If successful add
@@ -845,7 +845,6 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
845845
super.ensureAccessible(tpe, superAccess, pos)
846846
}
847847

848-
849848
override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree =
850849
tryInline(tree.asInstanceOf[tpd.Tree]) `orElse` super.typedIdent(tree, pt)
851850

@@ -865,6 +864,10 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
865864
if (isIdempotentExpr(cond1)) selected
866865
else Block(cond1 :: Nil, selected)
867866
case cond1 =>
867+
if (tree.isInline)
868+
errorTree(tree, em"""cannot reduce inline if
869+
| its condition ${tree.cond}
870+
| is not a constant value.""")
868871
val if1 = untpd.cpy.If(tree)(cond = untpd.TypedSplice(cond1))
869872
super.typedIf(if1, pt)
870873
}
@@ -873,7 +876,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
873876
constToLiteral(betaReduce(super.typedApply(tree, pt)))
874877

875878
override def typedMatchFinish(tree: untpd.Match, sel: Tree, selType: Type, pt: Type)(implicit ctx: Context) =
876-
if (tree.kind == MatchKind.Regular || ctx.owner.isInlineMethod) // don't reduce match of nested inline method yet
879+
if (!tree.isInline || ctx.owner.isInlineMethod) // don't reduce match of nested inline method yet
877880
super.typedMatchFinish(tree, sel, selType, pt)
878881
else
879882
reduceInlineMatch(tree, sel, sel.tpe, this) match {
@@ -888,7 +891,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
888891
def guardStr(guard: untpd.Tree) = if (guard.isEmpty) "" else i" if $guard"
889892
def patStr(cdef: untpd.CaseDef) = i"case ${cdef.pat}${guardStr(cdef.guard)}"
890893
val msg =
891-
if (tree.kind == MatchKind.Implicit)
894+
if (tree.selector.isEmpty)
892895
em"""cannot reduce implicit match with
893896
| patterns : ${tree.cases.map(patStr).mkString("\n ")}."""
894897
else

0 commit comments

Comments
 (0)