@@ -8,7 +8,7 @@ import Contexts._, Types._, Flags._, Symbols._
88import ProtoTypes ._
99import NameKinds .{AvoidNameKind , UniqueName }
1010import util .Spans ._
11- import util .{Stats , SimpleIdentityMap }
11+ import util .{Stats , SimpleIdentityMap , SrcPos }
1212import Decorators ._
1313import config .Printers .{gadts , typr }
1414import annotation .tailrec
@@ -28,11 +28,11 @@ object Inferencing {
2828 * but only if the overall result of `isFullyDefined` is `true`.
2929 * Variables that are successfully minimized do not count as uninstantiated.
3030 */
31- def isFullyDefined (tp : Type , force : ForceDegree .Value )(using Context ): Boolean = {
31+ def isFullyDefined (tp : Type , force : ForceDegree .Value , handleOverflow : Boolean = false )(using Context ): Boolean = {
3232 val nestedCtx = ctx.fresh.setNewTyperState()
3333 val result =
3434 try new IsFullyDefinedAccumulator (force)(using nestedCtx).process(tp)
35- catch case ex : StackOverflowError =>
35+ catch case ex : RecursionOverflow if handleOverflow =>
3636 false // can happen for programs with illegal recusions, e.g. neg/recursive-lower-constraint.scala
3737 if (result) nestedCtx.typerState.commit()
3838 result
@@ -49,9 +49,13 @@ object Inferencing {
4949 /** The fully defined type, where all type variables are forced.
5050 * Throws an error if type contains wildcards.
5151 */
52- def fullyDefinedType (tp : Type , what : String , span : Span )(using Context ): Type =
53- if (isFullyDefined(tp, ForceDegree .all)) tp
54- else throw new Error (i " internal error: type of $what $tp is not fully defined, pos = $span" ) // !!! DEBUG
52+ def fullyDefinedType (tp : Type , what : String , pos : SrcPos )(using Context ): Type =
53+ try
54+ if isFullyDefined(tp, ForceDegree .all) then tp
55+ else throw new Error (i " internal error: type of $what $tp is not fully defined, pos = $pos" )
56+ catch case ex : RecursionOverflow =>
57+ report.error(ex, pos)
58+ UnspecifiedErrorType
5559
5660 /** Instantiate selected type variables `tvars` in type `tp` in a special mode:
5761 * 1. If a type variable is constrained from below (i.e. constraint bound != given lower bound)
@@ -171,33 +175,37 @@ object Inferencing {
171175
172176 private var toMaximize : List [TypeVar ] = Nil
173177
174- def apply (x : Boolean , tp : Type ): Boolean = tp.dealias match {
175- case _ : WildcardType | _ : ProtoType =>
176- false
177- case tvar : TypeVar if ! tvar.isInstantiated =>
178- force.appliesTo(tvar)
179- && ctx.typerState.constraint.contains(tvar)
180- && {
181- val direction = instDirection(tvar.origin)
182- if minimizeSelected then
183- if direction <= 0 && tvar.hasLowerBound then
178+ def apply (x : Boolean , tp : Type ): Boolean =
179+ try tp.dealias match
180+ case _ : WildcardType | _ : ProtoType =>
181+ false
182+ case tvar : TypeVar if ! tvar.isInstantiated =>
183+ force.appliesTo(tvar)
184+ && ctx.typerState.constraint.contains(tvar)
185+ && {
186+ val direction = instDirection(tvar.origin)
187+ if minimizeSelected then
188+ if direction <= 0 && tvar.hasLowerBound then
189+ instantiate(tvar, fromBelow = true )
190+ else if direction >= 0 && tvar.hasUpperBound then
191+ instantiate(tvar, fromBelow = false )
192+ // else hold off instantiating unbounded unconstrained variable
193+ else if direction != 0 then
194+ instantiate(tvar, fromBelow = direction < 0 )
195+ else if variance >= 0 && (force.ifBottom == IfBottom .ok || tvar.hasLowerBound) then
184196 instantiate(tvar, fromBelow = true )
185- else if direction >= 0 && tvar.hasUpperBound then
186- instantiate(tvar, fromBelow = false )
187- // else hold off instantiating unbounded unconstrained variable
188- else if direction != 0 then
189- instantiate(tvar, fromBelow = direction < 0 )
190- else if variance >= 0 && (force.ifBottom == IfBottom .ok || tvar.hasLowerBound) then
191- instantiate(tvar, fromBelow = true )
192- else if variance >= 0 && force.ifBottom == IfBottom .fail then
193- return false
194- else
195- toMaximize = tvar :: toMaximize
196- foldOver(x, tvar)
197- }
198- case tp =>
199- foldOver(x, tp)
200- }
197+ else if variance >= 0 && force.ifBottom == IfBottom .fail then
198+ return false
199+ else
200+ toMaximize = tvar :: toMaximize
201+ foldOver(x, tvar)
202+ }
203+ case tp =>
204+ reporting.trace(s " IFT $tp" ) {
205+ foldOver(x, tp)
206+ }
207+ catch case ex : Throwable =>
208+ handleRecursive(" check fully defined" , tp.show, ex)
201209
202210 def process (tp : Type ): Boolean =
203211 // Maximize type vars in the order they were visited before */
@@ -313,7 +321,7 @@ object Inferencing {
313321 val (tl1, tvars) = constrained(tl, tree)
314322 var tree1 = AppliedTypeTree (tree.withType(tl1), tvars)
315323 tree1.tpe <:< pt
316- fullyDefinedType(tree1.tpe, " template parent" , tree.span )
324+ fullyDefinedType(tree1.tpe, " template parent" , tree.srcPos )
317325 tree1
318326 case _ =>
319327 tree
0 commit comments