diff options
author | Martin Odersky <odersky@gmail.com> | 2016-04-27 16:38:39 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-04-27 16:38:39 +0200 |
commit | ed8e2ba6623e755662ef503c0dbda72b40c9e27f (patch) | |
tree | 7176f21a1e39587c9ac8f48a2f2788eaf9638cfb | |
parent | 89b68608dda803398e16fa2146a1b94b7e59e04e (diff) | |
download | dotty-ed8e2ba6623e755662ef503c0dbda72b40c9e27f.tar.gz dotty-ed8e2ba6623e755662ef503c0dbda72b40c9e27f.tar.bz2 dotty-ed8e2ba6623e755662ef503c0dbda72b40c9e27f.zip |
Dealias more types in resultType
Since we now recognize more false dependencies,
we have to dealias the new dependencies accordingly.
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index f99e8eba6..8ef0e9fd1 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -2209,9 +2209,11 @@ object Types { if (dependencyStatus == FalseDeps) { // dealias all false dependencies val dealiasMap = new TypeMap { def apply(tp: Type) = tp match { - case tp @ TypeRef(MethodParam(`thisMethodType`, _), name) => // follow type alias to avoid dependency - val TypeAlias(alias) = tp.info - apply(alias) + case tp @ TypeRef(pre, name) => + tp.info match { + case TypeAlias(alias) if depStatus(pre) == TrueDeps => apply(alias) + case _ => mapOver(tp) + } case _ => mapOver(tp) } @@ -2222,10 +2224,31 @@ object Types { 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 + private def depStatus(tp: Type)(implicit ctx: Context): DependencyStatus = { + def combine(x: DependencyStatus, y: DependencyStatus) = { + val status = (x & StatusMask) max (y & StatusMask) + val provisional = (x | y) & Provisional + (if (status == TrueDeps) status else status | provisional).toByte + } + val depStatusAcc = new TypeAccumulator[DependencyStatus] { + def apply(status: DependencyStatus, tp: Type) = + if (status == TrueDeps) status + else + tp match { + case MethodParam(`thisMethodType`, _) => TrueDeps + case tp: TypeRef => + val status1 = foldOver(status, tp) + tp.info match { // follow type alias to avoid dependency + case TypeAlias(alias) if status1 == TrueDeps && status != TrueDeps => + combine(apply(status, alias), FalseDeps) + case _ => + status1 + } + case tp: TypeVar if !tp.isInstantiated => combine(status, Provisional) + case _ => foldOver(status, tp) + } + } + depStatusAcc(NoDeps, tp) } /** The dependency status of this method. Some examples: @@ -2239,25 +2262,7 @@ object Types { private def dependencyStatus(implicit ctx: Context): DependencyStatus = { if (myDependencyStatus != Unknown) myDependencyStatus else { - val isDepAcc = new TypeAccumulator[DependencyStatus] { - def apply(status: DependencyStatus, tp: Type) = - if (status == TrueDeps) status - else - tp match { - case MethodParam(`thisMethodType`, _) => TrueDeps - case tp: TypeRef => - val status1 = foldOver(status, tp) - tp.info match { // follow type alias to avoid dependency - case TypeAlias(alias) if status1 == TrueDeps && status != TrueDeps => - combine(apply(status, alias), FalseDeps) - case _ => - status1 - } - case tp: TypeVar if !tp.isInstantiated => combine(status, Provisional) - case _ => foldOver(status, tp) - } - } - val result = isDepAcc(NoDeps, resType) + val result = depStatus(resType) if ((result & Provisional) == 0) myDependencyStatus = result (result & StatusMask).toByte } |