diff options
author | Paul Phillips <paulp@improving.org> | 2013-06-08 12:04:27 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-06-08 12:04:27 -0700 |
commit | 45d61774eb255416c96e983cdb87960ad6415b74 (patch) | |
tree | 4aeb3debc1cf0a79ece22175f4be8450b607594b /src/reflect | |
parent | 04837e710552cc53b0b06b2bc47ee7d2856ae230 (diff) | |
download | scala-45d61774eb255416c96e983cdb87960ad6415b74.tar.gz scala-45d61774eb255416c96e983cdb87960ad6415b74.tar.bz2 scala-45d61774eb255416c96e983cdb87960ad6415b74.zip |
Eliminate needless Options.
Many of our core types have dedicated sentinels which serve
perfectly to communicate "no value", even more perfectly than
None. Saving a billion allocations is gravy.
Diffstat (limited to 'src/reflect')
6 files changed, 43 insertions, 41 deletions
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala index 368e1cde30..e3498a95a6 100644 --- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala +++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala @@ -66,15 +66,14 @@ trait BaseTypeSeqs { pending += i try { mergePrefixAndArgs(variants, Variance.Contravariant, lubDepth(variants)) match { - case Some(tp0) => + case NoType => typeError("no common type instance of base types "+(variants mkString ", and ")+" exists.") + case tp0 => pending(i) = false elems(i) = tp0 tp0 - case None => - typeError( - "no common type instance of base types "+(variants mkString ", and ")+" exists.") } - } catch { + } + catch { case CyclicInheritance => typeError( "computing the common type instance of base types "+(variants mkString ", and ")+" leads to a cycle.") diff --git a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala index 6251849182..073f124630 100644 --- a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala +++ b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala @@ -77,14 +77,14 @@ trait ExistentialsAndSkolems { * also replaced, except for term symbols of an Ident tree, where * only the type of the Ident is changed. */ - final def existentialTransform[T](rawSyms: List[Symbol], tp: Type, rawOwner: Option[Symbol] = None)(creator: (List[Symbol], Type) => T): T = { + final def existentialTransform[T](rawSyms: List[Symbol], tp: Type, rawOwner: Symbol = NoSymbol)(creator: (List[Symbol], Type) => T): T = { val allBounds = existentialBoundsExcludingHidden(rawSyms) val typeParams: List[Symbol] = rawSyms map { sym => val name = sym.name match { case x: TypeName => x case x => tpnme.singletonName(x) } - def rawOwner0 = rawOwner.getOrElse(abort(s"no owner provided for existential transform over raw parameter: $sym")) + def rawOwner0 = rawOwner orElse abort(s"no owner provided for existential transform over raw parameter: $sym") val bound = allBounds(sym) val sowner = if (isRawParameter(sym)) rawOwner0 else sym.owner val quantified = sowner.newExistential(name, sym.pos) @@ -106,7 +106,7 @@ trait ExistentialsAndSkolems { * @param hidden The original type * @param rawOwner The owner for Java raw types. */ - final def packSymbols(hidden: List[Symbol], tp: Type, rawOwner: Option[Symbol] = None): Type = + final def packSymbols(hidden: List[Symbol], tp: Type, rawOwner: Symbol = NoSymbol): Type = if (hidden.isEmpty) tp else existentialTransform(hidden, tp, rawOwner)(existentialAbstraction) } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index f3cea1fd00..2da9fa1cca 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -3413,6 +3413,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def mapParamss[T](sym: Symbol)(f: Symbol => T): List[List[T]] = mmap(sym.info.paramss)(f) + def existingSymbols(syms: List[Symbol]): List[Symbol] = + syms filter (s => (s ne null) && (s ne NoSymbol)) + /** Return closest enclosing method, unless shadowed by an enclosing class. */ // TODO Move back to ExplicitOuter when the other call site is removed. // no use of closures here in the interest of speed. diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index 6abf344adb..b75fd72526 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -137,20 +137,20 @@ abstract class TreeGen extends macros.TreeBuilder { /** Replaces tree type with a stable type if possible */ def stabilize(tree: Tree): Tree = stableTypeFor(tree) match { - case Some(tp) => tree setType tp - case _ => tree + case NoType => tree + case tp => tree setType tp } /** Computes stable type for a tree if possible */ - def stableTypeFor(tree: Tree): Option[Type] = - if (treeInfo.admitsTypeSelection(tree)) - tree match { - case This(_) => Some(ThisType(tree.symbol)) - case Ident(_) => Some(singleType(tree.symbol.owner.thisType, tree.symbol)) - case Select(qual, _) => Some(singleType(qual.tpe, tree.symbol)) - case _ => None - } - else None + def stableTypeFor(tree: Tree): Type = ( + if (!treeInfo.admitsTypeSelection(tree)) NoType + else tree match { + case This(_) => ThisType(tree.symbol) + case Ident(_) => singleType(tree.symbol.owner.thisType, tree.symbol) + case Select(qual, _) => singleType(qual.tpe, tree.symbol) + case _ => NoType + } + ) /** Builds a reference with stable type to given symbol */ def mkAttributedStableRef(pre: Type, sym: Symbol): Tree = diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index d942c71619..967146a130 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -4380,12 +4380,11 @@ trait Types /** Compute lub (if `variance == Covariant`) or glb (if `variance == Contravariant`) of given list * of types `tps`. All types in `tps` are typerefs or singletypes * with the same symbol. - * Return `Some(x)` if the computation succeeds with result `x`. - * Return `None` if the computation fails. + * Return `x` if the computation succeeds with result `x`. + * Return `NoType` if the computation fails. */ - def mergePrefixAndArgs(tps: List[Type], variance: Variance, depth: Int): Option[Type] = tps match { - case List(tp) => - Some(tp) + def mergePrefixAndArgs(tps: List[Type], variance: Variance, depth: Int): Type = tps match { + case tp :: Nil => tp case TypeRef(_, sym, _) :: rest => val pres = tps map (_.prefix) // prefix normalizes automatically val pre = if (variance.isPositive) lub(pres, depth) else glb(pres, depth) @@ -4397,12 +4396,13 @@ trait Types // if argss contain one value type and some other type, the lub is Object // if argss contain several reference types, the lub is an array over lub of argtypes if (argss exists typeListIsEmpty) { - None // something is wrong: an array without a type arg. - } else { + NoType // something is wrong: an array without a type arg. + } + else { val args = argss map (_.head) - if (args.tail forall (_ =:= args.head)) Some(typeRef(pre, sym, List(args.head))) - else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) Some(ObjectTpe) - else Some(typeRef(pre, sym, List(lub(args)))) + if (args.tail forall (_ =:= args.head)) typeRef(pre, sym, List(args.head)) + else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) ObjectTpe + else typeRef(pre, sym, List(lub(args))) } } else transposeSafe(argss) match { @@ -4411,7 +4411,7 @@ trait Types // catching just in case (shouldn't happen, but also doesn't cost us) // [JZ] It happens: see SI-5683. debuglog(s"transposed irregular matrix!? tps=$tps argss=$argss") - None + NoType case Some(argsst) => val args = map2(sym.typeParams, argsst) { (tparam, as0) => val as = as0.distinct @@ -4442,22 +4442,22 @@ trait Types } } } - if (args contains NoType) None - else Some(existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args))) + if (args contains NoType) NoType + else existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args)) } } catch { - case ex: MalformedType => None + case ex: MalformedType => NoType } case SingleType(_, sym) :: rest => val pres = tps map (_.prefix) val pre = if (variance.isPositive) lub(pres, depth) else glb(pres, depth) - try { - Some(singleType(pre, sym)) - } catch { - case ex: MalformedType => None - } + try singleType(pre, sym) + catch { case ex: MalformedType => NoType } case ExistentialType(tparams, quantified) :: rest => - mergePrefixAndArgs(quantified :: rest, variance, depth) map (existentialAbstraction(tparams, _)) + mergePrefixAndArgs(quantified :: rest, variance, depth) match { + case NoType => NoType + case tpe => existentialAbstraction(tparams, tpe) + } case _ => abort(s"mergePrefixAndArgs($tps, $variance, $depth): unsupported tps") } diff --git a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala index 0a7a2a127c..1d3c6b0f23 100644 --- a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala +++ b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala @@ -125,8 +125,8 @@ private[internal] trait GlbLubs { } val tails = tsBts map (_.tail) mergePrefixAndArgs(elimSub(ts1, depth) map elimHigherOrderTypeParam, Covariant, depth) match { - case Some(tp) => loop(tp :: pretypes, tails) - case _ => loop(pretypes, tails) + case NoType => loop(pretypes, tails) + case tp => loop(tp :: pretypes, tails) } } else { |