Skip to content

Commit 7fad5c7

Browse files
committed
Refine checking condition
Don't check for matchability if - pattern type is a subtype of tested type - we are unapplying a typetest or classtag test
1 parent a389a11 commit 7fad5c7

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

compiler/src/dotty/tools/dotc/core/Mode.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,7 @@ object Mode {
116116

117117
/** Are we typechecking the rhs of an extension method? */
118118
val InExtensionMethod: Mode = newMode(26, "InExtensionMethod")
119+
120+
/** Are we resolving a TypeTest node? */
121+
val InTypeTest: Mode = newMode(27, "InTypeTest")
119122
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,8 @@ trait Applications extends Compatibility {
11581158
def typedUnApply(tree: untpd.Apply, selType: Type)(using Context): Tree = {
11591159
record("typedUnApply")
11601160
val Apply(qual, args) = tree
1161-
checkMatchable(selType, tree.srcPos, pattern = true)
1161+
if !ctx.mode.is(Mode.InTypeTest) then
1162+
checkMatchable(selType, tree.srcPos, pattern = true)
11621163

11631164
def notAnExtractor(tree: Tree): Tree =
11641165
// prefer inner errors

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,10 @@ class Typer extends Namer
778778
val matched = ascription(tpt1, isWildcard = true)
779779
// special case for an abstract type that comes with a class tag
780780
val result = tryWithTypeTest(matched, pt)
781-
if (result eq matched) && pt != defn.ImplicitScrutineeTypeRef then
781+
if (result eq matched)
782+
&& pt != defn.ImplicitScrutineeTypeRef
783+
&& !(pt <:< tpt1.tpe)
784+
then
782785
// no check for matchability if TestTest was applied
783786
checkMatchable(pt, tree.srcPos, pattern = true)
784787
result
@@ -802,13 +805,15 @@ class Typer extends Namer
802805
inferImplicit(tpe, EmptyTree, tree.tpt.span)
803806
) match
804807
case SearchSuccess(clsTag, _, _) =>
805-
Some(typed(untpd.Apply(untpd.TypedSplice(clsTag), untpd.TypedSplice(tree.expr)), pt))
808+
withMode(Mode.InTypeTest) {
809+
Some(typed(untpd.Apply(untpd.TypedSplice(clsTag), untpd.TypedSplice(tree.expr)), pt))
810+
}
806811
case _ =>
807812
None
808813
}
809814
val tag = withTag(defn.TypeTestClass.typeRef.appliedTo(pt, tref))
810-
.orElse(withTag(defn.ClassTagClass.typeRef.appliedTo(tref)))
811-
.getOrElse(tree)
815+
.orElse(withTag(defn.ClassTagClass.typeRef.appliedTo(tref)))
816+
.getOrElse(tree)
812817
if tag.symbol.owner == defn.ClassTagClass && config.Feature.sourceVersion.isAtLeast(config.SourceVersion.`3.1`) then
813818
report.warning("Use of `scala.reflect.ClassTag` for type testing may be unsound. Consider using `scala.reflect.TypeTest` instead.", tree.srcPos)
814819
tag

0 commit comments

Comments
 (0)