File tree 2 files changed +25
-4
lines changed
compiler/src/dotty/tools/dotc/typer
2 files changed +25
-4
lines changed Original file line number Diff line number Diff line change @@ -3804,10 +3804,25 @@ class Typer extends Namer
3804
3804
mapOver(tp)
3805
3805
}
3806
3806
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
3811
3826
// We could check whether `equals` is overriden.
3812
3827
// Reasons for not doing so:
3813
3828
// - it complicates the protocol
Original file line number Diff line number Diff line change
1
+ object UnitTest extends App {
2
+ def foo (m : Unit ) = m match {
3
+ case runtime.BoxedUnit .UNIT => println(" ok" ) // error
4
+ }
5
+ foo(())
6
+ }
You can’t perform that action at this time.
0 commit comments