diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index a79408b756ee..1043451e3080 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -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) } diff --git a/sbt b/sbt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/neg/i22310.check b/tests/neg/i22310.check new file mode 100644 index 000000000000..f64557c5f7c7 --- /dev/null +++ b/tests/neg/i22310.check @@ -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. \ No newline at end of file diff --git a/tests/neg/i22310.scala b/tests/neg/i22310.scala new file mode 100644 index 000000000000..f8854f0e6bc7 --- /dev/null +++ b/tests/neg/i22310.scala @@ -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 +} \ No newline at end of file diff --git a/tests/pos/i22310-valid.scala b/tests/pos/i22310-valid.scala new file mode 100644 index 000000000000..c91fcb4afc46 --- /dev/null +++ b/tests/pos/i22310-valid.scala @@ -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 +} \ No newline at end of file