Skip to content

Commit e0614b5

Browse files
liufengyunmichelou
authored andcommitted
Fix scala#9166: Harden check for values in patterns based on class inheritance info
1 parent 7a04705 commit e0614b5

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3804,10 +3804,25 @@ class Typer extends Namer
38043804
mapOver(tp)
38053805
}
38063806

3807-
if tree.symbol.isOneOf(Module | Enum)
3808-
&& !(tree.tpe frozen_<:< pt) // fast track
3809-
&& !(tree.tpe frozen_<:< approx(pt))
3810-
then
3807+
val sym = tree.tpe.widen.classSymbol
3808+
3809+
// Is it certain that a value of `tree.tpe` is never a subtype of `pt`?
3810+
// It is true if either
3811+
// - the class of `tree.tpe` and class of `pt` cannot have common subclass, or
3812+
// - `tree` is an object or enum value, which cannot possibly be a subtype of `pt`
3813+
val isDefiniteNotSubtype = {
3814+
val clsA = tree.tpe.widenDealias.classSymbol
3815+
val clsB = pt.dealias.classSymbol
3816+
clsA.exists && clsB.exists
3817+
&& clsA != defn.NullClass
3818+
&& (!clsA.isNumericValueClass && !clsB.isNumericValueClass) // approximation for numeric conversion and boxing
3819+
&& !clsA.asClass.mayHaveCommonChild(clsB.asClass)
3820+
|| tree.symbol.isOneOf(Module | Enum)
3821+
&& !(tree.tpe frozen_<:< pt) // fast track
3822+
&& !(tree.tpe frozen_<:< approx(pt))
3823+
}
3824+
3825+
if isDefiniteNotSubtype then
38113826
// We could check whether `equals` is overriden.
38123827
// Reasons for not doing so:
38133828
// - it complicates the protocol

tests/neg/i9166.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object UnitTest extends App {
2+
def foo(m: Unit) = m match {
3+
case runtime.BoxedUnit.UNIT => println("ok") // error
4+
}
5+
foo(())
6+
}

0 commit comments

Comments
 (0)