Closed
Description
Compiler version
3.3.0
Minimized code
import scala.compiletime.ops.int.*
type AnyInt[A <: Int] <: Int = A match {
case _ => A
}
type IndexOf[A, T <: Tuple] <: Int = T match {
case EmptyTuple => -1
case A *: t => 0
case _ *: t =>
IndexOf[A, t] match {
case -1 => -1
case AnyInt[a] => S[a]
}
}
opaque type Indexes[A, T <: Tuple] = List[Int]
object Indexes {
extension [S, T <: Tuple](s: Indexes[S, T]) inline def toList: List[Int] = s
inline given of[A, T <: Tuple](using IndexOf[A, T] >= 0 =:= true)(using
index: ValueOf[IndexOf[A, T]],
next: Indexes[A, Tuple.Drop[T, S[IndexOf[A, T]]]]
): Indexes[A, T] = index.value :: next
inline given empty[A, T <: Tuple](using IndexOf[A, T] =:= -1): Indexes[A, T] = Nil
}
trait GetAll[A] {
def apply[T <: Tuple](t: T)(using indexes: Indexes[A, T]): List[A] =
indexes.toList.map(i => t.asInstanceOf[NonEmptyTuple](i).asInstanceOf[A])
}
private object GetAllInstance extends GetAll[Nothing]
def getAll[A]: GetAll[A] = GetAllInstance.asInstanceOf[GetAll[A]]
// the code here is trying to get all values from a tuple that has type [X] as a list
// this works if there are only two strings in the tuple
getAll[String](("str1", 1, "str2", false))
//but this not compiles if there are more than two strings in the tuple
getAll[String](("str1", 1, "str2", false, "str3"))
Output
The compiler error for the code getAll[String](("str1", 1, "str2", false, "str3"))
[error] -- [E172] Type Error: /Users/chunsenwang/projects/scala/reader/src/test/scala/tupleops/TypesSpec.scala:19:54
[error] 19 | getAll[String](("str1", 1, "str2", false, "str3"))
[error] | ^
[error] |No given instance of type tupleops.Indexes[String, (String, Int, String, Boolean, String)] was found for parameter indexes of method apply in trait GetAll.
[error] |I found:
[error] |
[error] | tupleops.Indexes.of[String, (String, Int, String, Boolean, String)](
[error] | <:<.refl[
[error] |
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String)] >=
[error] | (0 : Int)
[error] |
[error] | ]
[error] | )(new ValueOf[(0 : Int)](0),
[error] | tupleops.Indexes.of[String,
[error] |
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String)]]
[error] | ]
[error] |
[error] | ](
[error] | <:<.refl[
[error] |
[error] | tupleops.IndexOf[String,
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String)]]
[error] | ]
[error] | ] >= (0 : Int)
[error] |
[error] | ]
[error] | )(new ValueOf[(1 : Int)](1),
[error] | tupleops.Indexes.empty[String,
[error] |
[error] | Tuple.Drop[
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String)]]
[error] | ],
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String,
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String
[error] | )]
[error] | ]
[error] | ]
[error] | ]
[error] | ]
[error] | ]
[error] |
[error] | ](
[error] | /* missing */
[error] | summon[
[error] | tupleops.IndexOf[String,
[error] | Tuple.Drop[
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String
[error] | )]
[error] | ]
[error] | ],
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String,
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean,
[error] | String)]
[error] | ]
[error] | ]
[error] | ]
[error] | ]
[error] | ]
[error] | ]
[error] | =:= (-1 : Int)]
[error] | )
[error] | )
[error] | )
[error] |
[error] |But no implicit values were found that match type tupleops.IndexOf[String,
[error] | Tuple.Drop[
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String)]]
[error] | ],
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String,
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String)]]
[error] | ]
[error] | ]
[error] | ]
[error] | ]
[error] |] =:= (-1 : Int).
[error] one error found
[warn] Getting the hostname KDF03JGK00 was slow (5008.745334 ms). This is likely because the computer's hostname is not set. You can set the hostname with the command: scutil --set HostName "$(scutil --get LocalHostName).local".
[error] (Test / compileIncremental) Compilation failed
[error] Total time: 6 s, completed Jul 15, 2023, 1:19:29 AM
Expectation
for the error here
[error] | tupleops.Indexes.empty[String,
[error] |
[error] | Tuple.Drop[
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String)]]
[error] | ],
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String,
[error] | Tuple.Drop[(String, Int, String, Boolean, String),
[error] | scala.compiletime.ops.int.S[
[error] | tupleops.IndexOf[String, (String, Int, String, Boolean, String
[error] | )]
[error] | ]
[error] | ]
[error] | ]
[error] | ]
[error] | ]
the compiler should call tupleops.Indexes.of
, not tupleops.Indexes.empty