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

Context-bounded implicit defs sometimes fail to work #7609

Open
scabug opened this issue Jun 25, 2013 · 11 comments
Open

Context-bounded implicit defs sometimes fail to work #7609

scabug opened this issue Jun 25, 2013 · 11 comments
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Jun 25, 2013

class Test {
  trait Foo[T]
  object Foo { implicit def foo[T]: Foo[T] = new Foo[T]{} }
  implicit def conv[T: Foo](s: String): T = ???
  def foo(c: Int) = ???
  foo("")
}
00:29 ~/Projects/210x/sandbox (2.10.x)$ scalac -Xlog-implicits
Test.scala:6: conv is not a valid implicit value for String("") => Int because:
incompatible: (s: String)(implicit evidence$1: Test.this.Foo[T])T does not match expected type String("") => Int
  foo("")
      ^
Test.scala:6: error: type mismatch;
 found   : String("")
 required: Int
  foo("")
      ^
one error found
@scabug
Copy link
Author

scabug commented Jun 25, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7609?orig=1
Reporter: @xeno-by
Affected Versions: 2.10.2, 2.11.0-M3

@scabug
Copy link
Author

scabug commented Jun 25, 2013

@xeno-by said:
Removing the Foo context bound or changing foo("") to foo(conv("")) makes everything work.

@scabug
Copy link
Author

scabug commented Aug 15, 2013

Régis Jean-Gilles (rjean-gilles) said:
I stumbled upon this very problem and this is very frustrating as I can't find any work around.
Note that the issue is the same with any kind of implicit parameters (not just context bounds).

If one tries to fix the issue by resorting on macros (by doing something along the lines of implicit def conv[T](s: String): T = macro conv_impl,
in the vain hope that removing the implicit parameters in the function signature (now relegated to
an explicit call to inferImplicitValue/inferImplicitView inside the macro implementation "conv_impl")
would help, then deception ensues: this does not work either.

And of importance is the fact that when trying this macro implementation, one can see that the target type T is infered as "Nothing", thus preventing
to write any working implementation of this macro.

As a side note, Roman Janusz initially reported the issue on the scala-user group, and he too noticed the problem with the target type being inferred as "Nothing": https://groups.google.com/forum/#!topic/scala-user/3fXswCh7Xz8

Is there any plan to work on this issue in the forseable future?

@scabug
Copy link
Author

scabug commented Aug 17, 2013

Régis Jean-Gilles (rjean-gilles) said:
Also, while it is easy to dismiss this issue as unimportant because doing open ended conversions is a bad idea, let me point that the implicit conversion here is actually not open-ended, as it is entirely driven by the Foo type class.

The type class pattern has become ubiquitous for a good reason, and implicit conversions are also an important feature of scala.

It is only natural to want to combine both features by totally offloading the implementation of an implicit conversion to a type class.
This issue prevents this combination, and I would argue that this is a very bad thing.

@scabug
Copy link
Author

scabug commented Aug 17, 2013

@ghik said:
Passing implicit ClassTag/TypeTag to implicit conversion is another example of very natural usage of such combination. It's useful and I think it's not any more dangerous than plain implicit conversion.

@scabug
Copy link
Author

scabug commented Aug 17, 2013

@xeno-by said:
Yay, I finally figured out a workaround (been episodically thinking about this bug for some time already):

class Test {
  trait Foo[T, U]
  object Foo { implicit def foo: Foo[String, Int] = new Foo[String, Int]{} }
  implicit def conv[T, U](s: T)(implicit foo: Foo[T, U]): U = ???
  def foo(c: Int) = ???
  foo("")
}

This, however, requires a fix to #3346, which is a pull request currently under review: scala/scala#2822. If you're interested in having this bugfix in 2.11 and have some spare time, I can elaborate on how you can help.

@scabug
Copy link
Author

scabug commented Aug 17, 2013

Régis Jean-Gilles (rjean-gilles) said:
Nice! I had tried this exact same work around but it failed badly, I had no idea that there was an open issue for this (let alone a pending fix).

I am definitly interested in seeing this bugfix in 2.11.

@scabug
Copy link
Author

scabug commented Aug 17, 2013

Régis Jean-Gilles (rjean-gilles) said:
And I do have some spare time (not for long though), so if I can help let me know.

@scabug
Copy link
Author

scabug commented Aug 17, 2013

@xeno-by said:
Adriaan mentioned that it'd be good to rebuild scalaz, specs2 and scalatest using the changes introduced in scala/scala#2822. Lars said that scalaz currently doesn't build with 2.11, but if you could takes a look at specs2 and/or scalatest, it would be great.

@scabug scabug added the typer label Apr 7, 2017
@SethTisue SethTisue added this to the Backlog milestone Mar 2, 2018
@SethTisue
Copy link
Member

is this still relevant? should this stay open?

@milessabin
Copy link

I think it is. Let's keep this open.

The workaround mentioned here works now, which on the one hand makes this less urgent, but on the other is confirmation that this is a bug and fixable.

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

No branches or pull requests

3 participants