aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-03-02 22:46:17 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-03-18 11:14:13 +0100
commit6801850859cfdd33431ed63618559a224b1227fb (patch)
treec89e08356d4b85e38d75e3a40c9710dfa50257a7 /src/dotty/tools/dotc/core/Types.scala
parent8f3e32781e9112e1567b9a5a78c52acd55b3506a (diff)
downloaddotty-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/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala27
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 {