@@ -3784,11 +3784,32 @@ class Typer extends Namer
37843784 withMode(Mode .GadtConstraintInference ) {
37853785 TypeComparer .constrainPatternType(tree.tpe, pt)
37863786 }
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 )
37923813 case _ =>
37933814
37943815 private def checkStatementPurity (tree : tpd.Tree )(original : untpd.Tree , exprOwner : Symbol )(using Context ): Unit =
0 commit comments