summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-10-05 15:34:25 +0000
committerMartin Odersky <odersky@gmail.com>2006-10-05 15:34:25 +0000
commitac49199ed22c95d4d133034e77d96d6c436f079d (patch)
treed17a04510fa75f5f60b444e6346c1fdb10a8f8ef
parent2404604f2d5ba560a4f9523ab23688918dc075be (diff)
downloadscala-ac49199ed22c95d4d133034e77d96d6c436f079d.tar.gz
scala-ac49199ed22c95d4d133034e77d96d6c436f079d.tar.bz2
scala-ac49199ed22c95d4d133034e77d96d6c436f079d.zip
fixed bug763
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala26
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala25
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) {