@@ -3784,11 +3784,32 @@ class Typer extends Namer
3784
3784
withMode(Mode .GadtConstraintInference ) {
3785
3785
TypeComparer .constrainPatternType(tree.tpe, pt)
3786
3786
}
3787
- val cmp =
3788
- untpd.Apply (
3789
- untpd.Select (untpd.TypedSplice (tree), nme.EQ ),
3790
- untpd.TypedSplice (dummyTreeOfType(pt)))
3791
- typedExpr(cmp, defn.BooleanType )
3787
+
3788
+ // approximate type params with bounds
3789
+ def approx = new ApproximatingTypeMap {
3790
+ def apply (tp : Type ) = tp.dealias match
3791
+ case tp : TypeRef if ! tp.symbol.isClass =>
3792
+ expandBounds(tp.info.bounds)
3793
+ case _ =>
3794
+ mapOver(tp)
3795
+ }
3796
+
3797
+ if tree.symbol.is(Module )
3798
+ && ! (tree.tpe frozen_<:< pt) // fast track
3799
+ && ! (tree.tpe frozen_<:< approx(pt))
3800
+ then
3801
+ // We could check whether `equals` is overriden.
3802
+ // Reasons for not doing so:
3803
+ // - it complicates the protocol
3804
+ // - such code patterns usually implies hidden errors in the code
3805
+ // - it's safe/sound to reject the code
3806
+ report.error(TypeMismatch (tree.tpe, pt, " \n pattern type is incompatible with expected type" ), tree.srcPos)
3807
+ else
3808
+ val cmp =
3809
+ untpd.Apply (
3810
+ untpd.Select (untpd.TypedSplice (tree), nme.EQ ),
3811
+ untpd.TypedSplice (dummyTreeOfType(pt)))
3812
+ typedExpr(cmp, defn.BooleanType )
3792
3813
case _ =>
3793
3814
3794
3815
private def checkStatementPurity (tree : tpd.Tree )(original : untpd.Tree , exprOwner : Symbol )(using Context ): Unit =
0 commit comments