@@ -156,16 +156,24 @@ object Checking {
156
156
tp
157
157
}
158
158
159
- def apply (tp : Type ) = tp match {
159
+ private def apply (tp : Type , cycleOK : Boolean , nestedCycleOK : Boolean ): Type = {
160
+ val savedCycleOK = this .cycleOK
161
+ val savedNestedCycleOK = this .nestedCycleOK
162
+ this .cycleOK = cycleOK
163
+ this .nestedCycleOK = nestedCycleOK
164
+ try apply(tp)
165
+ finally {
166
+ this .cycleOK = savedCycleOK
167
+ this .nestedCycleOK = savedNestedCycleOK
168
+ }
169
+ }
170
+
171
+ def apply (tp : Type ): Type = tp match {
160
172
case tp : TermRef =>
161
173
this (tp.info)
162
174
mapOver(tp)
163
175
case tp @ RefinedType (parent, name) =>
164
- val parent1 = this (parent)
165
- val saved = cycleOK
166
- cycleOK = nestedCycleOK
167
- try tp.derivedRefinedType(parent1, name, this (tp.refinedInfo))
168
- finally cycleOK = saved
176
+ tp.derivedRefinedType(this (parent), name, this (tp.refinedInfo, nestedCycleOK, nestedCycleOK))
169
177
case tp @ TypeRef (pre, name) =>
170
178
try {
171
179
// A prefix is interesting if it might contain (transitively) a reference
@@ -182,19 +190,12 @@ object Checking {
182
190
case _ : RefinedType => true
183
191
case _ => false
184
192
}
185
- // If prefix is interesting, check info of typeref recursively, marking the referred symbol
186
- // with NoCompleter. This provokes a CyclicReference when the symbol
187
- // is hit again. Without this precaution we could stackoverflow here.
188
193
if (isInteresting(pre)) {
189
- val info = tp.info
190
- val sym = tp.symbol
191
- if (sym.infoOrCompleter == SymDenotations .NoCompleter ) throw CyclicReference (sym)
192
- val symInfo = sym.info
193
- if (sym.exists) sym.info = SymDenotations .NoCompleter
194
- try checkInfo(info)
195
- finally if (sym.exists) sym.info = symInfo
194
+ val pre1 = this (pre, false , false )
195
+ checkInfo(tp.info)
196
+ if (pre1 eq pre) tp else tp.newLikeThis(pre1)
196
197
}
197
- tp
198
+ else tp
198
199
} catch {
199
200
case ex : CyclicReference =>
200
201
ctx.debuglog(i " cycle detected for $tp, $nestedCycleOK, $cycleOK" )
@@ -210,9 +211,6 @@ object Checking {
210
211
* @pre sym is not yet initialized (i.e. its type is a Completer).
211
212
* @return `info` where every legal F-bounded reference is proctected
212
213
* by a `LazyRef`, or `ErrorType` if a cycle was detected and reported.
213
- * Furthermore: Add an #Apply to a fully instantiated type lambda, if none was
214
- * given before. This is necessary here because sometimes type lambdas are not
215
- * recognized when they are first formed.
216
214
*/
217
215
def checkNonCyclic (sym : Symbol , info : Type , reportErrors : Boolean )(implicit ctx : Context ): Type = {
218
216
val checker = new CheckNonCyclicMap (sym, reportErrors)(ctx.addMode(Mode .CheckCyclic ))
0 commit comments