Skip to content

Commit 1be3b2f

Browse files
committed
Extracting TypedCases to be reused for typedTry
1 parent 9f508df commit 1be3b2f

File tree

1 file changed

+39
-35
lines changed

1 file changed

+39
-35
lines changed

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

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -590,47 +590,51 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
590590
val selType = widenForMatchSelector(
591591
fullyDefinedType(sel1.tpe, "pattern selector", tree.pos))
592592

593-
/** gadtSyms = "all type parameters of enclosing methods that appear
594-
* non-variantly in the selector type" todo: should typevars
595-
* which appear with variances +1 and -1 (in different
596-
* places) be considered as well?
597-
*/
598-
val gadtSyms: Set[Symbol] = ctx.traceIndented(i"GADT syms of $selType", gadts) {
599-
val accu = new TypeAccumulator[Set[Symbol]] {
600-
def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = {
601-
val tsyms1 = t match {
602-
case tr: TypeRef if (tr.symbol is TypeParam) && tr.symbol.owner.isTerm && variance == 0 =>
603-
tsyms + tr.symbol
604-
case _ =>
605-
tsyms
606-
}
607-
foldOver(tsyms1, t)
608-
}
609-
}
610-
accu(Set.empty, selType)
611-
}
612-
613-
val cases1 = tree.cases mapconserve (typedCase(_, pt, selType, gadtSyms))
593+
val cases1 = typedCases(tree.cases, selType, pt)
614594
assignType(cpy.Match(tree)(sel1, cases1), cases1)
615595
}
616596
}
617597

618-
def typedCase(tree: untpd.CaseDef, pt: Type, selType: Type, gadtSyms: Set[Symbol])(implicit ctx: Context): CaseDef = track("typedCase") {
619-
def caseRest(pat: Tree)(implicit ctx: Context) = {
620-
gadtSyms foreach (_.resetGADTFlexType)
621-
pat foreachSubTree {
622-
case b: Bind =>
623-
if (ctx.scope.lookup(b.name) == NoSymbol) ctx.enter(b.symbol)
624-
else ctx.error(d"duplicate pattern variable: ${b.name}", b.pos)
625-
case _ =>
598+
def typedCases(cases: List[untpd.CaseDef], selType: Type, pt: Type)(implicit ctx: Context) = {
599+
600+
/** gadtSyms = "all type parameters of enclosing methods that appear
601+
* non-variantly in the selector type" todo: should typevars
602+
* which appear with variances +1 and -1 (in different
603+
* places) be considered as well?
604+
*/
605+
val gadtSyms: Set[Symbol] = ctx.traceIndented(i"GADT syms of $selType", gadts) {
606+
val accu = new TypeAccumulator[Set[Symbol]] {
607+
def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = {
608+
val tsyms1 = t match {
609+
case tr: TypeRef if (tr.symbol is TypeParam) && tr.symbol.owner.isTerm && variance == 0 =>
610+
tsyms + tr.symbol
611+
case _ =>
612+
tsyms
613+
}
614+
foldOver(tsyms1, t)
615+
}
616+
}
617+
accu(Set.empty, selType)
618+
}
619+
620+
def typedCase(tree: untpd.CaseDef): CaseDef = track("typedCase") {
621+
def caseRest(pat: Tree)(implicit ctx: Context) = {
622+
gadtSyms foreach (_.resetGADTFlexType)
623+
pat foreachSubTree {
624+
case b: Bind =>
625+
if (ctx.scope.lookup(b.name) == NoSymbol) ctx.enter(b.symbol)
626+
else ctx.error(d"duplicate pattern variable: ${b.name}", b.pos)
627+
case _ =>
628+
}
629+
val guard1 = typedExpr(tree.guard, defn.BooleanType)
630+
val body1 = typedExpr(tree.body, pt)
631+
assignType(cpy.CaseDef(tree)(pat, guard1, body1), body1)
626632
}
627-
val guard1 = typedExpr(tree.guard, defn.BooleanType)
628-
val body1 = typedExpr(tree.body, pt)
629-
assignType(cpy.CaseDef(tree)(pat, guard1, body1), body1)
633+
val doCase: () => CaseDef =
634+
() => caseRest(typedPattern(tree.pat, selType))(ctx.fresh.setNewScope)
635+
(doCase /: gadtSyms)((op, tsym) => tsym.withGADTFlexType(op))()
630636
}
631-
val doCase: () => CaseDef =
632-
() => caseRest(typedPattern(tree.pat, selType))(ctx.fresh.setNewScope)
633-
(doCase /: gadtSyms)((op, tsym) => tsym.withGADTFlexType(op))()
637+
cases mapconserve typedCase
634638
}
635639

636640
def typedReturn(tree: untpd.Return)(implicit ctx: Context): Return = track("typedReturn") {

0 commit comments

Comments
 (0)