summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala7
-rw-r--r--test/files/pos/t6301.scala9
3 files changed, 20 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 59741e95f8..49f3781372 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -1234,8 +1234,10 @@ abstract class GenICode extends SubComponent {
case NothingReference => ctx.bb.emit(THROW(ThrowableClass)) ; ctx.bb.enterIgnoreMode
case NullReference => ctx.bb.emit(Seq(DROP(from), CONSTANT(Constant(null))))
case ThrowableReference if !(ThrowableClass.tpe <:< to.toType) => ctx.bb.emit(CHECK_CAST(to)) // downcast throwables
- case BYTE | SHORT | CHAR | INT if to == LONG => coerce(INT, LONG) // widen subrange types
- case _ => ()
+ case _ =>
+ // widen subrange types
+ if (from.isIntSizedType && to == LONG)
+ coerce(INT, LONG)
}
else to match {
case UNIT => ctx.bb.emit(DROP(from), pos) // value discarding
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index c9de497dea..6c8417eb56 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -999,6 +999,7 @@ abstract class Erasure extends AddInterfaces
} else if (fn.symbol == Any_isInstanceOf) {
preEraseIsInstanceOf
} else if (fn.symbol.owner.isRefinementClass && !fn.symbol.isOverridingSymbol) {
+ // !!! Another spot where we produce overloaded types (see test run/t6301)
ApplyDynamic(qualifier, args) setSymbol fn.symbol setPos tree.pos
} else if (fn.symbol.isMethodWithExtension) {
Apply(gen.mkAttributedRef(extensionMethods.extensionMethod(fn.symbol)), qualifier :: args)
@@ -1068,6 +1069,12 @@ abstract class Erasure extends AddInterfaces
case s @ (ShortClass | ByteClass | CharClass) => numericConversion(qual, s)
case BooleanClass => If(qual, LIT(true.##), LIT(false.##))
case _ =>
+ // Since we are past typer, we need to avoid creating trees carrying
+ // overloaded types. This logic is custom (and technically incomplete,
+ // although serviceable) for def hash. What is really needed is for
+ // the overloading logic presently hidden away in a few different
+ // places to be properly exposed so we can just call "resolveOverload"
+ // after typer. Until then:
val alts = ScalaRunTimeModule.info.member(nme.hash_).alternatives
def alt1 = alts find (_.info.paramTypes.head =:= qual.tpe)
def alt2 = ScalaRunTimeModule.info.member(nme.hash_) suchThat (_.info.paramTypes.head.typeSymbol == AnyClass)
diff --git a/test/files/pos/t6301.scala b/test/files/pos/t6301.scala
new file mode 100644
index 0000000000..fa81bbfa77
--- /dev/null
+++ b/test/files/pos/t6301.scala
@@ -0,0 +1,9 @@
+trait LoadedOver[@specialized(Int) A] {
+ def foo(x: Any): A
+ def foo(xs: String): A
+}
+
+object Test {
+ def loaded: AnyRef with LoadedOver[Int] = sys.error("")
+ loaded.foo("")
+}