diff --git a/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala b/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala index 98376c497868..606c9f634b60 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala @@ -60,15 +60,24 @@ class TreeMapWithImplicits extends tpd.TreeMap { traverse(stats) } - private def nestedScopeCtx(defs: List[Tree])(using Context): Context = { + private def nestedScopeCtx(stats: List[Tree])(using Context): Context = { val nestedCtx = ctx.fresh.setNewScope - defs foreach { + stats.foreach { case d: DefTree if d.symbol.isOneOf(GivenOrImplicit) => nestedCtx.enter(d.symbol) case _ => } - nestedCtx + importScopeCtx(stats)(using nestedCtx) } + private def nestedPackageScopeCtx(tree: PackageDef)(using Context): Context = + importScopeCtx(tree.stats)(using ctx.withOwner(tree.symbol)) + + private def importScopeCtx(stats: List[Tree])(using Context): Context = + stats.foldLeft(ctx) { + case (acc, stat: Import) => ctx.importContext(stat, stat.symbol) + case (acc, _) => acc + } + private def patternScopeCtx(pattern: Tree)(using Context): Context = { val nestedCtx = ctx.fresh.setNewScope new TreeTraverser { @@ -100,8 +109,10 @@ class TreeMapWithImplicits extends tpd.TreeMap { } case EmptyValDef => tree - case _: PackageDef | _: MemberDef => - super.transform(tree)(using localCtx) + case tree: PackageDef => + super.transform(tree)(using nestedPackageScopeCtx(tree)) + case _: MemberDef => + super.transform(tree)(using localCtx) case impl @ Template(constr, parents, self, _) => cpy.Template(tree)( transformSub(constr), diff --git a/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala b/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala index f678a1930758..c23e90352d10 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala @@ -46,7 +46,7 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap /** The quotation level of the definition of the locally defined symbol */ protected def levelOf(sym: Symbol): Int = levelOfMap.getOrElse(sym, 0) - /** Localy defined symbols seen so far by `StagingTransformer.transform` */ + /** Locally defined symbols seen so far by `StagingTransformer.transform` */ protected def localSymbols: List[Symbol] = enteredSyms /** If we are inside a quote or a splice */ @@ -74,7 +74,7 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap /** Transform the expression splice `splice` which contains the spliced `body`. */ protected def transformSplice(body: Tree, splice: Apply)(using Context): Tree - /** Transform the typee splice `splice` which contains the spliced `body`. */ + /** Transform the type splice `splice` which contains the spliced `body`. */ protected def transformSpliceType(body: Tree, splice: Select)(using Context): Tree override def transform(tree: Tree)(using Context): Tree = @@ -109,7 +109,7 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap try dropEmptyBlocks(quotedTree) match { case Spliced(t) => // '{ $x } --> x - // and adapt the refinment of `Quotes { type tasty: ... } ?=> Expr[T]` + // and adapt the refinement of `Quotes { type reflect: ... } ?=> Expr[T]` transform(t).asInstance(tree.tpe) case _ => transformQuotation(quotedTree, tree) } diff --git a/tests/pos/i11538a.scala b/tests/pos/i11538a.scala new file mode 100644 index 000000000000..243900c43b44 --- /dev/null +++ b/tests/pos/i11538a.scala @@ -0,0 +1,23 @@ +package a: + + trait Printer[A]: + def print(a: A): Unit + + given Printer[String] with + def print(s: String) = println(s) + +package b: + + import a.{given, *} + + object test: + import scala.compiletime.{error, summonFrom} + + inline def summonStringPrinter = + summonFrom { + case given Printer[String] => () + case _ => error("Couldn't find a printer") + } + + val summoned = summon[Printer[String]] + val summonedFrom = summonStringPrinter diff --git a/tests/pos/i11538b.scala b/tests/pos/i11538b.scala new file mode 100644 index 000000000000..c061910b2e73 --- /dev/null +++ b/tests/pos/i11538b.scala @@ -0,0 +1,9 @@ +package a: + type Foo + given foo: Foo = ??? + +import a.{Foo, given} +object test: + inline def summonInlineFoo = scala.compiletime.summonInline[Foo] + val summoned = summon[Foo] + val summonedInline = summonInlineFoo diff --git a/tests/pos/i11557.scala b/tests/pos/i11557.scala new file mode 100644 index 000000000000..f886a98d1727 --- /dev/null +++ b/tests/pos/i11557.scala @@ -0,0 +1,12 @@ +type MyEncoder + +class MyContext: + given intEncoder: MyEncoder = ??? + +def doEncoding(ctx: MyContext): Unit = + import ctx.{*, given} + summon[MyEncoder] + summonInlineMyEncoder() + +inline def summonInlineMyEncoder(): Unit = + compiletime.summonInline[MyEncoder]