summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2015-11-26 14:26:33 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-02-01 13:23:20 +1000
commit6f8c05722ba4452279e353df2d81b58f260277d2 (patch)
tree2388344a8a22a4a059977e0d021bbb589017c254 /src
parent907fe03e57b3cac4d0a67663edcd2b3b040e6ff8 (diff)
downloadscala-6f8c05722ba4452279e353df2d81b58f260277d2.tar.gz
scala-6f8c05722ba4452279e353df2d81b58f260277d2.tar.bz2
scala-6f8c05722ba4452279e353df2d81b58f260277d2.zip
SI-9542 Unify different reprs. of module type refs
The new unit test shows failures in transitivity of subtyping and type equivalence, which boil down the the inconsistent handling of the semantically equivalent: ThisType(pre, ModuleClass) ModuleTypeRef(pre, ModuleClass) SingleType(pre, Module) This commit: - adds a case to `normalizePlus` to unwrap a `ThisType` to a `ModuleTypeRef` - Use `normalizePlus` more widely during subtype comparison - refactor `fourthTry` (part of `isSubType`) to remove code that becomes obviated by the use of `normalizePlus`. This fixes the regression in the extension methods phase which was triggered by https://github.com/scala/scala/pull/4749. We can also fix that regression by tweaking the extension methods phase itself to emit the `ThisType` representation of the owner of the value class, as before. I plan to demonstrate the two approaches to fixing the regression on separate branches, and the propose that the merged result of these two is useds.
Diffstat (limited to 'src')
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala11
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeComparers.scala28
2 files changed, 17 insertions, 22 deletions
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 2e6cd819b4..e53b47e808 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -3970,14 +3970,15 @@ trait Types
}
}
- def normalizePlus(tp: Type) = (
+ def normalizePlus(tp: Type): Type = {
if (isRawType(tp)) rawToExistential(tp)
else tp.normalize match {
- // Unify the two representations of module classes
- case st @ SingleType(_, sym) if sym.isModule => st.underlying.normalize
- case _ => tp.normalize
+ // Unify the representations of module classes
+ case st@SingleType(_, sym) if sym.isModule => st.underlying.normalize
+ case st@ThisType(sym) if sym.isModuleClass => normalizePlus(st.underlying)
+ case _ => tp.normalize
}
- )
+ }
/*
todo: change to:
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
index f9b10c90be..e6d7b11cad 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
@@ -463,7 +463,7 @@ trait TypeComparers {
case SingletonClass => tp1.isStable || fourthTry
case _: ClassSymbol => classOnRight
case _: TypeSymbol if sym2.isDeferred => abstractTypeOnRight(tp2.bounds.lo) || fourthTry
- case _: TypeSymbol => retry(tp1.normalize, tp2.normalize)
+ case _: TypeSymbol => retry(normalizePlus(tp1), normalizePlus(tp2))
case _ => fourthTry
}
}
@@ -517,7 +517,7 @@ trait TypeComparers {
* - handle typerefs, refined types, and singleton types.
*/
def fourthTry = {
- def retry(lhs: Type, rhs: Type) = isSubType(lhs, rhs, depth)
+ def retry(lhs: Type, rhs: Type) = ((tp1 ne lhs) || (tp2 ne rhs)) && isSubType(lhs, rhs, depth)
def abstractTypeOnLeft(hi: Type) = isDifferentTypeConstructor(tp1, hi) && retry(hi, tp2)
tp1 match {
@@ -526,22 +526,16 @@ trait TypeComparers {
case TypeRef(_, sym2, _) => sym1 isBottomSubClass sym2
case _ => isSingleType(tp2) && retry(tp1, tp2.widen)
}
- def moduleOnLeft = tp2 match {
- case SingleType(pre2, sym2) => equalSymsAndPrefixes(sym1.sourceModule, pre1, sym2, pre2)
- case _ => false
- }
- def classOnLeft = (
- if (isRawType(tp1)) retry(rawToExistential(tp1), tp2)
- else if (sym1.isModuleClass) moduleOnLeft
- else sym1.isRefinementClass && retry(sym1.info, tp2)
- )
+
sym1 match {
- case NothingClass => true
- case NullClass => nullOnLeft
- case _: ClassSymbol => classOnLeft
- case _: TypeSymbol if sym1.isDeferred => abstractTypeOnLeft(tp1.bounds.hi)
- case _: TypeSymbol => retry(tp1.normalize, tp2.normalize)
- case _ => false
+ case NothingClass => true
+ case NullClass => nullOnLeft
+ case _: ClassSymbol if isRawType(tp1) => retry(normalizePlus(tp1), normalizePlus(tp2))
+ case _: ClassSymbol if sym1.isModuleClass => retry(normalizePlus(tp1), normalizePlus(tp2))
+ case _: ClassSymbol if sym1.isRefinementClass => retry(sym1.info, tp2)
+ case _: TypeSymbol if sym1.isDeferred => abstractTypeOnLeft(tp1.bounds.hi)
+ case _: TypeSymbol => retry(normalizePlus(tp1), normalizePlus(tp2))
+ case _ => false
}
case RefinedType(parents, _) => parents exists (retry(_, tp2))
case _: SingletonType => retry(tp1.underlying, tp2)