Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False positive warning 'Extension method will never be selected' #21816

Open
SimY4 opened this issue Oct 20, 2024 · 8 comments · May be fixed by #21825
Open

False positive warning 'Extension method will never be selected' #21816

SimY4 opened this issue Oct 20, 2024 · 8 comments · May be fixed by #21825
Labels
area:extension-methods area:reporting Error reporting including formatting, implicit suggestions, etc itype:bug regression This worked in a previous version but doesn't anymore

Comments

@SimY4
Copy link

SimY4 commented Oct 20, 2024

Compiler version

Observing this failure since Scala 3.4, the error persisted all the way till 3.6.1

Minimized code

trait A extends Iterable[String]

trait Test {
  extension (a: A) def foo: String = "foo"
}

object Test {
  def foo(s: String, acc: List[String] = Nil) = ???
}

Output

a false positive compiler warning:

[Warn] /.../src/main/scala/Test.scala:6:24: Extension method foo will never be selected

Expectation

The code works as expected after compilation. Extension method is always rightfully selected. The actual code that triggers it in my project is even weirder because it's nested deeper inside companion object like so:

trait A extends Iterable[String]

trait Test {
  extension (a: A) def foo: String = "foo"
}

object Test {
  object Nested {
    def foo(s: String, acc: List[String] = Nil) = ???
  }
}

still triggers the same error.

@SimY4 SimY4 added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 20, 2024
@som-snytt
Copy link
Contributor

@SimY4 I'm unable to reproduce the symptom. How are you compiling it? Or if you can link to a sample project I'll try that.

@Gedochao Gedochao added stat:cannot reproduce area:reporting Error reporting including formatting, implicit suggestions, etc and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 21, 2024
@Gedochao
Copy link
Contributor

@SimY4 I can't seem to be able to reproduce, either.
Are you passing any compiler flags?

@SimY4
Copy link
Author

SimY4 commented Oct 22, 2024

@som-snytt @Gedochao I'm having a hard time extracting it into a self contained project. I'll need to figure out what is it in my project that triggers it. I'll come back to you.

@som-snytt
Copy link
Contributor

Glad to pursue with a test case.

@som-snytt som-snytt closed this as not planned Won't fix, can't repro, duplicate, stale Oct 22, 2024
@SimY4
Copy link
Author

SimY4 commented Oct 22, 2024

@som-snytt

So even smaller example is this one:

case class CC(a: String, b: String) extends Iterable[String] {
  override def iterator: Iterator[String] = Iterator(a, b)
}

trait T {
  extension (cc: CC) def className: String = "foo"
}

object O extends T {
  def foo = {
    val cc = CC("a", "b")
    cc.className
  }
}

O.foo

Look like it's reliably reproducible. The bit I missed is that the method name is important and the conflict occurs due to the fact that Iterable interface provides a method called def className: String So there's a conflict and a warning suggests that extension won't be preferred in scope of T but it is.

@Gedochao
Copy link
Contributor

Gedochao commented Oct 22, 2024

@SimY4 okay, I can reproduce with the new example.
Slight adjustment, as what you pasted is a script.
Here's a raw .scala minimization:

//> using scala 3.5.0
case class CC(a: String, b: String) extends Iterable[String] {
  override def iterator: Iterator[String] = Iterator(a, b)
}

trait T {
  extension (cc: CC) def className: String = "foo"
}

object O extends T {
  def foo = {
    val cc = CC("a", "b")
    println(cc.className)
  }
}

@main def main() = O.foo

And indeed, I'm getting the warning:

-- [E194] Potential Issue Warning: /Users/pchabelski/IdeaProjects/scala-cli-tests-2/untitled/compiler-repro/repro.scala:6:25 
7 |  extension (cc: CC) def className: String = "foo"
  |                         ^
  |Extension method className will never be selected
  |because CC already has a member with the same name and compatible parameter types.
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | An extension method can be invoked as a regular method, but if that is intended,
  | it should not be defined as an extension.
  | Although extensions can be overloaded, they do not overload existing member methods.
   -----------------------------------------------------------------------------
1 warning found

Looks like a bug, indeed.

@Gedochao
Copy link
Contributor

Observing this failure since Scala 3.4, the error persisted all the way till 3.6.1

So I dunno about 3.4.x, as I can't reproduce it before 3.5.0.
So it's potentially a regression.

Last good stable release: 3.4.3 (or chronologically, 3.4.2)
First bad stable release: 3.5.0
Last good nightly release: 3.5.0-RC1-bin-20240408-1e8a653-NIGHTLY
First bad nightly release: 3.5.0-RC1-bin-20240409-2148c8d-NIGHTLY

Bisect failed to pinpoint the exact commit, the culprit could be any of:

939f73e seems like it could be connected, so I'd guess it's the first to check.
cc @smarter

@Gedochao Gedochao added the regression This worked in a previous version but doesn't anymore label Oct 22, 2024
@som-snytt
Copy link
Contributor

The PR was on 3.5, but I see it was backported to LTS 3.3.

(It feels longer ago because it began in May 2023 but not merged until April 2024.)

The check doesn't consider access.

The feature request added to the ticket was not to warn for simple forwarder, which might be nice to add:

class Foo(val someField: Int)

extension (foo: Foo)
  def someField = foo.someField
  def bar1 = 1 + someField
  def bar2 = 2 + someField
  def bar3 = 3 + someField

Arguably, it's also about access.

@som-snytt som-snytt linked a pull request Oct 22, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:extension-methods area:reporting Error reporting including formatting, implicit suggestions, etc itype:bug regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants