@@ -1039,7 +1039,7 @@ trait Implicits:
10391039 * - if one of T, U is a subtype of the lifted version of the other,
10401040 * unless strict equality is set.
10411041 */
1042- def assumedCanEqual (ltp : Type , rtp : Type )(using Context ) = {
1042+ def assumedCanEqual (leftTreeOption : Option [ Tree ], ltp : Type , rtp : Type )(using Context ): Boolean = {
10431043 // Map all non-opaque abstract types to their upper bound.
10441044 // This is done to check whether such types might plausibly be comparable to each other.
10451045 val lift = new TypeMap {
@@ -1062,15 +1062,20 @@ trait Implicits:
10621062
10631063 ltp.isError
10641064 || rtp.isError
1065- || ! strictEquality && (ltp <:< lift(rtp) || rtp <:< lift(ltp))
1065+ || locally :
1066+ if strictEquality then
1067+ leftTreeOption.exists: leftTree =>
1068+ ltp <:< lift(rtp) && (leftTree.symbol.flags.isAllOf(Flags .EnumValue ) || (leftTree.symbol.flags.isAllOf(Flags .Module | Flags .Case )))
1069+ else
1070+ (ltp <:< lift(rtp) || rtp <:< lift(ltp))
10661071 }
10671072
10681073 /** Check that equality tests between types `ltp` and `rtp` make sense */
1069- def checkCanEqual (ltp : Type , rtp : Type , span : Span )(using Context ): Unit =
1070- if (! ctx.isAfterTyper && ! assumedCanEqual(ltp, rtp)) {
1074+ def checkCanEqual (left : Tree , rtp : Type , span : Span )(using Context ): Unit =
1075+ val ltp = left.tpe.widen
1076+ if ! ctx.isAfterTyper && ! assumedCanEqual(Some (left), ltp, rtp) then
10711077 val res = implicitArgTree(defn.CanEqualClass .typeRef.appliedTo(ltp, rtp), span)
10721078 implicits.println(i " CanEqual witness found for $ltp / $rtp: $res: ${res.tpe}" )
1073- }
10741079
10751080 object hasSkolem extends TreeAccumulator [Boolean ]:
10761081 def apply (x : Boolean , tree : Tree )(using Context ): Boolean =
0 commit comments