diff options
author | odersky <odersky@gmail.com> | 2016-09-04 19:32:13 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-04 19:32:13 +0300 |
commit | a0e7adb070ee9c73c0cca081196198296cbd63ab (patch) | |
tree | 955c80e27562ed452f92226f534ead57089db812 /tests/pos | |
parent | 1650add0d7c1f3108fcacd15bb989ebd42234888 (diff) | |
parent | 2dfe4db8b3babefeba83eb30ffdc92a5d84665bb (diff) | |
download | dotty-a0e7adb070ee9c73c0cca081196198296cbd63ab.tar.gz dotty-a0e7adb070ee9c73c0cca081196198296cbd63ab.tar.bz2 dotty-a0e7adb070ee9c73c0cca081196198296cbd63ab.zip |
Merge pull request #1482 from dotty-staging/fix-asapplicable-safe
More tweaks to type inference
Diffstat (limited to 'tests/pos')
-rw-r--r-- | tests/pos/isApplicableSafe.scala | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tests/pos/isApplicableSafe.scala b/tests/pos/isApplicableSafe.scala new file mode 100644 index 000000000..c54df1f22 --- /dev/null +++ b/tests/pos/isApplicableSafe.scala @@ -0,0 +1,54 @@ +import reflect.ClassTag + +// The same problems arise in real arrays. +class A { + + class Array[T] + object Array { + def apply[T: ClassTag](xs: T*): Array[T] = ??? + def apply(x: Int, xs: Int*): Array[Int] = ??? + } + + // Any of Array[List[Symbol]], List[Array[Symbol]], or List[List[Symbol]] compile. + var xs: Array[Array[Symbol]] = _ + var ys: Array[Map[Symbol, Set[Symbol]]] = _ + + //xs = Array(Array()) + // gives: + // + // isApplicableSafe.scala:15: error: type mismatch: + // found : A.this.Array[Nothing] + // required: A.this.Array[Symbol] + // xs = Array(Array()) + // + // Here's the sequence of events that leads to this problem: + // + // 1. the outer Array.apply is overloaded, so we need to typecheck the inner one + // without an expected prototype + // + // 2. The inner Array.apply needs a ClassTag, so we need to instantiate + // its type variable, and the best instantiation is Nothing. + // + // To prevent this, we'd need to do several things: + // + // 1. Pass argument types lazily into the isApplicable call in resolveOverloaded, + // so that we can call constrainResult before any arguments are evaluated. + // + // 2. This is still not enough because the result type is initially an IgnoredProto. + // (because an implicit might have to be inserted around the call, so we cannot + // automatically assume that the call result is a subtype of the expected type). + // Hence, we need to somehow create a closure in constrainResult that does the + // comparison with the real expected result type "on demand". + // + // 3. When instantiating a type variable we need to categorize that some instantiations + // are suspicous (e.g. scalac avoids instantiating to Nothing). In these + // circumstances we should try to excute the delayed constrainResult closures + // in order to get a better instance type. + // + // Quite a lot of work. It's looking really complicated to fix this. + + + ys = Array(Map(), Map()) + + val zs = Array(Map()) +} |