Skip to content

Commit ae4f1fa

Browse files
authored
Merge pull request #2408 from dotty-staging/fix-compile-strawman-3
Fix #2404: Fixes to make collections strawman compile, take 3
2 parents 058658d + 44d6d37 commit ae4f1fa

File tree

5 files changed

+58
-12
lines changed

5 files changed

+58
-12
lines changed

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

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,28 @@ object Denotations {
310310
}
311311
case tp1: MethodOrPoly =>
312312
tp2 match {
313-
case tp2: MethodOrPoly
314-
if ctx.typeComparer.matchingParams(tp1, tp2) &&
315-
tp1.isImplicit == tp2.isImplicit =>
316-
tp1.derivedLambdaType(
317-
mergeParamNames(tp1, tp2), tp1.paramInfos,
318-
infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1)))
313+
case tp2: MethodOrPoly =>
314+
// Two remedial strategies:
315+
//
316+
// 1. Prefer method types over poly types. This is necessary to handle
317+
// overloaded definitions like the following
318+
//
319+
// def ++ [B >: A](xs: C[B]): D[B]
320+
// def ++ (xs: C[A]): D[A]
321+
//
322+
// (Code like this is found in the collection strawman)
323+
//
324+
// 2. In the case of two method types or two polytypes with matching
325+
// parameters and implicit status, merge corresppnding parameter
326+
// and result types.
327+
if (tp1.isInstanceOf[PolyType] && tp2.isInstanceOf[MethodType]) tp2
328+
else if (tp2.isInstanceOf[PolyType] && tp1.isInstanceOf[MethodType]) tp1
329+
else if (ctx.typeComparer.matchingParams(tp1, tp2) &&
330+
tp1.isImplicit == tp2.isImplicit)
331+
tp1.derivedLambdaType(
332+
mergeParamNames(tp1, tp2), tp1.paramInfos,
333+
infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1)))
334+
else mergeConflict(tp1, tp2)
319335
case _ =>
320336
mergeConflict(tp1, tp2)
321337
}
@@ -553,7 +569,7 @@ object Denotations {
553569
if (sd1.exists)
554570
if (sd2.exists)
555571
if (isDoubleDef(denot1.symbol, denot2.symbol)) doubleDefError(denot1, denot2)
556-
else throw new TypeError(s"failure to disambiguate overloaded reference $this")
572+
else throw new TypeError(i"failure to disambiguate overloaded reference at $this")
557573
else sd1
558574
else sd2
559575
}

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

Lines changed: 15 additions & 1 deletion
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,6 +49,20 @@ case class Signature(paramsSig: List[TypeName], resSig: TypeName) {
4949
loop(this.paramsSig, that.paramsSig)
5050
}
5151

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+
}
65+
5266
/** The degree to which this signature matches `that`.
5367
* If parameter names are consistent and result types names match (i.e. they are the same
5468
* or one is a wildcard), the result is `FullMatch`.

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,8 +1867,18 @@ object Types {
18671867
}
18681868
else candidate
18691869

1870-
override def newLikeThis(prefix: Type)(implicit ctx: Context): TermRef =
1871-
fixDenot(TermRef.withSig(prefix, name, sig), prefix)
1870+
override def newLikeThis(prefix: Type)(implicit ctx: Context): TermRef = {
1871+
// If symbol exists, the new signature is the symbol's signature as seen
1872+
// from the new prefix, modulo consistency
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")
1880+
fixDenot(TermRef.withSig(prefix, name, newSig), prefix)
1881+
}
18721882

18731883
override def shadowed(implicit ctx: Context): NamedType =
18741884
fixDenot(TermRef.withSig(prefix, name.derived(ShadowedName), sig), prefix)

compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ object ErrorReporting {
9696

9797
def exprStr(tree: Tree): String = refStr(tree.tpe)
9898

99+
def takesNoParamsStr(tree: Tree, kind: String) =
100+
if (tree.tpe.widen.exists)
101+
i"${exprStr(tree)} does not take ${kind}parameters"
102+
else
103+
i"undefined: $tree # ${tree.uniqueId}: ${tree.tpe.toString}"
104+
99105
def patternConstrStr(tree: Tree): String = ???
100106

101107
def typeMismatch(tree: Tree, pt: Type, implicitFailure: SearchFailure = NoImplicitMatches): Tree =

compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ trait TypeAssigner {
340340
else
341341
errorType(i"wrong number of arguments for $fntpe: ${fn.tpe}, expected: ${fntpe.paramInfos.length}, found: ${args.length}", tree.pos)
342342
case t =>
343-
errorType(i"${err.exprStr(fn)} does not take parameters", tree.pos)
343+
errorType(err.takesNoParamsStr(fn, ""), tree.pos)
344344
}
345345
tree.withType(ownType)
346346
}
@@ -396,7 +396,7 @@ trait TypeAssigner {
396396
else wrongNumberOfTypeArgs(fn.tpe, pt.typeParams, args, tree.pos)
397397
}
398398
case _ =>
399-
errorType(i"${err.exprStr(fn)} does not take type parameters", tree.pos)
399+
errorType(err.takesNoParamsStr(fn, "type "), tree.pos)
400400
}
401401

402402
tree.withType(ownType)

0 commit comments

Comments
 (0)