blob: c54df1f22985b872e01741d3cb9052ea5f8794a5 (
plain) (
tree)
|
|
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())
}
|