diff options
author | Martin Odersky <odersky@gmail.com> | 2015-03-02 22:46:17 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-03-18 11:14:13 +0100 |
commit | 6801850859cfdd33431ed63618559a224b1227fb (patch) | |
tree | c89e08356d4b85e38d75e3a40c9710dfa50257a7 /src/dotty/tools/dotc | |
parent | 8f3e32781e9112e1567b9a5a78c52acd55b3506a (diff) | |
download | dotty-6801850859cfdd33431ed63618559a224b1227fb.tar.gz dotty-6801850859cfdd33431ed63618559a224b1227fb.tar.bz2 dotty-6801850859cfdd33431ed63618559a224b1227fb.zip |
More careful determination of MethodType#isDependent
If a result type is not fully defined (i.e. has type variables),
dependency status depends on the instantiation of the variables.
In this case we now still ignore the variable but do not cache
the status for future uses.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index c4f07fb8c..5ddcb62c8 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1940,7 +1940,13 @@ object Types { } else resType - private[this] var myDependencyStatus: DependencyStatus = Unknown + var myDependencyStatus: DependencyStatus = Unknown + + private def combine(x: DependencyStatus, y: DependencyStatus): DependencyStatus = { + val status = (x & StatusMask) max (y & StatusMask) + val provisional = (x | y) & Provisional + (if (status == TrueDeps) status else status | provisional).toByte + } /** The dependency status of this method. Some examples: * @@ -1951,26 +1957,27 @@ object Types { * // dependency can be eliminated by dealiasing. */ private def dependencyStatus(implicit ctx: Context): DependencyStatus = { - if (myDependencyStatus == Unknown) { + if (myDependencyStatus != Unknown) myDependencyStatus + else { val isDepAcc = new TypeAccumulator[DependencyStatus] { def apply(x: DependencyStatus, tp: Type) = if (x == TrueDeps) x - else x max { + else tp match { case MethodParam(`thisMethodType`, _) => TrueDeps case tp @ TypeRef(MethodParam(`thisMethodType`, _), name) => tp.info match { // follow type alias to avoid dependency - case TypeAlias(alias) => apply(x, alias) max FalseDeps + case TypeAlias(alias) => combine(apply(x, alias), FalseDeps) case _ => TrueDeps } - case _ => - foldOver(x, tp) + case tp: TypeVar if !tp.isInstantiated => combine(x, Provisional) + case _ => foldOver(x, tp) } - } } - myDependencyStatus = isDepAcc(NoDeps, resType) + val result = isDepAcc(NoDeps, resType) + if ((result & Provisional) == 0) myDependencyStatus = result + (result & StatusMask).toByte } - myDependencyStatus } /** Does result type contain references to parameters of this method type, @@ -2062,6 +2069,8 @@ object Types { private final val NoDeps: DependencyStatus = 1 // no dependent parameters found private final val FalseDeps: DependencyStatus = 2 // all dependent parameters are prefixes of non-depended alias types private final val TrueDeps: DependencyStatus = 3 // some truly dependent parameters exist + private final val StatusMask: DependencyStatus = 3 // the bits indicating actual dependency status + private final val Provisional: DependencyStatus = 4 // set if dependency status can still change due to type variable instantiations } object JavaMethodType extends MethodTypeCompanion { |