-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix regression: do not approximate prefixes when using memberType in reflect API #22448
Conversation
@@ -1826,7 +1826,7 @@ 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) | |||
member.info.asSeenFrom(self, member.owner, approximateUnstablePrefixes = false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I don't think we should do it this way. Perhaps we should do something like member.info.asSeenFrom(self.<thisType>, member.owner)
.
@dwijnand After spending some time on this, I don’t think I’m able to use thisType without it causing further regressions after all. Replacing symbols with thisType can cause certain type applications from the prefix to get ignored. val classSymbol = self.classSymbol
member.info
.asSeenFrom(classSymbol.thisType, member.owner)
.substThis(classSymbol.asClass, self) // we remove the added This(_) for compatibility But this caused issues for nested classes, like:
Then, to make sure any previously generated thisType class gets replaced with correct part of the original val qualTypeRepr = if self.typeSymbol.isClassDef then self.typeSymbol.thisType else self
val memberTypeWithThis = member.info
.asSeenFrom(qualTypeRepr, member.owner)
new TypeAccumulator[Types.Type] {
def apply(x: Types.Type, tp: Types.Type): Types.Type = tp match
case at @ AppliedType(prefix, args) => apply(
if at.typeSymbol.isClassDef then x.substThis(at.typeSymbol.asClass, at) else at,
prefix.asInstanceOf[Types.Type]
)
case other => foldOver(x, other)
}.apply(
if self.typeSymbol.isClassDef then memberTypeWithThis.substThis(self.typeSymbol.asClass, self) else memberTypeWithThis,
self
) This fixes the simple nested types like the example above, however it does not work for the following: trait B2T:
type T; case class C(t: T)
class B2C[U] extends B2T:
final override type T = U Where for |
From your example it seems like you create a I really don't like just pipelining a boolean into the algorithm, to crudely toggle it off. I feel like the problem is in the input data. |
I don't think I'm able to fix it then - I tried once again to concoct something like: val tempReplacements = scala.collection.mutable.ListBuffer[(dotc.core.Symbols.ClassSymbol, Types.Type)]();
val newSelf = new Types.TypeMap {
def apply(tp: Types.Type) = tp match
case t @ TermRef(prefix, _) if !t.isStable && t.typeSymbol.isClassDef =>
tempReplacements.addOne((t.typeSymbol.asClass, t))
t.typeSymbol.thisType
case other => mapOver(other)
}.apply(self)
val res = member.info
.asSeenFrom(newSelf, member.owner)
tempReplacements.reverse.foldLeft(res) {
case (memberTypeResult, (clsSymbol, replacingType)) =>
memberTypeResult.substThis(clsSymbol, replacingType)
} but artificially adding those thisTypes that still breaks shapeless-3 community build, no matter how much I try to minimize the this-type additions, and how much I try to strip them out later after the |
f52ff02
to
faa8a55
Compare
faa8a55
to
a688933
Compare
a688933
to
2545c8c
Compare
@dwijnand I finally found a solution that works well without changing asSeenFrom - it looks like it's easier to adjust |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, nicely done!!!
Thank you! |
Fixes #22424