From dc872cd1fda84d04dc4de7789a21517902322d68 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 17 Aug 2013 07:56:01 -0700 Subject: Broke up typed1's giant pattern match. Another level of dispatch based on what trees on can expect to see during what mode. This should be beneficial for both performance (smaller methods, fewer type tests) and correctness (prevent trees from reaching inappropriate typing methods by construction rather than via ad hoc checks.) This work also revealed that UnApply trees never reach here, so I removed typedUnApply as dead code. --- .../scala/tools/nsc/typechecker/Typers.scala | 111 ++++++++++++--------- 1 file changed, 66 insertions(+), 45 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d2ff47626d..dd92657de8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4993,13 +4993,6 @@ trait Typers extends Adaptations with Tags with TypersTracking { treeCopy.Star(tree, typed(tree.elem, mode, pt)) setType makeFullyDefined(pt) } - def typedUnApply(tree: UnApply) = { - val fun1 = typed(tree.fun) - val tpes = formalTypes(unapplyTypeList(tree.fun.pos, tree.fun.symbol, fun1.tpe, tree.args), tree.args.length) - val args1 = map2(tree.args, tpes)(typedPattern) - treeCopy.UnApply(tree, fun1, args1) setType pt - } - def issueTryWarnings(tree: Try): Try = { def checkForCatchAll(cdef: CaseDef) { def unbound(t: Tree) = t.symbol == null || t.symbol == NoSymbol @@ -5254,52 +5247,80 @@ trait Typers extends Adaptations with Tags with TypersTracking { typerWithLocalContext(context.makeNewScope(fun, fun.symbol))(_.typedFunction(fun, mode, pt)) } - // begin typed1 - //if (settings.debug.value && tree.isDef) log("typing definition of "+sym);//DEBUG - tree match { - case tree: Ident => typedIdentOrWildcard(tree) - case tree: Select => typedSelectOrSuperCall(tree) - case tree: Apply => typedApply(tree) + // Trees only allowed during pattern mode. + def typedInPatternMode(tree: Tree): Tree = tree match { + case tree: Alternative => typedAlternative(tree) + case tree: Star => typedStar(tree) + case _ => abort(s"unexpected tree in pattern mode: ${tree.getClass}\n$tree") + } + + def typedTypTree(tree: TypTree): Tree = tree match { case tree: TypeTree => typedTypeTree(tree) - case tree: Literal => typedLiteral(tree) - case tree: This => typedThis(tree) - case tree: ValDef => typedValDef(tree) - case tree: DefDef => defDefTyper(tree).typedDefDef(tree) - case tree: Block => typerWithLocalContext(context.makeNewScope(tree, context.owner))(_.typedBlock(tree, mode, pt)) - case tree: If => typedIf(tree) - case tree: TypeApply => typedTypeApply(tree) case tree: AppliedTypeTree => typedAppliedTypeTree(tree) - case tree: Bind => typedBind(tree) - case tree: Function => typedFunction(tree) - case tree: Match => typedVirtualizedMatch(tree) - case tree: New => typedNew(tree) - case tree: Assign => typedAssign(tree.lhs, tree.rhs) - case tree: AssignOrNamedArg => typedAssign(tree.lhs, tree.rhs) // called by NamesDefaults in silent typecheck - case tree: Super => typedSuper(tree) case tree: TypeBoundsTree => typedTypeBoundsTree(tree) - case tree: Typed => typedTyped(tree) - case tree: ClassDef => newTyper(context.makeNewScope(tree, sym)).typedClassDef(tree) - case tree: ModuleDef => newTyper(context.makeNewScope(tree, sym.moduleClass)).typedModuleDef(tree) - case tree: TypeDef => typedTypeDef(tree) - case tree: LabelDef => labelTyper(tree).typedLabelDef(tree) - case tree: PackageDef => typedPackageDef(tree) - case tree: DocDef => typedDocDef(tree, mode, pt) - case tree: Annotated => typedAnnotated(tree) case tree: SingletonTypeTree => typedSingletonTypeTree(tree) case tree: SelectFromTypeTree => typedSelectFromTypeTree(tree) case tree: CompoundTypeTree => typedCompoundTypeTree(tree) case tree: ExistentialTypeTree => typedExistentialTypeTree(tree) - case tree: Return => typedReturn(tree) - case tree: Try => typedTry(tree) - case tree: Throw => typedThrow(tree) - case tree: Alternative => typedAlternative(tree) - case tree: Star => typedStar(tree) - case tree: UnApply => typedUnApply(tree) - case tree: ArrayValue => typedArrayValue(tree) - case tree: ApplyDynamic => typedApplyDynamic(tree) - case tree: ReferenceToBoxed => typedReferenceToBoxed(tree) case tree: TypeTreeWithDeferredRefCheck => tree // TODO: retype the wrapped tree? TTWDRC would have to change to hold the wrapped tree (not a closure) - case _ => abort(s"unexpected tree: ${tree.getClass}\n$tree") + case _ => abort(s"unexpected type-representing tree: ${tree.getClass}\n$tree") + } + + def typedMemberDef(tree: MemberDef): Tree = tree match { + case tree: ValDef => typedValDef(tree) + case tree: DefDef => defDefTyper(tree).typedDefDef(tree) + case tree: ClassDef => newTyper(context.makeNewScope(tree, sym)).typedClassDef(tree) + case tree: ModuleDef => newTyper(context.makeNewScope(tree, sym.moduleClass)).typedModuleDef(tree) + case tree: TypeDef => typedTypeDef(tree) + case tree: PackageDef => typedPackageDef(tree) + case _ => abort(s"unexpected member def: ${tree.getClass}\n$tree") + } + + // Trees not allowed during pattern mode. + def typedOutsidePatternMode(tree: Tree): Tree = tree match { + case tree: Block => typerWithLocalContext(context.makeNewScope(tree, context.owner))(_.typedBlock(tree, mode, pt)) + case tree: If => typedIf(tree) + case tree: TypeApply => typedTypeApply(tree) + case tree: Function => typedFunction(tree) + case tree: Match => typedVirtualizedMatch(tree) + case tree: New => typedNew(tree) + case tree: Assign => typedAssign(tree.lhs, tree.rhs) + case tree: AssignOrNamedArg => typedAssign(tree.lhs, tree.rhs) // called by NamesDefaults in silent typecheck + case tree: Super => typedSuper(tree) + case tree: Annotated => typedAnnotated(tree) + case tree: Return => typedReturn(tree) + case tree: Try => typedTry(tree) + case tree: Throw => typedThrow(tree) + case tree: ArrayValue => typedArrayValue(tree) + case tree: ApplyDynamic => typedApplyDynamic(tree) + case tree: ReferenceToBoxed => typedReferenceToBoxed(tree) + case tree: LabelDef => labelTyper(tree).typedLabelDef(tree) + case tree: DocDef => typedDocDef(tree, mode, pt) + case _ => abort(s"unexpected tree: ${tree.getClass}\n$tree") + } + + // Trees allowed in or out of pattern mode. + def typedInAnyMode(tree: Tree): Tree = tree match { + case tree: Ident => typedIdentOrWildcard(tree) + case tree: Bind => typedBind(tree) + case tree: Apply => typedApply(tree) + case tree: Select => typedSelectOrSuperCall(tree) + case tree: Literal => typedLiteral(tree) + case tree: Typed => typedTyped(tree) + case tree: This => typedThis(tree) // SI-6104 + case tree: UnApply => abort(s"unexpected UnApply $tree") // turns out UnApply never reaches here + case _ => + if (mode.inPatternMode) + typedInPatternMode(tree) + else + typedOutsidePatternMode(tree) + } + + // begin typed1 + tree match { + case tree: TypTree => typedTypTree(tree) + case tree: MemberDef => typedMemberDef(tree) + case _ => typedInAnyMode(tree) } } -- cgit v1.2.3