diff options
author | Martin Odersky <odersky@gmail.com> | 2013-08-08 17:02:57 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-08-08 17:02:57 +0200 |
commit | db9f555e2f02ac345945cb3982b0bf872f44a880 (patch) | |
tree | e129eff7ee58520fc0072711a9db2b8ab00dafbd /src/dotty/tools/dotc/typer/Typer.scala | |
parent | 2985d1806b66d4bf59807f35a6427b81ef66961e (diff) | |
download | dotty-db9f555e2f02ac345945cb3982b0bf872f44a880.tar.gz dotty-db9f555e2f02ac345945cb3982b0bf872f44a880.tar.bz2 dotty-db9f555e2f02ac345945cb3982b0bf872f44a880.zip |
Implementation of match/case def including GADT pattern matching.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index ea1fa3729..32bb4f4d1 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -444,6 +444,44 @@ class Typer extends Namer with Applications with Implicits { cpy.Closure(tree, env1, meth1, EmptyTree).withType(ownType) } + def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context) = { + val sel1 = typedExpr(tree.selector) + val selType = + if (isFullyDefined(sel1.tpe)) sel1.tpe + else errorType("internal error: type of pattern selector is not fully defined", tree.pos) + + /** gadtSyms = "all type parameters of enclosing methods that appear + * non-variantly in the selector type */ + val gadtSyms: Set[Symbol] = { + val accu = new TypeAccumulator[Set[Symbol]] { + def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = { + val tsyms1 = t match { + case tr: TypeRef if (tr.symbol is TypeParam) && tr.symbol.owner.isTerm && variance == 0 => + tsyms + tr.symbol + case _ => + tsyms + } + foldOver(tsyms1, t) + } + } + accu(Set.empty, selType) + } + + def typedCase(tree: untpd.CaseDef)(implicit ctx: Context): CaseDef = { + val doCase: () => CaseDef = () => { + val pat1 = typedPattern(tree.pat, selType) + gadtSyms foreach (_.resetGADTFlexType) + val guard1 = typedExpr(tree.guard, defn.BooleanType) + val body1 = typedExpr(tree.body, pt) + cpy.CaseDef(tree, pat1, guard1, body1) withType body1.tpe + } + (doCase /: gadtSyms) ((op, tsym) => tsym.withGADTFlexType(op)) () + } + + val cases1 = tree.cases map (typedCase(_)(ctx.fresh.withNewScope)) + cpy.Match(tree, sel1, cases1).withType(ctx.lub(cases1.tpes)) + } + def typedModifiers(mods: untpd.Modifiers)(implicit ctx: Context): Modifiers = { val annotations1 = mods.annotations mapconserve typedAnnotation if (annotations1 eq mods.annotations) mods.asInstanceOf[Modifiers] |