Skip to content

Commit 45d6177

Browse files
committed
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.
1 parent 04837e7 commit 45d6177

File tree

10 files changed

+69
-67
lines changed

10 files changed

+69
-67
lines changed

src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,9 +1270,9 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
12701270
private def getSuperInterfaces(c: IClass): Array[String] = {
12711271

12721272
// Additional interface parents based on annotations and other cues
1273-
def newParentForAttr(attr: Symbol): Option[Symbol] = attr match {
1274-
case RemoteAttr => Some(RemoteInterfaceClass)
1275-
case _ => None
1273+
def newParentForAttr(ann: AnnotationInfo): Symbol = ann.symbol match {
1274+
case RemoteAttr => RemoteInterfaceClass
1275+
case _ => NoSymbol
12761276
}
12771277

12781278
/* Drop redundant interfaces (ones which are implemented by some other parent) from the immediate parents.
@@ -1295,7 +1295,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
12951295

12961296
val ps = c.symbol.info.parents
12971297
val superInterfaces0: List[Symbol] = if(ps.isEmpty) Nil else c.symbol.mixinClasses
1298-
val superInterfaces = (superInterfaces0 ++ c.symbol.annotations.flatMap(ann => newParentForAttr(ann.symbol))).distinct
1298+
val superInterfaces = existingSymbols(superInterfaces0 ++ c.symbol.annotations.map(newParentForAttr)).distinct
12991299

13001300
if(superInterfaces.isEmpty) EMPTY_STRING_ARRAY
13011301
else mkArray(minimizeInterfaces(superInterfaces) map javaName)

src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,9 @@ abstract class SymbolLoaders {
244244
}
245245

246246
class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader with FlagAssigningCompleter {
247-
private object classfileParser extends ClassfileParser {
247+
private object classfileParser extends {
248248
val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
249-
}
249+
} with ClassfileParser
250250

251251
protected def description = "class file "+ classfile.toString
252252

src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ abstract class ClassfileParser {
3939
protected var isScala: Boolean = _ // does class file describe a scala class?
4040
protected var isScalaAnnot: Boolean = _ // does class file describe a scala class with its pickled info in an annotation?
4141
protected var isScalaRaw: Boolean = _ // this class file is a scala class with no pickled info
42-
protected var busy: Option[Symbol] = None // lock to detect recursive reads
42+
protected var busy: Symbol = _ // lock to detect recursive reads
4343
protected var currentClass: Name = _ // JVM name of the current class
4444
protected var classTParams = Map[Name,Symbol]()
4545
protected var srcfile0 : Option[AbstractFile] = None
@@ -90,16 +90,15 @@ abstract class ClassfileParser {
9090
case e: RuntimeException => handleError(e)
9191
}
9292
@inline private def pushBusy[T](sym: Symbol)(body: => T): T = {
93-
busy match {
94-
case Some(`sym`) => throw new IOException(s"unsatisfiable cyclic dependency in '$sym'")
95-
case Some(sym1) => throw new IOException(s"illegal class file dependency between '$sym' and '$sym1'")
96-
case _ => ()
97-
}
93+
if (busy eq sym)
94+
throw new IOException(s"unsatisfiable cyclic dependency in '$sym'")
95+
else if ((busy ne null) && (busy ne NoSymbol))
96+
throw new IOException(s"illegal class file dependency between '$sym' and '$busy'")
9897

99-
busy = Some(sym)
98+
busy = sym
10099
try body
101100
catch parseErrorHandler
102-
finally busy = None
101+
finally busy = NoSymbol
103102
}
104103
@inline private def raiseLoaderLevel[T](body: => T): T = {
105104
loaders.parentsLevel += 1

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,7 +3185,7 @@ trait Typers extends Adaptations with Tags {
31853185
* to that. This is the last thing which is tried (after
31863186
* default arguments)
31873187
*/
3188-
def tryTupleApply: Option[Tree] = (
3188+
def tryTupleApply: Tree = (
31893189
if (eligibleForTupleConversion(paramTypes, argslen) && !phase.erasedTypes) {
31903190
val tupleArgs = List(atPos(tree.pos.makeTransparent)(gen.mkTuple(args)))
31913191
// expected one argument, but got 0 or >1 ==> try applying to tuple
@@ -3194,14 +3194,15 @@ trait Typers extends Adaptations with Tags {
31943194
silent(_.doTypedApply(tree, fun, tupleArgs, mode, pt)) map { t =>
31953195
// Depending on user options, may warn or error here if
31963196
// a Unit or tuple was inserted.
3197-
Some(t) filter (tupledTree =>
3197+
val keepTree = (
31983198
!mode.typingExprNotFun
3199-
|| tupledTree.symbol == null
3200-
|| checkValidAdaptation(tupledTree, args)
3199+
|| t.symbol == null
3200+
|| checkValidAdaptation(t, args)
32013201
)
3202-
} orElse { _ => context.undetparams = savedUndetparams ; None }
3203-
}
3204-
else None
3202+
if (keepTree) t else EmptyTree
3203+
} orElse { _ => context.undetparams = savedUndetparams ; EmptyTree }
3204+
}
3205+
else EmptyTree
32053206
)
32063207

32073208
/* Treats an application which uses named or default arguments.
@@ -3214,15 +3215,15 @@ trait Typers extends Adaptations with Tags {
32143215

32153216
def checkNotMacro() = {
32163217
if (treeInfo.isMacroApplication(fun))
3217-
tryTupleApply getOrElse duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun))
3218+
tryTupleApply orElse duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun))
32183219
}
32193220

32203221
if (mt.isErroneous) duplErrTree
32213222
else if (mode.inPatternMode) {
32223223
// #2064
32233224
duplErrorTree(WrongNumberOfArgsError(tree, fun))
32243225
} else if (lencmp > 0) {
3225-
tryTupleApply getOrElse duplErrorTree(TooManyArgsNamesDefaultsError(tree, fun))
3226+
tryTupleApply orElse duplErrorTree(TooManyArgsNamesDefaultsError(tree, fun))
32263227
} else if (lencmp == 0) {
32273228
// we don't need defaults. names were used, so this application is transformed
32283229
// into a block (@see transformNamedApplication in NamesDefaults)
@@ -3275,7 +3276,7 @@ trait Typers extends Adaptations with Tags {
32753276
if (!(context.diagnostic contains note)) context.diagnostic = note :: context.diagnostic
32763277
doTypedApply(tree, if (blockIsEmpty) fun else fun1, allArgs, mode, pt)
32773278
} else {
3278-
tryTupleApply getOrElse duplErrorTree(NotEnoughArgsError(tree, fun, missing))
3279+
tryTupleApply orElse duplErrorTree(NotEnoughArgsError(tree, fun, missing))
32793280
}
32803281
}
32813282
}
@@ -3311,7 +3312,7 @@ trait Typers extends Adaptations with Tags {
33113312
// instantiate dependent method types, must preserve singleton types where possible (stableTypeFor) -- example use case:
33123313
// val foo = "foo"; def precise(x: String)(y: x.type): x.type = {...}; val bar : foo.type = precise(foo)(foo)
33133314
// precise(foo) : foo.type => foo.type
3314-
val restpe = mt.resultType(args1 map (arg => gen.stableTypeFor(arg) getOrElse arg.tpe))
3315+
val restpe = mt.resultType(args1 map (arg => gen stableTypeFor arg orElse arg.tpe))
33153316
def ifPatternSkipFormals(tp: Type) = tp match {
33163317
case MethodType(_, rtp) if (mode.inPatternMode) => rtp
33173318
case _ => tp
@@ -3729,7 +3730,7 @@ trait Typers extends Adaptations with Tags {
37293730

37303731
/** Compute an existential type from raw hidden symbols `syms` and type `tp`
37313732
*/
3732-
def packSymbols(hidden: List[Symbol], tp: Type): Type = global.packSymbols(hidden, tp, Some(context0.owner))
3733+
def packSymbols(hidden: List[Symbol], tp: Type): Type = global.packSymbols(hidden, tp, context0.owner)
37333734

37343735
def isReferencedFrom(ctx: Context, sym: Symbol): Boolean = (
37353736
ctx.owner.isTerm &&

src/reflect/scala/reflect/internal/BaseTypeSeqs.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,14 @@ trait BaseTypeSeqs {
6666
pending += i
6767
try {
6868
mergePrefixAndArgs(variants, Variance.Contravariant, lubDepth(variants)) match {
69-
case Some(tp0) =>
69+
case NoType => typeError("no common type instance of base types "+(variants mkString ", and ")+" exists.")
70+
case tp0 =>
7071
pending(i) = false
7172
elems(i) = tp0
7273
tp0
73-
case None =>
74-
typeError(
75-
"no common type instance of base types "+(variants mkString ", and ")+" exists.")
7674
}
77-
} catch {
75+
}
76+
catch {
7877
case CyclicInheritance =>
7978
typeError(
8079
"computing the common type instance of base types "+(variants mkString ", and ")+" leads to a cycle.")

src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ trait ExistentialsAndSkolems {
7777
* also replaced, except for term symbols of an Ident tree, where
7878
* only the type of the Ident is changed.
7979
*/
80-
final def existentialTransform[T](rawSyms: List[Symbol], tp: Type, rawOwner: Option[Symbol] = None)(creator: (List[Symbol], Type) => T): T = {
80+
final def existentialTransform[T](rawSyms: List[Symbol], tp: Type, rawOwner: Symbol = NoSymbol)(creator: (List[Symbol], Type) => T): T = {
8181
val allBounds = existentialBoundsExcludingHidden(rawSyms)
8282
val typeParams: List[Symbol] = rawSyms map { sym =>
8383
val name = sym.name match {
8484
case x: TypeName => x
8585
case x => tpnme.singletonName(x)
8686
}
87-
def rawOwner0 = rawOwner.getOrElse(abort(s"no owner provided for existential transform over raw parameter: $sym"))
87+
def rawOwner0 = rawOwner orElse abort(s"no owner provided for existential transform over raw parameter: $sym")
8888
val bound = allBounds(sym)
8989
val sowner = if (isRawParameter(sym)) rawOwner0 else sym.owner
9090
val quantified = sowner.newExistential(name, sym.pos)
@@ -106,7 +106,7 @@ trait ExistentialsAndSkolems {
106106
* @param hidden The original type
107107
* @param rawOwner The owner for Java raw types.
108108
*/
109-
final def packSymbols(hidden: List[Symbol], tp: Type, rawOwner: Option[Symbol] = None): Type =
109+
final def packSymbols(hidden: List[Symbol], tp: Type, rawOwner: Symbol = NoSymbol): Type =
110110
if (hidden.isEmpty) tp
111111
else existentialTransform(hidden, tp, rawOwner)(existentialAbstraction)
112112
}

src/reflect/scala/reflect/internal/Symbols.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3413,6 +3413,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
34133413
*/
34143414
def mapParamss[T](sym: Symbol)(f: Symbol => T): List[List[T]] = mmap(sym.info.paramss)(f)
34153415

3416+
def existingSymbols(syms: List[Symbol]): List[Symbol] =
3417+
syms filter (s => (s ne null) && (s ne NoSymbol))
3418+
34163419
/** Return closest enclosing method, unless shadowed by an enclosing class. */
34173420
// TODO Move back to ExplicitOuter when the other call site is removed.
34183421
// no use of closures here in the interest of speed.

src/reflect/scala/reflect/internal/TreeGen.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,20 +137,20 @@ abstract class TreeGen extends macros.TreeBuilder {
137137

138138
/** Replaces tree type with a stable type if possible */
139139
def stabilize(tree: Tree): Tree = stableTypeFor(tree) match {
140-
case Some(tp) => tree setType tp
141-
case _ => tree
140+
case NoType => tree
141+
case tp => tree setType tp
142142
}
143143

144144
/** Computes stable type for a tree if possible */
145-
def stableTypeFor(tree: Tree): Option[Type] =
146-
if (treeInfo.admitsTypeSelection(tree))
147-
tree match {
148-
case This(_) => Some(ThisType(tree.symbol))
149-
case Ident(_) => Some(singleType(tree.symbol.owner.thisType, tree.symbol))
150-
case Select(qual, _) => Some(singleType(qual.tpe, tree.symbol))
151-
case _ => None
152-
}
153-
else None
145+
def stableTypeFor(tree: Tree): Type = (
146+
if (!treeInfo.admitsTypeSelection(tree)) NoType
147+
else tree match {
148+
case This(_) => ThisType(tree.symbol)
149+
case Ident(_) => singleType(tree.symbol.owner.thisType, tree.symbol)
150+
case Select(qual, _) => singleType(qual.tpe, tree.symbol)
151+
case _ => NoType
152+
}
153+
)
154154

155155
/** Builds a reference with stable type to given symbol */
156156
def mkAttributedStableRef(pre: Type, sym: Symbol): Tree =

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4380,12 +4380,11 @@ trait Types
43804380
/** Compute lub (if `variance == Covariant`) or glb (if `variance == Contravariant`) of given list
43814381
* of types `tps`. All types in `tps` are typerefs or singletypes
43824382
* with the same symbol.
4383-
* Return `Some(x)` if the computation succeeds with result `x`.
4384-
* Return `None` if the computation fails.
4383+
* Return `x` if the computation succeeds with result `x`.
4384+
* Return `NoType` if the computation fails.
43854385
*/
4386-
def mergePrefixAndArgs(tps: List[Type], variance: Variance, depth: Int): Option[Type] = tps match {
4387-
case List(tp) =>
4388-
Some(tp)
4386+
def mergePrefixAndArgs(tps: List[Type], variance: Variance, depth: Int): Type = tps match {
4387+
case tp :: Nil => tp
43894388
case TypeRef(_, sym, _) :: rest =>
43904389
val pres = tps map (_.prefix) // prefix normalizes automatically
43914390
val pre = if (variance.isPositive) lub(pres, depth) else glb(pres, depth)
@@ -4397,12 +4396,13 @@ trait Types
43974396
// if argss contain one value type and some other type, the lub is Object
43984397
// if argss contain several reference types, the lub is an array over lub of argtypes
43994398
if (argss exists typeListIsEmpty) {
4400-
None // something is wrong: an array without a type arg.
4401-
} else {
4399+
NoType // something is wrong: an array without a type arg.
4400+
}
4401+
else {
44024402
val args = argss map (_.head)
4403-
if (args.tail forall (_ =:= args.head)) Some(typeRef(pre, sym, List(args.head)))
4404-
else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) Some(ObjectTpe)
4405-
else Some(typeRef(pre, sym, List(lub(args))))
4403+
if (args.tail forall (_ =:= args.head)) typeRef(pre, sym, List(args.head))
4404+
else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) ObjectTpe
4405+
else typeRef(pre, sym, List(lub(args)))
44064406
}
44074407
}
44084408
else transposeSafe(argss) match {
@@ -4411,7 +4411,7 @@ trait Types
44114411
// catching just in case (shouldn't happen, but also doesn't cost us)
44124412
// [JZ] It happens: see SI-5683.
44134413
debuglog(s"transposed irregular matrix!? tps=$tps argss=$argss")
4414-
None
4414+
NoType
44154415
case Some(argsst) =>
44164416
val args = map2(sym.typeParams, argsst) { (tparam, as0) =>
44174417
val as = as0.distinct
@@ -4442,22 +4442,22 @@ trait Types
44424442
}
44434443
}
44444444
}
4445-
if (args contains NoType) None
4446-
else Some(existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args)))
4445+
if (args contains NoType) NoType
4446+
else existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args))
44474447
}
44484448
} catch {
4449-
case ex: MalformedType => None
4449+
case ex: MalformedType => NoType
44504450
}
44514451
case SingleType(_, sym) :: rest =>
44524452
val pres = tps map (_.prefix)
44534453
val pre = if (variance.isPositive) lub(pres, depth) else glb(pres, depth)
4454-
try {
4455-
Some(singleType(pre, sym))
4456-
} catch {
4457-
case ex: MalformedType => None
4458-
}
4454+
try singleType(pre, sym)
4455+
catch { case ex: MalformedType => NoType }
44594456
case ExistentialType(tparams, quantified) :: rest =>
4460-
mergePrefixAndArgs(quantified :: rest, variance, depth) map (existentialAbstraction(tparams, _))
4457+
mergePrefixAndArgs(quantified :: rest, variance, depth) match {
4458+
case NoType => NoType
4459+
case tpe => existentialAbstraction(tparams, tpe)
4460+
}
44614461
case _ =>
44624462
abort(s"mergePrefixAndArgs($tps, $variance, $depth): unsupported tps")
44634463
}

src/reflect/scala/reflect/internal/tpe/GlbLubs.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ private[internal] trait GlbLubs {
125125
}
126126
val tails = tsBts map (_.tail)
127127
mergePrefixAndArgs(elimSub(ts1, depth) map elimHigherOrderTypeParam, Covariant, depth) match {
128-
case Some(tp) => loop(tp :: pretypes, tails)
129-
case _ => loop(pretypes, tails)
128+
case NoType => loop(pretypes, tails)
129+
case tp => loop(tp :: pretypes, tails)
130130
}
131131
}
132132
else {

0 commit comments

Comments
 (0)