diff options
Diffstat (limited to 'src/reflect')
5 files changed, 20 insertions, 9 deletions
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala index 0ef52213e5..1cdefff2e9 100644 --- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala +++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala @@ -33,6 +33,9 @@ trait BaseTypeSeqs { protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) = new BaseTypeSeq(parents, elems) + protected def newMappedBaseTypeSeq(orig: BaseTypeSeq, f: Type => Type) = + new MappedBaseTypeSeq(orig, f) + /** Note: constructor is protected to force everyone to use the factory method newBaseTypeSeq instead. * This is necessary because when run from reflection every base type sequence needs to have a * SynchronizedBaseTypeSeq as mixin. @@ -125,7 +128,7 @@ trait BaseTypeSeqs { newBaseTypeSeq(parents, arr) } - def lateMap(f: Type => Type): BaseTypeSeq = new MappedBaseTypeSeq(this, f) + def lateMap(f: Type => Type): BaseTypeSeq = newMappedBaseTypeSeq(this, f) def exists(p: Type => Boolean): Boolean = elems exists p diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala index 9d39ef8b42..055f7c9d5b 100644 --- a/src/reflect/scala/reflect/internal/Names.scala +++ b/src/reflect/scala/reflect/internal/Names.scala @@ -296,11 +296,13 @@ trait Names extends api.Names { */ final def pos(s: String, start: Int): Int = { var i = pos(s.charAt(0), start) - while (i + s.length() <= len) { + val sLen = s.length() + if (sLen == 1) return i + while (i + sLen <= len) { var j = 1 while (s.charAt(j) == chrs(index + i + j)) { j += 1 - if (j == s.length()) return i + if (j == sLen) return i } i = pos(s.charAt(0), i + 1) } diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala index 24f8aa88e6..07ae71538c 100644 --- a/src/reflect/scala/reflect/internal/transform/Erasure.scala +++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala @@ -161,6 +161,11 @@ trait Erasure { } if (newParents eq parents) tp else ClassInfoType(newParents, decls, clazz) + + // can happen while this map is being used before erasure (e.g. when reasoning about sam types) + // the regular mapOver will cause a class cast exception because TypeBounds don't erase to TypeBounds + case _: BoundedWildcardType => tp // skip + case _ => mapOver(tp) } diff --git a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala index 3cede1b3c5..49ab0cb30e 100644 --- a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala +++ b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala @@ -92,7 +92,7 @@ class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader) } } - private val packages = mutable.Map[String, Package]() + private[this] val packages = mutable.Map[String, Package]() override def definePackage(name: String, specTitle: String, specVersion: String, specVendor: String, implTitle: String, implVersion: String, implVendor: String, sealBase: URL): Package = { throw new UnsupportedOperationException() diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala index f0d96e0fd6..eadafc8abb 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala @@ -18,6 +18,12 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable if (elems.exists(_.isInstanceOf[RefinedType])) new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq else new BaseTypeSeq(parents, elems) + override protected def newMappedBaseTypeSeq(orig: BaseTypeSeq, f: Type => Type) = + // MappedBaseTypeSeq's are used rarely enough that we unconditionally mixin the synchronized + // wrapper, rather than doing this conditionally. A previous attempt to do that broke the "late" + // part of the "lateMap" contract in inspecting the mapped elements. + new MappedBaseTypeSeq(orig, f) with SynchronizedBaseTypeSeq + trait SynchronizedBaseTypeSeq extends BaseTypeSeq { override def apply(i: Int): Type = gilSynchronized { super.apply(i) } override def rawElem(i: Int) = gilSynchronized { super.rawElem(i) } @@ -28,11 +34,6 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable override def exists(p: Type => Boolean): Boolean = gilSynchronized { super.exists(p) } override lazy val maxDepth = gilSynchronized { maxDepthOfElems } override def toString = gilSynchronized { super.toString } - - override def lateMap(f: Type => Type): BaseTypeSeq = - // only need to synchronize BaseTypeSeqs if they contain refined types - if (map(f).toList.exists(_.isInstanceOf[RefinedType])) new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq - else new MappedBaseTypeSeq(this, f) } // Scopes |