summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala29
-rw-r--r--test/files/pos/t7983.scala31
2 files changed, 43 insertions, 17 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 01acbb8cc2..025c262c8d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -388,11 +388,11 @@ trait Implicits {
*/
private def dominates(dtor: Type, dted: Type): Boolean = {
def core(tp: Type): Type = tp.dealiasWiden match {
- case RefinedType(parents, defs) => intersectionType(parents map core, tp.typeSymbol.owner)
+ case RefinedType(parents, defs) => intersectionType(parents map core, tp.typeSymbol.owner)
case AnnotatedType(annots, tp, selfsym) => core(tp)
- case ExistentialType(tparams, result) => core(result).subst(tparams, tparams map (t => core(t.info.bounds.hi)))
- case PolyType(tparams, result) => core(result).subst(tparams, tparams map (t => core(t.info.bounds.hi)))
- case _ => tp
+ case ExistentialType(tparams, result) => core(result).subst(tparams, tparams map (t => core(t.info.bounds.hi)))
+ case PolyType(tparams, result) => core(result).subst(tparams, tparams map (t => core(t.info.bounds.hi)))
+ case _ => tp
}
def stripped(tp: Type): Type = {
// `t.typeSymbol` returns the symbol of the normalized type. If that normalized type
@@ -401,23 +401,18 @@ trait Implicits {
val syms = for (t <- tp; if t.typeSymbol.isTypeParameter) yield t.typeSymbol
deriveTypeWithWildcards(syms.distinct)(tp)
}
- def sum(xs: List[Int]) = (0 /: xs)(_ + _)
- def complexity(tp: Type): Int = tp.dealiasWiden match {
- case NoPrefix =>
- 0
- case SingleType(pre, sym) =>
- if (sym.isPackage) 0 else complexity(tp.dealiasWiden)
- case TypeRef(pre, sym, args) =>
- complexity(pre) + sum(args map complexity) + 1
- case RefinedType(parents, _) =>
- sum(parents map complexity) + 1
- case _ =>
- 1
+ def complexity(tp: Type): Int = tp.dealias match {
+ case NoPrefix => 0
+ case SingleType(pre, sym) => if (sym.isPackage) 0 else complexity(tp.dealiasWiden)
+ case ThisType(sym) => if (sym.isPackage) 0 else 1
+ case TypeRef(pre, sym, args) => complexity(pre) + (args map complexity).sum + 1
+ case RefinedType(parents, _) => (parents map complexity).sum + 1
+ case _ => 1
}
def overlaps(tp1: Type, tp2: Type): Boolean = (tp1, tp2) match {
case (RefinedType(parents, _), _) => parents exists (overlaps(_, tp2))
case (_, RefinedType(parents, _)) => parents exists (overlaps(tp1, _))
- case _ => tp1.typeSymbol == tp2.typeSymbol
+ case _ => tp1.typeSymbol == tp2.typeSymbol
}
val dtor1 = stripped(core(dtor))
val dted1 = stripped(core(dted))
diff --git a/test/files/pos/t7983.scala b/test/files/pos/t7983.scala
new file mode 100644
index 0000000000..a583e538c5
--- /dev/null
+++ b/test/files/pos/t7983.scala
@@ -0,0 +1,31 @@
+package foo.bar.baz // the package nesting level material to this bug
+
+class DivergenceTest {
+
+ trait ColumnBase[T]
+
+ trait ShapeLevel
+ trait Flat extends ShapeLevel
+ trait Lower extends Flat
+
+ class Shape2[Level <: ShapeLevel, -M, U]
+
+ implicit final def columnBaseShape[Level >: Flat <: ShapeLevel, T, C <: ColumnBase[_]]
+ (implicit ev: C <:< ColumnBase[T]
+ ): Shape2[Level, C, T] = ???
+
+ implicit final def intShape[Level <: ShapeLevel, T]: Shape2[Level, Int, Int] = ???
+ implicit final def tuple2Shape[Level <: ShapeLevel, M1,M2, U1,U2]
+ (implicit u1: Shape2[_ <: Level, M1, U1],
+ u2: Shape2[_ <: Level, M2, U2]
+ ): Shape2[Level, (M1,M2), (U1,U2)] = ???
+
+ def foo {
+ class Coffees extends ColumnBase[Int]
+
+ def map1[F, T](f: F)(implicit shape: Shape2[_ <: Flat, F, T]) = ???
+
+ map1(((1, null: Coffees), 1))
+ map1(((null: Coffees, 1), 1)) // fails with implicit divergence error in 2.11.0-M6, works under 2.10.3
+ }
+}