@@ -3501,12 +3501,31 @@ class Typer extends Namer
3501
3501
typr.println(i " adapt to subtype ${tree.tpe} !<:< $pt" )
3502
3502
// typr.println(TypeComparer.explained(tree.tpe <:< pt))
3503
3503
adaptToSubType(wtp)
3504
- case CompareResult .OKwithGADTUsed if pt.isValueType =>
3504
+ case CompareResult .OKwithGADTUsed
3505
+ if pt.isValueType
3506
+ && ! inContext(ctx.fresh.setGadt(EmptyGadtConstraint )) {
3507
+ val res = (tree.tpe.widenExpr frozen_<:< pt)
3508
+ if res then
3509
+ // we overshot; a cast is not needed, after all.
3510
+ gadts.println(i " unnecessary GADTused for $tree: ${tree.tpe.widenExpr} vs $pt in ${ctx.source}" )
3511
+ res
3512
+ } =>
3505
3513
// Insert an explicit cast, so that -Ycheck in later phases succeeds.
3506
3514
// I suspect, but am not 100% sure that this might affect inferred types,
3507
3515
// if the expected type is a supertype of the GADT bound. It would be good to come
3508
3516
// up with a test case for this.
3509
- tree.cast(pt)
3517
+ val target =
3518
+ if tree.tpe.isSingleton then
3519
+ val conj = AndType (tree.tpe, pt)
3520
+ if tree.tpe.isStable && ! conj.isStable then
3521
+ // this is needed for -Ycheck. Without the annotation Ycheck will
3522
+ // skolemize the result type which will lead to different types before
3523
+ // and after checking. See i11955.scala.
3524
+ AnnotatedType (conj, Annotation (defn.StableAnnot ))
3525
+ else conj
3526
+ else pt
3527
+ gadts.println(i " insert GADT cast from $tree to $target" )
3528
+ tree.cast(target)
3510
3529
case _ =>
3511
3530
tree
3512
3531
}
0 commit comments