From aa7d3d29623a6e7ff70e47c6cc25579d6c5169b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Tue, 2 Jun 2026 11:40:09 +0200 Subject: [PATCH 1/2] feat(scala-3,core): port SourceInfo.here macro Wire SourceInfo.here to inline implicit def backed by Position.ofMacroExpansion + Symbol.spliceOwner.owner enclosing walk. Replaces Phase-1 ??? stub. Public signature unchanged. --- .../avsystem/commons/misc/SourceInfo.scala | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/com/avsystem/commons/misc/SourceInfo.scala b/core/src/main/scala/com/avsystem/commons/misc/SourceInfo.scala index bf418c3a2..63635197b 100644 --- a/core/src/main/scala/com/avsystem/commons/misc/SourceInfo.scala +++ b/core/src/main/scala/com/avsystem/commons/misc/SourceInfo.scala @@ -1,6 +1,9 @@ package com.avsystem.commons package misc +import scala.annotation.tailrec +import scala.quoted.* + /** Macro-materialized implicit value that provides information about callsite source file position. It can be used in * runtime for logging and debugging purposes. Similar to Scalactic's `Position`, but contains more information. */ @@ -25,6 +28,31 @@ case class SourceInfo( object SourceInfo { def apply()(implicit si: SourceInfo): SourceInfo = si - // TODO[scala3-port]: SourceInfo.here (Scala 2 macro def) (L) - implicit def here: SourceInfo = ??? + inline implicit def here: SourceInfo = ${ hereImpl } + + private[misc] def hereImpl(using quotes: Quotes): Expr[SourceInfo] = { + import quotes.reflect.* + val pos = Position.ofMacroExpansion + + @tailrec + def enclosingLoop(sym: Symbol, acc: Vector[String]): Seq[String] = + if (sym == defn.RootClass) acc + else enclosingLoop(sym.owner, acc :+ sym.name) + + '{ + SourceInfo( + ${ Expr(pos.sourceFile.path) }, + ${ Expr(pos.sourceFile.name) }, + ${ Expr(pos.start) }, + ${ Expr(pos.startLine + 1) }, + ${ Expr(pos.startColumn + 1) }, + ${ + Expr( + pos.sourceFile.content.flatMap(_.linesIterator.drop(pos.startLine).nextOption).getOrElse("") + ) + }, + ${ Expr(enclosingLoop(Symbol.spliceOwner.owner, Vector.empty).toList) }, + ) + } + } } From 5c3f49595973fb89fedbd980d353303c2ee83176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Tue, 2 Jun 2026 11:40:09 +0200 Subject: [PATCH 2/2] docs(migration): record SourceInfo.here port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add §3 entry under core — misc SourceInfo (slice 02-02 partial). Remove SourceInfo.here backlog row. --- MIGRATION.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index b99395701..a250a2622 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -55,6 +55,12 @@ the bottom of this file. Restoration ships incrementally per feature area. - `enum` was renamed to `e` at one call site in `GenKeyCodec` (`enum` is reserved in Scala 3). - `@targetName` annotation added to `CloseableIterator` overloaded methods. +### core — misc SourceInfo (slice 02-02 partial) + +- `SourceInfo.here` ported from Scala 2 `c.macroApplication` macro to Scala 3 `inline implicit def here: SourceInfo = ${ hereImpl }` using `Position.ofMacroExpansion` and `Symbol.spliceOwner.owner` enclosing-symbol walk. +- Public API preserved: `SourceInfo.here` remains an `implicit def` returning `SourceInfo`; callers unchanged. +- `positioned.here` deferred to a follow-up slice in 02-02 scope. + ### mongo - `BsonRef.Creator.ref`, `DataTypeDsl.{ref, as, is, isNot}`, `TypedMongoUtils.optionalizeFirstArg` are stubbed with @@ -173,7 +179,6 @@ Full per-file list with locations is in the Backlog table below (filter rows whe | `core/src/main/scala/com/avsystem/commons/misc/SelfInstance.scala:4` | C[_] existential narrowed to C[Any] (Scala 3 forbids HKT wildcard application) | S | | `core/src/main/scala/com/avsystem/commons/misc/SelfInstance.scala:7` | SelfInstance.materialize (Scala 2 macro def) | L | | `core/src/main/scala/com/avsystem/commons/misc/SimpleClassName.scala:8` | SimpleClassName.materialize (Scala 2 macro def) | L | -| `core/src/main/scala/com/avsystem/commons/misc/SourceInfo.scala:28` | SourceInfo.here (Scala 2 macro def) | L | | `core/src/main/scala/com/avsystem/commons/misc/Timestamp.scala:13` | Comparable[Timestamp] (Scala 3 forbids AnyVal inheriting Object-derived traits) | S | | `core/src/main/scala/com/avsystem/commons/misc/TypeString.scala:31` | TypeString.materialize (Scala 2 macro def) | L | | `core/src/main/scala/com/avsystem/commons/misc/TypeString.scala:90` | JavaClassName.materialize (Scala 2 macro def) | L |