Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Aug 29, 2025

Fixes a bug where the compiler incorrectly allowed override declarations that don't actually override anything when generic types with incompatible type arguments were involved.

Problem

The following code should produce an "overrides nothing" error but was incorrectly accepted:

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 = {} // Should error: overrides nothing
}

When A1 extends A0[String], the inherited method becomes func(arg0: A0[String], arg1: String): Unit. The override attempt with A0[Object] should fail because A0[Object] and A0[String] are incompatible types (generic classes are invariant by default).

Root Cause

The issue was in the override checking logic in RefChecks.scala. The isSignatureMatch function used signature-based matching that erased type arguments for user-defined generic classes. This caused A0[String] and A0[Object] to be treated as having the same signature, leading to false positive matches.

The signature matching logic in TypeErasure.sigName() only preserves type arguments for built-in types like Array and Pair, but erases them for user-defined classes through the erasureDependsOnArgs check.

Solution

Modified the override checking logic to use strict type comparison by calling matchesLoosely(other, alwaysCompareTypes = true) instead of matches(). This ensures that even when signatures match after type erasure, the system performs a full type comparison using info.matches(other.info) to validate that the parameter types are actually compatible.

Changes

  • compiler/src/dotty/tools/dotc/typer/RefChecks.scala: Updated isSignatureMatch to use matchesLoosely with alwaysCompareTypes = true for strict type checking in override validation
  • tests/neg/i22310.scala: Added comprehensive test cases covering the reported issue and similar scenarios
  • tests/neg/i22310.check: Expected compilation errors for invalid overrides
  • tests/pos/i22310-valid.scala: Test cases ensuring valid overrides continue to work correctly

The fix is minimal and targeted, only affecting override checking behavior while preserving all existing valid override scenarios including proper variance handling.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • esm.ubuntu.com
    • Triggering command: /usr/lib/apt/methods/https (dns block)
  • git.io
    • Triggering command: curl -Ls REDACTED (dns block)
  • repo.scala-sbt.org
    • Triggering command: /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@Copilot Copilot AI changed the title [WIP] Fix the bug in @scala/scala3/issues/22310 Fix issue #22310: Override checking incorrectly accepts incompatible generic types Aug 29, 2025
@Copilot Copilot AI requested a review from noti0na1 August 29, 2025 13:31
Copilot finished work on behalf of noti0na1 August 29, 2025 13:31
@noti0na1 noti0na1 closed this Aug 29, 2025
@som-snytt
Copy link
Contributor

Thanks, but could you add a section titled, "How I fixed it"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants