Skip to content

Commit ed86df2

Browse files
authored
Merge pull request #280 from scala/backport-lts-3.3-22448
Backport "Fix regression: do not approximate prefixes when using memberType in reflect API" to 3.3 LTS
2 parents 803b52e + 1cdc3cc commit ed86df2

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -1795,7 +1795,15 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
17951795
def termSymbol: Symbol = self.termSymbol
17961796
def isSingleton: Boolean = self.isSingleton
17971797
def memberType(member: Symbol): TypeRepr =
1798-
member.info.asSeenFrom(self, member.owner)
1798+
// we replace thisTypes here to avoid resolving otherwise unstable prefixes into Nothing
1799+
val memberInfo =
1800+
if self.typeSymbol.isClassDef then
1801+
member.info.substThis(self.classSymbol.asClass, self)
1802+
else
1803+
member.info
1804+
memberInfo
1805+
.asSeenFrom(self, member.owner)
1806+
17991807
def baseClasses: List[Symbol] = self.baseClasses
18001808
def baseType(cls: Symbol): TypeRepr = self.baseType(cls)
18011809
def derivesFrom(cls: Symbol): Boolean = self.derivesFrom(cls)

tests/pos-macros/i22424/Macro_1.scala

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
import scala.quoted.*
3+
4+
object MockMaker:
5+
inline def inlineMock[T]: Unit = ${instance[T]}
6+
transparent inline def transparentInlineMock[T]: Unit = ${instance[T]}
7+
8+
def instance[T: Type](using quotes: Quotes): Expr[Unit] =
9+
import quotes.reflect._
10+
val tpe = TypeRepr.of[T]
11+
val symbol = tpe.typeSymbol.methodMember("innerTraitInOptions").head
12+
tpe.memberType(symbol) match
13+
case mt @ MethodType(_, args, _) =>
14+
assert(args.head.typeSymbol != TypeRepr.of[Nothing].typeSymbol, "argument is incorrectly approximated")
15+
val shownType = mt.show
16+
val expectedType = "(x: m.Embedded#ATrait[scala.Predef.String, scala.Int])m.Embedded#ATrait[scala.Predef.String, scala.Int]"
17+
assert(shownType == expectedType, s"Incorrect type shown. Obtained: $shownType, Expected: $expectedType")
18+
'{()}
19+
20+
trait PolymorphicTrait {
21+
trait Embedded {
22+
trait ATrait[A, B]
23+
def innerTraitInOptions(x: ATrait[String, Int]): ATrait[String, Int]
24+
}
25+
}

tests/pos-macros/i22424/Test_2.scala

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@main def Test =
2+
val m = new PolymorphicTrait {}
3+
MockMaker.inlineMock[m.Embedded]
4+
MockMaker.transparentInlineMock[m.Embedded]

0 commit comments

Comments
 (0)