Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,11 @@ object RefChecks {

def isSignatureMatch(sym: Symbol) = sym.isType || {
val self = clazz.thisType
sym.asSeenFrom(self).matches(member.asSeenFrom(self))
val symDenotation = sym.asSeenFrom(self)
val memberDenotation = member.asSeenFrom(self)
// Use matchesLoosely with alwaysCompareTypes = true to ensure strict type checking for overrides
// This fixes issue #22310 where A0[String] was incorrectly considered to match A0[Object]
symDenotation.matchesLoosely(memberDenotation, alwaysCompareTypes = true)
&& !incompatibleRepeatedParam(sym, member)
}

Expand Down
Empty file added sbt
Empty file.
8 changes: 8 additions & 0 deletions tests/neg/i22310.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- [E177] Syntax Error: tests/neg/i22310.scala:9:2 --------------------------------
9 | override def func(arg0: A0[Object], arg1: String): Unit = {} // error: overrides nothing
| ^
| override def func overrides nothing.
-- [E177] Syntax Error: tests/neg/i22310.scala:16:2 -------------------------------
16| override def method(x: B0[Object, Int], y: String, z: Int): Unit = {} // error: overrides nothing
| ^
| override def method overrides nothing.
28 changes: 28 additions & 0 deletions tests/neg/i22310.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//> using options -Xfatal-warnings

// This should fail compilation but currently passes
abstract class A0[T] {
def func(arg0: A0[String], arg1: T): Unit
}

abstract class A1 extends A0[String] {
override def func(arg0: A0[Object], arg1: String): Unit = {} // error: overrides nothing
}

// Similar issue with multiple type parameters
abstract class B0[T, U] {
def method(x: B0[String, Int], y: T, z: U): Unit
}

abstract class B1 extends B0[String, Int] {
override def method(x: B0[Object, Int], y: String, z: Int): Unit = {} // error: overrides nothing
}

// This should work (correct override)
abstract class C0[T] {
def goodFunc(arg0: C0[String], arg1: T): Unit
}

abstract class C1 extends C0[String] {
override def goodFunc(arg0: C0[String], arg1: String): Unit = {} // OK - this should work
}
27 changes: 27 additions & 0 deletions tests/pos/i22310-valid.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Test cases to ensure valid overrides still work after fixing #22310

abstract class ValidCase1[T] {
def method(arg: ValidCase1[String], param: T): Unit
}

abstract class ValidCase1Sub extends ValidCase1[String] {
override def method(arg: ValidCase1[String], param: String): Unit = {} // OK - this should work
}

// Variance cases should still work correctly
abstract class CovariantCase[+T] {
def method(param: CovariantCase[String]): T
}

abstract class CovariantCaseSub extends CovariantCase[Object] {
override def method(param: CovariantCase[String]): Object = "valid" // OK - covariance in return type
}

// Test with concrete classes too
class ConcreteBase[T] {
def func(x: ConcreteBase[String], y: T): Unit = {}
}

class ConcreteDerived extends ConcreteBase[String] {
override def func(x: ConcreteBase[String], y: String): Unit = {} // OK - this should work
}
Loading