From b3336b2ce219023ecb3124c147b4ad8372377e6d Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Thu, 17 Oct 2024 10:12:57 +0900 Subject: [PATCH] fix type error if too many `.value` --- .../internal/util/appmacro/ContextUtil.scala | 28 ++++++- .../src/sbt-test/tests/many-values/build.sbt | 79 +++++++++++++++++++ sbt-app/src/sbt-test/tests/many-values/test | 1 + 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 sbt-app/src/sbt-test/tests/many-values/build.sbt create mode 100644 sbt-app/src/sbt-test/tests/many-values/test diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/ContextUtil.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/ContextUtil.scala index 99879ec99..070ce99f6 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/ContextUtil.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/ContextUtil.scala @@ -41,16 +41,40 @@ trait ContextUtil[C <: Quotes & scala.Singleton](val valStart: Int): def typed[A: Type](value: Term): Term = Typed(value, TypeTree.of[A]) + /** + * [[https://github.com/sbt/sbt/issues/7768]] + * [[https://github.com/scala/scala3/issues/21779]] + */ + private def exprOfTupleFromSeq(seq: Seq[Expr[Any]])(using q: Quotes): Expr[scala.Tuple] = { + def tupleTypeFromSeq(seq: Seq[Expr[Any]]): q.reflect.TypeRepr = { + import q.reflect.* + val consRef = Symbol.classSymbol("scala.*:").typeRef + seq.foldRight(TypeRepr.of[EmptyTuple]) { (expr, ts) => + AppliedType(consRef, expr.asTerm.tpe :: ts :: Nil) + } + } + + if (seq.sizeIs <= 22) { + Expr.ofTupleFromSeq(seq) + } else { + val tupleTpe = tupleTypeFromSeq(seq) + tupleTpe.asType match { + case '[tpe] => + '{ Tuple.fromIArray(IArray(${ Varargs(seq) }*)).asInstanceOf[tpe & scala.Tuple] } + } + } + } + def makeTuple(inputs: List[Input]): BuilderResult = new BuilderResult: override lazy val inputTupleTypeRepr: TypeRepr = tupleTypeRepr(inputs.map(_.tpe)) override def tupleExpr: Expr[Tuple] = - Expr.ofTupleFromSeq(inputs.map(_.term.asExpr)) + exprOfTupleFromSeq(inputs.map(_.term.asExpr)) override def cacheInputTupleTypeRepr: TypeRepr = tupleTypeRepr(inputs.filter(_.isCacheInput).map(_.tpe)) override def cacheInputExpr(tupleTerm: Term): Expr[Tuple] = - Expr.ofTupleFromSeq(inputs.zipWithIndex.flatMap { case (input, idx) => + exprOfTupleFromSeq(inputs.zipWithIndex.flatMap { case (input, idx) => if input.tags.nonEmpty then input.tpe.asType match case '[a] => diff --git a/sbt-app/src/sbt-test/tests/many-values/build.sbt b/sbt-app/src/sbt-test/tests/many-values/build.sbt new file mode 100644 index 000000000..b210990e3 --- /dev/null +++ b/sbt-app/src/sbt-test/tests/many-values/build.sbt @@ -0,0 +1,79 @@ +// https://github.com/sbt/sbt/issues/7768 + +val a1 = settingKey[Seq[Int]]("") +val a2 = settingKey[Int]("") +val a3 = settingKey[Int]("") +val a4 = settingKey[Int]("") +val a5 = settingKey[Int]("") +val a6 = settingKey[Int]("") +val a7 = settingKey[Int]("") +val a8 = settingKey[Int]("") +val a9 = settingKey[Int]("") +val a10 = settingKey[Int]("") +val a11 = settingKey[Int]("") +val a12 = settingKey[Int]("") +val a13 = settingKey[Int]("") +val a14 = settingKey[Int]("") +val a15 = settingKey[Int]("") +val a16 = settingKey[Int]("") +val a17 = settingKey[Int]("") +val a18 = settingKey[Int]("") +val a19 = settingKey[Int]("") +val a20 = settingKey[Int]("") +val a21 = settingKey[Int]("") +val a22 = settingKey[Int]("") +val a23 = settingKey[Int]("") + +a1 := List(1) +a2 := 2 +a3 := 3 +a4 := 4 +a5 := 5 +a6 := 6 +a7 := 7 +a8 := 8 +a9 := 9 +a10 := 10 +a11 := 11 +a12 := 12 +a13 := 13 +a14 := 14 +a15 := 15 +a16 := 16 +a17 := 17 +a18 := 18 +a19 := 19 +a20 := 20 +a21 := 21 +a22 := 22 +a23 := 23 + +TaskKey[Unit]("check") := { + val sum = ( + a1.value ++ List( + a2.value, + a3.value, + a4.value, + a5.value, + a6.value, + a7.value, + a8.value, + a9.value, + a10.value, + a11.value, + a12.value, + a13.value, + a14.value, + a15.value, + a16.value, + a17.value, + a18.value, + a19.value, + a20.value, + a21.value, + a22.value, + a23.value, + ) + ).sum + assert(sum == 276, sum) +} diff --git a/sbt-app/src/sbt-test/tests/many-values/test b/sbt-app/src/sbt-test/tests/many-values/test new file mode 100644 index 000000000..15675b169 --- /dev/null +++ b/sbt-app/src/sbt-test/tests/many-values/test @@ -0,0 +1 @@ +> check