aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-10-01 14:21:27 +0200
committerMartin Odersky <odersky@gmail.com>2013-10-01 14:21:27 +0200
commitf039fa7fa2544998426764bd05ea8f18179eb0bd (patch)
tree6f5431d1824702284d16e581eb620a849a1c2f91 /src/dotty/tools/dotc/typer
parentb733e929b60fd1b5a3fc961fd23e720679ce09d3 (diff)
downloaddotty-f039fa7fa2544998426764bd05ea8f18179eb0bd.tar.gz
dotty-f039fa7fa2544998426764bd05ea8f18179eb0bd.tar.bz2
dotty-f039fa7fa2544998426764bd05ea8f18179eb0bd.zip
Added option -Yheartbeat
… which shows snapshot of the callstack of tracked operations at fixed intervals.
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala54
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala29
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala21
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala255
4 files changed, 190 insertions, 169 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 3216e8b74..05008ac1a 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -5,6 +5,7 @@ package typer
import core._
import ast.{Trees, untpd, tpd, TreeInfo}
import util.Positions._
+import util.Stats.track
import Trees.Untyped
import Mode.ImplicitsEnabled
import Contexts._
@@ -447,8 +448,9 @@ trait Applications extends Compatibility { self: Typer =>
def treeToArg(arg: Tree): Tree = arg
}
- def typedApply(app: untpd.Apply, fun: Tree, methRef: TermRef, args: List[Tree], resultType: Type)(implicit ctx: Context): Tree =
+ def typedApply(app: untpd.Apply, fun: Tree, methRef: TermRef, args: List[Tree], resultType: Type)(implicit ctx: Context): Tree = track("typedApply") {
new ApplyToTyped(app, fun, methRef, args, resultType).result
+ }
def typedApply(fun: Tree, methRef: TermRef, args: List[Tree], resultType: Type)(implicit ctx: Context): Tree =
typedApply(untpd.Apply(untpd.TypedSplice(fun), args), fun, methRef, args, resultType)
@@ -458,7 +460,7 @@ trait Applications extends Compatibility { self: Typer =>
typedUnApply(tree, pt)
else {
- def realApply(implicit ctx: Context): Tree = {
+ def realApply(implicit ctx: Context): Tree = track("realApply") {
val proto = new FunProto(tree.args, pt, this)
val fun1 = typedExpr(tree.fun, proto)
methPart(fun1).tpe match {
@@ -473,7 +475,7 @@ trait Applications extends Compatibility { self: Typer =>
case Select(qual, name) =>
tryEither { implicit ctx =>
val qual1 = adapt(qual, new SelectionProto(name, proto))
- if (qual1.tpe.isError || (qual1 eq qual)) qual1
+ if (qual1.tpe.isError || (qual1 eq qual)) qual1
else
typedApply(
cpy.Apply(tree,
@@ -494,7 +496,7 @@ trait Applications extends Compatibility { self: Typer =>
}
}
- def typedOpAssign: Tree = {
+ def typedOpAssign: Tree = track("typedOpAssign") {
val Apply(Select(lhs, name), rhss) = tree
val lhs1 = typedExpr(lhs)
val lifted = new mutable.ListBuffer[Tree]
@@ -517,7 +519,7 @@ trait Applications extends Compatibility { self: Typer =>
}
}
- def typedTypeApply(tree: untpd.TypeApply, pt: Type)(implicit ctx: Context): Tree = {
+ def typedTypeApply(tree: untpd.TypeApply, pt: Type)(implicit ctx: Context): Tree = track("typedTypeApply") {
val typedFn = typedExpr(tree.fun, PolyProto(tree.args.length, pt))
val typedArgs = tree.args mapconserve (typedType(_))
val ownType = typedFn.tpe.widen match {
@@ -531,7 +533,7 @@ trait Applications extends Compatibility { self: Typer =>
cpy.TypeApply(tree, typedFn, typedArgs).withType(ownType)
}
- def typedUnApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
+ def typedUnApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = track("typedUnApply") {
val Apply(qual, args) = tree
def unapplyArgs(unapplyResult: Type)(implicit ctx: Context): List[Type] = {
@@ -662,7 +664,7 @@ trait Applications extends Compatibility { self: Typer =>
/** In a set of overloaded applicable alternatives, is `alt1` at least as good as
* `alt2`? `alt1` and `alt2` are nonoverloaded references.
*/
- def isAsGood(alt1: TermRef, alt2: TermRef)(implicit ctx: Context): Boolean = {
+ def isAsGood(alt1: TermRef, alt2: TermRef)(implicit ctx: Context): Boolean = track("isAsGood") {
/** Is class or module class `sym1` derived from class or module class `sym2`? */
def isDerived(sym1: Symbol, sym2: Symbol): Boolean =
@@ -712,30 +714,32 @@ trait Applications extends Compatibility { self: Typer =>
else /* 1/9 */ winsType1 || /* 2/27 */ !winsType2
}
- def narrowMostSpecific(alts: List[TermRef])(implicit ctx: Context): List[TermRef] = (alts: @unchecked) match {
- case alt :: alts1 =>
- def winner(bestSoFar: TermRef, alts: List[TermRef]): TermRef = alts match {
- case alt :: alts1 =>
- winner(if (isAsGood(alt, bestSoFar)) alt else bestSoFar, alts1)
- case nil =>
- bestSoFar
- }
- val best = winner(alt, alts1)
- def asGood(alts: List[TermRef]): List[TermRef] = alts match {
- case alt :: alts1 =>
- if ((alt eq best) || !isAsGood(alt, best)) asGood(alts1)
- else alt :: asGood(alts1)
- case nil =>
- Nil
- }
- best :: asGood(alts1)
+ def narrowMostSpecific(alts: List[TermRef])(implicit ctx: Context): List[TermRef] = track("narrowMostSpecific") {
+ (alts: @unchecked) match {
+ case alt :: alts1 =>
+ def winner(bestSoFar: TermRef, alts: List[TermRef]): TermRef = alts match {
+ case alt :: alts1 =>
+ winner(if (isAsGood(alt, bestSoFar)) alt else bestSoFar, alts1)
+ case nil =>
+ bestSoFar
+ }
+ val best = winner(alt, alts1)
+ def asGood(alts: List[TermRef]): List[TermRef] = alts match {
+ case alt :: alts1 =>
+ if ((alt eq best) || !isAsGood(alt, best)) asGood(alts1)
+ else alt :: asGood(alts1)
+ case nil =>
+ Nil
+ }
+ best :: asGood(alts1)
+ }
}
private lazy val dummyTree = untpd.Literal(Constant(null))
def dummyTreeOfType(tp: Type): Tree = dummyTree withTypeUnchecked tp
/** Resolve overloaded alternative `alts`, given expected type `pt`. */
- def resolveOverloaded(alts: List[TermRef], pt: Type)(implicit ctx: Context): List[TermRef] = {
+ def resolveOverloaded(alts: List[TermRef], pt: Type)(implicit ctx: Context): List[TermRef] = track("resolveOverloaded") {
def isDetermined(alts: List[TermRef]) = alts.isEmpty || alts.tail.isEmpty
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 52b856864..98163a7f5 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -5,6 +5,7 @@ package typer
import core._
import ast.{Trees, untpd, tpd, TreeInfo}
import util.Positions._
+import util.Stats.track
import Contexts._
import Types._
import Flags._
@@ -35,7 +36,7 @@ object Implicits {
def refs: List[TermRef]
/** Return those references in `refs` that are compatible with type `pt`. */
- protected def filterMatching(pt: Type)(implicit ctx: Context): List[TermRef] = {
+ protected def filterMatching(pt: Type)(implicit ctx: Context): List[TermRef] = track("filterMatching") {
def result(implicit ctx: Context) =
refs filter (ref => isCompatible(normalize(ref), pt))
result(ctx.fresh.withNewTyperState) // create a defensive copy of ctx to avoid constraint pollution
@@ -180,7 +181,7 @@ trait ImplicitRunInfo { self: RunInfo =>
}
// todo: compute implicits directly, without going via companionRefs
- private def computeImplicitScope(tp: Type): OfTypeImplicits = {
+ private def computeImplicitScope(tp: Type): OfTypeImplicits = track("computeImplicicScope") {
val comps = new TermRefSet
tp match {
case tp: NamedType =>
@@ -239,8 +240,9 @@ trait Implicits { self: Typer =>
/** Find an implicit conversion to apply to given tree `from` so that the
* result is compatible with type `to`.
*/
- def inferView(from: tpd.Tree, to: Type)(implicit ctx: Context): SearchResult =
+ def inferView(from: tpd.Tree, to: Type)(implicit ctx: Context): SearchResult = track("inferView") {
inferImplicit(to, from, from.pos)
+ }
/** Find an implicit parameter or conversion.
* @param pt The expected type of the parameter or conversion.
@@ -248,17 +250,18 @@ trait Implicits { self: Typer =>
* it should be applied, EmptyTree otherwise.
* @param pos The position where errors should be reported.
*/
- def inferImplicit(pt: Type, argument: Tree, pos: Position)(implicit ctx: Context): SearchResult =
+ def inferImplicit(pt: Type, argument: Tree, pos: Position)(implicit ctx: Context): SearchResult = track("inferImplicit") {
ctx.traceIndented(s"search implicit $pt, arg = ${argument.show}", show = true) {
- val isearch =
- if (ctx.settings.explaintypes.value) new ExplainedImplicitSearch(pt, argument, pos)
- else new ImplicitSearch(pt, argument, pos)
- val result = isearch.bestImplicit
- result match {
- case success: SearchSuccess => success.tstate.commit()
- case _ =>
+ val isearch =
+ if (ctx.settings.explaintypes.value) new ExplainedImplicitSearch(pt, argument, pos)
+ else new ImplicitSearch(pt, argument, pos)
+ val result = isearch.bestImplicit
+ result match {
+ case success: SearchSuccess => success.tstate.commit()
+ case _ =>
+ }
+ result
}
- result
}
/** An implicit search; parameters as in `inferImplicit` */
@@ -275,7 +278,7 @@ trait Implicits { self: Typer =>
ctx.typerState.checkConsistent // !!! DEBUG
/** Try to typecheck an implicit reference */
- def typedImplicit(ref: TermRef)(implicit ctx: Context): SearchResult = {
+ def typedImplicit(ref: TermRef)(implicit ctx: Context): SearchResult = track("typedImplicit") {
ctx.typerState.checkConsistent // !!! DEBUG
val id = Ident(ref).withPos(pos)
val tree =
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index c514699a3..6f78409d0 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -8,6 +8,7 @@ import Contexts._, Types._, Flags._, Denotations._, Names._, StdNames._, NameOps
import Trees._
import annotation.unchecked
import util.Positions._
+import util.Stats
import Decorators._
import ErrorReporting.InfoString
@@ -96,13 +97,15 @@ object Inferencing {
* - converts non-dependent method types to the corresponding function types
* - dereferences parameterless method types
*/
- def normalize(tp: Type)(implicit ctx: Context): Type = tp.widenSingleton match {
- case pt: PolyType => normalize(ctx.track(pt).resultType)
- case mt: MethodType if !mt.isDependent =>
- if (mt.isImplicit) mt.resultType
- else defn.FunctionType(mt.paramTypes, mt.resultType)
- case et: ExprType => et.resultType
- case _ => tp
+ def normalize(tp: Type)(implicit ctx: Context): Type = Stats.track("normalize") {
+ tp.widenSingleton match {
+ case pt: PolyType => normalize(ctx.track(pt).resultType)
+ case mt: MethodType if !mt.isDependent =>
+ if (mt.isImplicit) mt.resultType
+ else defn.FunctionType(mt.paramTypes, mt.resultType)
+ case et: ExprType => et.resultType
+ case _ => tp
+ }
}
/** Is type fully defined, meaning the type does not contain wildcard types
@@ -188,7 +191,7 @@ object Inferencing {
* approximate it by its lower bound. Otherwise, if it appears contravariantly
* in type `tp` approximate it by its upper bound.
*/
- def interpolateUndetVars(tp: Type, pos: Position): Unit = {
+ def interpolateUndetVars(tp: Type, pos: Position): Unit = Stats.track("interpolateUndetVars") {
val vs = tp.variances(tvar =>
(ctx.typerState.undetVars contains tvar) && (pos contains tvar.pos))
for ((tvar, v) <- vs)
@@ -211,7 +214,7 @@ object Inferencing {
* maximized and return None. If this is not possible, because a non-variant
* typevar is not uniquely determined, return that typevar in a Some.
*/
- def maximizeType(tp: Type): Option[TypeVar] = {
+ def maximizeType(tp: Type): Option[TypeVar] = Stats.track("maximizeType") {
val vs = tp.variances(tvar => ctx.typerState.undetVars contains tvar)
var result: Option[TypeVar] = None
for ((tvar, v) <- vs)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 224b3fcb1..e902864d6 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -27,6 +27,7 @@ import util.SourcePosition
import collection.mutable
import annotation.tailrec
import Implicits._
+import util.Stats.track
import language.implicitConversions
trait TyperContextOps { ctx: Context => }
@@ -151,7 +152,7 @@ class Typer extends Namer with Applications with Implicits {
* (2) Change imported symbols to selections
*
*/
- def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = {
+ def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = track("typedIdent") {
val name = tree.name
/** Method is necessary because error messages need to bind to
@@ -334,19 +335,19 @@ class Typer extends Namer with Applications with Implicits {
tree.withType(ownType.underlyingIfRepeated)
}
- def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
+ def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = track("typedSelect") {
val qual1 = typedExpr(tree.qualifier, selectionProto(tree.name, pt))
val ownType = checkedSelectionType(qual1, tree)
checkValue(ownType, pt, tree.pos)
cpy.Select(tree, qual1, tree.name).withType(ownType)
}
- def typedThis(tree: untpd.This)(implicit ctx: Context): Tree = {
+ def typedThis(tree: untpd.This)(implicit ctx: Context): Tree = track("typedThis") {
val cls = qualifyingClass(tree, tree.qual, packageOK = false)
tree.withType(cls.thisType)
}
- def typedSuper(tree: untpd.Super)(implicit ctx: Context): Tree = {
+ def typedSuper(tree: untpd.Super)(implicit ctx: Context): Tree = track("typedSuper") {
val mix = tree.mix
val qual1 = typed(tree.qual)
val cls = qual1.tpe.typeSymbol
@@ -367,7 +368,7 @@ class Typer extends Namer with Applications with Implicits {
cpy.Super(tree, qual1, mix).withType(SuperType(cls.thisType, owntype))
}
- def typedLiteral(tree: untpd.Literal)(implicit ctx: Context) =
+ def typedLiteral(tree: untpd.Literal)(implicit ctx: Context) = track("typedLiteral") {
tree.withType {
tree.const.tag match {
case UnitTag => defn.UnitType
@@ -375,21 +376,24 @@ class Typer extends Namer with Applications with Implicits {
case _ => ConstantType(tree.const)
}
}
+ }
- def typedNew(tree: untpd.New, pt: Type)(implicit ctx: Context) = tree.tpt match {
- case templ: Template =>
- import untpd._
- val x = tpnme.ANON_CLASS
- val clsDef = TypeDef(Modifiers(Final), x, templ)
- typed(cpy.Block(tree, clsDef :: Nil, New(Ident(x), Nil)), pt)
- case _ =>
- val tpt1 = typedType(tree.tpt)
- val cls = checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos)
- // todo in a later phase: checkInstantiatable(cls, tpt1.pos)
- cpy.New(tree, tpt1).withType(tpt1.tpe)
+ def typedNew(tree: untpd.New, pt: Type)(implicit ctx: Context) = track("typedNew") {
+ tree.tpt match {
+ case templ: Template =>
+ import untpd._
+ val x = tpnme.ANON_CLASS
+ val clsDef = TypeDef(Modifiers(Final), x, templ)
+ typed(cpy.Block(tree, clsDef :: Nil, New(Ident(x), Nil)), pt)
+ case _ =>
+ val tpt1 = typedType(tree.tpt)
+ val cls = checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos)
+ // todo in a later phase: checkInstantiatable(cls, tpt1.pos)
+ cpy.New(tree, tpt1).withType(tpt1.tpe)
+ }
}
- def typedPair(tree: untpd.Pair, pt: Type)(implicit ctx: Context) = {
+ def typedPair(tree: untpd.Pair, pt: Type)(implicit ctx: Context) = track("typedPair") {
val (leftProto, rightProto) = pt.typeArgs match {
case l :: r :: Nil if pt isRef defn.PairClass => (l, r)
case _ => (WildcardType, WildcardType)
@@ -399,51 +403,55 @@ class Typer extends Namer with Applications with Implicits {
cpy.Pair(tree, left1, right1).withType(defn.PairType.appliedTo(left1.tpe :: right1.tpe :: Nil))
}
- def typedTyped(tree: untpd.Typed, pt: Type)(implicit ctx: Context): Tree = tree.expr match {
- case id: Ident if (ctx.mode is Mode.Pattern) && isVarPattern(id) && id.name != nme.WILDCARD =>
- import untpd._
- typed(Bind(id.name, Typed(Ident(nme.WILDCARD), tree.tpt)).withPos(id.pos))
- case _ =>
- val tpt1 = typedType(tree.tpt)
- val expr1 = typedExpr(tree.expr, tpt1.tpe)
- cpy.Typed(tree, expr1, tpt1).withType(tpt1.tpe)
+ def typedTyped(tree: untpd.Typed, pt: Type)(implicit ctx: Context): Tree = track("typedTyped") {
+ tree.expr match {
+ case id: Ident if (ctx.mode is Mode.Pattern) && isVarPattern(id) && id.name != nme.WILDCARD =>
+ import untpd._
+ typed(Bind(id.name, Typed(Ident(nme.WILDCARD), tree.tpt)).withPos(id.pos))
+ case _ =>
+ val tpt1 = typedType(tree.tpt)
+ val expr1 = typedExpr(tree.expr, tpt1.tpe)
+ cpy.Typed(tree, expr1, tpt1).withType(tpt1.tpe)
+ }
}
- def typedNamedArg(tree: untpd.NamedArg, pt: Type)(implicit ctx: Context) = {
+ def typedNamedArg(tree: untpd.NamedArg, pt: Type)(implicit ctx: Context) = track("typedNamedArg") {
val arg1 = typed(tree.arg, pt)
cpy.NamedArg(tree, tree.name, arg1).withType(arg1.tpe)
}
- def typedAssign(tree: untpd.Assign, pt: Type)(implicit ctx: Context) = tree.lhs match {
- case lhs @ Apply(fn, args) =>
- typed(cpy.Apply(lhs, untpd.Select(fn, nme.update), args :+ tree.rhs), pt)
- case lhs =>
- val lhs1 = typed(lhs)
- def reassignmentToVal =
- errorTree(cpy.Assign(tree, lhs1, typed(tree.rhs, lhs1.tpe.widen)),
- "reassignment to val")
- lhs1.tpe match {
- case ref: TermRef if ref.symbol is Mutable =>
- cpy.Assign(tree, lhs1, typed(tree.rhs, ref.info)).withType(defn.UnitType)
- case ref: TermRef if ref.info.isParameterless =>
- val pre = ref.prefix
- val setterName = ref.name.setterName
- val setter = pre.member(setterName)
- lhs1 match {
- case lhs1: RefTree if setter.exists =>
- val setterTypeRaw = TermRef(pre, setterName).withDenot(setter)
- val setterType = checkAccessible(setterTypeRaw, isSuperSelection(tree), tree.pos)
- val lhs2 = lhs1.withName(setterName).withType(setterType)
- typed(cpy.Apply(tree, untpd.TypedSplice(lhs2), tree.rhs :: Nil))
- case _ =>
- reassignmentToVal
- }
- case _ =>
- reassignmentToVal
- }
+ def typedAssign(tree: untpd.Assign, pt: Type)(implicit ctx: Context) = track("typedAssign") {
+ tree.lhs match {
+ case lhs @ Apply(fn, args) =>
+ typed(cpy.Apply(lhs, untpd.Select(fn, nme.update), args :+ tree.rhs), pt)
+ case lhs =>
+ val lhs1 = typed(lhs)
+ def reassignmentToVal =
+ errorTree(cpy.Assign(tree, lhs1, typed(tree.rhs, lhs1.tpe.widen)),
+ "reassignment to val")
+ lhs1.tpe match {
+ case ref: TermRef if ref.symbol is Mutable =>
+ cpy.Assign(tree, lhs1, typed(tree.rhs, ref.info)).withType(defn.UnitType)
+ case ref: TermRef if ref.info.isParameterless =>
+ val pre = ref.prefix
+ val setterName = ref.name.setterName
+ val setter = pre.member(setterName)
+ lhs1 match {
+ case lhs1: RefTree if setter.exists =>
+ val setterTypeRaw = TermRef(pre, setterName).withDenot(setter)
+ val setterType = checkAccessible(setterTypeRaw, isSuperSelection(tree), tree.pos)
+ val lhs2 = lhs1.withName(setterName).withType(setterType)
+ typed(cpy.Apply(tree, untpd.TypedSplice(lhs2), tree.rhs :: Nil))
+ case _ =>
+ reassignmentToVal
+ }
+ case _ =>
+ reassignmentToVal
+ }
+ }
}
- def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context) = {
+ def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context) = track("typedBlock") {
val exprCtx = index(tree.stats)
val stats1 = typedStats(tree.stats, ctx.owner)
val expr1 = typedExpr(tree.expr, pt)(exprCtx)
@@ -457,14 +465,14 @@ class Typer extends Namer with Applications with Implicits {
i"local definition of ${leaks.head.name} escapes as part of block's type ${result.tpe}")
}
- def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context) = {
+ def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context) = track("typedIf") {
val cond1 = typed(tree.cond, defn.BooleanType)
val thenp1 = typed(tree.thenp, pt)
val elsep1 = typed(if (tree.elsep.isEmpty) unitLiteral else tree.elsep, pt)
cpy.If(tree, cond1, thenp1, elsep1).withType(thenp1.tpe | elsep1.tpe)
}
- def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context) = {
+ def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context) = track("typedFunction") {
val untpd.Function(args, body) = tree
if (ctx.mode is Mode.Type)
typed(cpy.AppliedTypeTree(tree,
@@ -493,7 +501,7 @@ class Typer extends Namer with Applications with Implicits {
}
}
- def typedClosure(tree: untpd.Closure, pt: Type)(implicit ctx: Context) = {
+ def typedClosure(tree: untpd.Closure, pt: Type)(implicit ctx: Context) = track("typedClosure") {
val env1 = tree.env mapconserve (typed(_))
val meth1 = typedUnadapted(tree.meth)
val ownType = meth1.tpe.widen match {
@@ -507,56 +515,58 @@ class Typer extends Namer with Applications with Implicits {
cpy.Closure(tree, env1, meth1, EmptyTree).withType(ownType)
}
- def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context) = tree.selector match {
- case EmptyTree =>
- typed(desugar.makeCaseLambda(tree.cases) withPos tree.pos, pt)
- case _ =>
- val sel1 = typedExpr(tree.selector)
- val selType =
- if (isFullyDefined(sel1.tpe)) sel1.tpe
- else errorType("internal error: type of pattern selector is not fully defined", tree.pos)
+ def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context) = track("typedMatch") {
+ tree.selector match {
+ case EmptyTree =>
+ typed(desugar.makeCaseLambda(tree.cases) withPos tree.pos, pt)
+ case _ =>
+ val sel1 = typedExpr(tree.selector)
+ val selType =
+ if (isFullyDefined(sel1.tpe)) sel1.tpe
+ else errorType("internal error: type of pattern selector is not fully defined", tree.pos)
+
+ /** gadtSyms = "all type parameters of enclosing methods that appear
+ * non-variantly in the selector type
+ */
+ val gadtSyms: Set[Symbol] = {
+ val accu = new TypeAccumulator[Set[Symbol]] {
+ def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = {
+ val tsyms1 = t match {
+ case tr: TypeRef if (tr.symbol is TypeParam) && tr.symbol.owner.isTerm && variance == 0 =>
+ tsyms + tr.symbol
+ case _ =>
+ tsyms
+ }
+ foldOver(tsyms1, t)
+ }
+ }
+ accu(Set.empty, selType)
+ }
- /** gadtSyms = "all type parameters of enclosing methods that appear
- * non-variantly in the selector type
- */
- val gadtSyms: Set[Symbol] = {
- val accu = new TypeAccumulator[Set[Symbol]] {
- def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = {
- val tsyms1 = t match {
- case tr: TypeRef if (tr.symbol is TypeParam) && tr.symbol.owner.isTerm && variance == 0 =>
- tsyms + tr.symbol
+ def typedCase(tree: untpd.CaseDef): CaseDef = track("typedCase") {
+ def caseRest(pat: Tree)(implicit ctx: Context) = {
+ gadtSyms foreach (_.resetGADTFlexType)
+ foreachSubTreeOf(pat) {
+ case b: Bind =>
+ if (ctx.scope.lookup(b.name) == NoSymbol) ctx.enter(b.symbol)
+ else ctx.error(i"duplicate pattern variable: ${b.name}", b.pos)
case _ =>
- tsyms
}
- foldOver(tsyms1, t)
+ val guard1 = typedExpr(tree.guard, defn.BooleanType)
+ val body1 = typedExpr(tree.body, pt)
+ cpy.CaseDef(tree, pat, guard1, body1) withType body1.tpe
}
+ val doCase: () => CaseDef =
+ () => caseRest(typedPattern(tree.pat, selType))(ctx.fresh.withNewScope)
+ (doCase /: gadtSyms)((op, tsym) => tsym.withGADTFlexType(op))()
}
- accu(Set.empty, selType)
- }
- def typedCase(tree: untpd.CaseDef): CaseDef = {
- def caseRest(pat: Tree)(implicit ctx: Context) = {
- gadtSyms foreach (_.resetGADTFlexType)
- foreachSubTreeOf(pat) {
- case b: Bind =>
- if (ctx.scope.lookup(b.name) == NoSymbol) ctx.enter(b.symbol)
- else ctx.error(i"duplicate pattern variable: ${b.name}", b.pos)
- case _ =>
- }
- val guard1 = typedExpr(tree.guard, defn.BooleanType)
- val body1 = typedExpr(tree.body, pt)
- cpy.CaseDef(tree, pat, guard1, body1) withType body1.tpe
- }
- val doCase: () => CaseDef =
- () => caseRest(typedPattern(tree.pat, selType))(ctx.fresh.withNewScope)
- (doCase /: gadtSyms) ((op, tsym) => tsym.withGADTFlexType(op)) ()
+ val cases1 = tree.cases mapconserve typedCase
+ cpy.Match(tree, sel1, cases1).withType(ctx.typeComparer.lub(cases1.tpes))
}
-
- val cases1 = tree.cases mapconserve typedCase
- cpy.Match(tree, sel1, cases1).withType(ctx.typeComparer.lub(cases1.tpes))
}
- def typedReturn(tree: untpd.Return)(implicit ctx: Context): Return = {
+ def typedReturn(tree: untpd.Return)(implicit ctx: Context): Return = track("typedReturn") {
def enclMethInfo(cx: Context): (Tree, Type) =
if (cx == NoContext || cx.tree.isInstanceOf[Trees.TypeDef[_]]) {
ctx.error("return outside method definition")
@@ -582,7 +592,7 @@ class Typer extends Namer with Applications with Implicits {
cpy.Return(tree, expr1, from) withType defn.NothingType
}
- def typedTry(tree: untpd.Try, pt: Type)(implicit ctx: Context): Try = {
+ def typedTry(tree: untpd.Try, pt: Type)(implicit ctx: Context): Try = track("typedTry") {
val expr1 = typed(tree.expr, pt)
val handler1 = typed(tree.handler, defn.FunctionType(defn.ThrowableType :: Nil, pt))
val finalizer1 = typed(tree.finalizer, defn.UnitType)
@@ -593,18 +603,18 @@ class Typer extends Namer with Applications with Implicits {
cpy.Try(tree, expr1, handler1, finalizer1).withType(expr1.tpe | handlerResultType)
}
- def typedThrow(tree: untpd.Throw)(implicit ctx: Context): Throw = {
+ def typedThrow(tree: untpd.Throw)(implicit ctx: Context): Throw = track("typedThrow") {
val expr1 = typed(tree.expr, defn.ThrowableType)
cpy.Throw(tree, expr1) withType defn.NothingType
}
- def typedSeqLiteral(tree: untpd.SeqLiteral, pt: Type)(implicit ctx: Context): SeqLiteral = {
+ def typedSeqLiteral(tree: untpd.SeqLiteral, pt: Type)(implicit ctx: Context): SeqLiteral = track("typedSeqLiteral") {
val proto1 = pt.elemType orElse WildcardType
val elems1 = tree.elems mapconserve (typed(_, proto1))
cpy.SeqLiteral(tree, elems1) withType ctx.typeComparer.lub(elems1.tpes)
}
- def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = {
+ def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") {
val (original1, ownType) = tree.original match {
case untpd.EmptyTree =>
assert(isFullyDefined(pt))
@@ -620,30 +630,30 @@ class Typer extends Namer with Applications with Implicits {
cpy.TypeTree(tree, original1) withType ownType
}
- def typedSingletonTypeTree(tree: untpd.SingletonTypeTree)(implicit ctx: Context): SingletonTypeTree = {
+ def typedSingletonTypeTree(tree: untpd.SingletonTypeTree)(implicit ctx: Context): SingletonTypeTree = track("typedSingletonTypeTree") {
val ref1 = typedExpr(tree.ref)
checkStable(ref1.qualifierType, tree.pos)
cpy.SingletonTypeTree(tree, ref1) withType ref1.tpe
}
- def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): SelectFromTypeTree = {
+ def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): SelectFromTypeTree = track("typedSelectFromTypeTree") {
val qual1 = typedType(tree.qualifier, selectionProto(tree.name, pt))
cpy.SelectFromTypeTree(tree, qual1, tree.name).withType(checkedSelectionType(qual1, tree))
}
- def typedAndTypeTree(tree: untpd.AndTypeTree)(implicit ctx: Context): AndTypeTree = {
+ def typedAndTypeTree(tree: untpd.AndTypeTree)(implicit ctx: Context): AndTypeTree = track("typedAndTypeTree") {
val left1 = typed(tree.left)
val right1 = typed(tree.right)
cpy.AndTypeTree(tree, left1, right1) withType left1.tpe & right1.tpe
}
- def typedOrTypeTree(tree: untpd.OrTypeTree)(implicit ctx: Context): OrTypeTree = {
+ def typedOrTypeTree(tree: untpd.OrTypeTree)(implicit ctx: Context): OrTypeTree = track("typedOrTypeTree") {
val left1 = typed(tree.left)
val right1 = typed(tree.right)
cpy.OrTypeTree(tree, left1, right1) withType left1.tpe | right1.tpe
}
- def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(implicit ctx: Context): RefinedTypeTree = {
+ def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(implicit ctx: Context): RefinedTypeTree = track("typedRefinedTypeTree") {
val tpt1 = typedAheadType(tree.tpt)
val refineClsDef = desugar.refinedTypeToClass(tree)
val refineCls = createSymbol(refineClsDef).asClass
@@ -664,7 +674,7 @@ class Typer extends Namer with Applications with Implicits {
(tpt1.tpe /: refinements1)(addRefinement)
}
- def typedAppliedTypeTree(tree: untpd.AppliedTypeTree)(implicit ctx: Context): AppliedTypeTree = {
+ def typedAppliedTypeTree(tree: untpd.AppliedTypeTree)(implicit ctx: Context): AppliedTypeTree = track("typedAppliedTypeTree") {
val tpt1 = typed(tree.tpt)
val args1 = tree.args mapconserve (typed(_))
val tparams = tpt1.tpe.typeParams
@@ -674,7 +684,7 @@ class Typer extends Namer with Applications with Implicits {
cpy.AppliedTypeTree(tree, tpt1, args1) withType tpt1.tpe.appliedTo(args1.tpes)
}
- def typedTypeBoundsTree(tree: untpd.TypeBoundsTree)(implicit ctx: Context): TypeBoundsTree = {
+ def typedTypeBoundsTree(tree: untpd.TypeBoundsTree)(implicit ctx: Context): TypeBoundsTree = track("typedTypeBoundsTree") {
val lo1 = typed(tree.lo)
val hi1 = typed(tree.hi)
if (!(lo1.tpe <:< hi1.tpe))
@@ -682,27 +692,28 @@ class Typer extends Namer with Applications with Implicits {
cpy.TypeBoundsTree(tree, lo1, hi1) withType TypeBounds(lo1.tpe, hi1.tpe)
}
- def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Bind = {
+ def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Bind = track("typedBind") {
val body1 = typed(tree.body, pt)
val sym = ctx.newSymbol(ctx.owner, tree.name.asTermName, EmptyFlags, pt, coord = tree.pos)
cpy.Bind(tree, tree.name, body1) withType TermRef.withSym(NoPrefix, sym)
}
- def typedAlternative(tree: untpd.Alternative, pt: Type)(implicit ctx: Context): Alternative = {
+ def typedAlternative(tree: untpd.Alternative, pt: Type)(implicit ctx: Context): Alternative = track("typedAlternative") {
val trees1 = tree.trees mapconserve (typed(_, pt))
cpy.Alternative(tree, trees1) withType ctx.typeComparer.lub(trees1.tpes)
}
- def typedModifiers(mods: untpd.Modifiers)(implicit ctx: Context): Modifiers = {
+ def typedModifiers(mods: untpd.Modifiers)(implicit ctx: Context): Modifiers = track("typedModifiers") {
val annotations1 = mods.annotations mapconserve typedAnnotation
if (annotations1 eq mods.annotations) mods.asInstanceOf[Modifiers]
else Modifiers(mods.flags, mods.privateWithin, annotations1)
}
- def typedAnnotation(annot: untpd.Tree)(implicit ctx: Context): Tree =
+ def typedAnnotation(annot: untpd.Tree)(implicit ctx: Context): Tree = track("typedAnnotation") {
typed(annot, defn.AnnotationClass.typeConstructor)
+ }
- def typedValDef(vdef: untpd.ValDef, sym: Symbol)(implicit ctx: Context) = {
+ def typedValDef(vdef: untpd.ValDef, sym: Symbol)(implicit ctx: Context) = track("typedValDef") {
val ValDef(mods, name, tpt, rhs) = vdef
val mods1 = typedModifiers(mods)
val tpt1 = typedType(tpt)
@@ -711,7 +722,7 @@ class Typer extends Namer with Applications with Implicits {
cpy.ValDef(vdef, mods1, name, tpt1, rhs1).withType(refType)
}
- def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = {
+ def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = track("typedDefDef") {
val DefDef(mods, name, tparams, vparamss, tpt, rhs) = ddef
val mods1 = typedModifiers(mods)
val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef])
@@ -722,14 +733,14 @@ class Typer extends Namer with Applications with Implicits {
//todo: make sure dependent method types do not depend on implicits or by-name params
}
- def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): TypeDef = {
+ def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): TypeDef = track("typedTypeDef") {
val TypeDef(mods, name, rhs) = tdef
val mods1 = typedModifiers(mods)
val rhs1 = typedType(rhs)
cpy.TypeDef(tdef, mods1, name, rhs1).withType(sym.symRef)
}
- def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context) = {
+ def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context) = track("typedClassDef") {
val TypeDef(mods, name, impl @ Template(constr, parents, self, body)) = cdef
val mods1 = typedModifiers(mods)
val constr1 = typed(constr).asInstanceOf[DefDef]
@@ -751,12 +762,12 @@ class Typer extends Namer with Applications with Implicits {
// 4. Polymorphic type defs override nothing.
}
- def typedImport(imp: untpd.Import, sym: Symbol)(implicit ctx: Context): Import = {
+ def typedImport(imp: untpd.Import, sym: Symbol)(implicit ctx: Context): Import = track("typedImport") {
val expr1 = typedExpr(imp.expr, AnySelectionProto)
cpy.Import(imp, expr1, imp.selectors).withType(sym.symRef)
}
- def typedAnnotated(tree: untpd.Annotated, pt: Type)(implicit ctx: Context): Tree = {
+ def typedAnnotated(tree: untpd.Annotated, pt: Type)(implicit ctx: Context): Tree = track("typedAnnotated") {
val annot1 = typed(tree.annot, defn.AnnotationClass.typeConstructor)
val arg1 = typed(tree.arg, pt)
val ownType = AnnotatedType(Annotation(annot1), arg1.tpe)
@@ -766,7 +777,7 @@ class Typer extends Namer with Applications with Implicits {
cpy.Typed(tree, arg1, TypeTree(ownType)) withType ownType
}
- def typedPackageDef(tree: untpd.PackageDef)(implicit ctx: Context): Tree = {
+ def typedPackageDef(tree: untpd.PackageDef)(implicit ctx: Context): Tree = track("typedPackageDef") {
val pid1 = typedExpr(tree.pid, AnySelectionProto)
val pkg = pid1.symbol
val packageContext =
@@ -953,7 +964,7 @@ class Typer extends Namer with Applications with Implicits {
* (14) When in mode EXPRmode, apply a view
* If all this fails, error
*/
- def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree = ctx.traceIndented(i"adapting $tree of type ${tree.tpe} to $pt", show = false) {
+ def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree = track("adapt") { ctx.traceIndented(i"adapting $tree of type ${tree.tpe} to $pt", show = false) {
assert(pt.exists)
@@ -1085,5 +1096,5 @@ class Typer extends Namer with Applications with Implicits {
}
}
}
- }
+ }}
} \ No newline at end of file