@@ -4966,41 +4966,57 @@ object Types {
49664966 }
49674967
49684968 class TypeSizeAccumulator (implicit ctx : Context ) extends TypeAccumulator [Int ] {
4969- def apply (n : Int , tp : Type ): Int = tp match {
4970- case tp : AppliedType =>
4971- foldOver(n + 1 , tp)
4972- case tp : RefinedType =>
4973- foldOver(n + 1 , tp)
4974- case tp : TypeRef if tp.info.isTypeAlias =>
4975- apply(n, tp.superType)
4976- case tp : TypeParamRef =>
4977- apply(n, ctx.typeComparer.bounds(tp))
4978- case _ =>
4979- foldOver(n, tp)
4969+ val seen : util.HashSet [Type ] = new util.HashSet [Type ](64 ) {
4970+ override def hash (x : Type ): Int = System .identityHashCode(x)
4971+ override def isEqual (x : Type , y : Type ) = x.eq(y)
4972+ }
4973+ def apply (n : Int , tp : Type ): Int =
4974+ if (seen contains tp) n
4975+ else {
4976+ seen.addEntry(tp)
4977+ tp match {
4978+ case tp : AppliedType =>
4979+ foldOver(n + 1 , tp)
4980+ case tp : RefinedType =>
4981+ foldOver(n + 1 , tp)
4982+ case tp : TypeRef if tp.info.isTypeAlias =>
4983+ apply(n, tp.superType)
4984+ case tp : TypeParamRef if ! seen(tp) =>
4985+ apply(n, ctx.typeComparer.bounds(tp))
4986+ case _ =>
4987+ foldOver(n, tp)
4988+ }
49804989 }
49814990 }
49824991
49834992 class CoveringSetAccumulator (implicit ctx : Context ) extends TypeAccumulator [Set [Symbol ]] {
4993+ val seen : util.HashSet [Type ] = new util.HashSet [Type ](64 ) {
4994+ override def hash (x : Type ): Int = System .identityHashCode(x)
4995+ override def isEqual (x : Type , y : Type ) = x.eq(y)
4996+ }
49844997 def apply (cs : Set [Symbol ], tp : Type ): Set [Symbol ] = {
4985- val sym = tp.typeSymbol
4986- tp match {
4987- case tp if tp.isTopType || tp.isBottomType =>
4988- cs
4989- case tp : AppliedType =>
4990- foldOver(cs + sym, tp)
4991- case tp : RefinedType =>
4992- foldOver(cs + sym, tp)
4993- case tp : TypeRef if tp.info.isTypeAlias =>
4994- apply(cs, tp.superType)
4995- case tp : TypeRef if sym.isClass =>
4996- foldOver(cs + sym, tp)
4997- case tp : TermRef =>
4998- val tsym = if (tp.termSymbol.is(Param )) tp.underlying.typeSymbol else tp.termSymbol
4999- foldOver(cs + tsym, tp)
5000- case tp : TypeParamRef =>
5001- apply(cs, ctx.typeComparer.bounds(tp))
5002- case other =>
5003- foldOver(cs, tp)
4998+ if (seen contains tp) cs
4999+ else {
5000+ seen.addEntry(tp)
5001+ tp match {
5002+ case tp if tp.isTopType || tp.isBottomType =>
5003+ cs
5004+ case tp : AppliedType =>
5005+ foldOver(cs + tp.typeSymbol, tp)
5006+ case tp : RefinedType =>
5007+ foldOver(cs + tp.typeSymbol, tp)
5008+ case tp : TypeRef if tp.info.isTypeAlias =>
5009+ apply(cs, tp.superType)
5010+ case tp : TypeRef if tp.typeSymbol.isClass =>
5011+ foldOver(cs + tp.typeSymbol, tp)
5012+ case tp : TermRef =>
5013+ val tsym = if (tp.termSymbol.is(Param )) tp.underlying.typeSymbol else tp.termSymbol
5014+ foldOver(cs + tsym, tp)
5015+ case tp : TypeParamRef =>
5016+ apply(cs, ctx.typeComparer.bounds(tp))
5017+ case other =>
5018+ foldOver(cs, tp)
5019+ }
50045020 }
50055021 }
50065022 }
0 commit comments