diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index c1ceb98ea5d3..86b007446f91 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -4621,6 +4621,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => case Bind(_, body) => foldTree(x, body)(owner) case Unapply(fun, implicits, patterns) => foldTrees(foldTrees(foldTree(x, fun)(owner), implicits)(owner), patterns)(owner) case Alternatives(patterns) => foldTrees(x, patterns)(owner) + case SummonFrom(cases) => foldTrees(x, cases)(owner) + case _ => throw MatchError(tree.show(using Printer.TreeStructure)) } } end TreeAccumulator @@ -4662,7 +4664,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def transformTree(tree: Tree)(owner: Symbol): Tree = { tree match { case tree: PackageClause => - PackageClause.copy(tree)(transformTerm(tree.pid).asInstanceOf[Ref], transformTrees(tree.stats)(tree.symbol)) + PackageClause.copy(tree)(transformTerm(tree.pid)(owner).asInstanceOf[Ref], transformTrees(tree.stats)(tree.symbol)) case tree: Import => Import.copy(tree)(transformTerm(tree.expr)(owner), tree.selectors) case tree: Export => @@ -4685,6 +4687,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => Alternatives.copy(pattern)(transformTrees(pattern.patterns)(owner)) case TypedOrTest(inner, tpt) => TypedOrTest.copy(tree)(transformTree(inner)(owner), transformTypeTree(tpt)(owner)) + case _ => + throw MatchError(tree.show(using Printer.TreeStructure)) } } @@ -4708,11 +4712,20 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => val owner = tree.symbol TypeDef.copy(tree)(tree.name, transformTree(tree.rhs)(owner)) case tree: ClassDef => - ClassDef.copy(tree)(tree.name, tree.constructor, tree.parents, tree.self, tree.body) + val constructor @ DefDef(_, _, _, _) = transformStatement(tree.constructor)(tree.symbol) + val parents = tree.parents.map(transformTree(_)(tree.symbol)) + val self = tree.self.map { slf => + transformStatement(slf)(tree.symbol) match + case self: ValDef => self + } + val body = tree.body.map(transformStatement(_)(tree.symbol)) + ClassDef.copy(tree)(tree.name, constructor, parents, self, body) case tree: Import => Import.copy(tree)(transformTerm(tree.expr)(owner), tree.selectors) case tree: Export => tree + case _ => + throw MatchError(tree.show(using Printer.TreeStructure)) } } @@ -4758,6 +4771,10 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => Repeated.copy(tree)(transformTerms(elems)(owner), transformTypeTree(elemtpt)(owner)) case Inlined(call, bindings, expansion) => Inlined.copy(tree)(call, transformSubTrees(bindings)(owner), transformTerm(expansion)(owner)) + case SummonFrom(cases) => + SummonFrom.copy(tree)(transformCaseDefs(cases)(owner)) + case _ => + throw MatchError(tree.show(using Printer.TreeStructure)) } } @@ -4786,6 +4803,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => TypeBind.copy(tree)(tree.name, tree.body) case tree: TypeBlock => TypeBlock.copy(tree)(tree.aliases, tree.tpt) + case _ => + throw MatchError(tree.show(using Printer.TreeStructure)) } def transformCaseDef(tree: CaseDef)(owner: Symbol): CaseDef = { diff --git a/tests/run-custom-args/tasty-inspector/i14789.scala b/tests/run-custom-args/tasty-inspector/i14789.scala new file mode 100644 index 000000000000..72e773a8df16 --- /dev/null +++ b/tests/run-custom-args/tasty-inspector/i14789.scala @@ -0,0 +1,45 @@ +import scala.quoted.* +import scala.tasty.inspector.* + +@main def Test = { + // Artefact of the current test infrastructure + // TODO improve infrastructure to avoid needing this code on each test + val classpath = dotty.tools.dotc.util.ClasspathFromClassloader(this.getClass.getClassLoader).split(java.io.File.pathSeparator).find(_.contains("runWithCompiler")).get + val allTastyFiles = dotty.tools.io.Path(classpath).walkFilter(_.extension == "tasty").map(_.toString).toList + val tastyFiles = allTastyFiles.filter(_.contains("App")) + + // in dotty-example-project + val inspector = new Inspector { + def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = { + import quotes.reflect.* + val traverser = new TreeTraverser { + override def traverseTree(tree: Tree)(owner: Symbol): Unit = { + try { + super.traverseTree(tree)(owner) + } catch { + case e => + report.error(s"unexpected error ${e}", tree.pos) + throw e + } + } + } + val mapper = new TreeMap { } + tastys.foreach{ tasty => + traverser.traverseTree(tasty.ast)(tasty.ast.symbol) + mapper.transformTree(tasty.ast)(tasty.ast.symbol) + } + } + } + TastyInspector.inspectTastyFiles(tastyFiles)(inspector) +} + +object App { + import scala.compiletime.* + + transparent inline def summonFirst0[T]: Any = + inline erasedValue[T] match + case _: (a *: b) => summonFrom { + case instance: `a` => instance + case _ => summonFirst0[b] + } +}