diff options
author | Paul Phillips <paulp@improving.org> | 2013-05-23 10:00:50 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-05-23 12:07:45 -0700 |
commit | d8b96bb8583161e59180527bab0283f783466426 (patch) | |
tree | a12ecf17379a579d5a2f4bda7a16819001eadb77 /src/compiler/scala/tools/nsc/transform/patmat | |
parent | b8641a97d669c945a1b9f47b4e8934aa6c98ffd7 (diff) | |
download | scala-d8b96bb8583161e59180527bab0283f783466426.tar.gz scala-d8b96bb8583161e59180527bab0283f783466426.tar.bz2 scala-d8b96bb8583161e59180527bab0283f783466426.zip |
Concision contribution.
We have lots of core classes for which we need not go through
the symbol to get the type:
ObjectClass.tpe -> ObjectTpe
AnyClass.tpe -> AnyTpe
I updated everything to use the concise/direct version,
and eliminated a bunch of noise where places were calling
typeConstructor, erasedTypeRef, and other different-seeming methods
only to always wind up with the same type they would have received
from sym.tpe. There's only one Object type, before or after erasure,
with or without type arguments.
Calls to typeConstructor were especially damaging because (see
previous commit) it had a tendency to cache a different type than
the type one would find via other means. The two types would
compare =:=, but possibly not == and definitely not eq. (I still
don't understand what == is expected to do with types.)
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/patmat')
5 files changed, 23 insertions, 29 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index 68883831a2..f527c30b8a 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -19,7 +19,7 @@ trait TreeAndTypeAnalysis extends Debugging { // we use subtyping as a model for implication between instanceof tests // i.e., when S <:< T we assume x.isInstanceOf[S] implies x.isInstanceOf[T] // unfortunately this is not true in general: - // SI-6022 expects instanceOfTpImplies(ProductClass.tpe, AnyRefClass.tpe) + // SI-6022 expects instanceOfTpImplies(ProductClass.tpe, AnyRefTpe) def instanceOfTpImplies(tp: Type, tpImplied: Type) = { val tpValue = tp.typeSymbol.isPrimitiveValueClass @@ -28,7 +28,7 @@ trait TreeAndTypeAnalysis extends Debugging { // this allows us to reuse subtyping as a model for implication between instanceOf tests // the latter don't see a difference between AnyRef, Object or Any when comparing non-value types -- SI-6022 val tpImpliedNormalizedToAny = - if (tpImplied =:= (if (tpValue) AnyValClass.tpe else AnyRefClass.tpe)) AnyClass.tpe + if (tpImplied =:= (if (tpValue) AnyValTpe else AnyRefTpe)) AnyTpe else tpImplied tp <:< tpImpliedNormalizedToAny @@ -48,7 +48,7 @@ trait TreeAndTypeAnalysis extends Debugging { tp.typeSymbol match { // TODO case _ if tp.isTupleType => // recurse into component types? case UnitClass => - Some(List(UnitClass.tpe)) + Some(List(UnitTpe)) case BooleanClass => Some((List(ConstantType(Constant(true)), ConstantType(Constant(false))))) // TODO case _ if tp.isTupleType => // recurse into component types diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala index 889615a39f..1e4c56529c 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala @@ -128,7 +128,7 @@ trait MatchCodeGen extends Interface { // __match.guard(`cond`, `res`).flatMap(`nextBinder` => `next`) def flatMapCond(cond: Tree, res: Tree, nextBinder: Symbol, next: Tree): Tree = flatMap(guard(cond, res), nextBinder, next) // __match.guard(`guardTree`, ()).flatMap((_: P[Unit]) => `next`) - def flatMapGuard(guardTree: Tree, next: Tree): Tree = flatMapCond(guardTree, CODE.UNIT, freshSym(guardTree.pos, pureType(UnitClass.tpe)), next) + def flatMapGuard(guardTree: Tree, next: Tree): Tree = flatMapCond(guardTree, CODE.UNIT, freshSym(guardTree.pos, pureType(UnitTpe)), next) } } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala index 31b04d0bd6..9854e4ef62 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala @@ -143,7 +143,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { } class ReusedCondTreeMaker(prevBinder: Symbol, val nextBinder: Symbol, cond: Tree, res: Tree, val pos: Position) extends TreeMaker { import CODE._ lazy val localSubstitution = Substitution(List(prevBinder), List(CODE.REF(nextBinder))) - lazy val storedCond = freshSym(pos, BooleanClass.tpe, "rc") setFlag MUTABLE + lazy val storedCond = freshSym(pos, BooleanTpe, "rc") setFlag MUTABLE lazy val treesToHoist: List[Tree] = { nextBinder setFlag MUTABLE List(storedCond, nextBinder) map { b => VAL(b) === codegen.mkZero(b.info) } @@ -503,7 +503,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { } class RegularSwitchMaker(scrutSym: Symbol, matchFailGenOverride: Option[Tree => Tree], val unchecked: Boolean) extends SwitchMaker { - val switchableTpe = Set(ByteClass.tpe, ShortClass.tpe, IntClass.tpe, CharClass.tpe) + val switchableTpe = Set(ByteTpe, ShortTpe, IntTpe, CharTpe) val alternativesSupported = true val canJump = true @@ -543,7 +543,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { else { // match on scrutSym -- converted to an int if necessary -- not on scrut directly (to avoid duplicating scrut) val scrutToInt: Tree = - if (scrutSym.tpe =:= IntClass.tpe) REF(scrutSym) + if (scrutSym.tpe =:= IntTpe) REF(scrutSym) else (REF(scrutSym) DOT (nme.toInt)) Some(BLOCK( VAL(scrutSym) === scrut, @@ -571,16 +571,16 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { } def isDefault(x: CaseDef): Boolean = x match { - case CaseDef(Typed(Ident(nme.WILDCARD), tpt), EmptyTree, _) if (tpt.tpe =:= ThrowableClass.tpe) => true - case CaseDef(Bind(_, Typed(Ident(nme.WILDCARD), tpt)), EmptyTree, _) if (tpt.tpe =:= ThrowableClass.tpe) => true + case CaseDef(Typed(Ident(nme.WILDCARD), tpt), EmptyTree, _) if (tpt.tpe =:= ThrowableTpe) => true + case CaseDef(Bind(_, Typed(Ident(nme.WILDCARD), tpt)), EmptyTree, _) if (tpt.tpe =:= ThrowableTpe) => true case CaseDef(Ident(nme.WILDCARD), EmptyTree, _) => true case _ => false } - lazy val defaultSym: Symbol = freshSym(NoPosition, ThrowableClass.tpe) + lazy val defaultSym: Symbol = freshSym(NoPosition, ThrowableTpe) def defaultBody: Tree = Throw(CODE.REF(defaultSym)) def defaultCase(scrutSym: Symbol = defaultSym, guard: Tree = EmptyTree, body: Tree = defaultBody): CaseDef = { import CODE._; atPos(body.pos) { - (CASE (Bind(scrutSym, Typed(Ident(nme.WILDCARD), TypeTree(ThrowableClass.tpe)))) IF guard) ==> body + (CASE (Bind(scrutSym, Typed(Ident(nme.WILDCARD), TypeTree(ThrowableTpe)))) IF guard) ==> body }} } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala index c8c3b741f1..fcee142932 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala @@ -14,14 +14,8 @@ import scala.reflect.internal.util.Statistics */ trait MatchTranslation { self: PatternMatching => import PatternMatchingStats._ - import global.{phase, currentRun, Symbol, - Apply, Bind, CaseDef, ClassInfoType, Ident, Literal, Match, - Alternative, Constant, EmptyTree, Select, Star, This, Throw, Typed, UnApply, - Type, MethodType, WildcardType, PolyType, ErrorType, NoType, TypeRef, typeRef, - Name, NoSymbol, Position, Tree, atPos, glb, rootMirror, treeInfo, nme, Transformer, - elimAnonymousClass, asCompactDebugString, hasLength, devWarning} - import global.definitions.{ThrowableClass, SeqClass, ScalaPackageClass, BooleanClass, UnitClass, RepeatedParamClass, - repeatedToSeq, isRepeatedParamType, getProductArgs} + import global._ + import definitions._ import global.analyzer.{ErrorUtils, formalTypes} trait MatchTranslator extends TreeMakers { @@ -169,7 +163,7 @@ trait MatchTranslation { self: PatternMatching => val bindersAndCases = caseDefs map { caseDef => // generate a fresh symbol for each case, hoping we'll end up emitting a type-switch (we don't have a global scrut there) // if we fail to emit a fine-grained switch, have to do translateCase again with a single scrutSym (TODO: uniformize substitution on treemakers so we can avoid this) - val caseScrutSym = freshSym(pos, pureType(ThrowableClass.tpe)) + val caseScrutSym = freshSym(pos, pureType(ThrowableTpe)) (caseScrutSym, propagateSubstitution(translateCase(caseScrutSym, pt)(caseDef), EmptySubstitution)) } @@ -179,10 +173,10 @@ trait MatchTranslation { self: PatternMatching => } val catches = if (swatches.nonEmpty) swatches else { - val scrutSym = freshSym(pos, pureType(ThrowableClass.tpe)) + val scrutSym = freshSym(pos, pureType(ThrowableTpe)) val casesNoSubstOnly = caseDefs map { caseDef => (propagateSubstitution(translateCase(scrutSym, pt)(caseDef), EmptySubstitution))} - val exSym = freshSym(pos, pureType(ThrowableClass.tpe), "ex") + val exSym = freshSym(pos, pureType(ThrowableTpe), "ex") List( atPos(pos) { @@ -194,7 +188,7 @@ trait MatchTranslation { self: PatternMatching => }) } - typer.typedCases(catches, ThrowableClass.tpe, WildcardType) + typer.typedCases(catches, ThrowableTpe, WildcardType) } @@ -595,7 +589,7 @@ trait MatchTranslation { self: PatternMatching => def treeMaker(patBinderOrCasted: Symbol, binderKnownNonNull: Boolean, pos: Position): TreeMaker = { // the extractor call (applied to the binder bound by the flatMap corresponding to the previous (i.e., enclosing/outer) pattern) val extractorApply = atPos(pos)(spliceApply(patBinderOrCasted)) - val binder = freshSym(pos, pureType(resultInMonad)) // can't simplify this when subPatBinders.isEmpty, since UnitClass.tpe is definitely wrong when isSeq, and resultInMonad should always be correct since it comes directly from the extractor's result type + val binder = freshSym(pos, pureType(resultInMonad)) // can't simplify this when subPatBinders.isEmpty, since UnitTpe is definitely wrong when isSeq, and resultInMonad should always be correct since it comes directly from the extractor's result type ExtractorTreeMaker(extractorApply, lengthGuard(binder), binder)(subPatBinders, subPatRefs(binder), resultType.typeSymbol == BooleanClass, checkedLength, patBinderOrCasted, ignoredSubPatBinders) } @@ -623,7 +617,7 @@ trait MatchTranslation { self: PatternMatching => // what's the extractor's result type in the monad? // turn an extractor's result type into something `monadTypeToSubPatTypesAndRefs` understands protected lazy val resultInMonad: Type = if(!hasLength(tpe.paramTypes, 1)) ErrorType else { - if (resultType.typeSymbol == BooleanClass) UnitClass.tpe + if (resultType.typeSymbol == BooleanClass) UnitTpe else matchMonadResult(resultType) } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala index 4dff445fe8..bce0a077fb 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala @@ -19,7 +19,7 @@ import scala.reflect.internal.util.Position */ trait MatchTreeMaking extends MatchCodeGen with Debugging { import global._ - import definitions.{SomeClass, AnyRefClass, UncheckedClass, BooleanClass} + import definitions._ final case class Suppression(exhaustive: Boolean, unreachable: Boolean) object Suppression { @@ -414,7 +414,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { case SingleType(_, sym) => and(equalsTest(gen.mkAttributedQualifier(expectedTp), testedBinder), typeTest(testedBinder, expectedTp.widen)) // must use == to support e.g. List() == Nil case ThisType(sym) if sym.isModule => and(equalsTest(CODE.REF(sym), testedBinder), typeTest(testedBinder, expectedTp.widen)) - case ConstantType(Constant(null)) if testedBinder.info.widen <:< AnyRefClass.tpe + case ConstantType(Constant(null)) if testedBinder.info.widen <:< AnyRefTpe => eqTest(expTp(CODE.NULL), testedBinder) case ConstantType(const) => equalsTest(expTp(Literal(const)), testedBinder) case ThisType(sym) => eqTest(expTp(This(sym)), testedBinder) @@ -428,7 +428,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { // since the types conform, no further checking is required if (expectedTp.typeSymbol.isPrimitiveValueClass) tru // have to test outer and non-null only when it's a reference type - else if (expectedTp <:< AnyRefClass.tpe) { + else if (expectedTp <:< AnyRefTpe) { // do non-null check first to ensure we won't select outer on null if (outerTestNeeded) and(nonNullTest(testedBinder), outerTest(testedBinder, expectedTp)) else nonNullTest(testedBinder) @@ -476,7 +476,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { ((casegen: Casegen) => combineExtractors(altTreeMakers :+ TrivialTreeMaker(casegen.one(mkTRUE)))(casegen)) ) - val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanClass.tpe)(combinedAlts, Some(x => mkFALSE)) + val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanTpe)(combinedAlts, Some(x => mkFALSE)) codegenAlt.ifThenElseZero(findAltMatcher, substitution(next)) } } |