Skip to content

Commit d351c64

Browse files
committed
Avoid exceptions when merging denotations
It's better to form a safe type than to thrown an exception.
1 parent 9e7e962 commit d351c64

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

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

+12-8
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,14 @@ object Denotations {
260260
(for ((name1, name2, idx) <- (tp1.paramNames, tp2.paramNames, tp1.paramNames.indices).zipped)
261261
yield if (name1 == name2) name1 else tp1.companion.syntheticParamName(idx)).toList
262262

263+
/** Merge parameter infos. This is always dowwards via gb because that's the
264+
* only safe direction. It's safe to assume that two method implementations
265+
* with the same signature work on the intersection of their domains.
266+
*/
267+
private def mergeParamInfos(tp1: LambdaType, tp2: LambdaType)(implicit ctx: Context): List[tp1.PInfo] =
268+
tp1.paramInfos.zipWithConserve(tp2.paramInfos)(
269+
(pi1: Type, pi2: Type) => (pi1 & pi2).asInstanceOf[tp1.PInfo])
270+
263271
/** Form a denotation by conjoining with denotation `that`.
264272
*
265273
* NoDenotations are dropped. MultiDenotations are handled by merging
@@ -326,12 +334,10 @@ object Denotations {
326334
// and result types.
327335
if (tp1.isInstanceOf[PolyType] && tp2.isInstanceOf[MethodType]) tp2
328336
else if (tp2.isInstanceOf[PolyType] && tp1.isInstanceOf[MethodType]) tp1
329-
else if (ctx.typeComparer.matchingParams(tp1, tp2) &&
330-
tp1.isImplicit == tp2.isImplicit)
337+
else
331338
tp1.derivedLambdaType(
332-
mergeParamNames(tp1, tp2), tp1.paramInfos,
339+
mergeParamNames(tp1, tp2), mergeParamInfos(tp1, tp2),
333340
infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1)))
334-
else mergeConflict(tp1, tp2)
335341
case _ =>
336342
mergeConflict(tp1, tp2)
337343
}
@@ -481,11 +487,9 @@ object Denotations {
481487
}
482488
case tp1: MethodOrPoly =>
483489
tp2 match {
484-
case tp2: MethodOrPoly
485-
if ctx.typeComparer.matchingParams(tp1, tp2) &&
486-
tp1.isImplicit == tp2.isImplicit =>
490+
case tp2: MethodOrPoly =>
487491
tp1.derivedLambdaType(
488-
mergeParamNames(tp1, tp2), tp1.paramInfos,
492+
mergeParamNames(tp1, tp2), mergeParamInfos(tp1, tp2),
489493
tp1.resultType | tp2.resultType.subst(tp2, tp1))
490494
case _ =>
491495
mergeConflict(tp1, tp2)

compiler/src/dotty/tools/dotc/transform/MixinOps.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx:
1717
lazy val JUnit4Annotations: List[Symbol] = List("Test", "Ignore", "Before", "After", "BeforeClass", "AfterClass").
1818
map(n => ctx.getClassIfDefined("org.junit." + n)).
1919
filter(_.exists)
20-
20+
2121
def implementation(member: TermSymbol): TermSymbol = {
2222
val res = member.copy(
2323
owner = cls,

0 commit comments

Comments
 (0)