Skip to content

Commit

Permalink
Special case comparison with Any
Browse files Browse the repository at this point in the history
Add the rule T <: Any for any *-Type T. This was not include fully before. We
did have the rule that T <: Any, if Any is in the base types of T. However,
it could be that the base type wrt Any does not exist. Example:

    Any#L <: Any

yielded false before, now yields true. This error manifested itself in i4031.scala.

With the new rule, we can drop again the special case in derivedSelect.

TODO: in the context of scala#4108, this seems questionable. Also, `Any#L` seems an
invalid type (even tho it is sound to consider it empty), and we'd probably not
want to accept it if the user writes it; here it is only OK because it's
introduced by avoidance. Or are user-written types checked elsewhere?
  • Loading branch information
odersky authored and Blaisorblade committed Dec 2, 2018
1 parent d655af2 commit 27b2456
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 8 deletions.
14 changes: 7 additions & 7 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
thirdTry
case tp1: TypeParamRef =>
def flagNothingBound = {
if (!frozenConstraint && tp2.isRef(defn.NothingClass) && state.isGlobalCommittable) {
if (!frozenConstraint && tp2.isRef(NothingClass) && state.isGlobalCommittable) {
def msg = s"!!! instantiated to Nothing: $tp1, constraint = ${constraint.show}"
if (Config.failOnInstantiationToNothing) assert(false, msg)
else ctx.log(msg)
Expand Down Expand Up @@ -404,8 +404,9 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
if (cls2.isClass) {
if (cls2.typeParams.isEmpty) {
if (cls2 eq AnyKindClass) return true
if (tp1.isRef(defn.NothingClass)) return true
if (tp1.isRef(NothingClass)) return true
if (tp1.isLambdaSub) return false
if (cls2 eq AnyClass) return true
// Note: We would like to replace this by `if (tp1.hasHigherKind)`
// but right now we cannot since some parts of the standard library rely on the
// idiom that e.g. `List <: Any`. We have to bootstrap without scalac first.
Expand All @@ -417,7 +418,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
val base = tp1.baseType(cls2)
if (base.typeSymbol == cls2) return true
}
else if (tp1.isLambdaSub && !tp1.isRef(defn.AnyKindClass))
else if (tp1.isLambdaSub && !tp1.isRef(AnyKindClass))
return recur(tp1, EtaExpansion(cls2.typeRef))
}
fourthTry
Expand Down Expand Up @@ -1382,7 +1383,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
// at run time. It would not work to replace that with `Nothing`.
// However, maybe we can still apply the replacement to
// types which are not explicitly written.
defn.NothingType
NothingType
case _ => andType(tp1, tp2)
}
case _ => andType(tp1, tp2)
Expand All @@ -1393,8 +1394,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
}

/** The greatest lower bound of a list types */
final def glb(tps: List[Type]): Type =
((defn.AnyType: Type) /: tps)(glb)
final def glb(tps: List[Type]): Type = ((AnyType: Type) /: tps)(glb)

/** The least upper bound of two types
* @param canConstrain If true, new constraints might be added to simplify the lub.
Expand Down Expand Up @@ -1424,7 +1424,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {

/** The least upper bound of a list of types */
final def lub(tps: List[Type]): Type =
((defn.NothingType: Type) /: tps)(lub(_,_, canConstrain = false))
((NothingType: Type) /: tps)(lub(_,_, canConstrain = false))

/** Try to produce joint arguments for a lub `A[T_1, ..., T_n] | A[T_1', ..., T_n']` using
* the following strategies:
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4588,7 +4588,7 @@ object Types {
forwarded.orElse(
range(super.derivedSelect(tp, preLo).loBound, super.derivedSelect(tp, preHi).hiBound))
case _ =>
if (pre == defn.AnyType) pre else super.derivedSelect(tp, pre) match {
super.derivedSelect(tp, pre) match {
case TypeBounds(lo, hi) => range(lo, hi)
case tp => tp
}
Expand Down

0 comments on commit 27b2456

Please sign in to comment.