@@ -44,7 +44,7 @@ import transform.TypeUtils._
44
44
import reporting .trace
45
45
import Nullables .{NotNullInfo , given _ }
46
46
import NullOpsDecorator ._
47
- import config .Printers .debug
47
+ import config .Printers .gadts
48
48
49
49
object Typer {
50
50
@@ -2764,7 +2764,7 @@ class Typer extends Namer
2764
2764
*/
2765
2765
def adapt (tree : Tree , pt : Type , locked : TypeVars , tryGadtHealing : Boolean = true )(using Context ): Tree = {
2766
2766
val last = Thread .currentThread.getStackTrace()(2 ).toString;
2767
- trace/* .force */ (i " adapting (tryGadtHealing= $tryGadtHealing) $tree to $pt\n {callsite: $last} " , typr, show = true ) {
2767
+ trace(i " adapting (tryGadtHealing= $tryGadtHealing) $tree to $pt\n {callsite: $last} " , typr, show = true ) {
2768
2768
record(" adapt" )
2769
2769
adapt1(tree, pt, locked, tryGadtHealing)
2770
2770
}
@@ -2774,7 +2774,6 @@ class Typer extends Namer
2774
2774
adapt(tree, pt, ctx.typerState.ownedVars)
2775
2775
2776
2776
private def adapt1 (tree : Tree , pt : Type , locked : TypeVars , tryGadtHealing : Boolean )(using Context ): Tree = {
2777
- // assert(pt.exists && !pt.isInstanceOf[ExprType])
2778
2777
assert(pt.exists && ! pt.isInstanceOf [ExprType ] || ctx.reporter.errorsReported)
2779
2778
def methodStr = err.refStr(methPart(tree).tpe)
2780
2779
@@ -3224,19 +3223,15 @@ class Typer extends Namer
3224
3223
}
3225
3224
3226
3225
def adaptToSubType (wtp : Type ): Tree = {
3227
- debug.println(" adaptToSubType" )
3228
- debug.println(" // try converting a constant to the target type" )
3229
3226
// try converting a constant to the target type
3230
3227
val folded = ConstFold (tree, pt)
3231
3228
if (folded ne tree)
3232
3229
return adaptConstant(folded, folded.tpe.asInstanceOf [ConstantType ])
3233
3230
3234
- debug.println(" // Try to capture wildcards in type" )
3235
3231
val captured = captureWildcards(wtp)
3236
3232
if (captured `ne` wtp)
3237
3233
return readapt(tree.cast(captured))
3238
3234
3239
- debug.println(" // drop type if prototype is Unit" )
3240
3235
// drop type if prototype is Unit
3241
3236
if (pt isRef defn.UnitClass ) {
3242
3237
// local adaptation makes sure every adapted tree conforms to its pt
@@ -3246,7 +3241,6 @@ class Typer extends Namer
3246
3241
return tpd.Block (tree1 :: Nil , Literal (Constant (())))
3247
3242
}
3248
3243
3249
- debug.println(" // convert function literal to SAM closure" )
3250
3244
// convert function literal to SAM closure
3251
3245
tree match {
3252
3246
case closure(Nil , id @ Ident (nme.ANON_FUN ), _)
@@ -3264,28 +3258,28 @@ class Typer extends Namer
3264
3258
case _ =>
3265
3259
}
3266
3260
3267
- debug.println(" // try GADT approximation" )
3268
- val foo = Inferencing .approximateGADT(wtp)
3269
- debug.println(
3270
- i """
3271
- foo = $foo
3261
+ val approximation = Inferencing .approximateGADT(wtp)
3262
+ gadts.println(
3263
+ i """ GADT approximation {
3264
+ approximation = $approximation
3272
3265
pt.isInstanceOf[SelectionProto] = ${pt.isInstanceOf [SelectionProto ]}
3273
3266
ctx.gadt.nonEmpty = ${ctx.gadt.nonEmpty}
3267
+ ctx.gadt = ${ctx.gadt.debugBoundsDescription}
3274
3268
pt.isMatchedBy = ${
3275
3269
if (pt.isInstanceOf [SelectionProto ])
3276
- pt.asInstanceOf [SelectionProto ].isMatchedBy(foo ).toString
3270
+ pt.asInstanceOf [SelectionProto ].isMatchedBy(approximation ).toString
3277
3271
else
3278
3272
" <not a SelectionProto>"
3279
3273
}
3274
+ }
3280
3275
"""
3281
3276
)
3282
3277
pt match {
3283
- case pt : SelectionProto if ctx.gadt.nonEmpty && pt.isMatchedBy(foo ) =>
3284
- return tpd.Typed (tree, TypeTree (foo ))
3278
+ case pt : SelectionProto if ctx.gadt.nonEmpty && pt.isMatchedBy(approximation ) =>
3279
+ return tpd.Typed (tree, TypeTree (approximation ))
3285
3280
case _ => ;
3286
3281
}
3287
3282
3288
- debug.println(" // try an extension method in scope" )
3289
3283
// try an extension method in scope
3290
3284
pt match {
3291
3285
case SelectionProto (name, mbrType, _, _) =>
@@ -3303,33 +3297,34 @@ class Typer extends Namer
3303
3297
val app = tryExtension(using nestedCtx)
3304
3298
if (! app.isEmpty && ! nestedCtx.reporter.hasErrors) {
3305
3299
nestedCtx.typerState.commit()
3306
- debug.println(" returning ext meth in scope" )
3307
3300
return ExtMethodApply (app)
3308
3301
}
3309
3302
case _ =>
3310
3303
}
3311
3304
3312
- debug.println(" // try an implicit conversion" )
3313
3305
// try an implicit conversion
3314
3306
val prevConstraint = ctx.typerState.constraint
3315
- def recover (failure : SearchFailureType ) =
3316
- {
3317
- debug.println(" recover" )
3307
+ def recover (failure : SearchFailureType ) = {
3318
3308
if (isFullyDefined(wtp, force = ForceDegree .all) &&
3319
3309
ctx.typerState.constraint.ne(prevConstraint)) readapt(tree)
3320
- // else if ({
3321
- // debug.println(i"tryGadtHealing=$tryGadtHealing && \n\tctx.gadt.nonEmpty=${ctx.gadt.nonEmpty}")
3322
- // tryGadtHealing && ctx.gadt.nonEmpty
3323
- // })
3324
- // {
3325
- // debug.println("here")
3326
- // readapt(
3327
- // tree = tpd.Typed(tree, TypeTree(Inferencing.approximateGADT(wtp))),
3328
- // shouldTryGadtHealing = false,
3329
- // )
3330
- // }
3331
- else err.typeMismatch(tree, pt, failure)
3332
- }
3310
+ else if (tryGadtHealing && ctx.gadt.nonEmpty) {
3311
+ // try recovering with a GADT approximation
3312
+ val nestedCtx = ctx.fresh.setNewTyperState()
3313
+ val res =
3314
+ readapt(
3315
+ tree = tpd.Typed (tree, TypeTree (Inferencing .approximateGADT(wtp))),
3316
+ shouldTryGadtHealing = false ,
3317
+ )(using nestedCtx)
3318
+ if (! nestedCtx.reporter.hasErrors) {
3319
+ // GADT recovery successful
3320
+ nestedCtx.typerState.commit()
3321
+ res
3322
+ } else {
3323
+ // otherwise fail with the error that would have been reported without the GADT recovery
3324
+ err.typeMismatch(tree, pt, failure)
3325
+ }
3326
+ } else err.typeMismatch(tree, pt, failure)
3327
+ }
3333
3328
if ctx.mode.is(Mode .ImplicitsEnabled ) && tree.typeOpt.isValueType then
3334
3329
if pt.isRef(defn.AnyValClass ) || pt.isRef(defn.ObjectClass ) then
3335
3330
ctx.error(em " the result of an implicit conversion must be more specific than $pt" , tree.sourcePos)
0 commit comments