Skip to content

Commit 90671f0

Browse files
authored
Merge pull request #5138 from dotty-staging/revert-inliner
Revert inliner to work on typed trees
2 parents c559d73 + 0b8ffaf commit 90671f0

File tree

66 files changed

+601
-1906
lines changed

Some content is hidden

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

66 files changed

+601
-1906
lines changed

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

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -497,10 +497,6 @@ object Trees {
497497
extends TermTree[T] {
498498
type ThisTree[-T >: Untyped] = If[T]
499499
}
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 toString = s"InlineIf($cond, $thenp, $elsep)"
503-
}
504500

505501
/** A closure with an environment and a reference to a method.
506502
* @param env The captured parameters of the closure
@@ -521,10 +517,6 @@ object Trees {
521517
extends TermTree[T] {
522518
type ThisTree[-T >: Untyped] = Match[T]
523519
}
524-
class InlineMatch[T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])
525-
extends Match(selector, cases) {
526-
override def toString = s"InlineMatch($selector, $cases)"
527-
}
528520

529521
/** case pat if guard => body; only appears as child of a Match */
530522
case class CaseDef[-T >: Untyped] private[ast] (pat: Tree[T], guard: Tree[T], body: Tree[T])
@@ -910,10 +902,8 @@ object Trees {
910902
type Assign = Trees.Assign[T]
911903
type Block = Trees.Block[T]
912904
type If = Trees.If[T]
913-
type InlineIf = Trees.InlineIf[T]
914905
type Closure = Trees.Closure[T]
915906
type Match = Trees.Match[T]
916-
type InlineMatch = Trees.InlineMatch[T]
917907
type CaseDef = Trees.CaseDef[T]
918908
type Labeled = Trees.Labeled[T]
919909
type Return = Trees.Return[T]
@@ -959,11 +949,6 @@ object Trees {
959949
case ys => Thicket(ys)
960950
}
961951

962-
/** Extractor for the synthetic scrutinee tree of an implicit match */
963-
object ImplicitScrutinee {
964-
def apply() = Ident(nme.IMPLICITkw)
965-
def unapply(id: Ident): Boolean = id.name == nme.IMPLICITkw && !id.isInstanceOf[BackquotedIdent]
966-
}
967952
// ----- Helper classes for copying, transforming, accumulating -----------------
968953

969954
val cpy: TreeCopier
@@ -1045,9 +1030,6 @@ object Trees {
10451030
case _ => finalize(tree, untpd.Block(stats, expr))
10461031
}
10471032
def If(tree: Tree)(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = tree match {
1048-
case tree: InlineIf =>
1049-
if ((cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep)) tree
1050-
else finalize(tree, untpd.InlineIf(cond, thenp, elsep))
10511033
case tree: If if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree
10521034
case _ => finalize(tree, untpd.If(cond, thenp, elsep))
10531035
}
@@ -1056,9 +1038,6 @@ object Trees {
10561038
case _ => finalize(tree, untpd.Closure(env, meth, tpt))
10571039
}
10581040
def Match(tree: Tree)(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = tree match {
1059-
case tree: InlineMatch =>
1060-
if ((selector eq tree.selector) && (cases eq tree.cases)) tree
1061-
else finalize(tree, untpd.InlineMatch(selector, cases))
10621041
case tree: Match if (selector eq tree.selector) && (cases eq tree.cases) => tree
10631042
case _ => finalize(tree, untpd.Match(selector, cases))
10641043
}
@@ -1169,10 +1148,6 @@ object Trees {
11691148
case tree: Annotated if (arg eq tree.arg) && (annot eq tree.annot) => tree
11701149
case _ => finalize(tree, untpd.Annotated(arg, annot))
11711150
}
1172-
def UntypedSplice(tree: Tree)(splice: untpd.Tree) = tree match {
1173-
case tree: tpd.UntypedSplice if tree.splice `eq` splice => tree
1174-
case _ => finalize(tree, tpd.UntypedSplice(splice))
1175-
}
11761151
def Thicket(tree: Tree)(trees: List[Tree]): Thicket = tree match {
11771152
case tree: Thicket if trees eq tree.trees => tree
11781153
case _ => finalize(tree, untpd.Thicket(trees))
@@ -1329,21 +1304,9 @@ object Trees {
13291304
def transformSub[Tr <: Tree](trees: List[Tr])(implicit ctx: Context): List[Tr] =
13301305
transform(trees).asInstanceOf[List[Tr]]
13311306

1332-
protected def transformMoreCases(tree: Tree)(implicit ctx: Context): Tree = tree match {
1333-
case tpd.UntypedSplice(usplice) =>
1334-
// For a typed tree map: homomorphism on the untyped part with
1335-
// recursive mapping of typed splices.
1336-
// The case is overridden in UntypedTreeMap.##
1337-
val untpdMap = new untpd.UntypedTreeMap {
1338-
override def transform(tree: untpd.Tree)(implicit ctx: Context): untpd.Tree = tree match {
1339-
case untpd.TypedSplice(tsplice) =>
1340-
untpd.cpy.TypedSplice(tree)(self.transform(tsplice).asInstanceOf[tpd.Tree])
1341-
// the cast is safe, since the UntypedSplice case is overridden in UntypedTreeMap.
1342-
case _ => super.transform(tree)
1343-
}
1344-
}
1345-
cpy.UntypedSplice(tree)(untpdMap.transform(usplice))
1346-
case _ if ctx.reporter.errorsReported => tree
1307+
protected def transformMoreCases(tree: Tree)(implicit ctx: Context): Tree = {
1308+
assert(ctx.reporter.errorsReported)
1309+
tree
13471310
}
13481311
}
13491312

@@ -1453,23 +1416,13 @@ object Trees {
14531416
}
14541417
}
14551418

1456-
def foldMoreCases(x: X, tree: Tree)(implicit ctx: Context): X = tree match {
1457-
case tpd.UntypedSplice(usplice) =>
1458-
// For a typed tree accumulator: skip the untyped part and fold all typed splices.
1459-
// The case is overridden in UntypedTreeAccumulator.
1460-
val untpdAcc = new untpd.UntypedTreeAccumulator[X] {
1461-
override def apply(x: X, tree: untpd.Tree)(implicit ctx: Context): X = tree match {
1462-
case untpd.TypedSplice(tsplice) => self(x, tsplice)
1463-
case _ => foldOver(x, tree)
1464-
}
1465-
}
1466-
untpdAcc(x, usplice)
1467-
case _ if ctx.reporter.errorsReported || ctx.mode.is(Mode.Interactive) =>
1419+
def foldMoreCases(x: X, tree: Tree)(implicit ctx: Context): X = {
1420+
assert(ctx.reporter.errorsReported || ctx.mode.is(Mode.Interactive))
14681421
// In interactive mode, errors might come from previous runs.
14691422
// In case of errors it may be that typed trees point to untyped ones.
14701423
// The IDE can still traverse inside such trees, either in the run where errors
14711424
// are reported, or in subsequent ones.
1472-
x
1425+
x
14731426
}
14741427
}
14751428

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ import scala.io.Codec
2121
/** Some creators for typed trees */
2222
object tpd extends Trees.Instance[Type] with TypedTreeInfo {
2323

24-
case class UntypedSplice(splice: untpd.Tree) extends Tree
25-
2624
private def ta(implicit ctx: Context) = ctx.typeAssigner
2725

2826
def Ident(tp: NamedType)(implicit ctx: Context): Ident =
@@ -722,7 +720,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
722720
new TreeTypeMap(oldOwners = from :: froms, newOwners = tos).apply(tree)
723721
}
724722
}
725-
loop(from, Nil, to :: Nil)
723+
if (from == to) tree else loop(from, Nil, to :: Nil)
726724
}
727725

728726
/** After phase `trans`, set the owner of every definition in this tree that was formerly
@@ -916,6 +914,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
916914
def outerSelect(levels: Int, tp: Type)(implicit ctx: Context): Tree =
917915
untpd.Select(tree, OuterSelectName(EmptyTermName, levels)).withType(SkolemType(tp))
918916

917+
def underlyingArgument(implicit ctx: Context): Tree = mapToUnderlying.transform(tree)
918+
919919
// --- Higher order traversal methods -------------------------------
920920

921921
/** Apply `f` to each subtree of this tree */
@@ -942,26 +942,38 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
942942
}
943943
}
944944

945+
/** Map Inlined nodes and InlineProxy references to underlying arguments */
946+
object mapToUnderlying extends TreeMap {
947+
override def transform(tree: Tree)(implicit ctx: Context): Tree = tree match {
948+
case tree: Ident if tree.symbol.is(InlineProxy) =>
949+
tree.symbol.defTree.asInstanceOf[ValOrDefDef].rhs.underlyingArgument
950+
case Inlined(_, _, arg) =>
951+
arg.underlyingArgument
952+
case tree =>
953+
super.transform(tree)
954+
}
955+
}
956+
945957
implicit class ListOfTreeDecorator(val xs: List[tpd.Tree]) extends AnyVal {
946958
def tpes: List[Type] = xs map (_.tpe)
947959
}
948960

949961
/** A trait for loaders that compute trees. Currently implemented just by DottyUnpickler. */
950962
trait TreeProvider {
951-
protected def computeTrees(implicit ctx: Context): List[Tree]
963+
protected def computeRootTrees(implicit ctx: Context): List[Tree]
952964

953965
private[this] var myTrees: List[Tree] = null
954966

955967
/** Get trees defined by this provider. Cache them if -Yretain-trees is set. */
956-
def trees(implicit ctx: Context): List[Tree] =
968+
def rootTrees(implicit ctx: Context): List[Tree] =
957969
if (ctx.settings.YretainTrees.value) {
958-
if (myTrees == null) myTrees = computeTrees
970+
if (myTrees == null) myTrees = computeRootTrees
959971
myTrees
960-
} else computeTrees
972+
} else computeRootTrees
961973

962974
/** Get first tree defined by this provider, or EmptyTree if none exists */
963975
def tree(implicit ctx: Context): Tree =
964-
trees.headOption.getOrElse(EmptyTree)
976+
rootTrees.headOption.getOrElse(EmptyTree)
965977

966978
/** Is it possible that the tree to load contains a definition of or reference to `id`? */
967979
def mightContain(id: String)(implicit ctx: Context) = true

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
272272
def Assign(lhs: Tree, rhs: Tree): Assign = new Assign(lhs, rhs)
273273
def Block(stats: List[Tree], expr: Tree): Block = new Block(stats, expr)
274274
def If(cond: Tree, thenp: Tree, elsep: Tree): If = new If(cond, thenp, elsep)
275-
def InlineIf(cond: Tree, thenp: Tree, elsep: Tree): If = new InlineIf(cond, thenp, elsep)
276275
def Closure(env: List[Tree], meth: Tree, tpt: Tree): Closure = new Closure(env, meth, tpt)
277276
def Match(selector: Tree, cases: List[CaseDef]): Match = new Match(selector, cases)
278-
def InlineMatch(selector: Tree, cases: List[CaseDef]): Match = new InlineMatch(selector, cases)
279277
def CaseDef(pat: Tree, guard: Tree, body: Tree): CaseDef = new CaseDef(pat, guard, body)
280278
def Labeled(bind: Bind, expr: Tree): Labeled = new Labeled(bind, expr)
281279
def Return(expr: Tree, from: Tree): Return = new Return(expr, from)
@@ -544,8 +542,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
544542
cpy.ContextBounds(tree)(transformSub(bounds), transform(cxBounds))
545543
case PatDef(mods, pats, tpt, rhs) =>
546544
cpy.PatDef(tree)(mods, transform(pats), transform(tpt), transform(rhs))
547-
case tpd.UntypedSplice(splice) =>
548-
cpy.UntypedSplice(tree)(transform(splice))
549545
case TypedSplice(_) =>
550546
tree
551547
case _ =>
@@ -595,8 +591,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
595591
this(this(this(x, pats), tpt), rhs)
596592
case TypedSplice(splice) =>
597593
this(x, splice)
598-
case tpd.UntypedSplice(splice) =>
599-
this(x, splice)
600594
case _ =>
601595
super.foldMoreCases(x, tree)
602596
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,13 @@ trait ConstraintHandling {
363363
final def canConstrain(param: TypeParamRef): Boolean =
364364
(!frozenConstraint || (caseLambda `eq` param.binder)) && constraint.contains(param)
365365

366+
/** Is `param` assumed to be a sub- and super-type of any other type?
367+
* This holds if `TypeVarsMissContext` is set unless `param` is a part
368+
* of a MatchType that is currently normalized.
369+
*/
370+
final def assumedTrue(param: TypeParamRef): Boolean =
371+
ctx.mode.is(Mode.TypevarsMissContext) && (caseLambda `ne` param.binder)
372+
366373
/** Add constraint `param <: bound` if `fromBelow` is false, `param >: bound` otherwise.
367374
* `bound` is assumed to be in normalized form, as specified in `firstTry` and
368375
* `secondTry` of `TypeComparer`. In particular, it should not be an alias type,

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

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,6 @@ class Definitions {
342342
def NullType = NullClass.typeRef
343343
lazy val RuntimeNullModuleRef = ctx.requiredModuleRef("scala.runtime.Null")
344344

345-
lazy val ImplicitScrutineeTypeSym =
346-
newSymbol(ScalaPackageClass, tpnme.IMPLICITkw, EmptyFlags, TypeBounds.empty).entered
347-
def ImplicitScrutineeTypeRef: TypeRef = ImplicitScrutineeTypeSym.typeRef
348-
349345
lazy val ScalaPredefModuleRef = ctx.requiredModuleRef("scala.Predef")
350346
def ScalaPredefModule(implicit ctx: Context) = ScalaPredefModuleRef.symbol
351347

@@ -939,7 +935,8 @@ class Definitions {
939935
def scalaClassName(ref: Type)(implicit ctx: Context): TypeName = scalaClassName(ref.classSymbol)
940936

941937
private def isVarArityClass(cls: Symbol, prefix: String) =
942-
scalaClassName(cls).testSimple(name =>
938+
cls.isClass && cls.owner.eq(ScalaPackageClass) &&
939+
cls.name.testSimple(name =>
943940
name.startsWith(prefix) &&
944941
name.length > prefix.length &&
945942
name.drop(prefix.length).forall(_.isDigit))
@@ -1159,6 +1156,14 @@ class Definitions {
11591156
def isAssuredNoInits(sym: Symbol) =
11601157
(sym `eq` SomeClass) || isTupleClass(sym)
11611158

1159+
/** If `cls` is Tuple1..Tuple22, add the corresponding *: type as last parent to `parents` */
1160+
def adjustForTuple(cls: ClassSymbol, tparams: List[TypeSymbol], parents: List[Type]): List[Type] = {
1161+
def syntheticParent(tparams: List[TypeSymbol]): Type =
1162+
if (tparams.isEmpty) TupleTypeRef
1163+
else (tparams :\ (UnitType: Type)) ((tparam, tail) => PairType.appliedTo(tparam.typeRef, tail))
1164+
if (isTupleClass(cls) || cls == UnitClass) parents :+ syntheticParent(tparams) else parents
1165+
}
1166+
11621167
// ----- primitive value class machinery ------------------------------------------
11631168

11641169
/** This class would also be obviated by the implicit function type design */
@@ -1254,33 +1259,12 @@ class Definitions {
12541259

12551260
/** Lists core methods that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
12561261
lazy val syntheticCoreMethods =
1257-
AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod, ImplicitScrutineeTypeSym)
1262+
AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod)
12581263

12591264
lazy val reservedScalaClassNames: Set[Name] = syntheticScalaClasses.map(_.name).toSet
12601265

12611266
private[this] var isInitialized = false
12621267

1263-
/** Add a `Tuple` as a parent to `Unit`.
1264-
* Add the right `*:` instance as a parent to Tuple1..Tuple22
1265-
*/
1266-
def fixTupleCompleter(cls: ClassSymbol): Unit = cls.infoOrCompleter match {
1267-
case completer: LazyType =>
1268-
cls.info = new LazyType {
1269-
def syntheticParent(tparams: List[TypeSymbol]): Type =
1270-
if (tparams.isEmpty) TupleTypeRef
1271-
else (tparams :\ (UnitType: Type)) ((tparam, tail) => PairType.appliedTo(tparam.typeRef, tail))
1272-
override def complete(denot: SymDenotation)(implicit ctx: Context) = {
1273-
completer.complete(denot)
1274-
denot.info match {
1275-
case info: ClassInfo =>
1276-
denot.info = info.derivedClassInfo(
1277-
classParents = info.classParents :+ syntheticParent(cls.typeParams))
1278-
}
1279-
}
1280-
}
1281-
case _ =>
1282-
}
1283-
12841268
def init()(implicit ctx: Context) = {
12851269
this.ctx = ctx
12861270
if (!isInitialized) {
@@ -1298,10 +1282,6 @@ class Definitions {
12981282
// force initialization of every symbol that is synthesized or hijacked by the compiler
12991283
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
13001284

1301-
fixTupleCompleter(UnitClass)
1302-
for (i <- 1 to MaxTupleArity)
1303-
fixTupleCompleter(TupleType(i).symbol.asClass)
1304-
13051285
isInitialized = true
13061286
}
13071287
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ object Flags {
351351
/** A bridge method. Set by Erasure */
352352
final val Bridge = termFlag(34, "<bridge>")
353353

354+
/** A proxy for an argument to an inline method */
355+
final val InlineProxy = termFlag(35, "<inline proxy>")
356+
354357
/** Symbol is a method which should be marked ACC_SYNCHRONIZED */
355358
final val Synchronized = termFlag(36, "<synchronized>")
356359

@@ -545,6 +548,9 @@ object Flags {
545548
/** Either method or lazy or deferred */
546549
final val MethodOrLazyOrDeferred = Method | Lazy | Deferred
547550

551+
/** An inline method or inline argument proxy */
552+
final val InlineOrProxy = Inline | InlineProxy
553+
548554
/** Assumed to be pure */
549555
final val StableOrErased = Stable | Erased
550556

0 commit comments

Comments
 (0)