summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-29 19:35:15 +0000
committerPaul Phillips <paulp@improving.org>2011-10-29 19:35:15 +0000
commit2d3fe5733cbc6bcf06892c8ee3cb19f7987f6b6a (patch)
tree6e7418bf49e9bf8dbcd05e233cc5b5c5f84497cd /src
parent48a26b9c2be3cb5390dafa8a13620c91fab0167d (diff)
downloadscala-2d3fe5733cbc6bcf06892c8ee3cb19f7987f6b6a.tar.gz
scala-2d3fe5733cbc6bcf06892c8ee3cb19f7987f6b6a.tar.bz2
scala-2d3fe5733cbc6bcf06892c8ee3cb19f7987f6b6a.zip
Fix for crasher in explicitouter.
Closes SI-4970, review by moors.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/TreeGen.scala71
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala16
2 files changed, 47 insertions, 40 deletions
diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala
index ce7fba6686..fae3975ed5 100644
--- a/src/compiler/scala/reflect/internal/TreeGen.scala
+++ b/src/compiler/scala/reflect/internal/TreeGen.scala
@@ -64,44 +64,47 @@ abstract class TreeGen {
* termSym as the Ident's symbol. In that case, termSym must
* not be NoSymbol.
*/
- def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = tpe match {
- case NoPrefix =>
- EmptyTree
- case ThisType(clazz) =>
- if (clazz.isEffectiveRoot) EmptyTree
- else mkAttributedThis(clazz)
- case SingleType(pre, sym) =>
- mkApplyIfNeeded(mkAttributedStableRef(pre, sym))
- case TypeRef(pre, sym, args) =>
- if (sym.isRoot) {
- mkAttributedThis(sym)
- } else if (sym.isModuleClass) {
- mkApplyIfNeeded(mkAttributedRef(pre, sym.sourceModule))
- } else if (sym.isModule || sym.isClass) {
- assert(phase.erasedTypes, tpe)
- mkAttributedThis(sym)
- } else if (sym.isType) {
- assert(termSym != NoSymbol, tpe)
- mkAttributedIdent(termSym) setType tpe
- } else {
- mkAttributedRef(pre, sym)
- }
+ def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = {
+ def failMessage = "mkAttributedQualifier(" + tpe + ", " + termSym + ")"
+ tpe match {
+ case NoPrefix =>
+ EmptyTree
+ case ThisType(clazz) =>
+ if (clazz.isEffectiveRoot) EmptyTree
+ else mkAttributedThis(clazz)
+ case SingleType(pre, sym) =>
+ mkApplyIfNeeded(mkAttributedStableRef(pre, sym))
+ case TypeRef(pre, sym, args) =>
+ if (sym.isRoot) {
+ mkAttributedThis(sym)
+ } else if (sym.isModuleClass) {
+ mkApplyIfNeeded(mkAttributedRef(pre, sym.sourceModule))
+ } else if (sym.isModule || sym.isClass) {
+ assert(phase.erasedTypes, failMessage)
+ mkAttributedThis(sym)
+ } else if (sym.isType) {
+ assert(termSym != NoSymbol, failMessage)
+ mkAttributedIdent(termSym) setType tpe
+ } else {
+ mkAttributedRef(pre, sym)
+ }
- case ConstantType(value) =>
- Literal(value) setType tpe
+ case ConstantType(value) =>
+ Literal(value) setType tpe
- case AnnotatedType(_, atp, _) =>
- mkAttributedQualifier(atp)
+ case AnnotatedType(_, atp, _) =>
+ mkAttributedQualifier(atp)
- case RefinedType(parents, _) =>
- // I am unclear whether this is reachable, but
- // the following implementation looks logical -Lex
- val firstStable = parents.find(_.isStable)
- assert(!firstStable.isEmpty, tpe)
- mkAttributedQualifier(firstStable.get)
+ case RefinedType(parents, _) =>
+ // I am unclear whether this is reachable, but
+ // the following implementation looks logical -Lex
+ val firstStable = parents.find(_.isStable)
+ assert(!firstStable.isEmpty, failMessage + " parents = " + parents)
+ mkAttributedQualifier(firstStable.get)
- case _ =>
- abort("bad qualifier: " + tpe)
+ case _ =>
+ abort("bad qualifier received: " + failMessage)
+ }
}
/** If this is a reference to a method with an empty
* parameter list, wrap it in an apply.
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 1bc283841b..192c4e9b59 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -346,12 +346,16 @@ abstract class ExplicitOuter extends InfoTransform
* @pre mixinClass is an inner class
*/
def mixinOuterAccessorDef(mixinClass: Symbol): Tree = {
- val outerAcc = outerAccessor(mixinClass) overridingSymbol currentClass
- assert(outerAcc != NoSymbol)
- val path =
- if (mixinClass.owner.isTerm) THIS(mixinClass.owner.enclClass)
- else gen.mkAttributedQualifier(currentClass.thisType baseType mixinClass prefix)
-
+ val outerAcc = outerAccessor(mixinClass) overridingSymbol currentClass
+ def mixinPrefix = currentClass.thisType baseType mixinClass prefix;
+ assert(outerAcc != NoSymbol, "No outer accessor for inner mixin " + mixinClass + " in " + currentClass)
+ // I added the mixinPrefix.typeArgs.nonEmpty condition to address the
+ // crash in SI-4970. I feel quite sure this can be improved.
+ val path = (
+ if (mixinClass.owner.isTerm) gen.mkAttributedThis(mixinClass.owner.enclClass)
+ else if (mixinPrefix.typeArgs.nonEmpty) gen.mkAttributedThis(mixinPrefix.typeSymbol)
+ else gen.mkAttributedQualifier(mixinPrefix)
+ )
localTyper typed {
(DEF(outerAcc) withPos currentClass.pos) === {
// Need to cast for nested outer refs in presence of self-types. See ticket #3274.