@@ -693,28 +693,21 @@ trait Types extends api.Types { self: SymbolTable =>
693693 * = Int
694694 */
695695 def asSeenFrom (pre : Type , clazz : Symbol ): Type = {
696- if (isTrivial || phase.erasedTypes && pre.typeSymbol != ArrayClass ) this
697- else {
698- // scala.tools.nsc.util.trace.when(pre.isInstanceOf[ExistentialType])("X "+this+".asSeenfrom("+pre+","+clazz+" = ")
699- Statistics .incCounter(asSeenFromCount)
700- val start = Statistics .pushTimer(typeOpsStack, asSeenFromNanos)
701- val pre1 = pre.normalize
702-
703- val result : Type = (
704- if (pre1.isTrivial && (clazz.isPackageClass || ! clazz.isClass)) this
705- else {
706- val m = new AsSeenFromMap (pre1, clazz)
707- val tp = m apply this
708- val tp1 = existentialAbstraction(m.capturedParams, tp)
709- if (m.capturedSkolems.isEmpty) tp1
710- else deriveType(m.capturedSkolems, _.cloneSymbol setFlag CAPTURED )(tp1)
711- }
696+ TypesStats .timedTypeOp(asSeenFromNanos) {
697+ val trivial = (
698+ this .isTrivial
699+ || phase.erasedTypes && pre.typeSymbol != ArrayClass
700+ || pre.normalize.isTrivial && ! isPossiblePrefix(clazz)
712701 )
713- Statistics .popTimer(typeOpsStack, start)
714- if ((result ne this ) && pre1.isTrivial)
715- debuglog(s " asSeenFrom( $pre1, $clazz) \n old: ${this }\n new: $result" )
702+ if (trivial) this
703+ else {
704+ val m = new AsSeenFromMap (pre.normalize, clazz)
705+ val tp = m(this )
706+ val tp1 = existentialAbstraction(m.capturedParams, tp)
716707
717- result
708+ if (m.capturedSkolems.isEmpty) tp1
709+ else deriveType(m.capturedSkolems, _.cloneSymbol setFlag CAPTURED )(tp1)
710+ }
718711 }
719712 }
720713
@@ -4265,15 +4258,21 @@ trait Types extends api.Types { self: SymbolTable =>
42654258
42664259 def singletonBounds (hi : Type ) = TypeBounds .upper(intersectionType(List (hi, SingletonClass .tpe)))
42674260
4261+ /** Might the given symbol be important when calculating the prefix
4262+ * of a type? When tp.asSeenFrom(pre, clazz) is called on `tp`,
4263+ * the result will be `tp` unchanged if `pre` is trivial and `clazz`
4264+ * is a symbol such that isPossiblePrefix(clazz) == false.
4265+ */
4266+ def isPossiblePrefix (clazz : Symbol ) = clazz.isClass && ! clazz.isPackageClass
4267+
42684268 /** A map to compute the asSeenFrom method */
42694269 class AsSeenFromMap (pre : Type , clazz : Symbol ) extends TypeMap with KeepOnlyTypeConstraints {
42704270 var capturedSkolems : List [Symbol ] = List ()
42714271 var capturedParams : List [Symbol ] = List ()
42724272
42734273 @ inline private def skipPrefixOf (pre : Type , clazz : Symbol ) = (
4274- (pre eq NoType ) || (pre eq NoPrefix ) || ! clazz.isClass
4274+ (pre eq NoType ) || (pre eq NoPrefix ) || ! isPossiblePrefix( clazz)
42754275 )
4276-
42774276 override def mapOver (tree : Tree , giveup : ()=> Nothing ): Tree = {
42784277 object annotationArgRewriter extends TypeMapTransformer {
42794278 private def canRewriteThis (sym : Symbol ) = (
@@ -6922,4 +6921,10 @@ object TypesStats {
69226921 val typerefBaseTypeSeqCount = Statistics .newSubCounter(" of which for typerefs" , baseTypeSeqCount)
69236922 val singletonBaseTypeSeqCount = Statistics .newSubCounter(" of which for singletons" , baseTypeSeqCount)
69246923 val typeOpsStack = Statistics .newTimerStack()
6924+
6925+ @ inline final def timedTypeOp [T ](c : Statistics .StackableTimer )(op : => T ): T = {
6926+ val start = Statistics .pushTimer(typeOpsStack, c)
6927+ try op
6928+ finally Statistics .popTimer(typeOpsStack, start)
6929+ }
69256930}
0 commit comments