Skip to content

Commit 44d6d37

Browse files
committed
Tweak signature update
Need to keep all consistent parts of original signature.
1 parent 7a1f187 commit 44d6d37

File tree

3 files changed

+24
-12
lines changed

3 files changed

+24
-12
lines changed

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,14 +311,16 @@ object Denotations {
311311
case tp1: MethodOrPoly =>
312312
tp2 match {
313313
case tp2: MethodOrPoly =>
314-
// Two remedial strategies
314+
// Two remedial strategies:
315+
//
315316
// 1. Prefer method types over poly types. This is necessary to handle
316317
// overloaded definitions like the following
317318
//
318319
// def ++ [B >: A](xs: C[B]): D[B]
319320
// def ++ (xs: C[A]): D[A]
320321
//
321322
// (Code like this is found in the collection strawman)
323+
//
322324
// 2. In the case of two method types or two polytypes with matching
323325
// parameters and implicit status, merge corresppnding parameter
324326
// and result types.

compiler/src/dotty/tools/dotc/core/Signature.scala

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package dotty.tools.dotc
22
package core
33

4-
import Names._, Types._, Contexts._, StdNames._
4+
import Names._, Types._, Contexts._, StdNames._, Decorators._
55
import TypeErasure.sigName
66

77
import scala.annotation.tailrec
@@ -49,12 +49,19 @@ case class Signature(paramsSig: List[TypeName], resSig: TypeName) {
4949
loop(this.paramsSig, that.paramsSig)
5050
}
5151

52-
/** Is this siganture consistent with that signature?
53-
* This is the case if the signatures have consistent parameters
54-
* and result types.
55-
*/
56-
final def consistentWith(that: Signature): Boolean =
57-
consistentParams(that) && consistent(resSig, that.resSig)
52+
/** `that` signature, but keeping all corresponding parts of `this` signature. */
53+
final def updateWith(that: Signature): Signature = {
54+
def update(name1: TypeName, name2: TypeName): TypeName =
55+
if (consistent(name1, name2)) name1 else name2
56+
if (this == that) this
57+
else if (!this.paramsSig.hasSameLengthAs(that.paramsSig)) that
58+
else {
59+
val mapped = Signature(
60+
this.paramsSig.zipWithConserve(that.paramsSig)(update),
61+
update(this.resSig, that.resSig))
62+
if (mapped == this) this else mapped
63+
}
64+
}
5865

5966
/** The degree to which this signature matches `that`.
6067
* If parameter names are consistent and result types names match (i.e. they are the same

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,10 +1870,13 @@ object Types {
18701870
override def newLikeThis(prefix: Type)(implicit ctx: Context): TermRef = {
18711871
// If symbol exists, the new signature is the symbol's signature as seen
18721872
// from the new prefix, modulo consistency
1873-
val symSig =
1874-
if (symbol.exists) symbol.info.asSeenFrom(prefix, symbol.owner).signature
1875-
else sig
1876-
val newSig = if (sig.consistentWith(symSig)) sig else symSig
1873+
val newSig =
1874+
if (sig == Signature.NotAMethod || !symbol.exists)
1875+
sig
1876+
else
1877+
sig.updateWith(symbol.info.asSeenFrom(prefix, symbol.owner).signature)
1878+
if (newSig ne sig)
1879+
core.println(i"sig change at ${ctx.phase} for $this, pre = $prefix, sig: $sig --> $newSig")
18771880
fixDenot(TermRef.withSig(prefix, name, newSig), prefix)
18781881
}
18791882

0 commit comments

Comments
 (0)