diff options
author | Martin Odersky <odersky@gmail.com> | 2013-08-01 18:21:23 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-08-01 18:21:23 +0200 |
commit | dbb4b3f7923427af4ba6e04f258309421d5ee1ab (patch) | |
tree | c8d47cbae32a0778d0bff3a22117d9d4a7c5ff7f /src/dotty/tools/dotc/ast/CheckTrees.scala | |
parent | 413f364887d5bde7610adbbc08020e23470b4c8c (diff) | |
download | dotty-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.scala | 43 |
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)) |