Skip to content

Commit fe6ed66

Browse files
committed
Drop variance in TypeAlias
1 parent a2e812e commit fe6ed66

File tree

12 files changed

+38
-119
lines changed

12 files changed

+38
-119
lines changed

compiler/src/dotty/tools/dotc/core/TypeApplications.scala

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ class TypeApplications(val self: Type) extends AnyVal {
382382
case arg :: args1 =>
383383
try {
384384
val tparam :: tparams1 = tparams
385-
matchParams(RefinedType(t, tparam.paramName, arg.toBounds(tparam)), tparams1, args1)
385+
matchParams(RefinedType(t, tparam.paramName, arg.toBounds), tparams1, args1)
386386
} catch {
387387
case ex: MatchError =>
388388
println(s"applied type mismatch: $self with underlying ${self.underlyingIfProxy}, args = $args, typeParams = $typParams") // !!! DEBUG
@@ -463,15 +463,10 @@ class TypeApplications(val self: Type) extends AnyVal {
463463
appliedTo(args)
464464
}
465465

466-
/** Turn this type, which is used as an argument for
467-
* type parameter `tparam`, into a TypeBounds RHS
468-
*/
469-
final def toBounds(tparam: ParamInfo)(implicit ctx: Context): TypeBounds = self match {
470-
case self: TypeBounds => // this can happen for wildcard args
471-
self
472-
case _ =>
473-
val v = tparam.paramVariance
474-
TypeAlias(self, v)
466+
/** Turns non-bounds types to type aliases */
467+
final def toBounds(implicit ctx: Context): TypeBounds = self match {
468+
case self: TypeBounds => self // this can happen for wildcard args
469+
case _ => TypeAlias(self)
475470
}
476471

477472
/** The type arguments of this type's base type instance wrt. `base`.

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
525525
case tp2 @ TypeBounds(lo2, hi2) =>
526526
def compareTypeBounds = tp1 match {
527527
case tp1 @ TypeBounds(lo1, hi1) =>
528-
(tp2.variance > 0 && tp1.variance >= 0 || (lo2 eq NothingType) || isSubType(lo2, lo1)) &&
529-
(tp2.variance < 0 && tp1.variance <= 0 || (hi2 eq AnyType) || isSubType(hi1, hi2))
528+
((lo2 eq NothingType) || isSubType(lo2, lo1)) &&
529+
((hi2 eq AnyType) || isSubType(hi1, hi2))
530530
case tp1: ClassInfo =>
531531
tp2 contains tp1
532532
case _ =>
@@ -963,8 +963,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
963963
tp2.refinedInfo match {
964964
case rinfo2: TypeBounds =>
965965
val ref1 = tp1.widenExpr.select(name)
966-
(rinfo2.variance > 0 || isSubType(rinfo2.lo, ref1)) &&
967-
(rinfo2.variance < 0 || isSubType(ref1, rinfo2.hi))
966+
isSubType(rinfo2.lo, ref1) && isSubType(ref1, rinfo2.hi)
968967
case _ =>
969968
false
970969
}
@@ -1447,13 +1446,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
14471446
val rinfo1 = tp1.refinedInfo
14481447
val rinfo2 = tp2.refinedInfo
14491448
val parent = tp1.parent & tp2.parent
1450-
1451-
def isNonvariantAlias(tp: Type) = tp match {
1452-
case tp: TypeAlias => tp.variance == 0
1453-
case _ => false
1454-
}
1455-
if (homogenizeArgs &&
1456-
isNonvariantAlias(rinfo1) && isNonvariantAlias(rinfo2))
1449+
if (homogenizeArgs && rinfo1.isAlias && rinfo2.isAlias) // @!!! probably drop this case?
14571450
isSameType(rinfo1, rinfo2) // establish new constraint
14581451

14591452
tp1.derivedRefinedType(parent, tp1.refinedName, rinfo1 & rinfo2)

compiler/src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
6363
tp
6464
case tp: RefinedType => //@!!!
6565
derivedRefinedType(tp, apply(tp.parent), apply(tp.refinedInfo))
66-
case tp: TypeAlias if tp.variance == 1 => // if variance != 1, need to do the variance calculation
67-
derivedTypeAlias(tp, apply(tp.alias))
6866
case _ =>
6967
mapOver(tp)
7068
}

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 17 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3557,23 +3557,13 @@ object Types {
35573557
assert(lo.isInstanceOf[TermType])
35583558
assert(hi.isInstanceOf[TermType])
35593559

3560-
def variance: Int = 0
3561-
35623560
override def underlying(implicit ctx: Context): Type = hi
35633561

35643562
/** The non-alias type bounds type with given bounds */
35653563
def derivedTypeBounds(lo: Type, hi: Type)(implicit ctx: Context) =
3566-
if ((lo eq this.lo) && (hi eq this.hi) && (variance == 0)) this
3564+
if ((lo eq this.lo) && (hi eq this.hi)) this
35673565
else TypeBounds(lo, hi)
35683566

3569-
/** If this is an alias, a derived alias with the new variance,
3570-
* Otherwise the type itself.
3571-
*/
3572-
def withVariance(variance: Int)(implicit ctx: Context) = this match {
3573-
case tp: TypeAlias => tp.derivedTypeAlias(tp.alias, variance)
3574-
case _ => this
3575-
}
3576-
35773567
def contains(tp: Type)(implicit ctx: Context): Boolean = tp match {
35783568
case tp: TypeBounds => lo <:< tp.lo && tp.hi <:< hi
35793569
case tp: ClassInfo =>
@@ -3603,58 +3593,31 @@ object Types {
36033593
case _ => super.| (that)
36043594
}
36053595

3606-
/** The implied bounds, where aliases are mapped to intervals from
3607-
* Nothing/Any
3608-
*/
3609-
def boundsInterval(implicit ctx: Context): TypeBounds = this
3610-
3611-
/** If this type and that type have the same variance, this variance, otherwise 0 */
3612-
final def commonVariance(that: TypeBounds): Int = (this.variance + that.variance) / 2
3596+
override def computeHash = doHash(lo, hi)
36133597

3614-
override def computeHash = doHash(variance, lo, hi)
3598+
// @!!! we are not systematic when we do referntial vs structural comparisons.
3599+
// Do referential everywhere?
36153600
override def equals(that: Any): Boolean = that match {
36163601
case that: TypeBounds =>
3617-
(this.lo eq that.lo) && (this.hi eq that.hi) && (this.variance == that.variance)
3602+
(this.lo eq that.lo) && (this.hi eq that.hi)
36183603
case _ =>
36193604
false
36203605
}
3621-
3622-
override def toString =
3623-
if (lo eq hi) s"TypeAlias($lo, $variance)" else s"TypeBounds($lo, $hi)"
36243606
}
36253607

36263608
class RealTypeBounds(lo: Type, hi: Type) extends TypeBounds(lo, hi)
36273609

36283610
// @!!! get rid of variance
3629-
abstract class TypeAlias(val alias: Type, override val variance: Int) extends TypeBounds(alias, alias) {
3630-
/** pre: this is a type alias */
3631-
def derivedTypeAlias(alias: Type, variance: Int = this.variance)(implicit ctx: Context) =
3632-
if ((alias eq this.alias) && (variance == this.variance)) this
3633-
else TypeAlias(alias, variance)
3634-
3635-
override def & (that: TypeBounds)(implicit ctx: Context): TypeBounds = {
3636-
val v = this commonVariance that
3637-
if (v > 0) derivedTypeAlias(this.hi & that.hi, v)
3638-
else if (v < 0) derivedTypeAlias(this.lo | that.lo, v)
3639-
else super.& (that)
3640-
}
3611+
abstract class TypeAlias(val alias: Type) extends TypeBounds(alias, alias) {
36413612

3642-
override def | (that: TypeBounds)(implicit ctx: Context): TypeBounds = {
3643-
val v = this commonVariance that
3644-
if (v > 0) derivedTypeAlias(this.hi | that.hi, v)
3645-
else if (v < 0) derivedTypeAlias(this.lo & that.lo, v)
3646-
else super.| (that)
3647-
}
3648-
3649-
override def boundsInterval(implicit ctx: Context): TypeBounds =
3650-
if (variance == 0) this
3651-
else if (variance < 0) TypeBounds.lower(alias)
3652-
else TypeBounds.upper(alias)
3613+
/** pre: this is a type alias */
3614+
def derivedTypeAlias(alias: Type)(implicit ctx: Context) =
3615+
if (alias eq this.alias) this else TypeAlias(alias)
36533616

3654-
override def computeHash = doHash(variance, alias)
3617+
override def computeHash = doHash(alias)
36553618
}
36563619

3657-
class CachedTypeAlias(alias: Type, variance: Int) extends TypeAlias(alias, variance)
3620+
class CachedTypeAlias(alias: Type) extends TypeAlias(alias)
36583621

36593622
object TypeBounds {
36603623
def apply(lo: Type, hi: Type)(implicit ctx: Context): TypeBounds =
@@ -3665,8 +3628,8 @@ object Types {
36653628
}
36663629

36673630
object TypeAlias {
3668-
def apply(alias: Type, variance: Int = 0)(implicit ctx: Context) =
3669-
unique(new CachedTypeAlias(alias, variance))
3631+
def apply(alias: Type)(implicit ctx: Context) =
3632+
unique(new CachedTypeAlias(alias))
36703633
def unapply(tp: TypeAlias): Option[Type] = Some(tp.alias)
36713634
}
36723635

@@ -3915,7 +3878,7 @@ object Types {
39153878
derivedRefinedType(tp, this(tp.parent), this(tp.refinedInfo))
39163879

39173880
case tp: TypeAlias =>
3918-
derivedTypeAlias(tp, atVariance(variance * tp.variance)(this(tp.alias)))
3881+
derivedTypeAlias(tp, atVariance(0)(this(tp.alias)))
39193882

39203883
case tp: TypeBounds =>
39213884
variance = -variance
@@ -4108,22 +4071,12 @@ object Types {
41084071
else info match {
41094072
case Range(infoLo: TypeBounds, infoHi: TypeBounds) =>
41104073
assert(variance == 0)
4111-
val v1 = infoLo.variance
4112-
val v2 = infoHi.variance
4113-
// There's some weirdness coming from the way aliases can have variance
4114-
// If infoLo and infoHi are both aliases with the same non-zero variance
4115-
// we can propagate to a range of the refined types. If they are both
4116-
// non-alias ranges we know that infoLo <:< infoHi and therefore we can
4117-
// propagate to refined types with infoLo and infoHi as bounds.
4118-
// In all other cases, Nothing..Any is the only interval that contains
4119-
// the range. i966.scala is a test case.
4120-
if (v1 > 0 && v2 > 0) propagate(infoLo, infoHi)
4121-
else if (v1 < 0 && v2 < 0) propagate(infoHi, infoLo)
4122-
else if (!infoLo.isAlias && !infoHi.isAlias) propagate(infoLo, infoHi)
4074+
if (!infoLo.isAlias && !infoHi.isAlias) propagate(infoLo, infoHi)
41234075
else range(tp.bottomType, tp.topType)
41244076
// Using `parent` instead of `tp.topType` would be better for normal refinements,
41254077
// but it would also turn *-types into hk-types, which is not what we want.
41264078
// We should revisit this point in case we represent applied types not as refinements anymore.
4079+
// @!!! revisit
41274080
case Range(infoLo, infoHi) =>
41284081
propagate(infoLo, infoHi)
41294082
case _ =>
@@ -4303,7 +4256,7 @@ object Types {
43034256
this(this(x, tp.parent), tp.refinedInfo)
43044257

43054258
case bounds @ TypeBounds(lo, hi) =>
4306-
if (lo eq hi) atVariance(variance * bounds.variance)(this(x, lo))
4259+
if (lo eq hi) atVariance(0)(this(x, lo))
43074260
else {
43084261
variance = -variance
43094262
val y = this(x, lo)

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,11 @@ Standard-Section: "ASTs" TopLevelStat*
153153
TYPEREFpkg fullyQualified_NameRef
154154
TYPEREF possiblySigned_NameRef qual_Type
155155
RECtype parent_Type
156+
TYPEALIAS alias_Type
156157
SUPERtype Length this_Type underlying_Type
157158
REFINEDtype Length underlying_Type refinement_NameRef info_Type
158159
APPLIEDtype Length tycon_Type arg_Type*
159160
TYPEBOUNDS Length low_Type high_Type
160-
TYPEALIAS Length alias_Type (COVARIANT | CONTRAVARIANT)?
161161
ANNOTATEDtype Length underlying_Type fullAnnotation_Term
162162
ANDtype Length left_Type right_Type
163163
ORtype Length left_Type right_Type
@@ -322,7 +322,8 @@ object TastyFormat {
322322
final val PRIVATEqualified = 104
323323
final val PROTECTEDqualified = 105
324324
final val RECtype = 106
325-
final val SINGLETONtpt = 107
325+
final val TYPEALIAS = 107
326+
final val SINGLETONtpt = 108
326327

327328
final val IDENT = 112
328329
final val IDENTtpt = 113
@@ -370,7 +371,6 @@ object TastyFormat {
370371
final val APPLIEDtpt = 162
371372
final val TYPEBOUNDS = 163
372373
final val TYPEBOUNDStpt = 164
373-
final val TYPEALIAS = 165
374374
final val ANDtype = 166
375375
final val ANDtpt = 167
376376
final val ORtype = 168

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,7 @@ class TreePickler(pickler: TastyPickler) {
220220
pickleType(tpe.parent)
221221
case tpe: TypeAlias =>
222222
writeByte(TYPEALIAS)
223-
withLength {
224-
pickleType(tpe.alias, richTypes)
225-
tpe.variance match {
226-
case 1 => writeByte(COVARIANT)
227-
case -1 => writeByte(CONTRAVARIANT)
228-
case 0 =>
229-
}
230-
}
223+
pickleType(tpe.alias, richTypes)
231224
case tpe: TypeBounds =>
232225
writeByte(TYPEBOUNDS)
233226
withLength { pickleType(tpe.lo, richTypes); pickleType(tpe.hi, richTypes) }

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,6 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
232232
readType().appliedTo(until(end)(readType()))
233233
case TYPEBOUNDS =>
234234
TypeBounds(readType(), readType())
235-
case TYPEALIAS =>
236-
val alias = readType()
237-
val variance =
238-
if (nextByte == COVARIANT) { readByte(); 1 }
239-
else if (nextByte == CONTRAVARIANT) { readByte(); -1 }
240-
else 0
241-
TypeAlias(alias, variance)
242235
case ANNOTATEDtype =>
243236
AnnotatedType(readType(), Annotation(readTerm()))
244237
case ANDtype =>
@@ -296,6 +289,8 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
296289
RecType(rt => registeringType(rt, readType()))
297290
case RECthis =>
298291
readTypeRef().asInstanceOf[RecType].recThis
292+
case TYPEALIAS =>
293+
TypeAlias(readType())
299294
case SHARED =>
300295
val ref = readAddr()
301296
typeAtAddr.getOrElseUpdate(ref, forkAt(ref).readType())
@@ -680,7 +675,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
680675
sym.info = NoCompleter
681676
sym.info = rhs.tpe match {
682677
case _: TypeBounds | _: ClassInfo => checkNonCyclic(sym, rhs.tpe, reportErrors = false)
683-
case _ => TypeAlias(rhs.tpe, sym.variance)
678+
case _ => TypeAlias(rhs.tpe)
684679
}
685680
TypeDef(rhs)
686681
}

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
314314
protected def toTextRHS(tp: Type): Text = controlled {
315315
homogenize(tp) match {
316316
case tp: TypeAlias =>
317-
val eql =
318-
if (tp.variance == 1) " =+ "
319-
else if (tp.variance == -1) " =- "
320-
else " = "
321-
eql ~ toText(tp.alias)
317+
" = " ~ toText(tp.alias)
322318
case tp @ TypeBounds(lo, hi) =>
323319
(if (lo isRef defn.NothingClass) Text() else " >: " ~ toText(lo)) ~
324320
(if (hi isRef defn.AnyClass) Text() else " <: " ~ toText(hi))

compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
379379
val name = "_"
380380
val ref = new api.ParameterRef(name)
381381
new api.Existential(ref,
382-
Array(apiTypeParameter(name, arg.variance, lo, hi)))
382+
Array(apiTypeParameter(name, 0, lo, hi)))
383383
}
384384
case _ =>
385385
apiType(arg)

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,10 +1178,7 @@ class Namer { typer: Typer =>
11781178
}
11791179
val rhsBodyType = typedAheadType(rhs).tpe
11801180
val rhsType = if (isDerived) rhsBodyType else abstracted(rhsBodyType)
1181-
val unsafeInfo = rhsType match {
1182-
case bounds: TypeBounds => bounds
1183-
case alias => TypeAlias(alias, if (sym is Local) sym.variance else 0)
1184-
}
1181+
val unsafeInfo = rhsType.toBounds
11851182
if (isDerived) sym.info = unsafeInfo
11861183
else {
11871184
sym.info = NoCompleter

compiler/src/dotty/tools/dotc/typer/Variances.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ object Variances {
7373
case tp @ TypeRef(pre, _) =>
7474
if (tp.symbol == tparam) Covariant else varianceInType(pre)(tparam)
7575
case tp @ TypeBounds(lo, hi) =>
76-
if (lo eq hi) compose(varianceInType(hi)(tparam), tp.variance)
76+
if (lo eq hi) cut(varianceInType(hi)(tparam))
7777
else flip(varianceInType(lo)(tparam)) & varianceInType(hi)(tparam)
7878
case tp @ RefinedType(parent, _, rinfo) =>
7979
varianceInType(parent)(tparam) & varianceInType(rinfo)(tparam)

tests/pos/Patterns.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ object Patterns {
1212
}
1313
}
1414
d match {
15-
case WildcardType(bounds: TypeBounds) =>
16-
bounds.variance
15+
case WildcardType(bounds: TypeBounds) => bounds.lo
1716
case a @ Assign(Ident(id), rhs) => id
1817
case a: Object => a
1918
}

0 commit comments

Comments
 (0)