summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2010-09-14 12:37:50 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2010-09-14 12:37:50 +0000
commitce755fb08dbd3bdfe202d3ea52a8e599d846b4c1 (patch)
tree5f07ea16f293ec578aea6347dd9393fc0a85e17c /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parentc0f03d837c9af04f404e800ce6fbeb65d1eac38a (diff)
downloadscala-ce755fb08dbd3bdfe202d3ea52a8e599d846b4c1.tar.gz
scala-ce755fb08dbd3bdfe202d3ea52a8e599d846b4c1.tar.bz2
scala-ce755fb08dbd3bdfe202d3ea52a8e599d846b4c1.zip
closes #3612.
given the definitions below (for full context, see test file), before, O0 would work but O would not, now both are accepted: {{{ object O0 extends C {} object O extends C { self => } }}} review by odersky
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala60
1 files changed, 30 insertions, 30 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 8248c5c950..461ed8b2cc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3206,44 +3206,44 @@ trait Typers { self: Analyzer =>
}
def typedNew(tpt: Tree) = {
- var tpt1 = typedTypeConstructor(tpt)
- checkClassType(tpt1, false, true)
- if (tpt1.hasSymbol && !tpt1.symbol.typeParams.isEmpty) {
- context.undetparams = cloneSymbols(tpt1.symbol.typeParams)
- tpt1 = TypeTree()
- .setOriginal(tpt1)
- .setType(appliedType(tpt1.tpe, context.undetparams map (_.tpe)))
+ val tpt1 = {
+ val tpt0 = typedTypeConstructor(tpt)
+ checkClassType(tpt0, false, true)
+ if (tpt0.hasSymbol && !tpt0.symbol.typeParams.isEmpty) {
+ context.undetparams = cloneSymbols(tpt0.symbol.typeParams)
+ TypeTree().setOriginal(tpt0)
+ .setType(appliedType(tpt0.tpe, context.undetparams map (_.tpe)))
+ } else tpt0
}
/** If current tree <tree> appears in <val x(: T)? = <tree>>
* return `tp with x.type' else return `tp'.
*/
- def narrowRhs(tp: Type) = {
- var sym = context.tree.symbol
- if (sym != null && sym != NoSymbol)
- if (sym.owner.isClass) {
- if (sym.getter(sym.owner) != NoSymbol) sym = sym.getter(sym.owner)
- } else if (sym hasFlag LAZY) {
- if (sym.lazyAccessor != NoSymbol) sym = sym.lazyAccessor
- }
+ def narrowRhs(tp: Type) = { val sym = context.tree.symbol
context.tree match {
- case ValDef(mods, _, _, Apply(Select(`tree`, _), _)) if !(mods hasFlag MUTABLE) =>
- val pre = if (sym.owner.isClass) sym.owner.thisType else NoPrefix
- intersectionType(List(tp, singleType(pre, sym)))
- case _ =>
- 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 &&
- !(narrowRhs(tpt1.tpe) <:< tpt1.tpe.typeOfThis) &&
- !phase.erasedTypes) {
- error(tree.pos, tpt1.tpe.typeSymbol +
+ case ValDef(mods, _, _, Apply(Select(`tree`, _), _)) if !(mods hasFlag MUTABLE) && sym != null && sym != NoSymbol =>
+ val sym1 = if (sym.owner.isClass && sym.getter(sym.owner) != NoSymbol) sym.getter(sym.owner)
+ else if ((sym hasFlag LAZY) && sym.lazyAccessor != NoSymbol) sym.lazyAccessor
+ else sym
+ val pre = if (sym1.owner.isClass) sym1.owner.thisType else NoPrefix
+ intersectionType(List(tp, singleType(pre, sym1)))
+ case _ => tp
+ }}
+
+ val tp = tpt1.tpe
+ val sym = tp.typeSymbol
+ if (sym.isAbstractType || (sym hasFlag ABSTRACT))
+ error(tree.pos, sym + " is abstract; cannot be instantiated")
+ else if (!( tp == sym.initialize.thisSym.tpe // when there's no explicit self type -- with (#3612) or without self variable
+ // sym.thisSym.tpe == tp.typeOfThis (except for objects)
+ || narrowRhs(tp) <:< tp.typeOfThis
+ || phase.erasedTypes
+ )) {
+ error(tree.pos, sym +
" cannot be instantiated because it does not conform to its self-type "+
- tpt1.tpe.typeOfThis)
+ tp.typeOfThis)
}
- treeCopy.New(tree, tpt1).setType(tpt1.tpe)
+ treeCopy.New(tree, tpt1).setType(tp)
}
def typedEta(expr1: Tree): Tree = expr1.tpe match {