Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

recursion given search not works correct. #18211

Closed
chunsenwang opened this issue Jul 14, 2023 · 1 comment
Closed

recursion given search not works correct. #18211

chunsenwang opened this issue Jul 14, 2023 · 1 comment
Assignees
Labels
Milestone

Comments

@chunsenwang
Copy link

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

@chunsenwang chunsenwang added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Jul 14, 2023
@nicolasstucki nicolasstucki added area:match-types stat:needs minimization Needs a self contained minimization and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jul 17, 2023
@nicolasstucki
Copy link
Contributor

Simplified

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]
    }
}

type Indexes[A, T <: Tuple]
object Indexes {
  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] = ???

  given empty[A, T <: Tuple](using IndexOf[A, T] =:= -1): Indexes[A, T] = ???
}

class GetAll[A]:
  def apply[T <: Tuple](t: T)(using indexes: Indexes[A, T]): List[A] = ???

def getAll[A]: GetAll[A] = new GetAll[A]

def test =
   // 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"))

sjrd added a commit to dotty-staging/dotty that referenced this issue Aug 30, 2023
This is also fixed by the parent commit.
@sjrd sjrd self-assigned this Aug 30, 2023
@sjrd sjrd closed this as completed in eb18e53 Sep 1, 2023
@sjrd sjrd added this to the 3.4.0 milestone Sep 1, 2023
WojciechMazur added a commit that referenced this issue Jun 19, 2024
This is also fixed by the parent commit.

[Cherry-picked eb18e53][modified]
WojciechMazur added a commit that referenced this issue Jun 20, 2024
This is also fixed by the parent commit.

[Cherry-picked eb18e53][modified]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants