Skip to content

Implicit conversion isn't applied for Id type alias #8049

Closed
@travisbrown

Description

@travisbrown

minimized code

import scala.language.implicitConversions

class Ops[A](a: A) {
  def bar: Unit = ()
}

implicit def toOps[A](a: A): Ops[A] = new Ops[A](a)

type Id[A] = A

class Foo[A](val value: Id[A]) {
  def same: Foo[A] = new Foo[A](value)
  def map[B](f: A => B): Foo[B] = new Foo[B](f(value))
}

val x: Int = 1
val foo: Foo[Int] = new Foo(1)

val res1 = x.bar
val res2 = foo.value.bar
val res3 = foo.same.value.bar
val res4 = foo.map[Int](_ + 1).value.bar
val res5 = foo.map(_ + 1).value.bar
Compilation output
-- [E008] Member Not Found Error: Id.scala:23:32 -------------------------------
23 |val res5 = foo.map(_ + 1).value.bar
   |           ^^^^^^^^^^^^^^^^^^^^^^^^
   |value bar is not a member of Id[B], but could be made available as an extension method.
   |
   |One of the following imports might fix the problem:
   |
   |  import Int.int2double
   |  import Int.int2float
   |  import Int.int2long
   |  import math.BigDecimal.int2bigDecimal
   |  import math.BigInt.int2bigInt
   |  import math.Numeric.IntIsIntegral.mkNumericOps
   |  import math.Numeric.BigIntIsIntegral.mkNumericOps
   |  import math.Numeric.IntIsIntegral.mkOrderingOps
   |  import math.Ordering.Int.mkOrderingOps
   |  import Long.long2double
   |  import Long.long2float
   |  import math.BigDecimal.long2bigDecimal
   |  import math.BigInt.long2bigInt
   |  import math.Numeric.LongIsIntegral.mkNumericOps
   |  import math.Numeric.FloatIsFractional.mkNumericOps
   |  import math.Ordering.Long.mkOrderingOps
   |  import Float.float2double
   |  import math.BigDecimal.double2bigDecimal
   |  import math.Numeric.DoubleIsFractional.mkNumericOps
   |  import math.Numeric.BigDecimalAsIfIntegral.mkNumericOps
   |  import math.Numeric.BigDecimalIsFractional.mkNumericOps
   |  import math.Numeric.LongIsIntegral.mkOrderingOps
   |  import math.Numeric.BigDecimalAsIfIntegral.mkOrderingOps
   |  import math.Numeric.BigDecimalIsFractional.mkOrderingOps
   |  import math.Numeric.BigIntIsIntegral.mkOrderingOps
   |  import math.Numeric.FloatIsFractional.mkOrderingOps
   |  import math.Numeric.DoubleIsFractional.mkOrderingOps
   |  import math.Ordering.BigDecimal.mkOrderingOps
   |  import math.Ordering.BigInt.mkOrderingOps
   |  import math.Ordering.DeprecatedFloatOrdering.mkOrderingOps
   |  import math.Ordering.Float.IeeeOrdering.mkOrderingOps
   |  import math.Ordering.Float.TotalOrdering.mkOrderingOps
   |  import math.Ordering.DeprecatedDoubleOrdering.mkOrderingOps
   |  import math.Ordering.Double.IeeeOrdering.mkOrderingOps
   |  import math.Ordering.Double.TotalOrdering.mkOrderingOps
   |  import math.Integral.Implicits.infixIntegralOps
   |  import math.Numeric.Implicits.infixNumericOps
   |  import math.Ordered.orderingToOrdered
   |  import math.Ordering.Implicits.infixOrderingOps
   |  import reflect.Selectable.reflectiveSelectable
   |  import implicits.Not.amb1
   |  import implicits.Not.amb2
   |         
   |
   |where:    B is a type variable with constraint >: Int
1 error found

expectation

This compiles on Scala 2. I'm running into this in the Cats tests, where we use ScalaTest's should matchers to tests methods on e.g. WriterT[Id, A, B], which return Id[C] where C is inferred.

If you change Id to something like type Id[A] = List[A] and edit Foo appropriately, it compiles fine on Dotty.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions