diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala | 22 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala | 17 |
2 files changed, 15 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 48263a496e..d6a6e027cb 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -373,16 +373,10 @@ abstract class ExplicitOuter extends InfoTransform /** The definition tree of the outer accessor of current class */ - def outerAccessorDef: Tree = { - val outerAcc = outerAccessor(currentClass) - val rhs: Tree = - if (outerAcc.isDeferred) EmptyTree - else This(currentClass) DOT outerField(currentClass) - - /* If we don't re-type the tree, we see self-type related crashes like #266. - */ - localTyper typed { - (DEF(outerAcc) withPos currentClass.pos withType null) === rhs + def outerAccessorDef: Tree = localTyper typed { + outerAccessor(currentClass) match { + case acc if acc.isDeferred => DefDef(acc, EmptyTree) + case acc => DefDef(acc, Select(This(currentClass), outerField(currentClass))) } } @@ -404,12 +398,8 @@ abstract class ExplicitOuter extends InfoTransform 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. - gen.mkCast(transformer.transform(path), outerAcc.info.resultType) - } - } + // Need to cast for nested outer refs in presence of self-types. See ticket #3274. + localTyper typed DefDef(outerAcc, gen.mkCast(transformer.transform(path), outerAcc.info.resultType)) } /** The main transformation method */ diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 3a5845c8ca..263b5ad784 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -397,6 +397,12 @@ trait MethodSynthesis { if (mods.isDeferred) basisSym else basisSym.getter(enclClass) ) + // Range position errors ensue if we don't duplicate this in some + // circumstances (at least: concrete vals with existential types.) + private def tptOriginal = ( + if (mods.isDeferred) tree.tpt // keep type tree of original abstract field + else tree.tpt.duplicate setPos tree.tpt.pos.focus // focused position of original tpt + ) override def derivedTree: DefDef = { // For existentials, don't specify a type for the getter, even one derived @@ -407,16 +413,11 @@ trait MethodSynthesis { // starts compiling (instead of failing like it's supposed to) because the typer // expects to be able to identify escaping locals in typedDefDef, and fails to // spot that brand of them. In other words it's an artifact of the implementation. - val tpt = derivedSym.tpe.finalResultType match { + val tpt = atPos(derivedSym.pos.focus)(derivedSym.tpe.finalResultType match { case ExistentialType(_, _) => TypeTree() case _ if mods.isDeferred => TypeTree() case tp => TypeTree(tp) - } - tpt setPos derivedSym.pos.focus - // keep type tree of original abstract field - if (mods.isDeferred) - tpt setOriginal tree.tpt - + }) // TODO - reconcile this with the DefDef creator in Trees (which // at this writing presented no way to pass a tree in for tpt.) atPos(derivedSym.pos) { @@ -425,7 +426,7 @@ trait MethodSynthesis { derivedSym.name.toTermName, Nil, Nil, - tpt, + tpt setOriginal tptOriginal, if (mods.isDeferred) EmptyTree else fieldSelection ) setSymbol derivedSym } |