diff --git a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala index 668daea5f1fd..d3b231788287 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala @@ -68,8 +68,13 @@ class TreeTypeMap( } } - def mapType(tp: Type): Type = - mapOwnerThis(typeMap(tp).substSym(substFrom, substTo)) + val mapType: Type => Type = + val substMap = new TypeMap(): + def apply(tp: Type): Type = tp match + case tp: TermRef if tp.symbol.isImport => mapOver(tp) + case tp => tp.substSym(substFrom, substTo) + typeMap.andThen(substMap).andThen(mapOwnerThis) + end mapType private def updateDecls(prevStats: List[Tree], newStats: List[Tree]): Unit = if (prevStats.isEmpty) assert(newStats.isEmpty) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index cb47bd92352e..b77a20fc5f7b 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -6280,6 +6280,12 @@ object Types extends TypeUtils { val ctx = this.mapCtx // optimization for performance given Context = ctx tp match { + case tp: TermRef if tp.symbol.isImport => + // see tests/pos/i19493.scala for examples requiring mapping over imports + val ImportType(e) = tp.info: @unchecked + val e1 = singleton(apply(e.tpe)) + newImportSymbol(tp.symbol.owner, e1).termRef + case tp: NamedType => if stopBecauseStaticOrLocal(tp) then tp else diff --git a/compiler/src/dotty/tools/dotc/inlines/Inliner.scala b/compiler/src/dotty/tools/dotc/inlines/Inliner.scala index a83c5eaa3ba8..7c79e972c126 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inliner.scala @@ -565,10 +565,6 @@ class Inliner(val call: tpd.Tree)(using Context): def apply(t: Type) = t match { case t: ThisType => thisProxy.getOrElse(t.cls, t) case t: TypeRef => paramProxy.getOrElse(t, mapOver(t)) - case t: TermRef if t.symbol.isImport => - val ImportType(e) = t.widenTermRefExpr: @unchecked - val e1 = singleton(apply(e.tpe)) - newImportSymbol(ctx.owner, e1).termRef case t: SingletonType => if t.termSymbol.isAllOf(InlineParam) then apply(t.widenTermRefExpr) else paramProxy.getOrElse(t, mapOver(t)) diff --git a/tests/pos-macros/i19436/Macro_1.scala b/tests/pos-macros/i19436/Macro_1.scala new file mode 100644 index 000000000000..689f64203131 --- /dev/null +++ b/tests/pos-macros/i19436/Macro_1.scala @@ -0,0 +1,18 @@ + +import scala.quoted.* +import scala.compiletime.summonInline + +trait SomeImplicits: + given int: Int + +object Macro: + + transparent inline def testSummon: SomeImplicits => Int = ${ testSummonImpl } + + private def testSummonImpl(using Quotes): Expr[SomeImplicits => Int] = + import quotes.reflect.* + '{ + (x: SomeImplicits) => + import x.given + summonInline[Int] + } \ No newline at end of file diff --git a/tests/pos-macros/i19436/Test_2.scala b/tests/pos-macros/i19436/Test_2.scala new file mode 100644 index 000000000000..aedaf1cb87fb --- /dev/null +++ b/tests/pos-macros/i19436/Test_2.scala @@ -0,0 +1,2 @@ + +def fn: Unit = Macro.testSummon diff --git a/tests/pos/i19493.scala b/tests/pos/i19493.scala index 93d9023d589c..082f1450fd9e 100644 --- a/tests/pos/i19493.scala +++ b/tests/pos/i19493.scala @@ -1,4 +1,3 @@ - import scala.compiletime.{summonAll, summonInline} import deriving.Mirror @@ -39,4 +38,12 @@ object Minimization: val a: A = ??? a.bar + + inline def baz() = (x: GivesString) => + import x.aString + summon[String] // ok + summonInline[String] // was error + + baz() + end Minimization