Skip to content

Inline (not transparent) with match type alters typechecking #13250

Open
@Katrix

Description

@Katrix

Compiler version

3.0.3-RC1-bin-20210803-010f8de-NIGHTLY

Minimized code

import scala.deriving.Mirror

class MyGeneric[A, Repr]

type TransformTuple[T <: Tuple] <: Tuple = T match {
  case x *: xs => x *: TransformTuple[xs]
  case EmptyTuple => EmptyTuple
}

//Both of these are equivalent with the exception that one is defined inline
object NotInline {
  given materializeProduct[T <: Product](
    using m: Mirror.ProductOf[T]
  ): MyGeneric[T, TransformTuple[m.MirroredElemTypes]] =
    new MyGeneric[T, TransformTuple[m.MirroredElemTypes]]
}

object WithInline {
  inline given materializeProduct[T <: Product](
    using m: Mirror.ProductOf[T]
  ): MyGeneric[T, TransformTuple[m.MirroredElemTypes]] =
    new MyGeneric[T, TransformTuple[m.MirroredElemTypes]]
}

@main def testGen = {
  val t = (23, "foo", true)
  type T = (Int, String, Boolean)
  val g1 = NotInline.materializeProduct[T]
  val g2 = WithInline.materializeProduct[T]

  //Passing g1 defined in a value which is not inline explicitly compiles
  takesGen(t)(using g1)

  //Inlining g1 fails
  //takesGen(t)(using NotInline.materializeProduct[T])

  //Fails
  val dummy1 = {
    import NotInline.materializeProduct
    //takesGen(t)
  }

  //Works fine
  val dummy2 = {
    import WithInline.materializeProduct
    takesGen(t)
  }
}

def takesGen[A, Repr](a: A)(using MyGeneric[A, Repr]): String = "Foo"

Note, the match type is required. Without it, everything works normally.

Output

error] -- [E007] Type Mismatch Error: D:\DevProjects\Stable\shapeless\core\src\main\scala-3\Testing.scala:35:20
[error] 35 |  takesGen(t)(using NotInline.materializeProduct[T])
[error]    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error]    |          Found:    MyGeneric[T, Int *: String *: Boolean *: EmptyTuple]
[error]    |          Required: MyGeneric[(Int, String, Boolean), TransformTuple[?]]
[error]    |
[error]    |          Note: a match type could not be fully reduced:
[error]    |
[error]    |            trying to reduce  TransformTuple[?]
[error]    |            failed since selector  Any
[error]    |            does not match  case x *: xs => x *: TransformTuple[xs]
[error]    |            and cannot be shown to be disjoint from it either.
[error]    |            Therefore, reduction cannot advance to the remaining case
[error]    |
[error]    |              case EmptyTuple => EmptyTuple
[error] -- Error: D:\DevProjects\Stable\shapeless\core\src\main\scala-3\Testing.scala:40:15
[error] 40 |    takesGen(t)
[error]    |               ^
[error]    |no implicit argument of type MyGeneric[(Int, String, Boolean), Repr] was found for parameter x$2 of method takesGen
[error]    |
[error]    |where:    Repr is a type variable
[error]    |.
[error]    |I found:
[error]    |
[error]    |    NotInline.materializeProduct[(Int, String, Boolean)](
[error]    |      {
[error]    |        final class $anon() extends Object() {
[error]    |          type MirroredMonoType = (Int, String, Boolean)
[error]    |        }
[error]    |        (new $anon():Object)
[error]    |      }.$asInstanceOf[
[error]    |
[error]    |          (
[error]    |            deriving.Mirror.Product{
[error]    |              MirroredType = (Int, String, Boolean);
[error]    |                MirroredMonoType = (Int, String, Boolean)
[error]    |              ; MirroredElemTypes <: Tuple
[error]    |            }
[error]    |           &
[error]    |            scala.deriving.Mirror.Product{
[error]    |              MirroredMonoType = (Int, String, Boolean);
[error]    |                MirroredType = (Int, String, Boolean)
[error]    |              ; MirroredLabel = ("Tuple3" : String)
[error]    |            }
[error]    |          ){
[error]    |            MirroredElemTypes = (Int, String, Boolean);
[error]    |              MirroredElemLabels = (("_1" : String), ("_2" : String),
[error]    |                ("_3" : String)
[error]    |              )
[error]    |          }
[error]    |
[error]    |      ]
[error]    |    )
[error]    |
[error]    |But given instance materializeProduct in object NotInline does not match type MyGeneric[(Int, String, Boolean), Repr].
[error]    |
[error]    |One of the following imports might make progress towards fixing the problem:
[error]    |
[error]    |  import shapeless.~?>.idKeyWitness
[error]    |  import shapeless.~?>.idValueWitness
[error]    |  import shapeless.~?>.witness
[error]    |
[error] two errors found

Expectation

Inline without transparent should not change typechecking. In this case I'd expect both to compile, but only the inline one does.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions