Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d433ebe

Browse files
change SIP-67 implementation based on @odersky's review
1 parent 0a565d0 commit d433ebe

File tree

5 files changed

+18
-14
lines changed

5 files changed

+18
-14
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,7 @@ trait Applications extends Compatibility {
13381338
case Apply(fn @ Select(left, _), right :: Nil) if fn.hasType =>
13391339
val op = fn.symbol
13401340
if (op == defn.Any_== || op == defn.Any_!=)
1341-
checkCanEqual(left.tpe.widen, right.tpe.widen, app.span)
1341+
checkCanEqual(left, right.tpe.widen, app.span)
13421342
case _ =>
13431343
}
13441344
app

‎compiler/src/dotty/tools/dotc/typer/Implicits.scala‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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 =

‎compiler/src/dotty/tools/dotc/typer/ReTyper.scala‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking
175175

176176
override def inferView(from: Tree, to: Type)(using Context): Implicits.SearchResult =
177177
Implicits.NoMatchingImplicitsFailure
178-
override def checkCanEqual(ltp: Type, rtp: Type, span: Span)(using Context): Unit = ()
178+
override def checkCanEqual(left: Tree, rtp: Type, span: Span)(using Context): Unit = ()
179179

180180
override def widenEnumCase(tree: Tree, pt: Type)(using Context): Tree = tree
181181

‎compiler/src/dotty/tools/dotc/typer/Synthesizer.scala‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
183183
* one of `tp1`, `tp2` has a reflexive `CanEqual` instance.
184184
*/
185185
def validEqAnyArgs(tp1: Type, tp2: Type)(using Context) =
186-
typer.assumedCanEqual(tp1, tp2)
186+
typer.assumedCanEqual(None, tp1, tp2)
187187
|| withMode(Mode.StrictEquality) {
188188
!hasEq(tp1) && !hasEq(tp2)
189189
}

‎compiler/src/dotty/tools/dotc/typer/Typer.scala‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5052,12 +5052,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
50525052

50535053
Linter.warnOnImplausiblePattern(tree, pt)
50545054

5055-
if ! (tree.tpe <:< pt && (tree.symbol.flags.isAllOf(Flags.EnumValue) || (tree.symbol.flags.isAllOf(Flags.Module | Flags.Case)))) then
5056-
val cmp =
5057-
untpd.Apply(
5058-
untpd.Select(untpd.TypedSplice(tree), nme.EQ),
5059-
untpd.TypedSplice(dummyTreeOfType(pt)))
5060-
typedExpr(cmp, defn.BooleanType)
5055+
val cmp =
5056+
untpd.Apply(
5057+
untpd.Select(untpd.TypedSplice(tree), nme.EQ),
5058+
untpd.TypedSplice(dummyTreeOfType(pt)))
5059+
typedExpr(cmp, defn.BooleanType)
50615060
case _ =>
50625061

50635062
private def checkStatementPurity(tree: tpd.Tree)(original: untpd.Tree, exprOwner: Symbol, isUnitExpr: Boolean = false)(using Context): Unit =

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /