Skip to content

asExprOf fails for tuples larger than 22 #17257

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

Closed
Katrix opened this issue Apr 13, 2023 · 3 comments · Fixed by #17261
Closed

asExprOf fails for tuples larger than 22 #17257

Katrix opened this issue Apr 13, 2023 · 3 comments · Fixed by #17261
Assignees
Labels
area:metaprogramming:quotes Issues related to quotes and splices itype:bug
Milestone

Comments

@Katrix
Copy link
Contributor

Katrix commented Apr 13, 2023

Compiler version

3.2.2

Minimized code

// file a.scala
inline def summonAllOptimized[T <: Tuple]: T =
  ${ summonAllOptimizedImpl[T] }

private def summonAllOptimizedImpl[T <: Tuple: Type](using q: Quotes): Expr[T] = {
  import q.reflect.*

  Expr
    .ofTupleFromSeq(typesOfTuple(TypeRepr.of[T], Nil).map { tpe =>
      tpe.asType match {
        case '[t] =>
          Expr.summon[t].getOrElse(report.errorAndAbort(s"Unable to to find implicit instance for ${tpe.show}"))
      }
    })
    .asExprOf[T]
}

@tailrec
private[derivation] def typesOfTuple(
    using q: Quotes
)(tpe: q.reflect.TypeRepr, acc: List[q.reflect.TypeRepr]): List[q.reflect.TypeRepr] =
  import q.reflect.*
  val cons = Symbol.classSymbol("scala.*:")
  tpe.widenTermRefByName.dealias match
    case AppliedType(fn, tpes) if defn.isTupleClass(fn.typeSymbol) =>
      tpes.reverse_:::(acc)
    case AppliedType(tp, List(headType, tailType)) if tp.derivesFrom(cons) =>
      typesOfTuple(tailType, headType :: acc)
    case tpe =>
      if tpe.derivesFrom(Symbol.classSymbol("scala.EmptyTuple")) then acc.reverse
      else report.errorAndAbort(s"Unknown type encountered in tuple ${tpe.show}")

//file b.scala
val test = Helpers.summonAllOptimized[(
    ValueOf["a"], ValueOf["a"], ValueOf["a"], ValueOf["a"], ValueOf["a"],
    ValueOf["a"], ValueOf["a"], ValueOf["a"], ValueOf["a"], ValueOf["a"],
    ValueOf["a"], ValueOf["a"], ValueOf["a"], ValueOf["a"], ValueOf["a"],
    ValueOf["a"], ValueOf["a"], ValueOf["a"], ValueOf["a"], ValueOf["a"],
    ValueOf["a"], ValueOf["a"], ValueOf["a"] //Commenting out the last one here fixes the compile error
  )]

Output

[error]     |Exception occurred while executing macro expansion.
[error]     |java.lang.Exception: Expr cast exception: scala.Tuple.fromIArray[scala.Any](scala.IArray$package.IArray.apply[scala.Any](new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"), new scala.ValueOf["a"]("a"))(scala.reflect.ClassTag.Any))
[error]     |of type: scala.Tuple
[error]     |did not conform to type: scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.*:[scala.ValueOf["a"], scala.Tuple$package.EmptyTuple]]]]]]]]]]]]]]]]]]]]]]]
[error]     |
[error]     |   at scala.quoted.runtime.impl.QuotesImpl.asExprOf(QuotesImpl.scala:73)
[error]     |   at perspective.derivation.Helpers$.summonAllOptimizedImpl(Helpers.scala:157)
[error]     |   at perspective.derivation.Helpers$.inline$summonAllOptimizedImpl(Helpers.scala:147)

Expectatio

I would expect the above to work just like it works for tuples of size 22 or less, or that this was at least better communicated.

@Katrix Katrix added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 13, 2023
@bishabosha
Copy link
Member

I think this could be resolved in the implementation pf Expr.ofTupleFromSeq by constructing a tuple type from extracting the elements of the seq and casting the result.

@bishabosha bishabosha self-assigned this Apr 14, 2023
@bishabosha bishabosha removed the stat:needs triage Every issue needs to have an "area" and "itype" label label Apr 14, 2023
@nicolasstucki nicolasstucki added the area:metaprogramming:reflection Issues related to the quotes reflection API label Apr 17, 2023
@nicolasstucki
Copy link
Contributor

I think this could be resolved in the implementation pf Expr.ofTupleFromSeq by constructing a tuple type from extracting the elements of the seq and casting the result.

Yes, that is what we should do.

@nicolasstucki nicolasstucki added area:metaprogramming:quotes Issues related to quotes and splices and removed area:metaprogramming:reflection Issues related to the quotes reflection API labels Apr 17, 2023
@nicolasstucki
Copy link
Contributor

I assume that this issue also extends to Expr.ofTuple. We should also test this work after the fix for ofTupleFromSeq.

bishabosha added a commit that referenced this issue Apr 17, 2023
identified that for all `Seq` with arity <= 22, the result had the most
precise type possible, for > 22 then it was only `Tuple`

fixes #17257
@Kordyjan Kordyjan added this to the 3.3.1 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:metaprogramming:quotes Issues related to quotes and splices itype:bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants