Skip to content

Commit 20f7389

Browse files
committed
Merge pull request scala#4452 from lrytz/valueClassSelfTypeBCode
Don't crash GenBCode for value classes with a self declaration
2 parents ba36c2b + 2fbd539 commit 20f7389

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,12 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
329329
* Build the [[InlineInfo]] for a class symbol.
330330
*/
331331
def buildInlineInfoFromClassSymbol(classSym: Symbol, classSymToInternalName: Symbol => InternalName, methodSymToDescriptor: Symbol => String): InlineInfo = {
332-
val selfType = {
332+
val traitSelfType = if (classSym.isTrait && !classSym.isImplClass) {
333333
// The mixin phase uses typeOfThis for the self parameter in implementation class methods.
334334
val selfSym = classSym.typeOfThis.typeSymbol
335335
if (selfSym != classSym) Some(classSymToInternalName(selfSym)) else None
336+
} else {
337+
None
336338
}
337339

338340
val isEffectivelyFinal = classSym.isEffectivelyFinal
@@ -394,6 +396,6 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
394396
}
395397
}).toMap
396398

397-
InlineInfo(selfType, isEffectivelyFinal, methodInlineInfos, warning)
399+
InlineInfo(traitSelfType, isEffectivelyFinal, methodInlineInfos, warning)
398400
}
399401
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
trait T
2+
3+
class V1(val l: Long) extends AnyVal { self: T =>
4+
def foo: V1 = self
5+
def bar: T = self
6+
}
7+
8+
class V2(val l: Long) extends AnyVal { self =>
9+
def foo: V2 = self
10+
}
11+
12+
class V3(val l: Long) extends AnyVal { self: Long =>
13+
def foo: V3 = self
14+
def bar: Long = self
15+
}
16+
17+
// non-value classes
18+
19+
class C1(val l: Long) { self: T =>
20+
def foo: C1 = self
21+
def bar: T = self
22+
}
23+
24+
class C2(val l: Long) { self =>
25+
def foo: C2 = self
26+
}
27+
28+
class C3(val l: Long) { self: Long =>
29+
def foo: C3 = self
30+
def bar: Long = self
31+
}
32+
33+
object Test extends App {
34+
// Rejected: superclass V1 is not a subclass of the superclass Object of the mixin trait T
35+
// new V1(1l) with T
36+
37+
assert(new V2(1l).foo.l == 1l)
38+
39+
// Rejected: V3 does not conform to its self-type V3 with Long
40+
// new V3(1l)
41+
42+
val c2 = new C1(2l) with T
43+
assert(c2.foo.l + c2.bar.asInstanceOf[C1].l == 4l)
44+
45+
assert(new C2(3l).foo.l == 3l)
46+
47+
// Rejected: C3 does not conform to its self-type C3 with Long
48+
// new C3(4l)
49+
50+
// Rejected: class Long needs to be a trait to be mixed in
51+
// new C3(4l) with Long
52+
}

0 commit comments

Comments
 (0)