diff options
author | Martin Odersky <odersky@gmail.com> | 2006-10-05 15:34:25 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-10-05 15:34:25 +0000 |
commit | ac49199ed22c95d4d133034e77d96d6c436f079d (patch) | |
tree | d17a04510fa75f5f60b444e6346c1fdb10a8f8ef | |
parent | 2404604f2d5ba560a4f9523ab23688918dc075be (diff) | |
download | scala-ac49199ed22c95d4d133034e77d96d6c436f079d.tar.gz scala-ac49199ed22c95d4d133034e77d96d6c436f079d.tar.bz2 scala-ac49199ed22c95d4d133034e77d96d6c436f079d.zip |
fixed bug763
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 26 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 25 |
2 files changed, 39 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index f7e8803a64..95a56585a5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -255,6 +255,24 @@ trait Contexts requires Analyzer { " " + scope.toList + "\n:: " + outer.toString() } + /** Return closest enclosing context that defines a superclass of `clazz', or NoContext + * if none exists */ + def enclosingSuperClassContext(clazz: Symbol): Context = { + var c = this.enclClass + while (c != NoContext && !clazz.isNonBottomSubClass(c.owner)) + c = c.outer.enclClass + c + } + + /** Return closest enclosing context that defines a subclass of `clazz', or NoContext + * if none exists */ + def enclosingSubClassContext(clazz: Symbol): Context = { + var c = this.enclClass + while (c != NoContext && !c.owner.isNonBottomSubClass(clazz)) + c = c.outer.enclClass + c + } + /** Is <code>sym</code> accessible as a member of tree `site' with type * <code>pre</code> in current context? * @@ -277,12 +295,8 @@ trait Contexts requires Analyzer { } /** Is `clazz' a subclass of an enclosing class? */ - def isSubClassOfEnclosing(clazz: Symbol): boolean = { - var c = this.enclClass - while (c != NoContext && !clazz.isNonBottomSubClass(c.owner)) - c = c.outer.enclClass - c != NoContext - } + def isSubClassOfEnclosing(clazz: Symbol): boolean = + enclosingSuperClassContext(clazz) != NoContext (pre == NoPrefix) || { val ab = sym.accessBoundary(sym.owner) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 588678c676..b9a664e753 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -338,11 +338,12 @@ trait Typers requires Analyzer { checkStable(tree) } else if ((mode & (EXPRmode | QUALmode)) == EXPRmode && !sym.isValue) { // (2) errorTree(tree, ""+sym+" is not a value") - } else if (sym.isStable && pre.isStable && tree.tpe.symbol != ByNameParamClass && - (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant || - sym.isModule && !sym.isMethod)) { - tree.setType(singleType(pre, sym)) - } else tree + } else { + if (sym.isStable && pre.isStable && tree.tpe.symbol != ByNameParamClass && + (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant || + sym.isModule && !sym.isMethod)) tree.setType(singleType(pre, sym)) + else tree + } } /** @@ -495,7 +496,19 @@ trait Typers requires Analyzer { ((mode & TAPPmode) == 0 || tree.tpe.typeParams.isEmpty) && adaptToName(tree, nme.apply).tpe.nonLocalMember(nme.apply) .filter(m => m.tpe.paramSectionCount > 0) != NoSymbol) { // (8) - typed(atPos(tree.pos)(Select(adaptToName(tree, nme.apply), nme.apply)), mode, pt) + val qual = adaptToName(tree, nme.apply) match { + case id @ Ident(_) => + val pre = if (id.symbol.owner.isPackageClass) id.symbol.owner.thisType + else if (id.symbol.owner.isClass) + context.enclosingSubClassContext(id.symbol.owner).prefix + else NoPrefix + stabilize(id, pre, EXPRmode | QUALmode, WildcardType) + case sel @ Select(qualqual, _) => + stabilize(sel, qualqual.tpe, EXPRmode | QUALmode, WildcardType) + case other => + other + } + typed(atPos(tree.pos)(Select(qual, nme.apply)), mode, pt) } else if (!context.undetparams.isEmpty && (mode & POLYmode) == 0) { // (9) instantiate(tree, mode, pt) } else if (tree.tpe <:< pt) { |