Skip to content

Cannot disambiguate public overload from package-private #15821

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

Closed
armanbilge opened this issue Aug 4, 2022 · 2 comments · Fixed by #18057
Closed

Cannot disambiguate public overload from package-private #15821

armanbilge opened this issue Aug 4, 2022 · 2 comments · Fixed by #18057
Assignees
Milestone

Comments

@armanbilge
Copy link
Contributor

Compiler version

3.2.1-RC1-bin-20220803-da2d44a-NIGHTLY

Minimized code

//> using scala "3.2.1-RC1-bin-20220803-da2d44a-NIGHTLY"

@main def main =
  foo.bar(42)

package object foo {
  def bar[F[_]]: Unit = ???
  def bar[F[_]](x: Int): Unit = ???
  private[foo] def bar[F[_]](x: Int)(implicit dummy: DummyImplicit): Unit = ???
}

Output

[error] ./bug.scala:4:3: Ambiguous overload. The overloaded alternatives of method bar in package foo with types
[error]  [F[_$3]](x: Int)(implicit dummy: DummyImplicit): Unit
[error]  [F[_$2]](x: Int): Unit
[error] both match arguments ((42 : Int))
[error]   foo.bar(42)
[error]   ^^^^^^^

Expectation

There should be no ambiguity because one of the "ambiguous" methods is package-private.

@armanbilge armanbilge added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Aug 4, 2022
@som-snytt
Copy link
Contributor

In the OP example, it must be a package object; an ordinary object works. All three bar are required.

My expectation was that accessibility does not determine overloading; candidate overloads must be applicable, but applicable does not entail accessible. I'm surprised the example compiles in Scala 2, and I'm surprised an ordinary object works in Scala 3.

(Accessibility was added as a requirement for override eligibility, so maybe it was added for overload applicability.)

The "doesn't use implicits" rule selects B in the first main:

import annotation._

//@main def main = foo.bar(42)(implicitly[DummyImplicit])   // B
//@main def main = foo.bar(42)  // C

package object foo {
  def bar[F[_]]: Unit = println("A")
  def bar[F[_]](x: Int)(dummy: DummyImplicit): Unit = println("B")
  @targetName("privvy")
  private[foo] def bar[F[_]](x: Int)(implicit dummy: DummyImplicit): Unit = println("C")
}

I thought I witnessed differing results if the main is in a separate file and depending on whether it was compiled by scalac or the scala runner, but that must be due to #15015

The point of that exercise was that people hint that private implies "private to a file"; or the opposing camp says compilation unit should not matter. With some code in the empty package, it's not obvious what is intended or specified.

Unqualified private is also ambiguous, even with main in a separate file:

package object foo {
  def bar[F[_]]: Unit = println("A")
  def bar[F[_]](x: Int): Unit = println("B")
  private def bar[F[_]](x: Int)(implicit dummy: DummyImplicit): Unit = println("C")
}

@WojciechMazur
Copy link
Contributor

It's also correct in the case of usage top-level definitions in a separate file which would be an idiomatic way of the same code in Scala 3 (package objects are going to be removed):

/// foo.scala
package foo

def bar[F[_]]: Unit = ???
def bar[F[_]](x: Int): Unit = ???
private def bar[F[_]](x: Int)(implicit dummy: DummyImplicit): Unit = ???
// test.scala
@main def main = foo.bar(42)

In case of removal def bar[F[_]](x: Int): Unit = ??? code would work correctly

@WojciechMazur WojciechMazur added area:typer and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Aug 5, 2022
@Kordyjan Kordyjan added this to the Future versions milestone Dec 12, 2022
@odersky odersky self-assigned this Dec 14, 2022
odersky added a commit to dotty-staging/dotty that referenced this issue Jun 25, 2023
Making a package object explicit re-computes the denotations of an overloaded method.
So it should not be done after we have pruned down those denotations by an accessibility
test. We now do it before checking accessibility.

Fixes scala#15821
odersky added a commit to dotty-staging/dotty that referenced this issue Jun 26, 2023
Making a package object explicit re-computes the denotations of an overloaded method.
So it should not be done after we have pruned down those denotations by an accessibility
test. We now do it before checking accessibility.

Fixes scala#15821
odersky added a commit that referenced this issue Jun 26, 2023
Making a package object explicit re-computes the denotations of an
overloaded method. So it should not be done after we have pruned down
those denotations by an accessibility test. We now do it before checking
accessibility.

Fixes #15821
Kordyjan pushed a commit to dotty-staging/dotty that referenced this issue Jun 28, 2023
Making a package object explicit re-computes the denotations of an overloaded method.
So it should not be done after we have pruned down those denotations by an accessibility
test. We now do it before checking accessibility.

Fixes scala#15821
@Kordyjan Kordyjan modified the milestones: Future versions, 3.4.0 Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants