Closed
Description
object Foo {
class Expr[T]
abstract class Liftable[T] {
def toExpr(x: T): Expr[T]
}
implicit class LiftExprOps[T](val x: T) extends AnyVal {
def toExpr(implicit ev: Liftable[T]): Expr[T] = ev.toExpr(x)
}
implicit def NilIsLiftable: Liftable[Nil.type] = ???
Nil.toExpr(NilIsLiftable)
(Nil.toExpr: Expr[Nil.type])
Nil.toExpr
}
fails with
-- Error: Foo.scala:49:12 ------------------------------------------------------
49 | Nil.toExpr
| ^
|no implicit argument of type Foo.Liftable[scala.collection.immutable.Nil] was found for parameter ev of method toExpr in class LiftExprOps
the last case inferes the type scala.collection.immutable.Nil$
instead of collection.immutable.Nil.type
for the type parameter of the implicit class LiftExprOps
.
This can be seen after typer
result of Foo.scala after frontend:
package <empty> {
final lazy module val Foo: Foo$ = new Foo$()
final module class Foo$() extends Object() { this: Foo.type =>
class Expr[T >: Nothing <: Any]() extends Object() {
T
}
abstract class Liftable[T >: Nothing <: Any]() extends Object() {
T
def toExpr(x: Liftable.this.T): Foo.Expr[Liftable.this.T]
}
final class LiftExprOps[T >: Nothing <: Any](x: T) extends AnyVal() {
T
val x: T
def toExpr(implicit ev: Foo.Liftable[LiftExprOps.this.T]):
Foo.Expr[LiftExprOps.this.T]
= ev.toExpr(LiftExprOps.this.x)
}
final lazy module val LiftExprOps: Foo.LiftExprOps$ = new Foo.LiftExprOps$()
final module class LiftExprOps$() extends Object() {
this: Foo.LiftExprOps.type =>
}
implicit def LiftExprOps[T >: Nothing <: Any](x: T): Foo.LiftExprOps[T] =
new Foo.LiftExprOps[T](x)
implicit def NilIsLiftable: Foo.Liftable[Nil.type] = ???
Foo.LiftExprOps[=> collection.immutable.Nil.type(Nil)](Nil).toExpr(
Foo.NilIsLiftable
)
Foo.LiftExprOps[=> collection.immutable.Nil.type(Nil)](Nil).toExpr(
Foo.NilIsLiftable
): Foo.Expr[Nil.type]
Foo.LiftExprOps[scala.collection.immutable.Nil$](Nil).toExpr(
/* missing */implicitly[<notype>]
)
}
}
This code does compile on Scala 2.