@@ -2765,7 +2765,7 @@ class Typer extends Namer
2765
2765
*/
2766
2766
def adapt (tree : Tree , pt : Type , locked : TypeVars , tryGadtHealing : Boolean = true )(using Context ): Tree = {
2767
2767
val last = Thread .currentThread.getStackTrace()(2 ).toString;
2768
- trace/* .force */ (i " adapting (tryGadtHealing= $tryGadtHealing) $tree to $pt\n {callsite: $last} " , typr, show = true ) {
2768
+ trace(i " adapting (tryGadtHealing= $tryGadtHealing) $tree to $pt\n {callsite: $last} " , typr, show = true ) {
2769
2769
record(" adapt" )
2770
2770
adapt1(tree, pt, locked, tryGadtHealing)
2771
2771
}
@@ -2775,7 +2775,6 @@ class Typer extends Namer
2775
2775
adapt(tree, pt, ctx.typerState.ownedVars)
2776
2776
2777
2777
private def adapt1 (tree : Tree , pt : Type , locked : TypeVars , tryGadtHealing : Boolean )(using Context ): Tree = {
2778
- // assert(pt.exists && !pt.isInstanceOf[ExprType])
2779
2778
assert(pt.exists && ! pt.isInstanceOf [ExprType ] || ctx.reporter.errorsReported)
2780
2779
def methodStr = err.refStr(methPart(tree).tpe)
2781
2780
@@ -3272,6 +3271,7 @@ class Typer extends Namer
3272
3271
foo = $foo
3273
3272
pt.isInstanceOf[SelectionProto] = ${pt.isInstanceOf [SelectionProto ]}
3274
3273
ctx.gadt.nonEmpty = ${ctx.gadt.nonEmpty}
3274
+ ctx.gadt = ${ctx.gadt.debugBoundsDescription}
3275
3275
pt.isMatchedBy = ${
3276
3276
if (pt.isInstanceOf [SelectionProto ])
3277
3277
pt.asInstanceOf [SelectionProto ].isMatchedBy(foo).toString
@@ -3316,20 +3316,31 @@ class Typer extends Namer
3316
3316
def recover (failure : SearchFailureType ) =
3317
3317
{
3318
3318
debug.println(" recover" )
3319
- if (isFullyDefined(wtp, force = ForceDegree .all) &&
3320
- ctx.typerState.constraint.ne(prevConstraint)) readapt(tree)
3321
- // else if ({
3322
- // debug.println(i"tryGadtHealing=$tryGadtHealing && \n\tctx.gadt.nonEmpty=${ctx.gadt.nonEmpty}")
3323
- // tryGadtHealing && ctx.gadt.nonEmpty
3324
- // })
3325
- // {
3326
- // debug.println("here")
3327
- // readapt(
3328
- // tree = tpd.Typed(tree, TypeTree(Inferencing.approximateGADT(wtp))),
3329
- // shouldTryGadtHealing = false,
3330
- // )
3331
- // }
3332
- else err.typeMismatch(tree, pt, failure)
3319
+ if (isFullyDefined(wtp, force = ForceDegree .all) &&
3320
+ ctx.typerState.constraint.ne(prevConstraint)) readapt(tree)
3321
+ else if ({
3322
+ debug.println(i " tryGadtHealing= $tryGadtHealing && \n\t ctx.gadt.nonEmpty= ${ctx.gadt.nonEmpty}" )
3323
+ tryGadtHealing && ctx.gadt.nonEmpty
3324
+ })
3325
+ {
3326
+ debug.println(" //try recover with GADT approximation" )
3327
+ val nestedCtx = ctx.fresh.setNewTyperState()
3328
+ val res =
3329
+ readapt(
3330
+ tree = tpd.Typed (tree, TypeTree (Inferencing .approximateGADT(wtp))),
3331
+ shouldTryGadtHealing = false ,
3332
+ )(using nestedCtx)
3333
+ if (! nestedCtx.reporter.hasErrors) {
3334
+ nestedCtx.typerState.commit()
3335
+ debug.println(" // GADT recovery successful" )
3336
+ res
3337
+ } else {
3338
+ // otherwise fail with the error that would have been reported without GADT recovery
3339
+ debug.println(" // GADT recovery failed, falling back to original error" )
3340
+ err.typeMismatch(tree, pt, failure)
3341
+ }
3342
+ }
3343
+ else err.typeMismatch(tree, pt, failure)
3333
3344
}
3334
3345
if ctx.mode.is(Mode .ImplicitsEnabled ) && tree.typeOpt.isValueType then
3335
3346
if pt.isRef(defn.AnyValClass ) || pt.isRef(defn.ObjectClass ) then
0 commit comments