From 25cb2f3e6081d7ec2201c538ad998169d2cc74b3 Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Mon, 1 Jun 2026 06:29:44 -0400 Subject: [PATCH] [2.x] fix: Add warning about trainsient key (#9288) **Problem** Transient key is silently excluded from caching. **Solution** Add a warning. --- .../sbt/internal/util/appmacro/Cont.scala | 26 +++++++++++++++++++ .../internal/util/appmacro/ContextUtil.scala | 24 +++++++++-------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala index 551887360..02f542515 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala @@ -304,6 +304,12 @@ trait Cont: val modifiedCacheConfigExpr = transformWrappers(cacheConfigExpr.asTerm.changeOwner(sym), substitute, sym) .asExprOf[BuildWideCacheConfiguration] + inputs.foreach: input => + if !input.isCacheInput then + if !Cont.transientAllowSet(input.sym.name) then + report.warning( + s"transient key ${input.sym.name} is excluded from the cache input" + ) if inputs.exists(_.isCacheInput) then val tags = inputs .withFilter(_.isCacheInput) @@ -480,3 +486,23 @@ trait Cont: else Console.err.println(r.show) r end Cont + +private[sbt] object Cont: + val transientAllowSet: Set[String] = Set( + "bspTargetIdentifier", + "bspCompileTask", + "cacheConfiguration", + "compileAnalysisFile", + "compileIncSetup", + "compileInputs", + "classDirectory", + "configuration", + "definedTests", + "earlyOutputPing", + "fileConverter", + "managedResources", + "managedSources", + "streams", + "unmanagedSources", + ) +end Cont 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 90363e535..b3547d3d6 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 @@ -85,19 +85,20 @@ trait ContextUtil[C <: Quotes & scala.Singleton](val valStart: Int): override def toString: String = s"Input($tpe, $qual, $term, $name, $tags)" def isCacheInput: Boolean = tags.nonEmpty - lazy val tags = extractTags(qual) + lazy val (tags, sym) = extractTags(qual) @tailrec - private def extractTags(tree: Term): List[CacheLevelTag] = - def getCacheLevelAnnotation(tree: Term): Option[Term] = + private def extractTags(tree: Term): (List[CacheLevelTag], Symbol) = + def getSymbol(tree: Term): Symbol = Option(tree.tpe.termSymbol) match - case Some(x) => x.getAnnotation(cacheLevelSym) - case None => tree.symbol.getAnnotation(cacheLevelSym) - def getTransientAnnotation(tree: Term): Option[Term] = - Option(tree.tpe.termSymbol) match - case Some(x) => x.getAnnotation(transientSym) - case None => tree.symbol.getAnnotation(transientSym) + case Some(x) => x + case None => tree.symbol + def getCacheLevelAnnotation(sym: Symbol): Option[Term] = + sym.getAnnotation(cacheLevelSym) + def getTransientAnnotation(sym: Symbol): Option[Term] = + sym.getAnnotation(transientSym) def extractTags0(tree: Term) = - getCacheLevelAnnotation(tree) match + val sym = getSymbol(tree) + val ann = getCacheLevelAnnotation(sym) match case Some(annot) => annot.asExprOf[cacheLevel] match case '{ cacheLevel(include = Array.empty[CacheLevelTag](using $_)) } => Nil @@ -105,9 +106,10 @@ trait ContextUtil[C <: Quotes & scala.Singleton](val valStart: Int): include.value.get.toList case _ => sys.error(Printer.TreeStructure.show(annot) + " does not match") case _ => - getTransientAnnotation(tree) match + getTransientAnnotation(sym) match case Some(annot) => Nil case _ => CacheLevelTag.all.toList + (ann, sym) tree match case Inlined(_, _, tree) => extractTags(tree) case Apply(_, List(arg)) => extractTags(arg)