aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-07-27 12:40:29 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-27 12:40:38 +0200
commit0d44e9ea121fc664a97791b6ad29631cd3aba8f6 (patch)
treee8ee267d2a19809a53bf321746c7472bda7a1e2a
parent568e48961e423a1dd1425c2c65bc129edba3f700 (diff)
downloaddotty-0d44e9ea121fc664a97791b6ad29631cd3aba8f6.tar.gz
dotty-0d44e9ea121fc664a97791b6ad29631cd3aba8f6.tar.bz2
dotty-0d44e9ea121fc664a97791b6ad29631cd3aba8f6.zip
Fix substDealias
substDealias did not follow aliases when the prefix of a typeref changed under substitution. This was exhibited by a bug in extensionMethods which was first discovered in CollectionStrawMan6 and was minimized in extmethods.
-rw-r--r--src/dotty/tools/dotc/core/Substituters.scala13
-rw-r--r--tests/pos/extmethods.scala11
2 files changed, 17 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala
index 0d1c78e2f..23683608a 100644
--- a/src/dotty/tools/dotc/core/Substituters.scala
+++ b/src/dotty/tools/dotc/core/Substituters.scala
@@ -102,14 +102,13 @@ trait Substituters { this: Context =>
}
if (sym.isStatic && !existsStatic(from)) tp
else {
- val prefix1 = substDealias(tp.prefix, from, to, theMap)
- if (prefix1 ne tp.prefix) tp.derivedSelect(prefix1)
- else if (sym.isAliasType) {
- val hi = sym.info.bounds.hi
- val hi1 = substDealias(hi, from, to, theMap)
- if (hi1 eq hi) tp else hi1
+ tp.info match {
+ case TypeAlias(alias) =>
+ val alias1 = substDealias(alias, from, to, theMap)
+ if (alias1 ne alias) return alias1
+ case _ =>
}
- else tp
+ tp.derivedSelect(substDealias(tp.prefix, from, to, theMap))
}
case _: ThisType | _: BoundType | NoPrefix =>
tp
diff --git a/tests/pos/extmethods.scala b/tests/pos/extmethods.scala
index cac1c4ec1..fe95a1c79 100644
--- a/tests/pos/extmethods.scala
+++ b/tests/pos/extmethods.scala
@@ -9,3 +9,14 @@ class Foo[+A <: AnyRef](val xs: List[A]) extends AnyVal {
def baz[B >: A](x: B): List[B] = ???
}
+object CollectionStrawMan {
+ import collection.mutable.ArrayBuffer
+ import reflect.ClassTag
+
+ implicit class ArrayOps[A](val xs: Array[A]) extends AnyVal {
+
+ def elemTag: ClassTag[A] = ClassTag(xs.getClass.getComponentType)
+
+ protected[this] def newBuilder = new ArrayBuffer[A].mapResult(_.toArray(elemTag))
+ }
+}