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

TypeTag disables implicit conversion #9680

Open
scabug opened this issue Mar 2, 2016 · 3 comments
Open

TypeTag disables implicit conversion #9680

scabug opened this issue Mar 2, 2016 · 3 comments

Comments

@scabug
Copy link

scabug commented Mar 2, 2016

This "bug" came up in a Stackoverflow question.
When you put a subtype constraint on a type parameter in an implicit conversion, the conversion is also applied when an unrelated type is involved. My guess is that Nothing is involved here somewhere. But when I want to check the type with a TypeTag, the conversion no longer kicks in for the unrelated type, and for the right type I get "error: macro has not been expanded".

scala> trait TestBase
defined trait TestBase

scala> class NotTest
defined class NotTest

scala> case class Foo()
defined class Foo

scala> implicit def conv[A <: TestBase](foo: Foo): A = {println(foo); null.asInstanceOf[A] }
warning: there were 1 feature warning(s); re-run with -feature for details
conv: [A <: TestBase](foo: Foo)A

scala> val test: NotTest = Foo()
Foo()
test: NotTest = null

scala> implicit def conv[A](foo: Foo)(implicit ev: A <:< TestBase): A = {println(foo); null.asInstanceOf[A] }
warning: there were 1 feature warning(s); re-run with -feature for details
conv: [A](foo: Foo)(implicit ev: <:<[A,TestBase])A

scala> val test: NotTest = Foo()
Foo()
test: NotTest = null

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> implicit def conv[A <: TestBase](foo: Foo)(implicit ev: TypeTag[A]): A = {println(ev); null.asInstanceOf[A] }
warning: there were 1 feature warning(s); re-run with -feature for details
conv: [A <: TestBase](foo: Foo)(implicit ev: reflect.runtime.universe.TypeTag[A])A

scala> val test: NotTest = Foo()
<console>:18: error: type mismatch;
 found   : Foo
 required: NotTest
       val test: NotTest = Foo()
                              ^

scala> val test: TestBase = Foo()
<console>:17: error: macro has not been expanded
       val test: TestBase = Foo()
                               ^
@scabug
Copy link
Author

scabug commented Mar 2, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9680?orig=1
Reporter: Jasper-M
Affected Versions: 2.10.4, 2.11.7
See #9633, #7608

@scabug
Copy link
Author

scabug commented Mar 2, 2016

@retronym said:
I'd suggest using -Xprint:typer to see what is inferred, rather than adding TypeTag-s. This might help you to untangle the issues better and determine if this is a bug or just a case of inference doing what it specced to do.

@scabug
Copy link
Author

scabug commented Mar 3, 2016

@szeiger said:
The first part works as expected (as -Xprint:typer will verify). The implicit conversion claims to be able to produce any subtype of TestBase, which includes Nothing. Since you need a cast to get there, it's not a soundness issue, either (but the similar #9633 is). You'd have to add a subtype of all the types the implicit conversion can really produce, and use that as an upper bound.

The fact that it doesn't work with a TypeTag looks like a legitimate bug to me. An explicit call conv(Foo()) compiles but conv is not picked as an implicit conversion.

@scabug scabug added this to the Backlog milestone Apr 7, 2017
@Jasper-M Jasper-M changed the title Implicit conversion disregards subtype constraints. TypeTag disables implicit conversion Jan 15, 2018
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

1 participant