@@ -293,7 +293,7 @@ trait Types extends api.Types { self: SymbolTable =>
293293 case SuperType (_, _) => false
294294 case SingleType (pre, sym) => notConcreteSym(sym)
295295 case ConstantType (_) => false
296- case TypeRef (_, sym, args) => notConcreteSym(sym) || (args exists (arg => notConcreteTpe(arg)) )
296+ case TypeRef (_, sym, args) => notConcreteSym(sym) || (args exists notConcreteTpe)
297297 case RefinedType (_, _) => false
298298 case ExistentialType (_, _) => false
299299 case AnnotatedType (_, tp, _) => notConcreteTpe(tp)
@@ -343,9 +343,9 @@ trait Types extends api.Types { self: SymbolTable =>
343343 */
344344 def isImmediatelyDependent : Boolean = false
345345
346- /** Does this depend on an enclosing method parameter ? */
347- def isDependent : Boolean = IsDependentCollector .collect( this )
348-
346+ /** Is this type a dependent method type ? */
347+ def isDependentMethodType : Boolean = false
348+
349349 /** True for WildcardType or BoundedWildcardType. */
350350 def isWildcard = false
351351
@@ -1579,10 +1579,10 @@ trait Types extends api.Types { self: SymbolTable =>
15791579 }
15801580
15811581 override def narrow : Type = typeSymbol.thisType
1582- override def isNotNull : Boolean = parents exists (_.isNotNull)
1582+ override def isNotNull : Boolean = parents exists typeIsNotNull
15831583
15841584 override def isStructuralRefinement : Boolean =
1585- typeSymbol.isAnonOrRefinementClass && decls. exists(_.isPossibleInRefinement )
1585+ typeSymbol.isAnonOrRefinementClass && ( decls exists symbolIsPossibleInRefinement )
15861586
15871587 // override def isNullable: Boolean =
15881588 // parents forall (p => p.isNullable && !p.typeSymbol.isAbstractType);
@@ -1598,7 +1598,7 @@ trait Types extends api.Types { self: SymbolTable =>
15981598 if (period != currentPeriod) {
15991599 tpe.baseTypeSeqPeriod = currentPeriod
16001600 if (! isValidForBaseClasses(period)) {
1601- if (tpe.parents. exists(_.exists(_. isInstanceOf [ TypeVar ])) ) {
1601+ if (tpe.parents exists typeContainsTypeVar ) {
16021602 // rename type vars to fresh type params, take base type sequence of
16031603 // resulting type, and rename back all the entries in that sequence
16041604 var tvs = Set [TypeVar ]()
@@ -2399,7 +2399,7 @@ trait Types extends api.Types { self: SymbolTable =>
23992399 private def needsPreString = (
24002400 settings.debug.value
24012401 || ! shorthands(sym.fullName)
2402- || sym.ownerChain. exists(s => ! s.isClass)
2402+ || ( sym.ownersIterator exists (s => ! s.isClass) )
24032403 )
24042404 private def preString = if (needsPreString) pre.prefixString else " "
24052405 private def argsString = if (args.isEmpty) " " else args.mkString(" [" , " ," , " ]" )
@@ -2530,7 +2530,7 @@ trait Types extends api.Types { self: SymbolTable =>
25302530 resultType.isTrivial && (resultType eq resultType.withoutAnnotations)
25312531
25322532 private def isTrivialParam (p : Symbol ) =
2533- p.tpe.isTrivial && ! (params.exists(_.tpe contains p) || (resultType contains p) )
2533+ p.tpe.isTrivial && ! typesContain(paramTypes, p) && ! (resultType contains p)
25342534
25352535 def isImplicit = params.nonEmpty && params.head.isImplicit
25362536 def isJava = false // can we do something like for implicits? I.e. do Java methods without parameters need to be recognized?
@@ -2546,13 +2546,15 @@ trait Types extends api.Types { self: SymbolTable =>
25462546
25472547 override def resultType (actuals : List [Type ]) =
25482548 if (isTrivial || phase.erasedTypes) resultType
2549- else if (sameLength(actuals, params)) {
2549+ else if (/* isDependentMethodType && */ sameLength(actuals, params)) {
25502550 val idm = new InstantiateDependentMap (params, actuals)
25512551 val res = idm(resultType)
25522552 existentialAbstraction(idm.existentialsNeeded, res)
25532553 }
25542554 else existentialAbstraction(params, resultType)
25552555
2556+ override lazy val isDependentMethodType : Boolean = IsDependentCollector .collect(resultType)
2557+
25562558 // implicit args can only be depended on in result type:
25572559 // TODO this may be generalised so that the only constraint is dependencies are acyclic
25582560 def approximate : MethodType = MethodType (params, resultApprox)
@@ -2567,7 +2569,7 @@ trait Types extends api.Types { self: SymbolTable =>
25672569 }
25682570
25692571 override def atOwner (owner : Symbol ) =
2570- if ((params exists (_. owner != owner) ) || (resultType.atOwner(owner) ne resultType))
2572+ if (! allSymbolsHaveOwner (params, owner) || (resultType.atOwner(owner) ne resultType))
25712573 cloneInfo(owner)
25722574 else
25732575 this
@@ -2655,7 +2657,7 @@ trait Types extends api.Types { self: SymbolTable =>
26552657 }
26562658
26572659 override def atOwner (owner : Symbol ) =
2658- if ((typeParams exists (_. owner != owner) ) || (resultType.atOwner(owner) ne resultType))
2660+ if (! allSymbolsHaveOwner (typeParams, owner) || (resultType.atOwner(owner) ne resultType))
26592661 cloneInfo(owner)
26602662 else
26612663 this
@@ -2759,7 +2761,7 @@ trait Types extends api.Types { self: SymbolTable =>
27592761 createFromClonedSymbolsAtOwner(quantified, owner, underlying)(newExistentialType)
27602762
27612763 override def atOwner (owner : Symbol ) =
2762- if (quantified exists (_.owner != owner)) cloneInfo(owner) else this
2764+ if (! allSymbolsHaveOwner(quantified, owner)) cloneInfo(owner) else this
27632765
27642766 override def kind = " ExistentialType"
27652767
@@ -2870,7 +2872,7 @@ trait Types extends api.Types { self: SymbolTable =>
28702872 * any results.
28712873 */
28722874 if (propagateParameterBoundsToTypeVars) {
2873- val exclude = bounds.isEmptyBounds || bounds. exists(_.typeSymbolDirect.isNonClassType )
2875+ val exclude = bounds.isEmptyBounds || ( bounds exists typeIsNonClassType )
28742876
28752877 if (exclude) new TypeConstraint
28762878 else TypeVar .trace(" constraint" , " For " + tparam.fullLocationString)(new TypeConstraint (bounds))
@@ -2916,13 +2918,12 @@ trait Types extends api.Types { self: SymbolTable =>
29162918 if (tp == NoType ) tp
29172919 else existentialAbstraction(existentialsInType(tp), tp)
29182920 )
2921+
29192922 def containsExistential (tpe : Type ) =
2920- tpe exists (_.typeSymbol.isExistentiallyBound)
2923+ tpe exists typeIsExistentiallyBound
29212924
2922- def existentialsInType (tpe : Type ) = (
2923- for (tp <- tpe ; if tp.typeSymbol.isExistentiallyBound) yield
2924- tp.typeSymbol
2925- )
2925+ def existentialsInType (tpe : Type ) =
2926+ tpe withFilter typeIsExistentiallyBound map typeSymbolOfType
29262927
29272928 /** Precondition: params.nonEmpty. (args.nonEmpty enforced structurally.)
29282929 */
@@ -4479,7 +4480,7 @@ trait Types extends api.Types { self: SymbolTable =>
44794480 if (sameLength(basesym.typeParams, baseargs))
44804481 instParam(basesym.typeParams, baseargs)
44814482 else
4482- if (symclazz.tpe.parents. exists(_.isErroneous) )
4483+ if (symclazz.tpe.parents exists typeIsErroneous )
44834484 ErrorType // don't be to overzealous with throwing exceptions, see #2641
44844485 else
44854486 throw new Error (
@@ -4530,7 +4531,7 @@ trait Types extends api.Types { self: SymbolTable =>
45304531 else subst(tp, sym, from.tail, to.tail)
45314532
45324533 val boundSyms = tp0.boundSyms
4533- val tp1 = if (boundSyms exists from.contains) renameBoundSyms(tp0) else tp0
4534+ val tp1 = if (boundSyms.nonEmpty && (boundSyms exists from.contains) ) renameBoundSyms(tp0) else tp0
45344535 val tp = mapOver(tp1)
45354536
45364537 tp match {
@@ -4671,6 +4672,8 @@ trait Types extends api.Types { self: SymbolTable =>
46714672 else mapOver(tp)
46724673 }
46734674
4675+ /** Note: This map is needed even for non-dependent method types, despite what the name might imply.
4676+ */
46744677 class InstantiateDependentMap (params : List [Symbol ], actuals0 : List [Type ]) extends TypeMap with KeepOnlyTypeConstraints {
46754678 private val actuals = actuals0.toIndexedSeq
46764679 private val existentials = new Array [Symbol ](actuals.size)
@@ -5897,9 +5900,17 @@ trait Types extends api.Types { self: SymbolTable =>
58975900
58985901 def specializesSym (tp : Type , sym : Symbol , depth : Int ): Boolean =
58995902 tp.typeSymbol == NothingClass ||
5900- tp.typeSymbol == NullClass && containsNull(sym.owner) ||
5901- (tp.nonPrivateMember(sym.name).alternatives exists
5902- (alt => sym == alt || specializesSym(tp.narrow, alt, sym.owner.thisType, sym, depth)))
5903+ tp.typeSymbol == NullClass && containsNull(sym.owner) || {
5904+ def specializedBy (membr : Symbol ): Boolean =
5905+ membr == sym || specializesSym(tp.narrow, membr, sym.owner.thisType, sym, depth)
5906+ val member = tp.nonPrivateMember(sym.name)
5907+ if (member eq NoSymbol ) false
5908+ else if (member.isOverloaded) member.alternatives exists specializedBy
5909+ else specializedBy(member)
5910+ // was
5911+ // (tp.nonPrivateMember(sym.name).alternatives exists
5912+ // (alt => sym == alt || specializesSym(tp.narrow, alt, sym.owner.thisType, sym, depth)))
5913+ }
59035914
59045915 /** Does member `sym1` of `tp1` have a stronger type
59055916 * than member `sym2` of `tp2`?
@@ -6145,9 +6156,9 @@ trait Types extends api.Types { self: SymbolTable =>
61456156 */
61466157 def isWithinBounds (pre : Type , owner : Symbol , tparams : List [Symbol ], targs : List [Type ]): Boolean = {
61476158 var bounds = instantiatedBounds(pre, owner, tparams, targs)
6148- if (targs. exists(_.annotations.nonEmpty) )
6159+ if (targs exists typeHasAnnotations )
61496160 bounds = adaptBoundsToAnnotations(bounds, tparams, targs)
6150- (bounds corresponds targs)(_ containsType _ )
6161+ (bounds corresponds targs)(boundsContainType )
61516162 }
61526163
61536164 def instantiatedBounds (pre : Type , owner : Symbol , tparams : List [Symbol ], targs : List [Type ]): List [TypeBounds ] =
@@ -6225,7 +6236,7 @@ trait Types extends api.Types { self: SymbolTable =>
62256236 def loop (tsBts : List [List [Type ]]): List [Type ] = {
62266237 lubListDepth += 1
62276238
6228- if (tsBts.isEmpty || tsBts. exists(_.isEmpty )) Nil
6239+ if (tsBts.isEmpty || ( tsBts exists typeListIsEmpty )) Nil
62296240 else if (tsBts.tail.isEmpty) tsBts.head
62306241 else {
62316242 // ts0 is the 1-dimensional frontier of symbols cutting through 2-dimensional tsBts.
@@ -6307,10 +6318,12 @@ trait Types extends api.Types { self: SymbolTable =>
63076318 * of some other element of the list. */
63086319 private def elimSuper (ts : List [Type ]): List [Type ] = ts match {
63096320 case List () => List ()
6321+ case List (t) => List (t)
63106322 case t :: ts1 =>
63116323 val rest = elimSuper(ts1 filter (t1 => ! (t <:< t1)))
63126324 if (rest exists (t1 => t1 <:< t)) rest else t :: rest
63136325 }
6326+
63146327 def elimAnonymousClass (t : Type ) = t match {
63156328 case TypeRef (pre, clazz, Nil ) if clazz.isAnonymousClass =>
63166329 clazz.classBound.asSeenFrom(pre, clazz.owner)
@@ -6327,6 +6340,7 @@ trait Types extends api.Types { self: SymbolTable =>
63276340 private def elimSub (ts : List [Type ], depth : Int ): List [Type ] = {
63286341 def elimSub0 (ts : List [Type ]): List [Type ] = ts match {
63296342 case List () => List ()
6343+ case List (t) => List (t)
63306344 case t :: ts1 =>
63316345 val rest = elimSub0(ts1 filter (t1 => ! isSubType(t1, t, decr(depth))))
63326346 if (rest exists (t1 => isSubType(t, t1, decr(depth)))) rest else t :: rest
@@ -6360,7 +6374,7 @@ trait Types extends api.Types { self: SymbolTable =>
63606374
63616375 def weakLub (ts : List [Type ]) =
63626376 if (ts.nonEmpty && (ts forall isNumericValueType)) (numericLub(ts), true )
6363- else if (ts.nonEmpty && (ts exists (_.annotations.nonEmpty)) )
6377+ else if (ts exists typeHasAnnotations )
63646378 (annotationsLub(lub(ts map (_.withoutAnnotations)), ts), true )
63656379 else (lub(ts), false )
63666380
@@ -6369,7 +6383,7 @@ trait Types extends api.Types { self: SymbolTable =>
63696383 val nglb = numericGlb(ts)
63706384 if (nglb != NoType ) (nglb, true )
63716385 else (glb(ts), false )
6372- } else if (ts.nonEmpty && (ts exists (_.annotations.nonEmpty)) ) {
6386+ } else if (ts exists typeHasAnnotations ) {
63736387 (annotationsGlb(glb(ts map (_.withoutAnnotations)), ts), true )
63746388 } else (glb(ts), false )
63756389 }
@@ -6554,7 +6568,7 @@ trait Types extends api.Types { self: SymbolTable =>
65546568 indent = indent stripSuffix " "
65556569 println(indent + " lub of " + ts + " is " + res)// debug
65566570 }
6557- if (ts forall (_.isNotNull) ) res.notNull else res
6571+ if (ts forall typeIsNotNull ) res.notNull else res
65586572 }
65596573
65606574 val GlbFailure = new Throwable
@@ -6700,7 +6714,7 @@ trait Types extends api.Types { self: SymbolTable =>
67006714
67016715 // if (settings.debug.value) { indent = indent.substring(0, indent.length() - 2); log(indent + "glb of " + ts + " is " + res) }//DEBUG
67026716
6703- if (ts exists (_.isNotNull) ) res.notNull else res
6717+ if (ts exists typeIsNotNull ) res.notNull else res
67046718 }
67056719
67066720 /** A list of the typevars in a type. */
@@ -6742,7 +6756,7 @@ trait Types extends api.Types { self: SymbolTable =>
67426756 // special treatment for lubs of array types after erasure:
67436757 // if argss contain one value type and some other type, the lub is Object
67446758 // if argss contain several reference types, the lub is an array over lub of argtypes
6745- if (argss exists (_.isEmpty) ) {
6759+ if (argss exists typeListIsEmpty ) {
67466760 None // something is wrong: an array without a type arg.
67476761 } else {
67486762 val args = argss map (_.head)
@@ -6935,7 +6949,7 @@ trait Types extends api.Types { self: SymbolTable =>
69356949 }
69366950 // Add serializable to a list of parents, unless one of them already is
69376951 def addSerializable (ps : Type * ): List [Type ] = (
6938- if (ps exists (_ <:< SerializableClass .tpe) ) ps.toList
6952+ if (ps exists typeIsSubTypeOfSerializable ) ps.toList
69396953 else (ps :+ SerializableClass .tpe).toList
69406954 )
69416955
@@ -6976,6 +6990,33 @@ trait Types extends api.Types { self: SymbolTable =>
69766990 tostringRecursions -= 1
69776991 }
69786992
6993+ // ----- Hoisted closures and convenience methods, for compile time reductions -------
6994+
6995+ private val typeIsNotNull = (tp : Type ) => tp.isNotNull
6996+ private val symbolIsPossibleInRefinement = (sym : Symbol ) => sym.isPossibleInRefinement
6997+ private val isTypeVar = (tp : Type ) => tp.isInstanceOf [TypeVar ]
6998+ private val typeContainsTypeVar = (tp : Type ) => tp exists isTypeVar
6999+ private val typeIsNonClassType = (tp : Type ) => tp.typeSymbolDirect.isNonClassType
7000+ private val typeIsExistentiallyBound = (tp : Type ) => tp.typeSymbol.isExistentiallyBound
7001+ private val typeSymbolOfType = (tp : Type ) => tp.typeSymbol
7002+ private val typeIsErroneous = (tp : Type ) => tp.isErroneous
7003+ private val typeHasAnnotations = (tp : Type ) => tp.annotations.nonEmpty
7004+ private val boundsContainType = (bounds : TypeBounds , tp : Type ) => bounds containsType tp
7005+ private val typeListIsEmpty = (ts : List [Type ]) => ts.isEmpty
7006+ private val typeIsSubTypeOfSerializable = (tp : Type ) => tp <:< SerializableClass .tpe
7007+
7008+ @ tailrec private def typesContain (tps : List [Type ], sym : Symbol ): Boolean = tps match {
7009+ case tp :: rest => (tp contains sym) || typesContain(rest, sym)
7010+ case _ => false
7011+ }
7012+
7013+ @ tailrec private def allSymbolsHaveOwner (syms : List [Symbol ], owner : Symbol ): Boolean = syms match {
7014+ case sym :: rest => sym.owner == owner && allSymbolsHaveOwner(rest, owner)
7015+ case _ => true
7016+ }
7017+
7018+ // -------------- Classtags --------------------------------------------------------
7019+
69797020 implicit val AnnotatedTypeTag = ClassTag [AnnotatedType ](classOf [AnnotatedType ])
69807021 implicit val BoundedWildcardTypeTag = ClassTag [BoundedWildcardType ](classOf [BoundedWildcardType ])
69817022 implicit val ClassInfoTypeTag = ClassTag [ClassInfoType ](classOf [ClassInfoType ])
@@ -6994,7 +7035,10 @@ trait Types extends api.Types { self: SymbolTable =>
69947035 implicit val TypeRefTag = ClassTag [TypeRef ](classOf [TypeRef ])
69957036 implicit val TypeTagg = ClassTag [Type ](classOf [Type ])
69967037
7038+ // -------------- Statistics --------------------------------------------------------
7039+
69977040 Statistics .newView(" #unique types" ) { if (uniques == null ) 0 else uniques.size }
7041+
69987042}
69997043
70007044object TypesStats {
0 commit comments