diff options
author | Martin Odersky <odersky@gmail.com> | 2015-07-21 18:42:17 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-09-18 18:12:17 +0200 |
commit | e8aecfa4d48383321549aa8f1ec8d1edb0ccaf06 (patch) | |
tree | 07b68f223127eff223adbbe4602c05b4a04339c6 /src/dotty/tools/dotc/typer/Typer.scala | |
parent | 4148970a984de945c69f345381f0f03e84d7d6c2 (diff) | |
download | dotty-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.scala | 29 |
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 } } |