Skip to content

Commit dbd5a4d

Browse files
committed
Scond step to typer reorg: Introduce TypeAssigners.
TypeAssigners assign a toplevel type to a node. They are mixed into Typer, and can be accessed from tpd using ctx.typeAssigner.
1 parent 2669fac commit dbd5a4d

File tree

7 files changed

+72
-41
lines changed

7 files changed

+72
-41
lines changed

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

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import config.Printers._
1111
/** Some creators for typed trees */
1212
object tpd extends Trees.Instance[Type] with TypedTreeInfo {
1313

14+
private def ta(implicit ctx: Context) = ctx.typeAssigner
15+
1416
def Modifiers(sym: Symbol)(implicit ctx: Context): Modifiers = Modifiers(
1517
sym.flags & ModifierFlags,
1618
if (sym.privateWithin.exists) sym.privateWithin.asType.name else tpnme.EMPTY,
@@ -68,27 +70,13 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
6870
}
6971

7072
def Literal(const: Constant)(implicit ctx: Context): Literal =
71-
typedLiteral(untpd.Literal(const))
72-
73-
def typedLiteral(tree: untpd.Literal)(implicit ctx: Context) =
74-
tree.withType {
75-
tree.const.tag match {
76-
case UnitTag => defn.UnitType
77-
case NullTag => defn.NullType
78-
case _ => ConstantType(tree.const)
79-
}
80-
}
73+
ta.assignType(untpd.Literal(const))
8174

8275
def unitLiteral(implicit ctx: Context): Literal =
8376
Literal(Constant(()))
8477

8578
def New(tpt: Tree)(implicit ctx: Context): New =
86-
untpd.New(tpt).withType(tpt.tpe).checked
87-
88-
def typedNew(tree: untpd.New)(implicit ctx: Context) = {
89-
ctx.typer.checkClassTypeWithStablePrefix(tree.tpt.tpe, tree.tpt.pos, traitReq = false)
90-
tree.withType(tree.tpt.tpe)
91-
}
79+
ta.assignType(untpd.New(tpt))
9280

9381
def New(tp: Type)(implicit ctx: Context): New = New(TypeTree(tp))
9482

src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,11 @@ object Contexts {
119119
protected def scope_=(scope: Scope) = _scope = scope
120120
def scope: Scope = _scope
121121

122-
/** The current typer */
123-
private[this] var _typer: Typer = _
124-
protected def typer_=(typer: Typer) = _typer = typer
125-
def typer: Typer = _typer
122+
/** The current type assigner ot typer */
123+
private[this] var _typeAssigner: TypeAssigner = _
124+
protected def typeAssigner_=(typeAssigner: TypeAssigner) = _typeAssigner = typeAssigner
125+
def typeAssigner: TypeAssigner = _typeAssigner
126+
def typer: Typer = _typeAssigner.asInstanceOf[Typer]
126127

127128
/** The currently active import info */
128129
private[this] var _importInfo: ImportInfo = _
@@ -312,7 +313,8 @@ object Contexts {
312313
def withTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this }
313314
def withScope(scope: Scope): this.type = { this.scope = scope; this }
314315
def withNewScope: this.type = { this.scope = newScope; this }
315-
def withTyper(typer: Typer): this.type = { this.typer = typer; this.scope = typer.scope; this }
316+
def withTypeAssigner(typeAssigner: TypeAssigner): this.type = { this.typeAssigner = typeAssigner; this }
317+
def withTyper(typer: Typer): this.type = { this.scope = typer.scope; withTypeAssigner(typer) }
316318
def withImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this }
317319
def withRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this }
318320
def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
@@ -342,6 +344,7 @@ object Contexts {
342344
owner = NoSymbol
343345
sstate = settings.defaultState
344346
tree = untpd.EmptyTree
347+
typeAssigner = TypeAssigner
345348
runInfo = new RunInfo(this)
346349
diagnostics = None
347350
moreProperties = Map.empty

src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,23 @@ import ErrorReporting.{errorType, InfoString}
1818
import config.Printers._
1919
import collection.mutable
2020

21-
trait Checking {
21+
trait NoChecking {
22+
import tpd._
23+
def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit = ()
24+
def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = ()
25+
def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp
26+
def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = ()
27+
def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = ()
28+
def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp
29+
def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = ()
30+
}
31+
32+
trait Checking extends NoChecking {
2233

2334
import tpd._
2435

2536
/** Check that type arguments `args` conform to corresponding bounds in `poly` */
26-
def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit =
37+
override def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit =
2738
for ((arg, bounds) <- args zip poly.paramBounds) {
2839
def notConforms(which: String, bound: Type) =
2940
ctx.error(i"Type argument ${arg.tpe} does not conform to $which bound $bound", arg.pos)
@@ -34,14 +45,14 @@ trait Checking {
3445
/** Check that type `tp` is stable.
3546
* @return The type itself
3647
*/
37-
def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit =
48+
override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit =
3849
if (!tp.isStable) ctx.error(i"Prefix of type ${tp.widenIfUnstable} is not stable", pos)
3950

4051
/** Check that `tp` is a class type with a stable prefix. Also, if `isFirst` is
4152
* false check that `tp` is a trait.
4253
* @return `tp` itself if it is a class or trait ref, ObjectClass.typeRef if not.
4354
*/
44-
def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type =
55+
override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type =
4556
tp.underlyingClassRef match {
4657
case tref: TypeRef =>
4758
checkStable(tref.prefix, pos)
@@ -53,7 +64,7 @@ trait Checking {
5364
}
5465

5566
/** Check that (return) type of implicit definition is not empty */
56-
def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = defTree.tpt match {
67+
override def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = defTree.tpt match {
5768
case TypeTree(original) if original.isEmpty =>
5869
val resStr = if (defTree.isInstanceOf[untpd.DefDef]) "result " else ""
5970
ctx.error(i"${resStr}type of implicit definition needs to be given explicitly", defTree.pos)
@@ -63,7 +74,7 @@ trait Checking {
6374
/** Check that a non-implicit parameter making up the first parameter section of an
6475
* implicit conversion is not a singleton type.
6576
*/
66-
def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = vparamss match {
77+
override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = vparamss match {
6778
case (vparam :: Nil) :: _ if !(vparam.symbol is Implicit) =>
6879
if (vparam.tpt.tpe.isInstanceOf[SingletonType])
6980
ctx.error(s"implicit conversion may not have a parameter of singleton type", vparam.tpt.pos)
@@ -74,7 +85,7 @@ trait Checking {
7485
* their lower bound conforms to their upper cound. If a type argument is
7586
* infeasible, issue and error and continue with upper bound.
7687
*/
77-
def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp match {
88+
override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp match {
7889
case tp: RefinedType =>
7990
tp.derivedRefinedType(tp.parent, tp.refinedName, checkFeasible(tp.refinedInfo, pos, where))
8091
case tp @ TypeBounds(lo, hi) if !(lo <:< hi) =>
@@ -85,7 +96,7 @@ trait Checking {
8596
}
8697

8798
/** Check that class does not define */
88-
def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = {
99+
override def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = {
89100
val seen = new mutable.HashMap[Name, List[Symbol]] {
90101
override def default(key: Name) = Nil
91102
}

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,16 @@ trait NamerContextOps { this: Context =>
5858
/** The symbol (stored in some typer's symTree) of an enclosing context definition */
5959
def symOfContextTree(tree: untpd.Tree) = {
6060
def go(ctx: Context): Symbol = {
61-
val typer = ctx.typer
62-
if (typer == null) NoSymbol
63-
else tree.getAttachment(typer.SymOfTree) match {
64-
case Some(sym) => sym
65-
case None =>
66-
var cx = ctx.outer
67-
while (cx.typer eq typer) cx = cx.outer
68-
go(cx)
61+
ctx.typeAssigner match {
62+
case typer: Typer =>
63+
tree.getAttachment(typer.SymOfTree) match {
64+
case Some(sym) => sym
65+
case None =>
66+
var cx = ctx.outer
67+
while (cx.typeAssigner eq typer) cx = cx.outer
68+
go(cx)
69+
}
70+
case _ => NoSymbol
6971
}
7072
}
7173
go(this)

src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ object ProtoTypes {
103103
def map(tm: TypeMap)(implicit ctx: Context) = derivedSelectionProto(name, tm(memberProto), compat)
104104
def fold[T](x: T, ta: TypeAccumulator[T])(implicit ctx: Context) = ta(x, memberProto)
105105

106-
override def computeHash = addDelta(doHash(name, memberProto), if (compat == NoViewsAllowed) 1 else 0)
106+
override def computeHash = addDelta(doHash(name, memberProto), if (compat eq NoViewsAllowed) 1 else 0)
107107
}
108108

109109
class CachedSelectionProto(name: Name, memberProto: Type, compat: Compatibility) extends SelectionProto(name, memberProto, compat)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package dotty.tools
2+
package dotc
3+
package typer
4+
5+
import core._
6+
import ast._
7+
import Scopes._, Contexts._, Constants._, Types._, Symbols._
8+
9+
trait TypeAssigner extends NoChecking {
10+
11+
def assignType(tree: untpd.New)(implicit ctx: Context) = {
12+
checkClassTypeWithStablePrefix(tree.tpt.tpe, tree.tpt.pos, traitReq = false)
13+
tree.withType(tree.tpt.tpe)
14+
}
15+
16+
def assignType(tree: untpd.Literal)(implicit ctx: Context) =
17+
tree.withType {
18+
tree.const.tag match {
19+
case UnitTag => defn.UnitType
20+
case NullTag => defn.NullType
21+
case _ => ConstantType(tree.const)
22+
}
23+
}
24+
}
25+
26+
object TypeAssigner extends TypeAssigner
27+

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ object Typer {
4848
}
4949
}
5050

51-
class Typer extends Namer with Applications with Implicits with Inferencing with Checking {
51+
class Typer extends Namer with TypeAssigner with Applications with Implicits with Inferencing with Checking {
5252

5353
import Typer._
5454
import tpd.{cpy => _, _}
@@ -413,7 +413,7 @@ class Typer extends Namer with Applications with Implicits with Inferencing with
413413
}
414414

415415
def typedLiteral(tree: untpd.Literal)(implicit ctx: Context) = track("typedLiteral") {
416-
tpd.typedLiteral(tree)
416+
assignType(tree)
417417
}
418418

419419
def typedNew(tree: untpd.New, pt: Type)(implicit ctx: Context) = track("typedNew") {
@@ -425,7 +425,7 @@ class Typer extends Namer with Applications with Implicits with Inferencing with
425425
typed(cpy.Block(tree, clsDef :: Nil, New(Ident(x), Nil)), pt)
426426
case _ =>
427427
val tpt1 = typedType(tree.tpt)
428-
tpd.typedNew(cpy.New(tree, tpt1))
428+
assignType(cpy.New(tree, tpt1))
429429
// todo in a later phase: checkInstantiatable(cls, tpt1.pos)
430430
}
431431
}

0 commit comments

Comments
 (0)