diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 25 | ||||
-rw-r--r-- | test/files/pos/t4036.scala | 13 | ||||
-rw-r--r-- | test/files/run/names-defaults.scala | 1 |
3 files changed, 34 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index a36ba92c88..752931388d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2137,7 +2137,7 @@ trait Typers { self: Analyzer => def checkNoDoubleDefsAndAddSynthetics(stats: List[Tree]): List[Tree] = { val scope = if (inBlock) context.scope else context.owner.info.decls - val newStats = new ListBuffer[Tree] + var newStats = new ListBuffer[Tree] var needsCheck = true var moreToAdd = true while (moreToAdd) { @@ -2177,12 +2177,27 @@ trait Typers { self: Analyzer => } if (newStats.isEmpty) stats else { - val (defaultGetters, others) = newStats.toList.partition { - case DefDef(mods, _, _, _, _, _) => mods.hasDefaultFlag + // put default getters next to the method they belong to, + // same for companion objects. fixes #2489 and #4036. + def matches(stat: Tree, synt: Tree) = (stat, synt) match { + case (DefDef(_, statName, _, _, _, _), DefDef(mods, syntName, _, _, _, _)) => + mods.hasDefaultFlag && syntName.toString.startsWith(statName.toString) + + case (ClassDef(_, className, _, _), ModuleDef(_, moduleName, _)) => + className.toTermName == moduleName + case _ => false } - // default getters first: see #2489 - defaultGetters ::: stats ::: others + + def matching(stat: Tree): List[Tree] = { + val (pos, neg) = newStats.partition(synt => matches(stat, synt)) + newStats = neg + pos.toList + } + + (stats foldRight List[Tree]())((stat, res) => { + stat :: matching(stat) ::: res + }) ::: newStats.toList } } val result = stats mapConserve (typedStat) diff --git a/test/files/pos/t4036.scala b/test/files/pos/t4036.scala new file mode 100644 index 0000000000..b902a3153b --- /dev/null +++ b/test/files/pos/t4036.scala @@ -0,0 +1,13 @@ +object Error { + def f { + case class X(b: Boolean = false) + val r = X() + } + def g = { + val x = 0 + var y = 1 // no constant type + def foo(z: Int = y) = 1 + val z = 2 + foo() + } +} diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala index 5e84b9c132..63f7950d61 100644 --- a/test/files/run/names-defaults.scala +++ b/test/files/run/names-defaults.scala @@ -274,6 +274,7 @@ object Test extends Application { // #2489 class A2489 { def foo { def bar(a: Int = 1) = a; bar(); val u = 0 } } + class A2489x2 { def foo { val v = 10; def bar(a: Int = 1, b: Int = 2) = a; bar(); val u = 0 } } // a bug reported on the mailing lists, related to #2489 class Test2489 { |