Skip to content

Commit 72c71b0

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 894791a commit 72c71b0

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
@@ -494,6 +494,12 @@ object Trees {
494494
case class If[-T >: Untyped] private[ast] (cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
495495
extends TermTree[T] {
496496
type ThisTree[-T >: Untyped] = If[T]
497+
def isInline = false
498+
}
499+
class InlineIf[T >: Untyped] private[ast] (cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
500+
extends If(cond, thenp, elsep) {
501+
override def isInline = true
502+
override def toString = s"InlineIf($cond, $thenp, $elsep)"
497503
}
498504

499505
/** A closure with an environment and a reference to a method.
@@ -511,16 +517,15 @@ object Trees {
511517
}
512518

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

526531
/** case pat if guard => body; only appears as child of a Match */
@@ -907,8 +912,10 @@ object Trees {
907912
type Assign = Trees.Assign[T]
908913
type Block = Trees.Block[T]
909914
type If = Trees.If[T]
915+
type InlineIf = Trees.InlineIf[T]
910916
type Closure = Trees.Closure[T]
911917
type Match = Trees.Match[T]
918+
type InlineMatch = Trees.InlineMatch[T]
912919
type CaseDef = Trees.CaseDef[T]
913920
type Labeled = Trees.Labeled[T]
914921
type Return = Trees.Return[T]
@@ -1036,16 +1043,16 @@ object Trees {
10361043
}
10371044
def If(tree: Tree)(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = tree match {
10381045
case tree: If if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree
1046+
case tree: InlineIf => finalize(tree, untpd.InlineIf(cond, thenp, elsep))
10391047
case _ => finalize(tree, untpd.If(cond, thenp, elsep))
10401048
}
10411049
def Closure(tree: Tree)(env: List[Tree], meth: Tree, tpt: Tree)(implicit ctx: Context): Closure = tree match {
10421050
case tree: Closure if (env eq tree.env) && (meth eq tree.meth) && (tpt eq tree.tpt) => tree
10431051
case _ => finalize(tree, untpd.Closure(env, meth, tpt))
10441052
}
10451053
def Match(tree: Tree)(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = tree match {
1046-
case tree: Match =>
1047-
if ((selector eq tree.selector) && (cases eq tree.cases)) tree
1048-
else finalize(tree, untpd.Match(selector, cases, tree.kind))
1054+
case tree: Match if (selector eq tree.selector) && (cases eq tree.cases) => tree
1055+
case tree: InlineMatch => finalize(tree, untpd.InlineMatch(selector, cases))
10491056
case _ => finalize(tree, untpd.Match(selector, cases))
10501057
}
10511058
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
@@ -269,8 +269,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
269269
def Assign(lhs: Tree, rhs: Tree): Assign = new Assign(lhs, rhs)
270270
def Block(stats: List[Tree], expr: Tree): Block = new Block(stats, expr)
271271
def If(cond: Tree, thenp: Tree, elsep: Tree): If = new If(cond, thenp, elsep)
272+
def InlineIf(cond: Tree, thenp: Tree, elsep: Tree): If = new InlineIf(cond, thenp, elsep)
272273
def Closure(env: List[Tree], meth: Tree, tpt: Tree): Closure = new Closure(env, meth, tpt)
273-
def Match(selector: Tree, cases: List[CaseDef], kind: MatchKind = MatchKind.Regular): Match = new Match(selector, cases)(kind)
274+
def Match(selector: Tree, cases: List[CaseDef]): Match = new Match(selector, cases)
275+
def InlineMatch(selector: Tree, cases: List[CaseDef]): Match = new InlineMatch(selector, cases)
274276
def CaseDef(pat: Tree, guard: Tree, body: Tree): CaseDef = new CaseDef(pat, guard, body)
275277
def Labeled(bind: Bind, expr: Tree): Labeled = new Labeled(bind, expr)
276278
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
@@ -1286,5 +1286,4 @@ class Definitions {
12861286
isInitialized = true
12871287
}
12881288
}
1289-
12901289
}

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
@@ -236,7 +235,7 @@ Standard Section: "Comments" Comment*
236235
object TastyFormat {
237236

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

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

418415
// In binary: 101101EI
419416
// I = implicit method type
@@ -586,7 +583,6 @@ object TastyFormat {
586583
case IF => "IF"
587584
case LAMBDA => "LAMBDA"
588585
case MATCH => "MATCH"
589-
case INLINEMATCH => "INLINEMATCH"
590586
case RETURN => "RETURN"
591587
case WHILE => "WHILE"
592588
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
@@ -1085,19 +1085,26 @@ class TreeUnpickler(reader: TastyReader,
10851085
val expansion = exprReader.readTerm() // need bindings in scope, so needs to be read before
10861086
Inlined(call, bindings, expansion)
10871087
case IF =>
1088-
If(readTerm(), readTerm(), readTerm())
1088+
if (nextByte == INLINE) {
1089+
readByte()
1090+
InlineIf(readTerm(), readTerm(), readTerm())
1091+
}
1092+
else
1093+
If(readTerm(), readTerm(), readTerm())
10891094
case LAMBDA =>
10901095
val meth = readTerm()
10911096
val tpt = ifBefore(end)(readTpt(), EmptyTree)
10921097
Closure(Nil, meth, tpt)
10931098
case MATCH =>
1094-
Match(readTerm(), readCases(end))
1095-
case INLINEMATCH =>
10961099
if (nextByte == IMPLICIT) {
10971100
readByte()
1098-
Match(EmptyTree, readCases(end), MatchKind.Implicit)
1101+
InlineMatch(EmptyTree, readCases(end))
1102+
}
1103+
else if (nextByte == INLINE) {
1104+
readByte()
1105+
InlineMatch(readTerm(), readCases(end))
10991106
}
1100-
else Match(readTerm(), readCases(end), MatchKind.Inline)
1107+
else Match(readTerm(), readCases(end))
11011108
case RETURN =>
11021109
val from = readSymRef()
11031110
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
@@ -1102,8 +1102,8 @@ object Parsers {
11021102
* | Expr
11031103
* BlockResult ::= [FunArgMods] FunParams =>' Block
11041104
* | Expr1
1105-
* Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] else Expr]
1106-
* | `if' Expr `then' Expr [[semi] else Expr]
1105+
* Expr1 ::= [‘inline’] `if' `(' Expr `)' {nl} Expr [[semi] else Expr]
1106+
* | [‘inline’] `if' Expr `then' Expr [[semi] else Expr]
11071107
* | `while' `(' Expr `)' {nl} Expr
11081108
* | `while' Expr `do' Expr
11091109
* | `do' Expr [semi] `while' Expr
@@ -1214,11 +1214,16 @@ object Parsers {
12141214
case _ =>
12151215
if (isIdent(nme.INLINEkw)) {
12161216
val start = in.skipToken()
1217-
val t = postfixExpr()
1218-
if (in.token == MATCH) matchExpr(t, start, MatchKind.Inline)
1219-
else {
1220-
syntaxErrorOrIncomplete(i"`match` expected but ${in.token} found")
1221-
t
1217+
in.token match {
1218+
case IF =>
1219+
ifExpr(start, InlineIf)
1220+
case _ =>
1221+
val t = postfixExpr()
1222+
if (in.token == MATCH) matchExpr(t, start, InlineMatch)
1223+
else {
1224+
syntaxErrorOrIncomplete(i"`match` or `if` expected but ${in.token} found")
1225+
t
1226+
}
12221227
}
12231228
}
12241229
else expr1Rest(postfixExpr(), location)
@@ -1235,7 +1240,7 @@ object Parsers {
12351240
case COLON =>
12361241
ascription(t, location)
12371242
case MATCH =>
1238-
matchExpr(t, startOffset(t), MatchKind.Regular)
1243+
matchExpr(t, startOffset(t), Match)
12391244
case _ =>
12401245
t
12411246
}
@@ -1281,9 +1286,9 @@ object Parsers {
12811286

12821287
/** `match' { CaseClauses }
12831288
*/
1284-
def matchExpr(t: Tree, start: Offset, kind: MatchKind): Match =
1289+
def matchExpr(t: Tree, start: Offset, mkMatch: (Tree, List[CaseDef]) => Match) =
12851290
atPos(start, in.skipToken()) {
1286-
inBraces(Match(t, caseClauses(caseClause), kind))
1291+
inBraces(mkMatch(t, caseClauses(caseClause)))
12871292
}
12881293

12891294
/** `match' { ImplicitCaseClauses }
@@ -1297,7 +1302,8 @@ object Parsers {
12971302
case Mod.Implicit() :: mods => markFirstIllegal(mods)
12981303
case mods => markFirstIllegal(mods)
12991304
}
1300-
val result @ Match(t, cases) = matchExpr(EmptyTree, start, MatchKind.Implicit)
1305+
val result @ Match(t, cases) =
1306+
matchExpr(EmptyTree, start, InlineMatch)
13011307
for (CaseDef(pat, _, _) <- cases) {
13021308
def isImplicitPattern(pat: Tree) = pat match {
13031309
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)