Skip to content

Implicit conversion never applied but influences type inference #12044

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
mariogalic opened this issue Jun 17, 2020 · 6 comments · Fixed by scala/scala#11053
Closed

Implicit conversion never applied but influences type inference #12044

mariogalic opened this issue Jun 17, 2020 · 6 comments · Fixed by scala/scala#11053
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) implicit infer typer
Milestone

Comments

@mariogalic
Copy link

reproduction steps

https://stackoverflow.com/questions/62415172/mere-presence-of-implicit-conversion-makes-the-program-compile-despite-never-bei/62426914

using Scala 2.13.2,

scala> class Bar
class Bar

scala> def f[F[_], A](v: F[A]) = v
def f[F[_], A](v: F[A]): F[A]

scala> implicit def barToList(b: Bar): List[Int] = List(42)
def barToList(b: Bar): List[Int]

scala> f(new Bar)
val res1: Any = Bar@56881196

problem

I would expect implicit conversion would result in

scala> f[List, Int](new Bar)
val res2: List[Int] = List(42)

where the following is inferred

F[_] = List
A = Int 

instead of actual

F[_] = Any
A = Nothing 

Examining the output of -Xprint:typer shows the following implicit conversion never happend

f(barToList(new Bar()))
@SethTisue
Copy link
Member

Curious whether Dotty is different here.

@mariogalic
Copy link
Author

mariogalic commented Jun 17, 2020

It works in Dotty 0.24.0-RC1:

➜  ~ dotr
Starting dotty REPL...
scala> class Bar
// defined class Bar

scala> def f[F[_], A](v: F[A]) = v
def f[F[_$1], A](v: F[A]): F[A]

scala> implicit def barToList(b: Bar): List[Int] = List(42)
def barToList(b: Bar): List[Int]

scala> f(new Bar)
val res1: List[Int] = List(42)

@SethTisue SethTisue added fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) implicit labels Jun 17, 2020
@som-snytt
Copy link

Just f("": Any) in scala 2 but not 3.

Inferring Any was almost linted under #9248. "It makes for a great test of how far we could push abide."

@joroKr21
Copy link
Member

Mutability 😭
Screenshot 2020-06-18 at 22 08 12

@joroKr21
Copy link
Member

To explain a bit - just testing implicit conversions accumulated type constraints.
It also turns into an error with -Yno-predef

@dwijnand dwijnand added this to the Backlog milestone Nov 11, 2020
@som-snytt
Copy link

Dotty progressed. I think there is a ticket to improve more specific than F[A].

scala-cli compile --server=false -S 3 t12044.scala
-- [E007] Type Mismatch Error: /home/amarki/snips/t12044.scala:11:6 ------------
11 |    f(new Bar)
   |      ^^^^^^^
   |Found:    Bar
   |Required: F[A]
   |
   |where:    A is a type variable
   |          F is a type variable with constraint <: [_] =>> Any
   |
   |Note that implicit conversions were not tried because the result of an implicit conversion
   |must be more specific than F[A]
   |
   | longer explanation available when compiling with `-explain`
[[syntax trees at end of                     typer]] // /home/amarki/snips/t12044.scala
package <empty> {
  import language.implicitConversions
  class Bar() extends Object() {}
  final lazy module val Test: Test = new Test()
  final module class Test() extends Object(), App { this: Test.type =>
    def f[F[_ >: Nothing <: Any] >: Nothing <: Any, A >: Nothing <: Any](v: F[A]
      ): F[A] = v
    implicit def barToList(b: Bar): List[Int] = List.apply[Int]([42 : Int]*)
    Console.println(
      {
        Test.f[[_] =>> Any, Any](new Bar())
      }
    )
  }
}

1 error found
Compilation failed

With -Yno-predef, Scala 2 seems to be stuck.

scala-cli compile --server=false -S 2 t12044.scala
/home/amarki/snips/t12044.scala:11: error: type mismatch;
 found   : Bar
 required: List[A]
    f(new Bar)
      ^
[[syntax trees at end of                     typer]] // t12044.scala
package <empty> {
  import scala.language.implicitConversions;
  class Bar extends scala.AnyRef {
    def <init>(): Bar = {
      Bar.super.<init>();
      ()
    }
  };
  object Test extends AnyRef with App {
    def <init>(): Test.type = {
      Test.super.<init>();
      ()
    };
    def f[F[_] >: [_]Nothing <: [_]Any, A](v: F[A]): F[A] = v;
    implicit def barToList(b: Bar): List[Int] = scala.`package`.List.apply[Int](42);
    scala.Console.println(f(new Bar()))
  }
}

1 error
Compilation failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) implicit infer typer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants