diff options
author | Martin Odersky <odersky@gmail.com> | 2014-05-07 19:06:17 +0200 |
---|---|---|
committer | Samuel Gruetter <samuel.gruetter@epfl.ch> | 2014-05-20 13:38:49 +0200 |
commit | fb3dba1bac13a755d2304928cbd49e7dde6f1bf9 (patch) | |
tree | a4e712103779decdebc439e33aa2c3f8f16890e8 /src/dotty/tools/dotc/typer/TypeAssigner.scala | |
parent | f7910005038c188e573e8d1a42ff3e31c69c90c1 (diff) | |
download | dotty-fb3dba1bac13a755d2304928cbd49e7dde6f1bf9.tar.gz dotty-fb3dba1bac13a755d2304928cbd49e7dde6f1bf9.tar.bz2 dotty-fb3dba1bac13a755d2304928cbd49e7dde6f1bf9.zip |
Avoid hoisting of local classes out of method bodies.
Doing so is unsound. We instead approximate local classes by their parents, but
only if the expected type is not fully defined.
This makes the test t2421_delitedsl1.scala in the commit pass. The oter test,
blockEscapesNeg.scala is modified to fail. Previously it failed outright but with the
new rules the nested class Bar is approximated to Object. That means that the block
containing `Foo.Bar` typechecks, but with type `Object` instead of the unreachable `Bar`.
Diffstat (limited to 'src/dotty/tools/dotc/typer/TypeAssigner.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/TypeAssigner.scala | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index 13f65d424..48c263085 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -52,10 +52,14 @@ trait TypeAssigner { def apply(tp: Type) = tp match { case tp: TermRef if toAvoid(tp) && variance > 0 => apply(tp.info) - case tp: TypeRef if toAvoid(tp.prefix) => + case tp: TypeRef if (forbidden contains tp.symbol) || toAvoid(tp.prefix) => tp.info match { - case TypeAlias(ref) => apply(ref) - case _ => mapOver(tp) + case TypeAlias(ref) => + apply(ref) + case info: ClassInfo => + mapOver(info.instantiatedParents.reduceLeft(AndType(_, _))) + case _ => + mapOver(tp) } case tp: RefinedType => val tp1 @ RefinedType(parent1, _) = mapOver(tp) @@ -247,7 +251,7 @@ trait TypeAssigner { tree.withType(defn.UnitType) def assignType(tree: untpd.Block, stats: List[Tree], expr: Tree)(implicit ctx: Context) = - tree.withType(avoid(expr.tpe, localSyms(stats))) + tree.withType(avoid(expr.tpe, localSyms(stats) filter (_.isTerm))) def assignType(tree: untpd.If, thenp: Tree, elsep: Tree)(implicit ctx: Context) = tree.withType(thenp.tpe | elsep.tpe) |