-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #10769: change synthesized type in def ordinal #10785
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
Conversation
cc500c9
to
7851412
Compare
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.
- We need
reachableTermRef
,reachableTypeRef
andreachableRawTypeRef
, all of those can be useful (and for ordinal we needreachableTermRef
too since we can have a child object in an inner object). - Instead of using a TypeMap, I would suggest trying to define them directly in a recursive manner like termRef and typeRef
- Instead of special-casing objects, I would suggest also replacing references to inner classes
A.this.B
withA#B
, this could be used to fix exception caught when loading class C: Cyclic reference involving class C #10888 (comment) nicely and get rid ofprocessInner
in ClassfileParser - I think this is useful enough to be defined directly in SymDenotations, but that's not super important
- This is likely useful enough to be exposed in tasty reflect, but that can be done later.
I'm not sure about this change, as it changes the meaning of the types. It might work for Java, but generally does not work for Dotty. Updated: #11006 is proposed to fix the issue above separately. |
0355247
to
98267e6
Compare
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.
Instead of special-casing objects, I would suggest also replacing references to inner classes A.this.B with A#B, this could be used to fix #10888 (comment) nicely and get rid of processInner in ClassfileParser
I'm not sure about this change, as it changes the meaning of the types. It might work for Java, but generally does not work for Dotty.
The type A.this.B
is not meaningful if we're not inside A
or a subclass of A
. Imagine that we change the test case to use an inner class instead of an inner object:
package stm
trait STMLike[F[_]] {
import Internals._
sealed abstract class Txn[+A] {}
object Txn {
def abort[A](e: Throwable): Txn[A] = Abort(e)
}
class Internals {
case class Abort(error: Throwable) extends Txn[Nothing]
}
}
In the generated ordinal
method for Txn
, we want to have a case _: Internals#Abort
, because case _: Internals.this.Abort
isn't valid.
I agree. However, given that we don't know the context where the method is called, it's dangerous. We could make the change On the other hand, in the current usage of /**
* - all of its children are addressable through a path from its companion object
*/
def whyNotGenericSum(using Context): String = ... With such a precondition, the usage of Generally, I think similar care should be taken in doing complex things with (Interestingly, all such use cases I know of are related to children of sealed classes.) |
Ah thanks, I had missed that! |
Right, to be correct we would have to check the current |
As pointed out by @smarter in scala#10769, for the following code: package stm trait STMLike[F[_]] { import Internals._ sealed abstract class Txn[+A] {} object Txn { def abort[A](e: Throwable): Txn[A] = Abort(e) } object Internals { case class Abort(error: Throwable) extends Txn[Nothing] } } The compiler synthesized the following code for the object `Txn`: object Txn { type MirroredMonoType = STMLike.this.Txn[?] def ordinal(x: Txn.MirroredMonoType): Int = x match { case _:stm.STMLike.Internals.Abort => 0 } def abort[A](e: Throwable): Txn[A] = Abort(e) } In the method `ordinal`, the type for `Internals.Abort` is TypeRef(ThisType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class stm)),trait STMLike)),module class Internals$)),class Abort) This type is incorrect, as we are not in the object `Internals`. The explicit outer can only handle such types if it's static. In this case, the object is not static, thus it crashes the explicit outer. Co-authored-by: Guillaume Martres <[email protected]>
The first test ensures that the mirror is generated. The second test will not have mirrors generated.
else if this.is(Module) then | ||
TermRef(owner.reachableThisType, this.sourceModule) | ||
else | ||
ThisType.raw(TypeRef(owner.reachableThisType, symbol.asType)) |
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.
What abotu the ThisType.raw here?
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.
This one is different, as we need to call owner. reachableThisType
.
@@ -1410,6 +1410,33 @@ object SymDenotations { | |||
def namedType(using Context): NamedType = | |||
if (isType) typeRef else termRef | |||
|
|||
/** The typeRef where `pre.O$.this` is changed to `pre.O.type` if `O` is a non-static object |
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.
These documentation comments need to be updated since we also do this for static objects now.
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.
Done.
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, thanks!
Co-authored-by: Guillaume Martres [email protected]
Fix #10769: change synthesized type in def ordinal
As pointed out by @smarter in #10769, for the following code:
The compiler synthesized the following code for the object
Txn
:In the method
ordinal
, the type forInternals.Abort
isThis type is incorrect, as we are not in the object
Internals
. Theexplicit outer can only handle such types if it's static. In this
case, the object is not static, thus it crashes the explicit outer.
Co-authored-by: Guillaume Martres [email protected]