@@ -84,6 +84,9 @@ object Implicits:
84
84
def strictEquality (using Context ): Boolean =
85
85
ctx.mode.is(Mode .StrictEquality ) || Feature .enabled(nme.strictEquality)
86
86
87
+ def strictEqualityPatternMatching (using Context ): Boolean =
88
+ Feature .enabled(Feature .strictEqualityPatternMatching)
89
+
87
90
88
91
/** A common base class of contextual implicits and of-type implicits which
89
92
* represents a set of references to implicit definitions.
@@ -1038,8 +1041,9 @@ trait Implicits:
1038
1041
* - if one of T, U is an error type, or
1039
1042
* - if one of T, U is a subtype of the lifted version of the other,
1040
1043
* unless strict equality is set.
1044
+ * - if strictEqualityPatternMatching is set and the necessary conditions are met
1041
1045
*/
1042
- def assumedCanEqual (ltp : Type , rtp : Type )(using Context ) = {
1046
+ def assumedCanEqual (ltp : Type , rtp : Type , leftTree : Tree = EmptyTree )(using Context ): Boolean = {
1043
1047
// Map all non-opaque abstract types to their upper bound.
1044
1048
// This is done to check whether such types might plausibly be comparable to each other.
1045
1049
val lift = new TypeMap {
@@ -1062,15 +1066,23 @@ trait Implicits:
1062
1066
1063
1067
ltp.isError
1064
1068
|| rtp.isError
1065
- || ! strictEquality && (ltp <:< lift(rtp) || rtp <:< lift(ltp))
1069
+ || locally :
1070
+ if strictEquality then
1071
+ strictEqualityPatternMatching &&
1072
+ (leftTree.symbol.isAllOf(Flags .EnumValue ) || leftTree.symbol.isAllOf(Flags .Module | Flags .Case )) &&
1073
+ ltp <:< lift(rtp)
1074
+ else
1075
+ ltp <:< lift(rtp) || rtp <:< lift(ltp)
1066
1076
}
1067
1077
1068
- /** 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)) {
1078
+ /** Check that equality tests between types `ltp` and `left.tpe` make sense.
1079
+ * `left` is required to check for the condition for language.strictEqualityPatternMatching.
1080
+ */
1081
+ def checkCanEqual (left : Tree , rtp : Type , span : Span )(using Context ): Unit =
1082
+ val ltp = left.tpe.widen
1083
+ if ! ctx.isAfterTyper && ! assumedCanEqual(ltp, rtp, left) then
1071
1084
val res = implicitArgTree(defn.CanEqualClass .typeRef.appliedTo(ltp, rtp), span)
1072
1085
implicits.println(i " CanEqual witness found for $ltp / $rtp: $res: ${res.tpe}" )
1073
- }
1074
1086
1075
1087
object hasSkolem extends TreeAccumulator [Boolean ]:
1076
1088
def apply (x : Boolean , tree : Tree )(using Context ): Boolean =
0 commit comments