Skip to content

Commit 72fb8a8

Browse files
committed
Check that pattern matches make sense wrt equality
1 parent b0bbd93 commit 72fb8a8

File tree

1 file changed

+49
-22
lines changed

1 file changed

+49
-22
lines changed

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

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,26 +1540,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
15401540
tree.withType(wtp.resultType)
15411541
}
15421542
val args = (wtp.paramNames, wtp.paramTypes).zipped map { (pname, formal) =>
1543-
def where = d"parameter $pname of $methodStr"
1544-
inferImplicit(formal, EmptyTree, tree.pos.endPos) match {
1545-
case SearchSuccess(arg, _, _) =>
1546-
arg
1547-
case ambi: AmbiguousImplicits =>
1548-
implicitArgError(s"ambiguous implicits: ${ambi.explanation} of $where")
1549-
case failure: SearchFailure =>
1550-
val arg = synthesizedClassTag(formal)
1551-
if (!arg.isEmpty) arg
1552-
else {
1553-
var msg = d"no implicit argument of type $formal found for $where" + failure.postscript
1554-
for (notFound <- formal.typeSymbol.getAnnotation(defn.ImplicitNotFoundAnnot);
1555-
Literal(Constant(raw: String)) <- notFound.argument(0))
1556-
msg = err.implicitNotFoundString(
1557-
raw,
1558-
formal.typeSymbol.typeParams.map(_.name.unexpandedName.toString),
1559-
formal.argInfos)
1560-
implicitArgError(msg)
1561-
}
1562-
}
1543+
def implicitArgError(msg: String => String) =
1544+
errors += (() => msg(d"parameter $pname of $methodStr"))
1545+
inferImplicitArg(formal, implicitArgError)
15631546
}
15641547
if (errors.nonEmpty) {
15651548
// If there are several arguments, some arguments might already
@@ -1609,8 +1592,19 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
16091592
else
16101593
missingArgs
16111594
case _ =>
1612-
if (tree.tpe <:< pt) tree
1613-
else if (ctx.mode is Mode.Pattern) tree // no subtype check for pattern
1595+
if (ctx.mode is Mode.Pattern) {
1596+
tree match {
1597+
case _: RefTree | _: Literal
1598+
if !ctx.isAfterTyper && !isVarPattern(tree) && pt.derivesFrom(defn.EqClassClass) =>
1599+
def implicitArgError(msg: String => String) =
1600+
ctx.error(msg("pattern match"), tree.pos.endPos)
1601+
val commonEq = defn.EqType.appliedTo(pt | wtp)
1602+
inferImplicitArg(commonEq, implicitArgError)(ctx.retractMode(Mode.Pattern))
1603+
case _ =>
1604+
}
1605+
tree
1606+
}
1607+
else if (tree.tpe <:< pt) tree
16141608
else if (wtp.isInstanceOf[MethodType]) missingArgs
16151609
else {
16161610
typr.println(i"adapt to subtype ${tree.tpe} !<:< $pt")
@@ -1619,6 +1613,39 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
16191613
}
16201614
}
16211615

1616+
/** Find an implicit argument for parameter `formal`.
1617+
* @param error An error handler that gets an error message parameter
1618+
* which is itself parameterized by another string,
1619+
* indicating where the implicit parameter is needed
1620+
*/
1621+
def inferImplicitArg(formal: Type, error: (String => String) => Unit)(implicit ctx: Context): Tree =
1622+
inferImplicit(formal, EmptyTree, tree.pos.endPos) match {
1623+
case SearchSuccess(arg, _, _) =>
1624+
arg
1625+
case ambi: AmbiguousImplicits =>
1626+
error(where => s"ambiguous implicits: ${ambi.explanation} of $where")
1627+
EmptyTree
1628+
case failure: SearchFailure =>
1629+
val arg = synthesizedClassTag(formal)
1630+
if (!arg.isEmpty) arg
1631+
else {
1632+
var msgFn = (where: String) =>
1633+
d"no implicit argument of type $formal found for $where" + failure.postscript
1634+
for {
1635+
notFound <- formal.typeSymbol.getAnnotation(defn.ImplicitNotFoundAnnot)
1636+
Literal(Constant(raw: String)) <- notFound.argument(0)
1637+
} {
1638+
msgFn = where =>
1639+
err.implicitNotFoundString(
1640+
raw,
1641+
formal.typeSymbol.typeParams.map(_.name.unexpandedName.toString),
1642+
formal.argInfos)
1643+
}
1644+
error(msgFn)
1645+
EmptyTree
1646+
}
1647+
}
1648+
16221649
/** If `formal` is of the form ClassTag[T], where `T` is a class type,
16231650
* synthesize a class tag for `T`.
16241651
*/

0 commit comments

Comments
 (0)