aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeOps.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-06-05 22:38:01 +0200
committerMartin Odersky <odersky@gmail.com>2015-06-06 11:05:27 +0200
commit0ee8e506dac87bae6ec432b2cd277109df872145 (patch)
tree1a916c66c738c9005b534ed2efe48c382ccaa031 /src/dotty/tools/dotc/core/TypeOps.scala
parent84bf5902dba61c88f1b50229bb3afa5a335ded94 (diff)
downloaddotty-0ee8e506dac87bae6ec432b2cd277109df872145.tar.gz
dotty-0ee8e506dac87bae6ec432b2cd277109df872145.tar.bz2
dotty-0ee8e506dac87bae6ec432b2cd277109df872145.zip
Skolemize unstable prefixes in asSeenFrom
Skolemize unstable prefixes in asSeenFrom provided - the prefix appears at least once in non-variant or contra-variant position - we are in phase typer. After typer, we have already established soundness, so there's no need to do skolemization again. We can simply do the (otherwise unsound) substitution from this-type to prefix.
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeOps.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala19
1 files changed, 11 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index fb641f247..7c371a96e 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -13,19 +13,19 @@ import ast.tpd._
trait TypeOps { this: Context => // TODO: Make standalone object.
final def asSeenFrom(tp: Type, pre: Type, cls: Symbol): Type = {
- val m = if (pre.isStable || ctx.isAfterTyper) null else new AsSeenFromMap(pre, cls)
- asSeenFrom(tp, pre, cls, null)
+ val m = if (pre.isStable || !ctx.phase.isTyper) null else new AsSeenFromMap(pre, cls)
+ var res = asSeenFrom(tp, pre, cls, m)
+ if (m != null && m.unstable) asSeenFrom(tp, SkolemType(pre), cls) else res
}
-
+
final def asSeenFrom(tp: Type, pre: Type, cls: Symbol, theMap: AsSeenFromMap): Type = {
def toPrefix(pre: Type, cls: Symbol, thiscls: ClassSymbol): Type = /*>|>*/ ctx.conditionalTraceIndented(TypeOps.track, s"toPrefix($pre, $cls, $thiscls)") /*<|<*/ {
if ((pre eq NoType) || (pre eq NoPrefix) || (cls is PackageClass))
tp
else if (thiscls.derivesFrom(cls) && pre.baseTypeRef(thiscls).exists) {
- if (!pre.isStable && theMap != null && theMap.currentVariance <= 0) {
+ if (theMap != null && theMap.currentVariance <= 0 && !pre.isStable)
theMap.unstable = true
- }
pre match {
case SuperType(thispre, _) => thispre
case _ => pre
@@ -43,10 +43,13 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
val sym = tp.symbol
if (sym.isStatic) tp
else {
+ val prevStable = theMap == null || !theMap.unstable
val pre1 = asSeenFrom(tp.prefix, pre, cls, theMap)
- if (theMap != null && theMap.unstable) {
+ if (theMap != null && theMap.unstable && prevStable) {
pre1.member(tp.name).info match {
- case TypeAlias(alias) => return alias
+ case TypeAlias(alias) =>
+ theMap.unstable = false
+ return alias
case _ =>
}
}
@@ -61,7 +64,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
asSeenFrom(tp.parent, pre, cls, theMap),
tp.refinedName,
asSeenFrom(tp.refinedInfo, pre, cls, theMap))
- case tp: TypeAlias =>
+ case tp: TypeAlias if theMap == null => // if theMap exists, need to do the variance calculation
tp.derivedTypeAlias(asSeenFrom(tp.alias, pre, cls, theMap))
case _ =>
(if (theMap != null) theMap else new AsSeenFromMap(pre, cls))