aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Typer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-07-21 18:42:17 +0200
committerMartin Odersky <odersky@gmail.com>2015-09-18 18:12:17 +0200
commite8aecfa4d48383321549aa8f1ec8d1edb0ccaf06 (patch)
tree07b68f223127eff223adbbe4602c05b4a04339c6 /src/dotty/tools/dotc/typer/Typer.scala
parent4148970a984de945c69f345381f0f03e84d7d6c2 (diff)
downloaddotty-e8aecfa4d48383321549aa8f1ec8d1edb0ccaf06.tar.gz
dotty-e8aecfa4d48383321549aa8f1ec8d1edb0ccaf06.tar.bz2
dotty-e8aecfa4d48383321549aa8f1ec8d1edb0ccaf06.zip
Disallow wildcard arguments to higher-kinded types...
...unless the HK type can be eta-reduced to a class type.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index d35356a85..a3c64f526 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -844,7 +844,34 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
val args1 = args.zipWithConserve(tparams)(typedArg(_, _)).asInstanceOf[List[Tree]]
// check that arguments conform to bounds is done in phase PostTyper
- assignType(cpy.AppliedTypeTree(tree)(tpt1, args1), tpt1, args1)
+ val tree1 = assignType(cpy.AppliedTypeTree(tree)(tpt1, args1), tpt1, args1)
+ if (tree1.tpe.isHKApply)
+ for (arg @ TypeBoundsTree(_, _) <- args1)
+ ctx.error("illegal wildcard type argument; does not correspond to type parameter of a class", arg.pos)
+ // The reason for outlawing such arguments is illustrated by the following example.
+ // Say we have
+ //
+ // type RMap[A, B] = Map[B, A]
+ //
+ // Then
+ //
+ // Rmap[_, Int]
+ //
+ // translates to
+ //
+ // Lambda$I { type hk$0; type hk$1 = Int; type $apply = Map[$hk1, $hk0] } # $apply
+ //
+ // Let's call the last type T. You would expect that
+ //
+ // Map[Int, String] <: RMap[_, Int]
+ //
+ // But that's not the case given the standard subtyping rules. In fact, the rhs reduces to
+ //
+ // Map[Int, T # $hk0]
+ //
+ // That means the second argument to `Map` is unknown and String is certainly not a subtype of it.
+ // To avoid the surprise we outlaw problematic wildcard arguments from the start.
+ tree1
}
}