Skip to content

Commit

Permalink
Also handle imports on parameters of lambdas returned from inline defs
Browse files Browse the repository at this point in the history
Both i19493 and i19436 require mapping the type of
the expr in an `ImportType` which is itself the info of a `TermRef`.
In the first issue, for the substitution of an inline def parameter proxy.
In the second issue, for the parameter of a lambda returned from an inline def.

Both can be handled in `TypeMap` by mapping over references to `ImportType`s.
The second case also requires modifying `TreeTypeMap#mapType` such that
the logic mapping over imports is done within a `TypeMap` doing the symbol substitutions.

Fixes #19436
  • Loading branch information
EugeneFlesselle committed Jun 27, 2024
1 parent 6ad4fd8 commit c4e703f
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 7 deletions.
9 changes: 7 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions compiler/src/dotty/tools/dotc/inlines/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
18 changes: 18 additions & 0 deletions tests/pos-macros/i19436/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -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]
}
2 changes: 2 additions & 0 deletions tests/pos-macros/i19436/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

def fn: Unit = Macro.testSummon
9 changes: 8 additions & 1 deletion tests/pos/i19493.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import scala.compiletime.{summonAll, summonInline}
import deriving.Mirror

Expand Down Expand Up @@ -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

0 comments on commit c4e703f

Please sign in to comment.