Skip to content

Refactor Tree parameterization, with tweaks #16301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ import scala.collection.mutable

import scala.annotation.tailrec

trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>

// Note: the <: Type constraint looks necessary (and is needed to make the file compile in dotc).
// But Scalac accepts the program happily without it. Need to find out why.
trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] =>

def unsplice(tree: Trees.Tree[T]): Trees.Tree[T] = tree

Expand Down
308 changes: 153 additions & 155 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
/** mods object name impl */
case class ModuleDef(name: TermName, impl: Template)(implicit @constructorOnly src: SourceFile)
extends MemberDef {
type ThisTree[-T >: Untyped] <: Trees.NameTree[T] with Trees.MemberDef[T] with ModuleDef
type ThisTree[+T <: Untyped] <: Trees.NameTree[T] with Trees.MemberDef[T] with ModuleDef
def withName(name: Name)(using Context): ModuleDef = cpy.ModuleDef(this)(name.toTermName, impl)
}

Expand Down
10 changes: 5 additions & 5 deletions compiler/src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ object Contexts {
final def owner: Symbol = _owner

/** The current tree */
private var _tree: Tree[? >: Untyped]= _
protected def tree_=(tree: Tree[? >: Untyped]): Unit = _tree = tree
final def tree: Tree[? >: Untyped] = _tree
private var _tree: Tree[?]= _
protected def tree_=(tree: Tree[?]): Unit = _tree = tree
final def tree: Tree[?] = _tree

/** The current scope */
private var _scope: Scope = _
Expand Down Expand Up @@ -469,7 +469,7 @@ object Contexts {
}

/** The context of expression `expr` seen as a member of a statement sequence */
def exprContext(stat: Tree[? >: Untyped], exprOwner: Symbol): Context =
def exprContext(stat: Tree[?], exprOwner: Symbol): Context =
if (exprOwner == this.owner) this
else if (untpd.isSuperConstrCall(stat) && this.owner.isClass) superCallContext
else fresh.setOwner(exprOwner)
Expand Down Expand Up @@ -592,7 +592,7 @@ object Contexts {
assert(owner != NoSymbol)
this.owner = owner
this
def setTree(tree: Tree[? >: Untyped]): this.type =
def setTree(tree: Tree[?]): this.type =
util.Stats.record("Context.setTree")
this.tree = tree
this
Expand Down
10 changes: 0 additions & 10 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -745,16 +745,6 @@ object Types {
// which means that we always defensively copy the type in the future. This second
// measure is necessary because findMember calls might be cached, so do not
// necessarily appear in nested order.
// Without the defensive copy, Typer.scala fails to compile at the line
//
// untpd.rename(lhsCore, setterName).withType(setterType), WildcardType)
//
// because the subtype check
//
// ThisTree[Untyped]#ThisTree[Typed] <: Tree[Typed]
//
// fails (in fact it thinks the underlying type of the LHS is `Tree[Untyped]`.)
//
// Without the `openedTwice` trick, Typer.scala fails to Ycheck
// at phase resolveSuper.
val rt =
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
def toText(sc: Scope): Text =
("Scope{" ~ dclsText(sc.toList) ~ "}").close

def toText[T >: Untyped](tree: Tree[T]): Text = {
def toText[T <: Untyped](tree: Tree[T]): Text = {
def toTextElem(elem: Any): Text = elem match {
case elem: Showable => elem.toText(this)
case elem: List[?] => "List(" ~ Text(elem map toTextElem, ",") ~ ")"
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/printing/Printer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ abstract class Printer {
def toText(sc: Scope): Text

/** Textual representation of tree */
def toText[T >: Untyped](tree: Tree[T]): Text
def toText[T <: Untyped](tree: Tree[T]): Text

/** Textual representation of source position */
def toText(pos: SourcePosition): Text
Expand Down
34 changes: 17 additions & 17 deletions compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {

override def printerContext: Context = myCtx

def withEnclosingDef(enclDef: Tree[? >: Untyped])(op: => Text): Text = {
def withEnclosingDef(enclDef: Tree[?])(op: => Text): Text = {
val savedCtx = myCtx
if (enclDef.hasType && enclDef.symbol.exists)
myCtx = ctx.withOwner(enclDef.symbol)
Expand Down Expand Up @@ -308,15 +308,15 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
protected def exprToText(tp: ExprType): Text =
"=> " ~ toText(tp.resType)

protected def blockToText[T >: Untyped](block: Block[T]): Text =
protected def blockToText[T <: Untyped](block: Block[T]): Text =
blockText(block.stats :+ block.expr)

protected def blockText[T >: Untyped](trees: List[Tree[T]]): Text =
protected def blockText[T <: Untyped](trees: List[Tree[T]]): Text =
inContextBracket {
("{" ~ toText(trees, "\n") ~ "}").close
}

protected def typeApplyText[T >: Untyped](tree: TypeApply[T]): Text = {
protected def typeApplyText[T <: Untyped](tree: TypeApply[T]): Text = {
val funText = toTextLocal(tree.fun)
tree.fun match {
case Select(New(tpt), nme.CONSTRUCTOR) if tpt.typeOpt.dealias.isInstanceOf[AppliedType] =>
Expand All @@ -326,7 +326,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}
}

protected def toTextCore[T >: Untyped](tree: Tree[T]): Text = {
protected def toTextCore[T <: Untyped](tree: Tree[T]): Text = {
import untpd._

def isLocalThis(tree: Tree) = tree.typeOpt match {
Expand Down Expand Up @@ -739,7 +739,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}
}

override def toText[T >: Untyped](tree: Tree[T]): Text = controlled {
override def toText[T <: Untyped](tree: Tree[T]): Text = controlled {
import untpd._

var txt = toTextCore(tree)
Expand Down Expand Up @@ -826,7 +826,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {

protected def dropAnnotForModText(sym: Symbol): Boolean = sym == defn.BodyAnnot

protected def optAscription[T >: Untyped](tpt: Tree[T]): Text = optText(tpt)(": " ~ _)
protected def optAscription[T <: Untyped](tpt: Tree[T]): Text = optText(tpt)(": " ~ _)

private def idText(tree: untpd.Tree): Text =
(if showUniqueIds && tree.hasType && tree.symbol.exists then s"#${tree.symbol.id}" else "") ~
Expand All @@ -842,7 +842,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
private def useSymbol(tree: untpd.Tree) =
tree.hasType && tree.symbol.exists && ctx.settings.YprintSyms.value

protected def nameIdText[T >: Untyped](tree: NameTree[T]): Text =
protected def nameIdText[T <: Untyped](tree: NameTree[T]): Text =
if (tree.hasType && tree.symbol.exists) {
val str = nameString(tree.symbol)
tree match {
Expand All @@ -856,13 +856,13 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
private def toTextOwner(tree: Tree[?]) =
"[owner = " ~ tree.symbol.maybeOwner.show ~ "]" provided ctx.settings.YprintDebugOwners.value

protected def dclTextOr[T >: Untyped](tree: Tree[T])(treeText: => Text): Text =
protected def dclTextOr[T <: Untyped](tree: Tree[T])(treeText: => Text): Text =
toTextOwner(tree) ~ {
if (useSymbol(tree)) annotsText(tree.symbol) ~~ dclText(tree.symbol)
else treeText
}

def paramsText[T>: Untyped](params: ParamClause[T]): Text = (params: @unchecked) match
def paramsText[T <: Untyped](params: ParamClause[T]): Text = (params: @unchecked) match
case Nil =>
"()"
case untpd.ValDefs(vparams @ (vparam :: _)) =>
Expand All @@ -872,18 +872,18 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case untpd.TypeDefs(tparams) =>
"[" ~ toText(tparams, ", ") ~ "]"

def addParamssText[T >: Untyped](leading: Text, paramss: List[ParamClause[T]]): Text =
def addParamssText[T <: Untyped](leading: Text, paramss: List[ParamClause[T]]): Text =
paramss.foldLeft(leading)((txt, params) => txt ~ paramsText(params))

protected def valDefToText[T >: Untyped](tree: ValDef[T]): Text = {
protected def valDefToText[T <: Untyped](tree: ValDef[T]): Text = {
dclTextOr(tree) {
modText(tree.mods, tree.symbol, keywordStr(if (tree.mods.is(Mutable)) "var" else "val"), isType = false) ~~
valDefText(nameIdText(tree)) ~ optAscription(tree.tpt) ~
withEnclosingDef(tree) { optText(tree.rhs)(" = " ~ _) }
}
}

protected def defDefToText[T >: Untyped](tree: DefDef[T]): Text = {
protected def defDefToText[T <: Untyped](tree: DefDef[T]): Text = {
import untpd._
dclTextOr(tree) {
val defKeyword = modText(tree.mods, tree.symbol, keywordStr("def"), isType = false)
Expand Down Expand Up @@ -989,8 +989,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
)
}

protected def toTextPackageId[T >: Untyped](pid: Tree[T]): Text =
if (homogenizedView && pid.hasType) toTextLocal(pid.tpe.asInstanceOf[Showable])
protected def toTextPackageId[T <: Untyped](pid: Tree[T]): Text =
if (homogenizedView && pid.hasType) toTextLocal(pid.typeOpt)
else toTextLocal(pid)

protected def packageDefText(tree: PackageDef): Text = {
Expand Down Expand Up @@ -1044,10 +1044,10 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
def optText(name: Name)(encl: Text => Text): Text =
if (name.isEmpty) "" else encl(toText(name))

def optText[T >: Untyped](tree: Tree[T])(encl: Text => Text): Text =
def optText[T <: Untyped](tree: Tree[T])(encl: Text => Text): Text =
if (tree.isEmpty) "" else encl(toText(tree))

def optText[T >: Untyped](tree: List[Tree[T]])(encl: Text => Text): Text =
def optText[T <: Untyped](tree: List[Tree[T]])(encl: Text => Text): Text =
if (tree.exists(!_.isEmpty)) encl(blockText(tree)) else ""

override protected def treatAsTypeParam(sym: Symbol): Boolean = sym.is(TypeParam)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,7 @@ import cc.CaptureSet.IdentityCaptRefMap
|""".stripMargin
}

class TypeDoesNotTakeParameters(tpe: Type, params: List[Trees.Tree[Trees.Untyped]])(using Context)
class TypeDoesNotTakeParameters(tpe: Type, params: List[untpd.Tree])(using Context)
extends TypeMsg(TypeDoesNotTakeParametersID) {
private def fboundsAddendum =
if tpe.typeSymbol.isAllOf(Provisional | TypeParam) then
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ object Erasure {
* are handled separately by [[typedDefDef]], [[typedValDef]] and [[typedTyped]].
*/
override def typedTypeTree(tree: untpd.TypeTree, pt: Type)(using Context): TypeTree =
checkNotErasedClass(tree.withType(erasure(tree.tpe)))
checkNotErasedClass(tree.withType(erasure(tree.typeOpt)))

/** This override is only needed to semi-erase type ascriptions */
override def typedTyped(tree: untpd.Typed, pt: Type)(using Context): Tree =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class InterceptedMethods extends MiniPhase {
override def transformApply(tree: Apply)(using Context): Tree = {
lazy val qual = tree.fun match {
case Select(qual, _) => qual
case ident @ Ident(_) =>
case ident: Ident =>
ident.tpe match {
case TermRef(prefix: TermRef, _) =>
tpd.ref(prefix)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ class TreeChecker extends Phase with SymTransformer {

override def typedIdent(tree: untpd.Ident, pt: Type)(using Context): Tree = {
assert(tree.isTerm || !ctx.isAfterTyper, tree.show + " at " + ctx.phase)
assert(tree.isType || ctx.mode.is(Mode.Pattern) && untpd.isWildcardArg(tree) || !needsSelect(tree.tpe), i"bad type ${tree.tpe} for $tree # ${tree.uniqueId}")
assert(tree.isType || ctx.mode.is(Mode.Pattern) && untpd.isWildcardArg(tree) || !needsSelect(tree.typeOpt), i"bad type ${tree.tpe} for $tree # ${tree.uniqueId}")
assertDefined(tree)

checkNotRepeated(super.typedIdent(tree, pt))
Expand Down
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import core._
import ast.{Trees, tpd, untpd, desugar}
import util.Stats.record
import util.{SrcPos, NoSourcePosition}
import Trees.Untyped
import Contexts._
import Flags._
import Symbols._
Expand Down Expand Up @@ -491,7 +490,7 @@ trait Applications extends Compatibility {
i"${err.refStr(methRef)}$infoStr"

/** Re-order arguments to correctly align named arguments */
def reorder[T >: Untyped](args: List[Trees.Tree[T]]): List[Trees.Tree[T]] = {
def reorder[T <: Untyped](args: List[Trees.Tree[T]]): List[Trees.Tree[T]] = {

/** @param pnames The list of parameter names that are missing arguments
* @param args The list of arguments that are not yet passed, or that are waiting to be dropped
Expand Down Expand Up @@ -754,7 +753,7 @@ trait Applications extends Compatibility {
/** Subclass of Application for type checking an Apply node, where
* types of arguments are either known or unknown.
*/
abstract class TypedApply[T >: Untyped](
abstract class TypedApply[T <: Untyped](
app: untpd.Apply, fun: Tree, methRef: TermRef, args: List[Trees.Tree[T]], resultType: Type,
override val applyKind: ApplyKind)(using Context)
extends Application(methRef, fun.tpe, args, resultType) {
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/ReTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking
promote(tree)

override def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(using Context): TypTree =
promote(TypeTree(tree.tpe).withSpan(tree.span))
promote(TypeTree(tree.typeOpt).withSpan(tree.span))

override def typedExport(exp: untpd.Export)(using Context): Export =
promote(exp)
Expand All @@ -87,8 +87,8 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking
// retract PatternOrTypeBits like in typedExpr
withoutMode(Mode.PatternOrTypeBits)(typedUnadapted(tree.fun, AnyFunctionProto))
val implicits1 = tree.implicits.map(typedExpr(_))
val patterns1 = tree.patterns.mapconserve(pat => typed(pat, pat.tpe))
untpd.cpy.UnApply(tree)(fun1, implicits1, patterns1).withType(tree.tpe)
val patterns1 = tree.patterns.mapconserve(pat => typed(pat, pat.typeOpt))
untpd.cpy.UnApply(tree)(fun1, implicits1, patterns1).withType(tree.typeOpt)
}

override def typedUnApply(tree: untpd.Apply, selType: Type)(using Context): Tree =
Expand Down