@@ -106,7 +106,7 @@ object Types {
106
106
final def isValueTypeOrLambda : Boolean = isValueType || this .isInstanceOf [PolyType ]
107
107
108
108
/** Does this type denote a stable reference (i.e. singleton type)? */
109
- final def isStable (implicit ctx : Context ): Boolean = stripTypeVar match {
109
+ @ tailrec final def isStable (implicit ctx : Context ): Boolean = stripTypeVar match {
110
110
case tp : TermRef => tp.termSymbol.isStable && tp.prefix.isStable
111
111
case _ : SingletonType | NoPrefix => true
112
112
case tp : RefinedOrRecType => tp.parent.isStable
@@ -154,16 +154,16 @@ object Types {
154
154
155
155
/** Is this type an instance of a non-bottom subclass of the given class `cls`? */
156
156
final def derivesFrom (cls : Symbol )(implicit ctx : Context ): Boolean = {
157
- def loop (tp : Type ) = tp match {
157
+ def loop (tp : Type ): Boolean = tp match {
158
158
case tp : TypeRef =>
159
159
val sym = tp.symbol
160
- if (sym.isClass) sym.derivesFrom(cls) else tp.superType.derivesFrom(cls)
160
+ if (sym.isClass) sym.derivesFrom(cls) else loop( tp.superType) : @ tailrec
161
161
case tp : TypeProxy =>
162
- tp.underlying.derivesFrom(cls)
162
+ loop( tp.underlying) : @ tailrec
163
163
case tp : AndType =>
164
- tp.tp1.derivesFrom(cls ) || tp.tp2.derivesFrom(cls)
164
+ loop( tp.tp1) || loop( tp.tp2) : @ tailrec
165
165
case tp : OrType =>
166
- tp.tp1.derivesFrom(cls ) && tp.tp2.derivesFrom(cls)
166
+ loop( tp.tp1) && loop( tp.tp2) : @ tailrec
167
167
case tp : JavaArrayType =>
168
168
cls == defn.ObjectClass
169
169
case _ =>
@@ -189,7 +189,7 @@ object Types {
189
189
final def isErroneous (implicit ctx : Context ): Boolean = existsPart(_.isError, forceLazy = false )
190
190
191
191
/** Does the type carry an annotation that is an instance of `cls`? */
192
- final def hasAnnotation (cls : ClassSymbol )(implicit ctx : Context ): Boolean = stripTypeVar match {
192
+ @ tailrec final def hasAnnotation (cls : ClassSymbol )(implicit ctx : Context ): Boolean = stripTypeVar match {
193
193
case AnnotatedType (tp, annot) => (annot matches cls) || (tp hasAnnotation cls)
194
194
case _ => false
195
195
}
@@ -278,7 +278,7 @@ object Types {
278
278
// ----- Associated symbols ----------------------------------------------
279
279
280
280
/** The type symbol associated with the type */
281
- final def typeSymbol (implicit ctx : Context ): Symbol = this match {
281
+ @ tailrec final def typeSymbol (implicit ctx : Context ): Symbol = this match {
282
282
case tp : TypeRef => tp.symbol
283
283
case tp : ClassInfo => tp.cls
284
284
// case ThisType(cls) => cls // needed?
@@ -293,16 +293,16 @@ object Types {
293
293
*/
294
294
final def classSymbol (implicit ctx : Context ): Symbol = this match {
295
295
case ConstantType (constant) =>
296
- constant.tpe.classSymbol
296
+ constant.tpe.classSymbol: @ tailrec
297
297
case tp : TypeRef =>
298
298
val sym = tp.symbol
299
- if (sym.isClass) sym else tp.superType.classSymbol
299
+ if (sym.isClass) sym else tp.superType.classSymbol: @ tailrec
300
300
case tp : ClassInfo =>
301
301
tp.cls
302
302
case tp : SingletonType =>
303
303
NoSymbol
304
304
case tp : TypeProxy =>
305
- tp.underlying.classSymbol
305
+ tp.underlying.classSymbol: @ tailrec
306
306
case AndType (l, r) =>
307
307
val lsym = l.classSymbol
308
308
val rsym = r.classSymbol
@@ -326,9 +326,9 @@ object Types {
326
326
tp.cls :: Nil
327
327
case tp : TypeRef =>
328
328
val sym = tp.symbol
329
- if (sym.isClass) sym.asClass :: Nil else tp.superType.classSymbols
329
+ if (sym.isClass) sym.asClass :: Nil else tp.superType.classSymbols: @ tailrec
330
330
case tp : TypeProxy =>
331
- tp.underlying.classSymbols
331
+ tp.underlying.classSymbols: @ tailrec
332
332
case AndType (l, r) =>
333
333
l.classSymbols union r.classSymbols
334
334
case OrType (l, r) =>
@@ -338,7 +338,7 @@ object Types {
338
338
}
339
339
340
340
/** The term symbol associated with the type */
341
- final def termSymbol (implicit ctx : Context ): Symbol = this match {
341
+ @ tailrec final def termSymbol (implicit ctx : Context ): Symbol = this match {
342
342
case tp : TermRef => tp.symbol
343
343
case tp : TypeProxy => tp.underlying.termSymbol
344
344
case _ => NoSymbol
@@ -369,11 +369,11 @@ object Types {
369
369
* Defined by ClassInfo, inherited by type proxies.
370
370
* Empty scope for all other types.
371
371
*/
372
- final def decls (implicit ctx : Context ): Scope = this match {
372
+ @ tailrec final def decls (implicit ctx : Context ): Scope = this match {
373
373
case tp : ClassInfo =>
374
374
tp.decls
375
375
case tp : TypeProxy =>
376
- tp.underlying.decls
376
+ tp.underlying.decls: @ tailrec
377
377
case _ =>
378
378
EmptyScope
379
379
}
@@ -395,7 +395,7 @@ object Types {
395
395
* name, as seen from prefix type `pre`. Declarations that have a flag
396
396
* in `excluded` are omitted.
397
397
*/
398
- final def findDecl (name : Name , excluded : FlagSet )(implicit ctx : Context ): Denotation = this match {
398
+ @ tailrec final def findDecl (name : Name , excluded : FlagSet )(implicit ctx : Context ): Denotation = this match {
399
399
case tp : ClassInfo =>
400
400
tp.decls.denotsNamed(name).filterExcluded(excluded).toDenot(NoPrefix )
401
401
case tp : TypeProxy =>
@@ -615,7 +615,7 @@ object Types {
615
615
val ns = tp.parent.memberNames(keepOnly, pre)
616
616
if (keepOnly(pre, tp.refinedName)) ns + tp.refinedName else ns
617
617
case tp : TypeProxy =>
618
- tp.underlying.memberNames(keepOnly, pre)
618
+ tp.underlying.memberNames(keepOnly, pre): @ tailrec
619
619
case tp : AndType =>
620
620
tp.tp1.memberNames(keepOnly, pre) | tp.tp2.memberNames(keepOnly, pre)
621
621
case tp : OrType =>
@@ -822,23 +822,23 @@ object Types {
822
822
* def o: Outer
823
823
* <o.x.type>.widen = o.C
824
824
*/
825
- final def widen (implicit ctx : Context ): Type = widenSingleton match {
825
+ @ tailrec final def widen (implicit ctx : Context ): Type = widenSingleton match {
826
826
case tp : ExprType => tp.resultType.widen
827
827
case tp => tp
828
828
}
829
829
830
830
/** Widen from singleton type to its underlying non-singleton
831
831
* base type by applying one or more `underlying` dereferences.
832
832
*/
833
- final def widenSingleton (implicit ctx : Context ): Type = stripTypeVar match {
833
+ @ tailrec final def widenSingleton (implicit ctx : Context ): Type = stripTypeVar match {
834
834
case tp : SingletonType if ! tp.isOverloaded => tp.underlying.widenSingleton
835
835
case _ => this
836
836
}
837
837
838
838
/** Widen from TermRef to its underlying non-termref
839
839
* base type, while also skipping Expr types.
840
840
*/
841
- final def widenTermRefExpr (implicit ctx : Context ): Type = stripTypeVar match {
841
+ @ tailrec final def widenTermRefExpr (implicit ctx : Context ): Type = stripTypeVar match {
842
842
case tp : TermRef if ! tp.isOverloaded => tp.underlying.widenExpr.widenTermRefExpr
843
843
case _ => this
844
844
}
@@ -852,7 +852,7 @@ object Types {
852
852
}
853
853
854
854
/** Widen type if it is unstable (i.e. an ExprType, or TermRef to unstable symbol */
855
- final def widenIfUnstable (implicit ctx : Context ): Type = stripTypeVar match {
855
+ @ tailrec final def widenIfUnstable (implicit ctx : Context ): Type = stripTypeVar match {
856
856
case tp : ExprType => tp.resultType.widenIfUnstable
857
857
case tp : TermRef if ! tp.symbol.isStable => tp.underlying.widenIfUnstable
858
858
case _ => this
@@ -875,20 +875,20 @@ object Types {
875
875
case tp : TypeRef =>
876
876
if (tp.symbol.isClass) tp
877
877
else tp.info match {
878
- case TypeAlias (tp) => tp.dealias(keepAnnots)
878
+ case TypeAlias (tp) => tp.dealias(keepAnnots): @ tailrec
879
879
case _ => tp
880
880
}
881
881
case tp : TypeVar =>
882
882
val tp1 = tp.instanceOpt
883
- if (tp1.exists) tp1.dealias(keepAnnots) else tp
883
+ if (tp1.exists) tp1.dealias(keepAnnots): @ tailrec else tp
884
884
case tp : AnnotatedType =>
885
885
val tp1 = tp.tpe.dealias(keepAnnots)
886
886
if (keepAnnots) tp.derivedAnnotatedType(tp1, tp.annot) else tp1
887
887
case tp : LazyRef =>
888
- tp.ref.dealias(keepAnnots)
888
+ tp.ref.dealias(keepAnnots): @ tailrec
889
889
case app @ HKApply (tycon, args) =>
890
890
val tycon1 = tycon.dealias(keepAnnots)
891
- if (tycon1 ne tycon) app.superType.dealias(keepAnnots)
891
+ if (tycon1 ne tycon) app.superType.dealias(keepAnnots): @ tailrec
892
892
else this
893
893
case _ => this
894
894
}
@@ -908,7 +908,7 @@ object Types {
908
908
dealias(keepAnnots = false )
909
909
910
910
/** Perform successive widenings and dealiasings until none can be applied anymore */
911
- final def widenDealias (implicit ctx : Context ): Type = {
911
+ @ tailrec final def widenDealias (implicit ctx : Context ): Type = {
912
912
val res = this .widen.dealias
913
913
if (res eq this ) res else res.widenDealias
914
914
}
@@ -991,22 +991,22 @@ object Types {
991
991
* (*) normalizes means: follow instantiated typevars and aliases.
992
992
*/
993
993
def lookupRefined (name : Name )(implicit ctx : Context ): Type = {
994
- def loop (pre : Type ): Type = pre.stripTypeVar match {
994
+ @ tailrec def loop (pre : Type ): Type = pre.stripTypeVar match {
995
995
case pre : RefinedType =>
996
996
pre.refinedInfo match {
997
997
case TypeAlias (alias) =>
998
998
if (pre.refinedName ne name) loop(pre.parent) else alias
999
999
case _ => loop(pre.parent)
1000
1000
}
1001
1001
case pre : RecType =>
1002
- val candidate = loop( pre.parent)
1002
+ val candidate = pre.parent.lookupRefined(name )
1003
1003
if (candidate.exists && ! pre.isReferredToBy(candidate)) {
1004
1004
// println(s"lookupRefined ${this.toString} . $name, pre: $pre ---> $candidate / ${candidate.toString}")
1005
1005
candidate
1006
1006
}
1007
1007
else NoType
1008
1008
case SkolemType (tp) =>
1009
- tp.lookupRefined(name )
1009
+ loop(tp )
1010
1010
case pre : WildcardType =>
1011
1011
WildcardType
1012
1012
case pre : TypeRef =>
@@ -1046,7 +1046,7 @@ object Types {
1046
1046
* Inherited by all other type proxies.
1047
1047
* `NoType` for all other types.
1048
1048
*/
1049
- final def normalizedPrefix (implicit ctx : Context ): Type = this match {
1049
+ @ tailrec final def normalizedPrefix (implicit ctx : Context ): Type = this match {
1050
1050
case tp : NamedType =>
1051
1051
if (tp.symbol.info.isAlias) tp.info.normalizedPrefix else tp.prefix
1052
1052
case tp : ClassInfo =>
@@ -1102,14 +1102,14 @@ object Types {
1102
1102
1103
1103
1104
1104
/** The parameter types in the first parameter section of a generic type or MethodType, Empty list for others */
1105
- final def firstParamTypes (implicit ctx : Context ): List [Type ] = this match {
1105
+ @ tailrec final def firstParamTypes (implicit ctx : Context ): List [Type ] = this match {
1106
1106
case mt : MethodType => mt.paramTypes
1107
1107
case pt : PolyType => pt.resultType.firstParamTypes
1108
1108
case _ => Nil
1109
1109
}
1110
1110
1111
1111
/** Is this either not a method at all, or a parameterless method? */
1112
- final def isParameterless (implicit ctx : Context ): Boolean = this match {
1112
+ @ tailrec final def isParameterless (implicit ctx : Context ): Boolean = this match {
1113
1113
case mt : MethodType => false
1114
1114
case pt : PolyType => pt.resultType.isParameterless
1115
1115
case _ => true
@@ -2101,7 +2101,7 @@ object Types {
2101
2101
}
2102
2102
2103
2103
object RefinedType {
2104
- def make (parent : Type , names : List [Name ], infos : List [Type ])(implicit ctx : Context ): Type =
2104
+ @ tailrec def make (parent : Type , names : List [Name ], infos : List [Type ])(implicit ctx : Context ): Type =
2105
2105
if (names.isEmpty) parent
2106
2106
else make(RefinedType (parent, names.head, infos.head), names.tail, infos.tail)
2107
2107
@@ -3709,7 +3709,7 @@ object Types {
3709
3709
this (x, prefix)
3710
3710
3711
3711
case tp @ HKApply (tycon, args) =>
3712
- def foldArgs (x : T , tparams : List [TypeParamInfo ], args : List [Type ]): T =
3712
+ @ tailrec def foldArgs (x : T , tparams : List [TypeParamInfo ], args : List [Type ]): T =
3713
3713
if (args.isEmpty) {
3714
3714
assert(tparams.isEmpty)
3715
3715
x
@@ -3752,7 +3752,7 @@ object Types {
3752
3752
case _ => x
3753
3753
}
3754
3754
3755
- final def foldOver (x : T , ts : List [Type ]): T = ts match {
3755
+ @ tailrec final def foldOver (x : T , ts : List [Type ]): T = ts match {
3756
3756
case t :: ts1 => foldOver(apply(x, t), ts1)
3757
3757
case nil => x
3758
3758
}
0 commit comments