Skip to content

by name implicit generate unsound Tree #24178

@xuwei-k

Description

@xuwei-k

Compiler version

  • 3.3.7
  • 3.7.3
  • 3.8.0-RC1-bin-20251012-89e617d-NIGHTLY

Minimized code

//> using scala 3.7.3

package example

import scala.deriving.Mirror

class MyTypeClass[T](value: T) {
  def map[S](f: T => S): MyTypeClass[S] =
    new MyTypeClass[S](f(value))

  def flatMap[S](f: T => MyTypeClass[S]): MyTypeClass[S] =
    f(value)
}

object MyTypeClass {

  given MyTypeClass[EmptyTuple] =
    new MyTypeClass[EmptyTuple](EmptyTuple)

  given [H, T <: Tuple](using H: => MyTypeClass[H], T: => MyTypeClass[T]): MyTypeClass[H *: T] =
    for {
      h <- H
      t <- T
    } yield h *: t

  given [P <: Product, A](
    using m: Mirror.ProductOf[P],
    i: A =:= m.MirroredElemTypes,
    w: MyTypeClass[A]
  ): MyTypeClass[P] =
    w.map(a => m.fromProduct(i(a)))

  given MyTypeClass[Int] = MyTypeClass(3)
}

case class A(
  x: Int,
  y: C
)

sealed trait C
object C {
  case object C1 extends C
}

object Main {
  def main(args: Array[String]): Unit = {
    println(summon[MyTypeClass[A]])
  }
}

Output

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "example.MyTypeClass.map(scala.Function1)" because "w" is null
	at example.MyTypeClass$.given_MyTypeClass_P(hoge.scala:31)
	at example.Main$$_lazy_implicit_$2$1.<init>(hoge.scala:48)
	at example.Main$.main(hoge.scala:48)
	at example.Main.main(hoge.scala)

Expectation

compile error or warning

Note

with -Xprint:typer

         val x$proxy1: example.MyTypeClass[example.A] =
              {
                final class $_lazy_implicit_$2() extends Object(), Serializable
                   {
                  val $_lazy_implicit_$1:
                    example.MyTypeClass[example.C *: EmptyTuple.type] =
                    example.MyTypeClass.given_MyTypeClass_P[
                      example.C *: EmptyTuple.type, example.C *: EmptyTuple.type
                      ](
                      new scala.runtime.TupleMirror(1).$asInstanceOf[
                        
                          scala.deriving.Mirror.Product{
                            type MirroredMonoType = example.C *: EmptyTuple.type
                              ;
                              type MirroredType = example.C *: EmptyTuple.type;
                              type MirroredLabel = ("Tuple1" : String);
                              type MirroredElemTypes = example.C *:
                                EmptyTuple.type;
                              type MirroredElemLabels = ("_1" : String) *:
                                EmptyTuple.type
                          }
                        
                      ],
                    <:<.refl[example.C *: EmptyTuple.type],
                      this.$_lazy_implicit_$1)
                }
                val $_lazy_implicit_$3: $_lazy_implicit_$2 =
                  new $_lazy_implicit_$2()
                example.MyTypeClass.given_MyTypeClass_P[example.A,
                  (Int, example.C)](
                  example.A.$asInstanceOf[
                    
                      scala.deriving.Mirror.Product{
                        type MirroredMonoType = example.A;
                          type MirroredType = example.A;
                          type MirroredLabel = ("A" : String);
                          type MirroredElemTypes = (Int, example.C);
                          type MirroredElemLabels = (("x" : String),
                            ("y" : String))
                      }
                    
                  ],
                <:<.refl[(Int, example.C)],
                  example.MyTypeClass.given_MyTypeClass_*:[Int,
                    example.C *: EmptyTuple.type](
                    example.MyTypeClass.given_MyTypeClass_Int,
                    $_lazy_implicit_$3.$_lazy_implicit_$1)
                )
              }
            x$proxy1

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:implicitsrelated to implicitsitype:bugitype:soundnessSoundness bug (it lets us compile code that crashes at runtime with a ClassCastException)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions