summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala43
1 files changed, 28 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 0c32ff32c0..915d7a98db 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -326,22 +326,35 @@ trait MethodSynthesis {
super.validate()
}
- // keep type tree of original abstract field
- private def fixTypeTree(dd: DefDef): DefDef = {
- dd.tpt match {
- case tt: TypeTree if dd.rhs == EmptyTree =>
- tt setOriginal tree.tpt
- case tpt =>
- tpt setPos tree.tpt.pos.focus
- }
- dd
- }
override def derivedTree: DefDef = {
- fixTypeTree {
- DefDef(derivedSym,
- if (mods.isDeferred) EmptyTree
- else gen.mkCheckInit(fieldSelection)
- )
+ // For existentials, don't specify a type for the getter, even one derived
+ // from the symbol! This leads to incompatible existentials for the field and
+ // the getter. Let the typer do all the work. You might think "why only for
+ // existentials, why not always," and you would be right, except: a single test
+ // fails, but it looked like some work to deal with it. Test neg/t0606.scala
+ // 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 {
+ case ExistentialType(_, _) => TypeTree()
+ case tp => TypeTree(tp)
+ }
+ tpt setPos focusPos(derivedSym.pos)
+ // 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) {
+ DefDef(
+ Modifiers(derivedSym.flags),
+ derivedSym.name.toTermName,
+ Nil,
+ Nil,
+ tpt,
+ if (mods.isDeferred) EmptyTree else gen.mkCheckInit(fieldSelection)
+ ) setSymbol derivedSym
}
}
}