diff --git a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala index 668daea5f1fd..98d9a0ca85f6 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala @@ -69,7 +69,12 @@ class TreeTypeMap( } def mapType(tp: Type): Type = - mapOwnerThis(typeMap(tp).substSym(substFrom, substTo)) + 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) + mapOwnerThis(substMap(typeMap(tp))) + 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 6d84242648b2..aa1813f572f7 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -6295,6 +6295,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/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 new file mode 100644 index 000000000000..082f1450fd9e --- /dev/null +++ b/tests/pos/i19493.scala @@ -0,0 +1,49 @@ +import scala.compiletime.{summonAll, summonInline} +import deriving.Mirror + +type Sc[X] = X +case class Row[T[_]](name: T[String]) + +class DialectTypeMappers: + given String = ??? + +inline def metadata(dialect: DialectTypeMappers)(using m: Mirror.Of[Row[Sc]]): m.MirroredElemTypes = + import dialect.given + summonAll[m.MirroredElemTypes] + +def f = metadata(???) + + +object Minimization: + + class GivesString: + given aString: String = ??? + + inline def foo(x: GivesString): Unit = + import x.aString + summon[String] // ok + summonInline[String] // was error + + foo(???) + + + trait A: + val x: GivesString + + inline def bar: Unit = + import this.x.aString + summon[String] // ok + summonInline[String] // was error + + val a: A = ??? + a.bar + + + inline def baz() = (x: GivesString) => + import x.aString + summon[String] // ok + summonInline[String] // was error + + baz() + +end Minimization