diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index 43d820736d29..7b96062dda95 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -252,8 +252,7 @@ trait ConstraintHandling { val bound = legalBound(param, rawBound, isUpper) val oldBounds @ TypeBounds(lo, hi) = constraint.nonParamBounds(param) val equalBounds = (if isUpper then lo else hi) eq bound - val isGadt = ctx.mode.is(Mode.GadtConstraintInference) - if equalBounds && !isGadt && !bound.existsPart(_ eq param, StopAt.Static) then + if equalBounds && !bound.existsPart(_ eq param, StopAt.Static) then // The narrowed bounds are equal and not recursive, // so we can remove `param` from the constraint. constraint = constraint.replace(param, bound) @@ -268,12 +267,8 @@ trait ConstraintHandling { homogenizeArgs = Config.alignArgsInAnd try trustBounds = false - if isUpper then - if isGadt && !hi.isAny && hi.isValueTypeOrWildcard && bound.isValueTypeOrWildcard then oldBounds.derivedTypeBounds(lo, AndType(hi, bound)) - else oldBounds.derivedTypeBounds(lo, hi & bound) - else - if isGadt && !lo.isNothingType && lo.isValueTypeOrWildcard && bound.isValueTypeOrWildcard then oldBounds.derivedTypeBounds(OrType(lo, bound, soft = true), hi) - else oldBounds.derivedTypeBounds(lo | bound, hi) + if isUpper then oldBounds.derivedTypeBounds(lo, hi & bound) + else oldBounds.derivedTypeBounds(lo | bound, hi) finally homogenizeArgs = savedHomogenizeArgs trustBounds = savedTrustBounds diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala index a304fa9f5705..76cdb4253c80 100644 --- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -162,16 +162,13 @@ class OrderingConstraint(private val boundsMap: ParamBounds, def contains(pt: TypeLambda): Boolean = boundsMap(pt) != null - def contains(param: TypeParamRef): Boolean = { - val entries = boundsMap(param.binder) - entries != null && isBounds(entries(param.paramNum)) - } + def contains(param: TypeParamRef): Boolean = boundsMap(param.binder) != null def contains(tvar: TypeVar): Boolean = { val origin = tvar.origin val entries = boundsMap(origin.binder) val pnum = origin.paramNum - entries != null && isBounds(entries(pnum)) && (typeVar(entries, pnum) eq tvar) + entries != null && (typeVar(entries, pnum) eq tvar) } // ---------- Dependency handling ---------------------------------------------- @@ -548,7 +545,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, def forallParams(p: TypeParamRef => Boolean): Boolean = boundsMap.forallBinding { (poly, entries) => - !0.until(paramCount(entries)).exists(i => isBounds(entries(i)) && !p(poly.paramRefs(i))) + (0 until paramCount(entries)).forall(i => p(poly.paramRefs(i))) } def foreachParam(p: (TypeLambda, Int) => Unit): Unit = diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index c248d2634d8c..744122d141ec 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -117,7 +117,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling protected def gadtAddLowerBound(sym: Symbol, b: Type): Boolean = ctx.gadt.addBound(sym, b, isUpper = false) protected def gadtAddUpperBound(sym: Symbol, b: Type): Boolean = ctx.gadt.addBound(sym, b, isUpper = true) - protected def typeVarInstance(tvar: TypeVar)(using Context): Type = tvar.underlying + protected def typeVarInstance(tvar: TypeVar)(using Context): Type = tvar.inst.orElse(tvar.origin) // Subtype testing `<:<` @@ -1201,7 +1201,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling def compareLower(tycon2bounds: TypeBounds, tyconIsTypeRef: Boolean): Boolean = if ((tycon2bounds.lo `eq` tycon2bounds.hi) && !tycon2bounds.isInstanceOf[MatchAlias]) if (tyconIsTypeRef) recur(tp1, tp2.superTypeNormalized) - else recur(tp1, tycon2bounds.lo.applyIfParameterized(args2)) + else isSubApproxHi(tp1, tycon2bounds.lo.applyIfParameterized(args2)) else fallback(tycon2bounds.lo) diff --git a/tests/pos/i15289.scala b/tests/pos/i15289.scala index 905f1bb3db7d..a0bb31e494cb 100644 --- a/tests/pos/i15289.scala +++ b/tests/pos/i15289.scala @@ -18,14 +18,14 @@ class Test: // max: Bar[X] // what's more correct? -// * unapp arg tpe = Bar[X] gadt: X =:= String -// * unapp arg tpe = Bar[String] gadt: X =:= String +// * unapp arg tpe = Bar[X] gadt: X := String +// * unapp arg tpe = Bar[String] gadt: X := String // after fix: // ptc: Bar[C] aka Foo[C, C] vs Foo[X, String] -// ptc: C >: X ~> cstr: C >: X -// ptc: C <: X ~> cstr: C =:= X -// ptc: C >: String ~> cstr: C >: X | String <: X gadt: X >: String -// ptc: C <: String ~> cstr: C >: X | String <: X & String gadt: X =:= String +// ptc: C >: X ~> cstr: C >: X +// ptc: C <: X ~> cstr: C >: X <: X +// ptc: C >: String ~> cstr: C >: X | String <: X gadt: X >: String +// ptc: C <: String ~> cstr: C >: X | String <: String gadt: X := String // ptc: Bar[C] // max: Bar[String]