Skip to content

Should we allow polymorphic overloads with the same number of type parameters? #9109

Closed
@smarter

Description

@smarter

These two overloads are considered valid by Dotty, because their signatures are different:

class A {
  def foo[T <: Serializable](x: T): Unit = {}
  def foo[T <: Cloneable](x: T): Unit = {}
}

... but trying to override one of them fails, because refchecks uses Types#matches to find overrides which does not take signatures into account (it calls TypeComparer#matchesType which in turns does matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1)), therefore comparing (x: T): Unit to (x: T): Unit):

class B extends A {
  override def foo[T <: Serializable](x: T): Unit = {}
}
-- Error: try/B.scala:21:15 ----------------------------------------------------
21 |  override def foo[T <: Serializable](x: T): Unit = {}
   |               ^
   |  error overriding method foo in class A of type [T <: Cloneable](x: T): Unit;
   |    method foo of type [T <: Serializable](x: T): Unit has incompatible type

So the question is: should we disallow these overloads, or should we strive to support them? The answer is not clear cut to me because Scala 2 never supported them:

try/B.scala:16: error: method foo is defined twice;
  the conflicting method foo was defined at line 15:7
  def foo[S <: Cloneable](x: S): Unit = {}
      ^

... but Java does support them, so if we don't support them we're still in trouble when trying to override them (and in fact scala 2 cannot override them):

public class A {
  public <T extends java.io.Serializable> void foo(T x) {}
  public <T extends Cloneable> void foo(T x) {}
}

I would be in favor of supporting them for better interoperability and because it doesn't seem too hard (require matching param signatures for Types#matches to bring it in line with Denotation#matches)

WDYT @odersky ?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions