diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 52 | ||||
-rw-r--r-- | test/files/neg/t3399.check | 4 | ||||
-rw-r--r-- | test/files/neg/t3399.scala | 24 |
3 files changed, 56 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 880137ea2c..15c5fb6c0e 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -5087,37 +5087,41 @@ A type's typeSymbol should never be inspected directly. case List(tp) => Some(tp) case TypeRef(_, sym, _) :: rest => - val pres = tps map (_.prefix) + val pres = tps map (_.prefix) // prefix normalizes automatically val pre = if (variance == 1) lub(pres, depth) else glb(pres, depth) - val argss = tps map (_.typeArgs) + val argss = tps map (_.normalize.typeArgs) // symbol equality (of the tp in tps) was checked using typeSymbol, which normalizes, so should normalize before retrieving arguments val capturedParams = new ListBuffer[Symbol] - val args = (sym.typeParams, argss.transpose).zipped map { - (tparam, as) => - if (depth == 0) - if (tparam.variance == variance) AnyClass.tpe - else if (tparam.variance == -variance) NothingClass.tpe - else NoType - else - if (tparam.variance == variance) lub(as, decr(depth)) - else if (tparam.variance == -variance) glb(as, decr(depth)) - else { - val l = lub(as, decr(depth)) - val g = glb(as, decr(depth)) - if (l <:< g) l - else { // Martin: I removed this, because incomplete. Not sure there is a good way to fix it. For the moment we - // just err on the conservative side, i.e. with a bound that is too high. - // if(!(tparam.info.bounds contains tparam)){ //@M can't deal with f-bounds, see #2251 - val qvar = commonOwner(as) freshExistential "" setInfo TypeBounds(g, l) - capturedParams += qvar - qvar.tpe - } - } - } try { + val args = (sym.typeParams, argss.transpose).zipped map { + (tparam, as) => + if (depth == 0) + if (tparam.variance == variance) AnyClass.tpe + else if (tparam.variance == -variance) NothingClass.tpe + else NoType + else + if (tparam.variance == variance) lub(as, decr(depth)) + else if (tparam.variance == -variance) glb(as, decr(depth)) + else { + val l = lub(as, decr(depth)) + val g = glb(as, decr(depth)) + if (l <:< g) l + else { // Martin: I removed this, because incomplete. Not sure there is a good way to fix it. For the moment we + // just err on the conservative side, i.e. with a bound that is too high. + // if(!(tparam.info.bounds contains tparam)){ //@M can't deal with f-bounds, see #2251 + val qvar = commonOwner(as) freshExistential "" setInfo TypeBounds(g, l) + capturedParams += qvar + qvar.tpe + } + } + } if (args contains NoType) None else Some(existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args))) } catch { case ex: MalformedType => None + case ex: IndexOutOfBoundsException => // transpose freaked out because of irregular argss + // catching just in case (shouldn't happen, but also doesn't cost us) + if (settings.debug.value) log("transposed irregular matrix!?"+ (tps, argss)) + None } case SingleType(_, sym) :: rest => val pres = tps map (_.prefix) diff --git a/test/files/neg/t3399.check b/test/files/neg/t3399.check new file mode 100644 index 0000000000..eb6c679704 --- /dev/null +++ b/test/files/neg/t3399.check @@ -0,0 +1,4 @@ +t3399.scala:23: error: could not find implicit value for parameter e: =:=[Nats.Add[Nats._1,Nats._1],Nats._1] + implicitly[ Add[_1, _1] =:= _1] + ^ +one error found diff --git a/test/files/neg/t3399.scala b/test/files/neg/t3399.scala new file mode 100644 index 0000000000..3edaa0724f --- /dev/null +++ b/test/files/neg/t3399.scala @@ -0,0 +1,24 @@ +object Nats { + sealed trait Nat { + // fold right on N, N-1, ..., 1 + type FoldR[Init <: Type, Type, F <: Fold[Nat, Type]] <: Type + } + sealed trait _0 extends Nat { + type FoldR[Init <: Type, Type, F <: Fold[Nat, Type]] = Init + } + sealed trait Succ[N <: Nat] extends Nat { + type FoldR[Init <: Type, Type, F <: Fold[Nat, Type]] = + F#Apply[Succ[N], N#FoldR[Init, Type, F]] + } + + type Add[A <: Nat, B <: Nat] = A#FoldR[B, Nat, Inc] + trait Fold[-Elem, Value] { + type Apply[N <: Elem, Acc <: Value] <: Value + } + type Inc = Fold[Any, Nat] { + type Apply[N <: Any, Acc <: Nat] = Succ[Acc] + } + + type _1 = Succ[_0] + implicitly[ Add[_1, _1] =:= _1] +}
\ No newline at end of file |