@@ -3501,12 +3501,31 @@ class Typer extends Namer
35013501 typr.println(i " adapt to subtype ${tree.tpe} !<:< $pt" )
35023502 // typr.println(TypeComparer.explained(tree.tpe <:< pt))
35033503 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+ } =>
35053513 // Insert an explicit cast, so that -Ycheck in later phases succeeds.
35063514 // I suspect, but am not 100% sure that this might affect inferred types,
35073515 // if the expected type is a supertype of the GADT bound. It would be good to come
35083516 // 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)
35103529 case _ =>
35113530 tree
35123531 }
0 commit comments