aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/ast/CheckTrees.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-01 18:21:23 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-01 18:21:23 +0200
commitdbb4b3f7923427af4ba6e04f258309421d5ee1ab (patch)
treec8d47cbae32a0778d0bff3a22117d9d4a7c5ff7f /src/dotty/tools/dotc/ast/CheckTrees.scala
parent413f364887d5bde7610adbbc08020e23470b4c8c (diff)
downloaddotty-dbb4b3f7923427af4ba6e04f258309421d5ee1ab.tar.gz
dotty-dbb4b3f7923427af4ba6e04f258309421d5ee1ab.tar.bz2
dotty-dbb4b3f7923427af4ba6e04f258309421d5ee1ab.zip
Handling typevars in inference.
Fleshed out handling of typevars for type inference. Also added some more methods to typer, for blocks, ifs and assignments. (Closures are still wip).
Diffstat (limited to 'src/dotty/tools/dotc/ast/CheckTrees.scala')
-rw-r--r--src/dotty/tools/dotc/ast/CheckTrees.scala43
1 files changed, 23 insertions, 20 deletions
diff --git a/src/dotty/tools/dotc/ast/CheckTrees.scala b/src/dotty/tools/dotc/ast/CheckTrees.scala
index a004789e6..b1806df4b 100644
--- a/src/dotty/tools/dotc/ast/CheckTrees.scala
+++ b/src/dotty/tools/dotc/ast/CheckTrees.scala
@@ -17,6 +17,27 @@ object CheckTrees {
check(bounds contains arg.tpe)
}
+ def escapingRefs(block: Block)(implicit ctx: Context): Set[NamedType] = {
+ var hoisted: Set[Symbol] = Set()
+ lazy val locals = localSyms(block.stats).toSet
+ def isNonLocal(sym: Symbol): Boolean =
+ !(locals contains sym) || isHoistableClass(sym)
+ def isHoistableClass(sym: Symbol) =
+ sym.isClass && {
+ (hoisted contains sym) || {
+ hoisted += sym
+ !classLeaks(sym.asClass)
+ }
+ }
+ def leakingTypes(tp: Type): Set[NamedType] =
+ tp namedPartsWith (tp => isNonLocal(tp.symbol))
+ def typeLeaks(tp: Type) = leakingTypes(tp).isEmpty
+ def classLeaks(sym: ClassSymbol): Boolean =
+ (sym.info.parents exists typeLeaks) ||
+ (sym.decls.toList exists (t => typeLeaks(t.info)))
+ leakingTypes(block.tpe)
+ }
+
def checkType(tree: Tree)(implicit ctx: Context): Unit = tree match {
case Ident(name) =>
case Select(qualifier, name) =>
@@ -79,27 +100,9 @@ object CheckTrees {
check(false)
}
check(rhs.tpe <:< lhs.tpe.widen)
- case Block(stats, expr) =>
- var hoisted: Set[Symbol] = Set()
- lazy val locals = localSyms(stats).toSet
+ case tree @ Block(stats, expr) =>
check(expr.isValue)
- def isNonLocal(sym: Symbol): Boolean =
- !(locals contains sym) || isHoistableClass(sym)
- def isHoistableClass(sym: Symbol) =
- sym.isClass && {
- (hoisted contains sym) || {
- hoisted += sym
- noLeaksInClass(sym.asClass)
- }
- }
- def noLeaksIn(tp: Type): Boolean = tp forallParts {
- case tp: NamedType => isNonLocal(tp.symbol)
- case _ => true
- }
- def noLeaksInClass(sym: ClassSymbol): Boolean =
- (sym.info.parents forall noLeaksIn) &&
- (sym.decls.toList forall (t => noLeaksIn(t.info)))
- check(noLeaksIn(tree.tpe))
+ check(escapingRefs(tree).isEmpty)
case If(cond, thenp, elsep) =>
check(cond.isValue); check(thenp.isValue); check(elsep.isValue)
check(cond.tpe.derivesFrom(defn.BooleanClass))