Skip to content

Commit 8a1cbe5

Browse files
Merge branch 'master' into add-transparent-7
2 parents 51d3b40 + a0b429b commit 8a1cbe5

File tree

305 files changed

+2605
-1306
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

305 files changed

+2605
-1306
lines changed

bench/tests/power-macro/PowerMacro.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import scala.quoted.Expr
22

33
object PowerMacro {
44

5-
rewrite def power(transparent n: Long, x: Double) = ~powerCode(n, '(x))
5+
inline def power(inline n: Long, x: Double) = ~powerCode(n, '(x))
66

77
def powerCode(n: Long, x: Expr[Double]): Expr[Double] =
88
if (n == 0) '(1.0)

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
6363
type Throw = tpd.Apply
6464
type Labeled = tpd.Labeled
6565
type Return = tpd.Return
66+
type WhileDo = tpd.WhileDo
6667
type Block = tpd.Block
6768
type Typed = tpd.Typed
6869
type Match = tpd.Match
@@ -196,6 +197,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
196197
implicit val ThrowTag: ClassTag[Throw] = ClassTag[Throw](classOf[Throw])
197198
implicit val LabeledTag: ClassTag[Labeled] = ClassTag[Labeled](classOf[Labeled])
198199
implicit val ReturnTag: ClassTag[Return] = ClassTag[Return](classOf[Return])
200+
implicit val WhileDoTag: ClassTag[WhileDo] = ClassTag[WhileDo](classOf[WhileDo])
199201
implicit val LiteralTag: ClassTag[Literal] = ClassTag[Literal](classOf[Literal])
200202
implicit val BlockTag: ClassTag[Block] = ClassTag[Block](classOf[Block])
201203
implicit val TypedTag: ClassTag[Typed] = ClassTag[Typed](classOf[Typed])
@@ -1088,6 +1090,11 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
10881090
def _2: Symbol = if (field.from.symbol.isLabel) field.from.symbol else NoSymbol
10891091
}
10901092

1093+
object WhileDo extends WhileDoDeconstructor {
1094+
def _1: Tree = field.cond
1095+
def _2: Tree = field.body
1096+
}
1097+
10911098
object Ident extends IdentDeconstructor {
10921099
def get = field.name
10931100
}

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

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -928,13 +928,6 @@ object desugar {
928928
/** Main desugaring method */
929929
def apply(tree: Tree)(implicit ctx: Context): Tree = {
930930

931-
/** { label def lname(): Unit = rhs; call }
932-
*/
933-
def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = {
934-
val ldef = DefDef(lname, Nil, ListOfNil, TypeTree(defn.UnitType), rhs).withFlags(Label | Synthetic)
935-
Block(ldef, call)
936-
}
937-
938931
/** Create tree for for-comprehension `<for (enums) do body>` or
939932
* `<for (enums) yield body>` where mapName and flatMapName are chosen
940933
* corresponding to whether this is a for-do or a for-yield.
@@ -1159,16 +1152,10 @@ object desugar {
11591152
case PrefixOp(op, t) =>
11601153
val nspace = if (ctx.mode.is(Mode.Type)) tpnme else nme
11611154
Select(t, nspace.UNARY_PREFIX ++ op.name)
1162-
case WhileDo(cond, body) =>
1163-
// { <label> def while$(): Unit = if (cond) { body; while$() } ; while$() }
1164-
val call = Apply(Ident(nme.WHILE_PREFIX), Nil).withPos(tree.pos)
1165-
val rhs = If(cond, Block(body, call), unitLiteral)
1166-
labelDefAndCall(nme.WHILE_PREFIX, rhs, call)
11671155
case DoWhile(body, cond) =>
1168-
// { label def doWhile$(): Unit = { body; if (cond) doWhile$() } ; doWhile$() }
1169-
val call = Apply(Ident(nme.DO_WHILE_PREFIX), Nil).withPos(tree.pos)
1170-
val rhs = Block(body, If(cond, call, unitLiteral))
1171-
labelDefAndCall(nme.DO_WHILE_PREFIX, rhs, call)
1156+
// while ({ { body }; { cond } }) { () }
1157+
// the inner blocks are there to protect the scopes of body and cond from each other
1158+
WhileDo(Block(Block(Nil, body), Block(Nil, cond)), Literal(Constant(())))
11721159
case ForDo(enums, body) =>
11731160
makeFor(nme.foreach, nme.foreach, enums, body) orElse tree
11741161
case ForYield(enums, body) =>

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
306306
case mdef: TypeDef =>
307307
def isBounds(rhs: Tree): Boolean = rhs match {
308308
case _: TypeBoundsTree => true
309+
case _: MatchTypeTree => true // Typedefs with Match rhs classify as abstract
309310
case LambdaTypeTree(_, body) => isBounds(body)
310311
case _ => false
311312
}
@@ -392,20 +393,21 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
392393
case Ident(_) =>
393394
refPurity(tree)
394395
case Select(qual, _) =>
395-
refPurity(tree).min(exprPurity(qual))
396+
if (tree.symbol.is(Erased)) Pure
397+
else refPurity(tree).min(exprPurity(qual))
396398
case New(_) =>
397399
SimplyPure
398400
case TypeApply(fn, _) =>
399-
exprPurity(fn)
401+
if (fn.symbol.is(Erased)) Pure else exprPurity(fn)
400402
case Apply(fn, args) =>
401403
def isKnownPureOp(sym: Symbol) =
402404
sym.owner.isPrimitiveValueClass || sym.owner == defn.StringClass
403405
if (tree.tpe.isInstanceOf[ConstantType] && isKnownPureOp(tree.symbol)
404406
// A constant expression with pure arguments is pure.
405407
|| fn.symbol.isStable)
406408
minOf(exprPurity(fn), args.map(exprPurity)) `min` Pure
407-
else
408-
Impure
409+
else if (fn.symbol.is(Erased)) Pure
410+
else Impure
409411
case Typed(expr, _) =>
410412
exprPurity(expr)
411413
case Block(stats, expr) =>
@@ -462,11 +464,11 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
462464
* Strictly speaking we can't replace `O.x` with `42`. But this would make
463465
* most expressions non-constant. Maybe we can change the spec to accept this
464466
* kind of eliding behavior. Or else enforce true purity in the compiler.
465-
* The choice will be affected by what we will do with `transparent` and with
467+
* The choice will be affected by what we will do with `inline` and with
466468
* Singleton type bounds (see SIP 23). Presumably
467469
*
468470
* object O1 { val x: Singleton = 42; println("43") }
469-
* object O2 { transparent val x = 42; println("43") }
471+
* object O2 { inline val x = 42; println("43") }
470472
*
471473
* should behave differently.
472474
*
@@ -476,8 +478,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
476478
*
477479
* O2.x = 42
478480
*
479-
* Revisit this issue once we have standardized on `transparent`. Then we can demand
480-
* purity of the prefix unless the selection goes to a transparent val.
481+
* Revisit this issue once we have standardized on `inline`. Then we can demand
482+
* purity of the prefix unless the selection goes to a inline val.
481483
*
482484
* Note: This method should be applied to all term tree nodes that are not literals,
483485
* that can be idempotent, and that can have constant types. So far, only nodes

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

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,9 @@ object Trees {
498498
extends TermTree[T] {
499499
type ThisTree[-T >: Untyped] = If[T]
500500
}
501-
class RewriteIf[T >: Untyped] private[ast] (cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
501+
class InlineIf[T >: Untyped] private[ast] (cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
502502
extends If(cond, thenp, elsep) {
503-
override def toString = s"RewriteIf($cond, $thenp, $elsep)"
503+
override def toString = s"InlineIf($cond, $thenp, $elsep)"
504504
}
505505

506506
/** A closure with an environment and a reference to a method.
@@ -522,9 +522,9 @@ object Trees {
522522
extends TermTree[T] {
523523
type ThisTree[-T >: Untyped] = Match[T]
524524
}
525-
class RewriteMatch[T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])
525+
class InlineMatch[T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])
526526
extends Match(selector, cases) {
527-
override def toString = s"RewriteMatch($selector, $cases)"
527+
override def toString = s"InlineMatch($selector, $cases)"
528528
}
529529

530530
/** case pat if guard => body; only appears as child of a Match */
@@ -550,6 +550,12 @@ object Trees {
550550
type ThisTree[-T >: Untyped] = Return[T]
551551
}
552552

553+
/** while (cond) { body } */
554+
case class WhileDo[-T >: Untyped] private[ast] (cond: Tree[T], body: Tree[T])
555+
extends TermTree[T] {
556+
type ThisTree[-T >: Untyped] = WhileDo[T]
557+
}
558+
553559
/** try block catch handler finally finalizer
554560
*
555561
* Note: if the handler is a case block CASES of the form
@@ -662,6 +668,12 @@ object Trees {
662668
type ThisTree[-T >: Untyped] = LambdaTypeTree[T]
663669
}
664670

671+
/** [bound] selector match { cases } */
672+
case class MatchTypeTree[-T >: Untyped] private[ast] (bound: Tree[T], selector: Tree[T], cases: List[CaseDef[T]])
673+
extends TypTree[T] {
674+
type ThisTree[-T >: Untyped] = MatchTypeTree[T]
675+
}
676+
665677
/** => T */
666678
case class ByNameTypeTree[-T >: Untyped] private[ast] (result: Tree[T])
667679
extends TypTree[T] {
@@ -899,13 +911,14 @@ object Trees {
899911
type Assign = Trees.Assign[T]
900912
type Block = Trees.Block[T]
901913
type If = Trees.If[T]
902-
type RewriteIf = Trees.RewriteIf[T]
914+
type InlineIf = Trees.InlineIf[T]
903915
type Closure = Trees.Closure[T]
904916
type Match = Trees.Match[T]
905-
type RewriteMatch = Trees.RewriteMatch[T]
917+
type InlineMatch = Trees.InlineMatch[T]
906918
type CaseDef = Trees.CaseDef[T]
907919
type Labeled = Trees.Labeled[T]
908920
type Return = Trees.Return[T]
921+
type WhileDo = Trees.WhileDo[T]
909922
type Try = Trees.Try[T]
910923
type SeqLiteral = Trees.SeqLiteral[T]
911924
type JavaSeqLiteral = Trees.JavaSeqLiteral[T]
@@ -917,6 +930,7 @@ object Trees {
917930
type RefinedTypeTree = Trees.RefinedTypeTree[T]
918931
type AppliedTypeTree = Trees.AppliedTypeTree[T]
919932
type LambdaTypeTree = Trees.LambdaTypeTree[T]
933+
type MatchTypeTree = Trees.MatchTypeTree[T]
920934
type ByNameTypeTree = Trees.ByNameTypeTree[T]
921935
type TypeBoundsTree = Trees.TypeBoundsTree[T]
922936
type Bind = Trees.Bind[T]
@@ -1032,9 +1046,9 @@ object Trees {
10321046
case _ => finalize(tree, untpd.Block(stats, expr))
10331047
}
10341048
def If(tree: Tree)(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = tree match {
1035-
case tree: RewriteIf =>
1049+
case tree: InlineIf =>
10361050
if ((cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep)) tree
1037-
else finalize(tree, untpd.RewriteIf(cond, thenp, elsep))
1051+
else finalize(tree, untpd.InlineIf(cond, thenp, elsep))
10381052
case tree: If if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree
10391053
case _ => finalize(tree, untpd.If(cond, thenp, elsep))
10401054
}
@@ -1043,9 +1057,9 @@ object Trees {
10431057
case _ => finalize(tree, untpd.Closure(env, meth, tpt))
10441058
}
10451059
def Match(tree: Tree)(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = tree match {
1046-
case tree: RewriteMatch =>
1060+
case tree: InlineMatch =>
10471061
if ((selector eq tree.selector) && (cases eq tree.cases)) tree
1048-
else finalize(tree, untpd.RewriteMatch(selector, cases))
1062+
else finalize(tree, untpd.InlineMatch(selector, cases))
10491063
case tree: Match if (selector eq tree.selector) && (cases eq tree.cases) => tree
10501064
case _ => finalize(tree, untpd.Match(selector, cases))
10511065
}
@@ -1061,6 +1075,10 @@ object Trees {
10611075
case tree: Return if (expr eq tree.expr) && (from eq tree.from) => tree
10621076
case _ => finalize(tree, untpd.Return(expr, from))
10631077
}
1078+
def WhileDo(tree: Tree)(cond: Tree, body: Tree)(implicit ctx: Context): WhileDo = tree match {
1079+
case tree: WhileDo if (cond eq tree.cond) && (body eq tree.body) => tree
1080+
case _ => finalize(tree, untpd.WhileDo(cond, body))
1081+
}
10641082
def Try(tree: Tree)(expr: Tree, cases: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try = tree match {
10651083
case tree: Try if (expr eq tree.expr) && (cases eq tree.cases) && (finalizer eq tree.finalizer) => tree
10661084
case _ => finalize(tree, untpd.Try(expr, cases, finalizer))
@@ -1100,6 +1118,10 @@ object Trees {
11001118
case tree: LambdaTypeTree if (tparams eq tree.tparams) && (body eq tree.body) => tree
11011119
case _ => finalize(tree, untpd.LambdaTypeTree(tparams, body))
11021120
}
1121+
def MatchTypeTree(tree: Tree)(bound: Tree, selector: Tree, cases: List[CaseDef]): MatchTypeTree = tree match {
1122+
case tree: MatchTypeTree if (bound eq tree.bound) && (selector eq tree.selector) && (cases eq tree.cases) => tree
1123+
case _ => finalize(tree, untpd.MatchTypeTree(bound, selector, cases))
1124+
}
11031125
def ByNameTypeTree(tree: Tree)(result: Tree): ByNameTypeTree = tree match {
11041126
case tree: ByNameTypeTree if result eq tree.result => tree
11051127
case _ => finalize(tree, untpd.ByNameTypeTree(result))
@@ -1235,6 +1257,8 @@ object Trees {
12351257
cpy.Labeled(tree)(transformSub(bind), transform(expr))
12361258
case Return(expr, from) =>
12371259
cpy.Return(tree)(transform(expr), transformSub(from))
1260+
case WhileDo(cond, body) =>
1261+
cpy.WhileDo(tree)(transform(cond), transform(body))
12381262
case Try(block, cases, finalizer) =>
12391263
cpy.Try(tree)(transform(block), transformSub(cases), transform(finalizer))
12401264
case SeqLiteral(elems, elemtpt) =>
@@ -1256,6 +1280,8 @@ object Trees {
12561280
case LambdaTypeTree(tparams, body) =>
12571281
implicit val ctx = localCtx
12581282
cpy.LambdaTypeTree(tree)(transformSub(tparams), transform(body))
1283+
case MatchTypeTree(bound, selector, cases) =>
1284+
cpy.MatchTypeTree(tree)(transform(bound), transform(selector), transformSub(cases))
12591285
case ByNameTypeTree(result) =>
12601286
cpy.ByNameTypeTree(tree)(transform(result))
12611287
case TypeBoundsTree(lo, hi) =>
@@ -1369,6 +1395,8 @@ object Trees {
13691395
this(this(x, bind), expr)
13701396
case Return(expr, from) =>
13711397
this(this(x, expr), from)
1398+
case WhileDo(cond, body) =>
1399+
this(this(x, cond), body)
13721400
case Try(block, handler, finalizer) =>
13731401
this(this(this(x, block), handler), finalizer)
13741402
case SeqLiteral(elems, elemtpt) =>
@@ -1390,6 +1418,8 @@ object Trees {
13901418
case LambdaTypeTree(tparams, body) =>
13911419
implicit val ctx = localCtx
13921420
this(this(x, tparams), body)
1421+
case MatchTypeTree(bound, selector, cases) =>
1422+
this(this(this(x, bound), selector), cases)
13931423
case ByNameTypeTree(result) =>
13941424
this(x, result)
13951425
case TypeBoundsTree(lo, hi) =>

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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,10 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
115115
}
116116

117117
def CaseDef(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef =
118-
ta.assignType(untpd.CaseDef(pat, guard, body), body)
118+
ta.assignType(untpd.CaseDef(pat, guard, body), pat, body)
119119

120120
def Match(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match =
121-
ta.assignType(untpd.Match(selector, cases), cases)
121+
ta.assignType(untpd.Match(selector, cases), selector, cases)
122122

123123
def Labeled(bind: Bind, expr: Tree)(implicit ctx: Context): Labeled =
124124
ta.assignType(untpd.Labeled(bind, expr))
@@ -129,6 +129,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
129129
def Return(expr: Tree, from: Tree)(implicit ctx: Context): Return =
130130
ta.assignType(untpd.Return(expr, from))
131131

132+
def WhileDo(cond: Tree, body: Tree)(implicit ctx: Context): WhileDo =
133+
ta.assignType(untpd.WhileDo(cond, body))
134+
132135
def Try(block: Tree, cases: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try =
133136
ta.assignType(untpd.Try(block, cases, finalizer), block, cases)
134137

@@ -165,6 +168,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
165168
def LambdaTypeTree(tparams: List[TypeDef], body: Tree)(implicit ctx: Context): LambdaTypeTree =
166169
ta.assignType(untpd.LambdaTypeTree(tparams, body), tparams, body)
167170

171+
def MatchTypeTree(bound: Tree, selector: Tree, cases: List[CaseDef])(implicit ctx: Context): MatchTypeTree =
172+
ta.assignType(untpd.MatchTypeTree(bound, selector, cases), bound, selector, cases)
173+
168174
def TypeBoundsTree(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree =
169175
ta.assignType(untpd.TypeBoundsTree(lo, hi), lo, hi)
170176

@@ -575,7 +581,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
575581
}
576582
}
577583

578-
579584
override def Closure(tree: Tree)(env: List[Tree], meth: Tree, tpt: Tree)(implicit ctx: Context): Closure = {
580585
val tree1 = untpd.cpy.Closure(tree)(env, meth, tpt)
581586
tree match {
@@ -584,6 +589,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
584589
case _ => ta.assignType(tree1, meth, tpt)
585590
}
586591
}
592+
587593
override def Match(tree: Tree)(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = {
588594
@tailrec
589595
def sameCases(trees: List[CaseDef], trees1: List[CaseDef]): Boolean = {
@@ -600,15 +606,15 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
600606
val tree1 = untpd.cpy.Match(tree)(selector, cases)
601607
tree match {
602608
case tree: Match if (selector.tpe eq tree.selector.tpe) && sameCases(cases, tree.cases) => tree1.withTypeUnchecked(tree.tpe)
603-
case _ => ta.assignType(tree1, cases)
609+
case _ => ta.assignType(tree1, selector, cases)
604610
}
605611
}
606612

607613
override def CaseDef(tree: Tree)(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef = {
608614
val tree1 = untpd.cpy.CaseDef(tree)(pat, guard, body)
609615
tree match {
610616
case tree: CaseDef if body.tpe eq tree.body.tpe => tree1.withTypeUnchecked(tree.tpe)
611-
case _ => ta.assignType(tree1, body)
617+
case _ => ta.assignType(tree1, pat, body)
612618
}
613619
}
614620

@@ -618,6 +624,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
618624
override def Return(tree: Tree)(expr: Tree, from: Tree)(implicit ctx: Context): Return =
619625
ta.assignType(untpd.cpy.Return(tree)(expr, from))
620626

627+
override def WhileDo(tree: Tree)(cond: Tree, body: Tree)(implicit ctx: Context): WhileDo =
628+
ta.assignType(untpd.cpy.WhileDo(tree)(cond, body))
629+
621630
override def Try(tree: Tree)(expr: Tree, cases: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try = {
622631
val tree1 = untpd.cpy.Try(tree)(expr, cases, finalizer)
623632
tree match {
@@ -833,7 +842,10 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
833842

834843
/** `tree == that` */
835844
def equal(that: Tree)(implicit ctx: Context) =
836-
applyOverloaded(tree, nme.EQ, that :: Nil, Nil, defn.BooleanType)
845+
if (that.tpe.widen.isRef(defn.NothingClass))
846+
Literal(Constant(false))
847+
else
848+
applyOverloaded(tree, nme.EQ, that :: Nil, Nil, defn.BooleanType)
837849

838850
/** `tree.isInstanceOf[tp]`, with special treatment of singleton types */
839851
def isInstance(tp: Type)(implicit ctx: Context): Tree = tp.dealias match {

0 commit comments

Comments
 (0)