Skip to content

Commit

Permalink
Keep HasDefault flag updated in overriding methods
Browse files Browse the repository at this point in the history
Fixes #16006

#16006 started failing since we now count the number of default parameters
for better precision in overloading resolution. But that count was wrong since
it did not take inherited default getters from overridden methods into account.
We fix this by setting the HasDefault flag also for parameters that don't have
a default value themselves, but that correspond to parameters with default
values in overridden methods.
  • Loading branch information
odersky committed Sep 9, 2022
1 parent a503b7a commit 82c8c63
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
18 changes: 15 additions & 3 deletions compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -938,15 +938,27 @@ object SymDenotations {

/** Does this symbol have defined or inherited default parameters?
* Default parameters are recognized until erasure.
* As a side effect, sets HasDefault flag of parameters in methods that
* override a method with a corresponding default parameter.
*/
def hasDefaultParams(using Context): Boolean =
if ctx.erasedTypes then false
else if is(HasDefaultParams) then true
else if is(NoDefaultParams) || !is(Method) then false
else
val result =
rawParamss.nestedExists(_.is(HasDefault))
|| allOverriddenSymbols.exists(_.hasDefaultParams)
val inheritedDefaultParamNames = util.HashSet[Name]()
for prev <- allOverriddenSymbols do
if prev.hasDefaultParams then
for params <- prev.rawParamss do
for param <- params do
if param.is(HasDefault) then inheritedDefaultParamNames += param.name
if !inheritedDefaultParamNames.isEmpty then
for params <- rawParamss do
for param <- params do
if inheritedDefaultParamNames.contains(param.name) then
param.setFlag(HasDefault)
val result = rawParamss.nestedExists(_.is(HasDefault))
if allOverriddenSymbols.exists(_.hasDefaultParams) && !ctx.isAfterTyper then assert(result)
setFlag(if result then HasDefaultParams else NoDefaultParams)
result

Expand Down
1 change: 1 addition & 0 deletions tests/run/i16006.check
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
overriden (3, 10)
11 changes: 11 additions & 0 deletions tests/run/i16006.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class X:
def toString(maxLines: Int = 10, maxWidth: Int = 10): String = (maxLines -> maxWidth).toString

class Foo extends X:
override def toString(maxLines: Int, maxWidth: Int): String = s"overriden ($maxLines, $maxWidth)"
override def toString(): String = toString(maxLines = 3)


@main def Test = {
println(Foo().toString())
}

0 comments on commit 82c8c63

Please # to comment.