diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 46ae4d0c804e..16dc571e7c99 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -1694,7 +1694,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler end SimpleSelectorTypeTest object SimpleSelector extends SimpleSelectorModule: - def apply(name: String): SimpleSelector = + def apply(name: String): SimpleSelector = withDefaultPos(untpd.ImportSelector(untpd.Ident(name.toTermName))) def unapply(x: SimpleSelector): Some[String] = Some(x.name.toString) end SimpleSelector @@ -1837,7 +1837,15 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def termSymbol: Symbol = self.termSymbol def isSingleton: Boolean = self.isSingleton def memberType(member: Symbol): TypeRepr = - member.info.asSeenFrom(self, member.owner) + // we replace thisTypes here to avoid resolving otherwise unstable prefixes into Nothing + val memberInfo = + if self.typeSymbol.isClassDef then + member.info.substThis(self.classSymbol.asClass, self) + else + member.info + memberInfo + .asSeenFrom(self, member.owner) + def baseClasses: List[Symbol] = self.baseClasses def baseType(cls: Symbol): TypeRepr = self.baseType(cls) def derivesFrom(cls: Symbol): Boolean = self.derivesFrom(cls) diff --git a/tests/pos-macros/i22424/Macro_1.scala b/tests/pos-macros/i22424/Macro_1.scala new file mode 100644 index 000000000000..634cfb0055c7 --- /dev/null +++ b/tests/pos-macros/i22424/Macro_1.scala @@ -0,0 +1,25 @@ + +import scala.quoted.* + +object MockMaker: + inline def inlineMock[T]: Unit = ${instance[T]} + transparent inline def transparentInlineMock[T]: Unit = ${instance[T]} + + def instance[T: Type](using quotes: Quotes): Expr[Unit] = + import quotes.reflect._ + val tpe = TypeRepr.of[T] + val symbol = tpe.typeSymbol.methodMember("innerTraitInOptions").head + tpe.memberType(symbol) match + case mt @ MethodType(_, args, _) => + assert(args.head.typeSymbol != TypeRepr.of[Nothing].typeSymbol, "argument is incorrectly approximated") + val shownType = mt.show + val expectedType = "(x: m.Embedded#ATrait[scala.Predef.String, scala.Int])m.Embedded#ATrait[scala.Predef.String, scala.Int]" + assert(shownType == expectedType, s"Incorrect type shown. Obtained: $shownType, Expected: $expectedType") + '{()} + +trait PolymorphicTrait { + trait Embedded { + trait ATrait[A, B] + def innerTraitInOptions(x: ATrait[String, Int]): ATrait[String, Int] + } +} diff --git a/tests/pos-macros/i22424/Test_2.scala b/tests/pos-macros/i22424/Test_2.scala new file mode 100644 index 000000000000..0a231d820381 --- /dev/null +++ b/tests/pos-macros/i22424/Test_2.scala @@ -0,0 +1,4 @@ +@main def Test = + val m = new PolymorphicTrait {} + MockMaker.inlineMock[m.Embedded] + MockMaker.transparentInlineMock[m.Embedded]