Skip to content

Implicit conversions taking by-name and by-value args are now ambiguous #8047

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
travisbrown opened this issue Jan 21, 2020 · 4 comments
Closed

Comments

@travisbrown
Copy link
Contributor

minimized code

import scala.language.implicitConversions

class Ops1 {
  def foo: String = "1"
}

class Ops2 {
  def foo: String = "2"
}

object Ops {
  implicit def toOps1(value: => String): Ops1 = new Ops1
  implicit def toOps2(value: String): Ops2 = new Ops2
}

object ExtensionTest {
  import Ops._

  val res = "".foo
}
Compilation output
-- [E007] Type Mismatch Error: ExtensionTest.scala:19:12 -----------------------
19 |  val res = "".foo
   |            ^^
   |Found:    ("" : String)
   |Required: ?{ foo: ? }
   |Note that implicit extension methods cannot be applied because they are ambiguous;
   |both method toOps1 in object Ops and method toOps2 in object Ops provide an extension method `foo` on ("" : String)
1 error found

expectation

This code compiles on Scala 2 (the by-value conversion is chosen). I ran into this issue in ScalaCheck, where importing org.scalacheck.Prop._ causes problems on Dotty:

1 |true :| "foo"
  |^^^^^^^
  |value :is not a member of Boolean, but could be made available as an extension method.
  |
  |One of the following imports might fix the problem:
  |
  |  import org.scalacheck.Prop.BooleanOperators
  |  import org.scalacheck.Prop.propBoolean
  |  import org.scalacheck.Gen.const
  |         

This should generally be easy to work around in this particular case, since there's not any good reason to import Prop._ wholesale (and also BooleanOperators is now deprecated), but that's what sbt-doctest does at the moment (I'm opening a PR there now).

I thought there was a slight chance this might be related to #8035, but compiling with #8046 gives the same error.

@odersky
Copy link
Contributor

odersky commented Jan 21, 2020

That one is known and intentional. See https://dotty.epfl.ch/docs/reference/changed-features/implicit-resolution.html point 6. I think the fix would have to be in the libraries.

@odersky odersky closed this as completed Jan 21, 2020
@smarter
Copy link
Member

smarter commented Jan 21, 2020

Note that I fixed scalacheck upstream to remove the ambiguity, but there's no release of scalacheck with the fix yet.

@dwijnand
Copy link
Member

Should the doc expand on why the behaviour was dropped? Optionally, why it was like that in the first place in Scala 2?

If someone can drop the reason here I can pipe it into a PR.

@smarter
Copy link
Member

smarter commented Jan 21, 2020

I think it's just that there was no good reason for A to be considered more specific than => A.

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

No branches or pull requests

5 participants