diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 9191692a23b..e33944aa7dc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -339,7 +339,10 @@ public abstract class StackValue { } public static StackValue thisOrOuter(ExpressionCodegen codegen, ClassDescriptor descriptor, boolean isSuper) { - return new ThisOuter(codegen, descriptor, isSuper); + // Coerce this/super for traits to support traits with required classes + // Do not coerce for other classes due to the 'protected' access issues (JVMS 7, 4.9.2 Structural Constraints) + boolean coerceType = descriptor.getKind() == ClassKind.TRAIT; + return new ThisOuter(codegen, descriptor, isSuper, coerceType); } public static StackValue postIncrement(int index, int increment) { @@ -1187,18 +1190,20 @@ public abstract class StackValue { private final ExpressionCodegen codegen; private final ClassDescriptor descriptor; private final boolean isSuper; + private final boolean coerceType; - public ThisOuter(ExpressionCodegen codegen, ClassDescriptor descriptor, boolean isSuper) { + public ThisOuter(ExpressionCodegen codegen, ClassDescriptor descriptor, boolean isSuper, boolean coerceType) { super(OBJECT_TYPE); this.codegen = codegen; this.descriptor = descriptor; this.isSuper = isSuper; + this.coerceType = coerceType; } @Override public void put(Type type, InstructionAdapter v) { final StackValue stackValue = codegen.generateThisOrOuter(descriptor, isSuper); - stackValue.put(stackValue.type, v); // no coercion here + stackValue.put(coerceType ? type : stackValue.type, v); } } diff --git a/compiler/testData/codegen/regressions/kt2963.kt b/compiler/testData/codegen/regressions/kt2963.kt new file mode 100644 index 00000000000..03b1d72120b --- /dev/null +++ b/compiler/testData/codegen/regressions/kt2963.kt @@ -0,0 +1,15 @@ +open class Base + +trait Derived : Base { + fun foo(): String { + return object { + fun bar() = baz(this@Derived) + }.bar() + } +} + +class DerivedImpl : Derived, Base() + +fun baz(b: Base) = "OK" + +fun box() = DerivedImpl().foo() diff --git a/compiler/tests/org/jetbrains/jet/codegen/TraitsTest.java b/compiler/tests/org/jetbrains/jet/codegen/TraitsTest.java index 17ab1a4ec47..66641e776c4 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/TraitsTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/TraitsTest.java @@ -84,4 +84,8 @@ public class TraitsTest extends CodegenTestCase { public void testKt1936_2() throws Exception { blackBoxFile("regressions/kt1936_2.kt"); } + + public void testKt2963() { + blackBoxFile("regressions/kt2963.kt"); + } }