diff options
author | Martin Odersky <odersky@gmail.com> | 2008-04-15 15:10:29 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2008-04-15 15:10:29 +0000 |
commit | 9b98538679982778c37b8c7e822d014a484fa10b (patch) | |
tree | 7d3dadfc1f20990b0c94d2a890ac109e665c0898 | |
parent | 1ce782ce2f6e38823037cd8f8694fcac379313d7 (diff) | |
download | scala-9b98538679982778c37b8c7e822d014a484fa10b.tar.gz scala-9b98538679982778c37b8c7e822d014a484fa10b.tar.bz2 scala-9b98538679982778c37b8c7e822d014a484fa10b.zip |
refined type checking rules wrt selftypes for n...
refined type checking rules wrt selftypes for new's in valdefs.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 6d75b2c9a4..481b7159f6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2364,14 +2364,29 @@ trait Typers { self: Analyzer => .setOriginal(tpt1) /* .setPos(tpt1.pos) */ .setType(appliedType(tpt1.tpe, context.undetparams map (_.tpe))) } + def narrowRhs(tp: Type) = { + var sym = context.tree.symbol + if (sym != null && sym != NoSymbol && sym.owner.isClass && sym.getter(sym.owner) != NoSymbol) + sym = sym.getter(sym.owner) + context.tree match { + case ValDef(_, _, _, Apply(Select(`tree`, _), _)) if (sym.isStable) => +// println("narrowing...") + val pre = if (sym.owner.isClass) sym.owner.thisType else NoPrefix + intersectionType(List(tp, singleType(pre, sym))) + case _ => +// println("no narrow: "+sym+" "+sym.isStable+" "+context.tree+"//"+tree) + tp + } + } if (tpt1.tpe.typeSymbol.isAbstractType || (tpt1.tpe.typeSymbol hasFlag ABSTRACT)) error(tree.pos, tpt1.tpe.typeSymbol + " is abstract; cannot be instantiated") else if (tpt1.tpe.typeSymbol.initialize.thisSym != tpt1.tpe.typeSymbol && - !(tpt1.tpe <:< tpt1.tpe.typeOfThis) && - !phase.erasedTypes) + !(narrowRhs(tpt1.tpe) <:< tpt1.tpe.typeOfThis) && + !phase.erasedTypes) { error(tree.pos, tpt1.tpe.typeSymbol + " cannot be instantiated because it does not conform to its self-type "+ tpt1.tpe.typeOfThis) + } copy.New(tree, tpt1).setType(tpt1.tpe) } |