Skip to content

recursion given search not works correct. #18211

Closed
@chunsenwang

Description

@chunsenwang

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions