Skip to content

Commit 11a2c31

Browse files
committed
Properly handle self-types in reflection member lookup
The type on which we lookup things needs to be the this-type of the class, otherwise it will not include members that only appear in the self-type, since these members can appear in the types of members of the current class, this could lead to a MissingType exception being thrown. Fixes #12081.
1 parent f003711 commit 11a2c31

File tree

5 files changed

+39
-5
lines changed

5 files changed

+39
-5
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,13 +2485,13 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
24852485

24862486
def memberField(name: String): Symbol = fieldMember(name)
24872487
def fieldMember(name: String): Symbol =
2488-
appliedTypeRef(self).allMembers.iterator.map(_.symbol).find {
2488+
self.thisType.allMembers.iterator.map(_.symbol).find {
24892489
sym => isField(sym) && sym.name.toString == name
24902490
}.getOrElse(dotc.core.Symbols.NoSymbol)
24912491

24922492
def memberFields: List[Symbol] = fieldMembers
24932493
def fieldMembers: List[Symbol] =
2494-
appliedTypeRef(self).allMembers.iterator.map(_.symbol).collect {
2494+
self.thisType.allMembers.iterator.map(_.symbol).collect {
24952495
case sym if isField(sym) => sym.asTerm
24962496
}.toList
24972497

@@ -2507,13 +2507,13 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
25072507

25082508
def memberMethod(name: String): List[Symbol] = methodMember(name)
25092509
def methodMember(name: String): List[Symbol] =
2510-
appliedTypeRef(self).allMembers.iterator.map(_.symbol).collect {
2510+
self.thisType.allMembers.iterator.map(_.symbol).collect {
25112511
case sym if isMethod(sym) && sym.name.toString == name => sym.asTerm
25122512
}.toList
25132513

25142514
def memberMethods: List[Symbol] = methodMembers
25152515
def methodMembers: List[Symbol] =
2516-
appliedTypeRef(self).allMembers.iterator.map(_.symbol).collect {
2516+
self.thisType.allMembers.iterator.map(_.symbol).collect {
25172517
case sym if isMethod(sym) => sym.asTerm
25182518
}.toList
25192519

scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ object SyntheticsSupport:
7474
import dotty.tools.dotc
7575
given ctx: dotc.core.Contexts.Context = quotes.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx
7676
val sym = rsym.asInstanceOf[dotc.core.Symbols.Symbol]
77-
sym.typeRef.appliedTo(sym.typeParams.map(_.typeRef)).allMembers.iterator.map(_.symbol)
77+
dotc.core.Types.ThisType.raw(sym.typeRef).allMembers.iterator.map(_.symbol)
7878
.collect {
7979
case sym if
8080
(!sym.is(dotc.core.Flags.ModuleVal) || sym.is(dotc.core.Flags.Given)) &&

tests/run-macros/self.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
MethodType(List(x), List(TypeRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),Predef),String)), TypeRef(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <root>)),module class <empty>)),B),X))
2+
MethodType(List(x), List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),Int)), TypeRef(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <root>)),module class <empty>)),B),X))

tests/run-macros/self/Macro_1.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import scala.quoted.*
2+
3+
trait A {
4+
type X
5+
}
6+
trait B { self: A =>
7+
def foo(x: Int): X
8+
def foo(x: String): X
9+
}
10+
11+
object Macros {
12+
13+
inline def test(): String = ${ testImpl }
14+
15+
private def testImpl(using Quotes) : Expr[String] = {
16+
import quotes.reflect.*
17+
val classTpe = TypeRepr.of[B]
18+
val classSym = classTpe.classSymbol.get
19+
val methSyms = classSym.methodMember("foo") // Used to throw a MissingType exception
20+
val methTpes = methSyms.map(classTpe.memberType)
21+
Expr(methTpes.map(_.toString).sorted.mkString("\n"))
22+
}
23+
24+
}

tests/run-macros/self/Test_2.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
object Test {
3+
4+
def main(args: Array[String]): Unit = {
5+
println(Macros.test())
6+
}
7+
8+
}

0 commit comments

Comments
 (0)