Skip to content

Commit 5bc95a0

Browse files
committed
Widen implied objects to their parent types
If we have a situation like this: ``` type A type B <: A implied a for A implied b for B ``` we should recognize `b` to be more specific than `a`. Before this commit that was not the case, since `a: A$`, `b: B$` and `B$` is not a subtype of `A$`.
1 parent 3361d44 commit 5bc95a0

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ object TypeUtils {
2525
case _ => if (ctx.erasedTypes) MethodType(Nil, self) else ExprType(self)
2626
}
2727

28+
def widenToParents(implicit ctx: Context): Type = self.parents match {
29+
case Nil => self
30+
case ps => ps.reduceLeft(AndType(_, _))
31+
}
32+
2833
/** The arity of this tuple type, which can be made up of Unit, TupleX and `*:` pairs,
2934
* or -1 if this is not a tuple type.
3035
*/

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import StdNames._
2121
import NameKinds.DefaultGetterName
2222
import ProtoTypes._
2323
import Inferencing._
24+
import transform.TypeUtils._
2425

2526
import collection.mutable
2627
import config.Printers.{overload, typr, unapp}
@@ -1332,6 +1333,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
13321333
* iff
13331334
*
13341335
* T => R <:s U => R
1336+
*
1337+
* Also: If a compared type refers to an implied object or its module class, use
1338+
* the intersection of its parent classes instead.
13351339
*/
13361340
def isAsSpecificValueType(tp1: Type, tp2: Type)(implicit ctx: Context) =
13371341
if (ctx.mode.is(Mode.OldOverloadingResolution))
@@ -1347,7 +1351,12 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
13471351
case _ => mapOver(t)
13481352
}
13491353
}
1350-
(flip(tp1) relaxed_<:< flip(tp2)) || viewExists(tp1, tp2)
1354+
def prepare(tp: Type) = tp.stripTypeVar match {
1355+
case tp: NamedType if tp.symbol.is(Module) && tp.symbol.sourceModule.is(Implied) =>
1356+
flip(tp.widen.widenToParents
1357+
case _ => flip(tp)
1358+
}
1359+
(prepare(tp1) relaxed_<:< prepare(tp2)) || viewExists(tp1, tp2)
13511360
}
13521361

13531362
/** Widen the result type of synthetic implied methods from the implementation class to the
@@ -1375,11 +1384,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
13751384
case pt: PolyType =>
13761385
pt.derivedLambdaType(pt.paramNames, pt.paramInfos, widenImplied(pt.resultType, alt))
13771386
case _ =>
1378-
if (alt.symbol.is(SyntheticImpliedMethod))
1379-
tp.parents match {
1380-
case Nil => tp
1381-
case ps => ps.reduceLeft(AndType(_, _))
1382-
}
1387+
if (alt.symbol.is(SyntheticImpliedMethod)) tp.widenToParents
13831388
else tp
13841389
}
13851390

0 commit comments

Comments
 (0)