@@ -523,18 +523,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
523
523
def handlePattern : Tree = {
524
524
val tpt1 = typedTpt
525
525
// special case for an abstract type that comes with a class tag
526
- tpt1.tpe.dealias match {
527
- case tref : TypeRef if ! tref.symbol.isClass && ! ctx.isAfterTyper =>
528
- inferImplicit(defn.ClassTagType .appliedTo(tref),
529
- EmptyTree , tpt1.pos)(ctx.retractMode(Mode .Pattern )) match {
530
- case SearchSuccess (arg, _, _, _) =>
531
- return typed(untpd.Apply (untpd.TypedSplice (arg), tree.expr), pt)
532
- case _ =>
533
- }
534
- case _ =>
535
- if (! ctx.isAfterTyper) tpt1.tpe.<:< (pt)(ctx.addMode(Mode .GADTflexible ))
536
- }
537
- ascription(tpt1, isWildcard = true )
526
+ if (! ctx.isAfterTyper) tpt1.tpe.<:< (pt)(ctx.addMode(Mode .GADTflexible ))
527
+ tryWithClassTag(ascription(tpt1, isWildcard = true ), pt)
538
528
}
539
529
cases(
540
530
ifPat = handlePattern,
@@ -543,6 +533,23 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
543
533
}
544
534
}
545
535
536
+ /** For a typed tree `e: T`, if `T` is an abstract type for which an implicit class tag `ctag`
537
+ * exists, rewrite to `ctag(e)`.
538
+ * @pre We are in pattern-matching mode (Mode.Pattern)
539
+ */
540
+ def tryWithClassTag (tree : Typed , pt : Type )(implicit ctx : Context ) = tree.tpt.tpe.dealias match {
541
+ case tref : TypeRef if ! tref.symbol.isClass && ! ctx.isAfterTyper =>
542
+ require(ctx.mode.is(Mode .Pattern ))
543
+ inferImplicit(defn.ClassTagType .appliedTo(tref),
544
+ EmptyTree , tree.tpt.pos)(ctx.retractMode(Mode .Pattern )) match {
545
+ case SearchSuccess (clsTag, _, _, _) =>
546
+ typed(untpd.Apply (untpd.TypedSplice (clsTag), untpd.TypedSplice (tree.expr)), pt)
547
+ case _ =>
548
+ tree
549
+ }
550
+ case _ => tree
551
+ }
552
+
546
553
def typedNamedArg (tree : untpd.NamedArg , pt : Type )(implicit ctx : Context ) = track(" typedNamedArg" ) {
547
554
val arg1 = typed(tree.arg, pt)
548
555
assignType(cpy.NamedArg (tree)(tree.name, arg1), arg1)
@@ -1121,15 +1128,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1121
1128
def typedBind (tree : untpd.Bind , pt : Type )(implicit ctx : Context ): Tree = track(" typedBind" ) {
1122
1129
val pt1 = fullyDefinedType(pt, " pattern variable" , tree.pos)
1123
1130
val body1 = typed(tree.body, pt1)
1124
- typr.println(i " typed bind $tree pt = $pt1 bodytpe = ${body1.tpe}" )
1125
1131
body1 match {
1126
- case UnApply (fn, Nil , arg :: Nil ) if tree.body.isInstanceOf [untpd.Typed ] =>
1127
- // A typed pattern `x @ (_: T)` with an implicit `ctag: ClassTag[T]`
1128
- // was rewritten to `x @ ctag(_)`.
1129
- // Rewrite further to `ctag(x @ _)`
1130
- assert(fn.symbol.owner == defn.ClassTagClass )
1132
+ case UnApply (fn, Nil , arg :: Nil ) if fn.symbol.owner == defn.ClassTagClass && ! body1.tpe.isError =>
1133
+ // A typed pattern `x @ (e: T)` with an implicit `ctag: ClassTag[T]`
1134
+ // was rewritten to `x @ ctag(e)` by `tryWithClassTag`.
1135
+ // Rewrite further to `ctag(x @ e)`
1131
1136
tpd.cpy.UnApply (body1)(fn, Nil ,
1132
- typed(untpd.Bind (tree.name, arg).withPos(tree.pos), arg.tpe) :: Nil )
1137
+ typed(untpd.Bind (tree.name, untpd. TypedSplice ( arg) ).withPos(tree.pos), arg.tpe) :: Nil )
1133
1138
case _ =>
1134
1139
val sym = newPatternBoundSym(tree.name, body1.tpe, tree.pos)
1135
1140
assignType(cpy.Bind (tree)(tree.name, body1), sym)
0 commit comments