-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #8799: Use initial denotation for signatures #8813
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
Changes from all commits
ffffcac
7dea1c0
c04d9e2
d40cd69
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1892,27 +1892,25 @@ object Types { | |
/** The signature of the last known denotation, or if there is none, the | ||
* signature of the symbol | ||
*/ | ||
protected def computeSignature(implicit ctx: Context): Signature = { | ||
val lastd = lastDenotation | ||
if (lastd != null) lastd.signature | ||
else symbol.asSeenFrom(prefix).signature | ||
} | ||
protected def computeSignature(implicit ctx: Context): Signature = | ||
lastDenotation match | ||
case null => symbol.asSeenFrom(prefix).initial.signature | ||
case sd: SingleDenotation => sd.initial.signature | ||
case d => d.signature | ||
|
||
/** The signature of the current denotation if it is known without forcing. | ||
* Otherwise the signature of the current symbol if it is known without forcing. | ||
* Otherwise NotAMethod. | ||
*/ | ||
private def currentSignature(implicit ctx: Context): Signature = | ||
if (ctx.runId == mySignatureRunId) mySignature | ||
else { | ||
val lastd = lastDenotation | ||
if (lastd != null) lastd.signature | ||
else { | ||
else lastDenotation match | ||
case null => | ||
val sym = currentSymbol | ||
if (sym.exists) sym.asSeenFrom(prefix).signature | ||
if (sym.exists) sym.asSeenFrom(prefix).initial.signature | ||
else Signature.NotAMethod | ||
} | ||
} | ||
case sd: SingleDenotation => sd.initial.signature | ||
case d => d.signature | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is the non-SingleDenotation case handled specially without calling initial ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do not have an initial for general denotations There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, and it's fine because their signature is always |
||
|
||
final def symbol(implicit ctx: Context): Symbol = | ||
// We can rely on checkedPeriod (unlike in the definition of `denot` below) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package dotty.tools | ||
|
||
import vulpix.TestConfiguration | ||
|
||
import org.junit.Test | ||
|
||
import dotc.ast.Trees._ | ||
import dotc.core.Decorators._ | ||
import dotc.core.Contexts._ | ||
import dotc.core.Types._ | ||
import dotc.core.Denotations._ | ||
|
||
import java.io.File | ||
import java.nio.file._ | ||
|
||
class SignaturesTest: | ||
@Test def signatureCaching: Unit = | ||
inCompilerContext(TestConfiguration.basicClasspath, "case class Foo(value: Unit)") { | ||
val defn = ctx.definitions | ||
val leftCls = ctx.requiredClass("Foo") | ||
val ref = leftCls.requiredMethod("value").termRef | ||
|
||
def checkSig()(using Context): Unit = | ||
val denot = ref.denot match | ||
case sd: SingleDenotation => sd.initial | ||
case d => d | ||
assert(ref.signature == denot.signature, i"Wrong cached signature at phase ${ctx.phase} for $ref.\nActual denotation signature: ${denot.signature}\nCached ref signature: ${ref.signature}") | ||
|
||
checkSig() | ||
checkSig()(using ctx.withPhase(ctx.erasurePhase.next)) | ||
} |
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.
Perhaps Denotation#signature itself should do the work of calling initial? That way we're sure to never use the wrong signature
Uh oh!
There was an error while loading. Please reload this page.
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.
Case in point: the code just below for
currentSignature
callslastd.signature
andlastd
might not be the initial denotation. Similarly,symbol.asSeenFrom(prefix).signature
above will also be computed at the current phase.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.
As long as signatures are defined in denotations, I think they should apply to the owner denotation. If we wanted to always go for initial, then signatures should be defined on symbols.
Agree that
currentSignature
needs to be fixed as well.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.
That might make sense, I can see how different prefixes can lead to different signatures for denotations, but I don't think that should ever be needed to disambiguate between overloads ?
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.
hmm I guess that would probably interfere with how we deal with merging denotations.
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.
Yes, I think it's better to leave them on denotations.