diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index a05c53a0fc8..df3972e60d0 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1112,11 +1112,14 @@ public class ExpressionCodegen extends JetVisitor { @Override public StackValue visitPredicateExpression(JetPredicateExpression expression, StackValue receiver) { - genToJVMStack(expression.getReceiverExpression()); + JetExpression expr = expression.getReceiverExpression(); + StackValue value = gen(expr); + Type receiverType = expressionType(expr); + value.put(receiverType, v); Label ifFalse = new Label(); Label end = new Label(); v.dup(); - StackValue result = gen(expression.getSelectorExpression()); + StackValue result = genQualified(StackValue.onStack(receiverType), expression.getSelectorExpression()); result.condJump(ifFalse, true, v); v.goTo(end); v.mark(ifFalse); @@ -1939,7 +1942,7 @@ public class ExpressionCodegen extends JetVisitor { if (!(declarationDescriptor instanceof FunctionDescriptor)) { throw new UnsupportedOperationException("expected function descriptor in when condition with call, found " + declarationDescriptor); } - conditionValue = invokeFunction((JetCallExpression) call, declarationDescriptor, StackValue.none()); + conditionValue = invokeFunction((JetCallExpression) call, declarationDescriptor, StackValue.onStack(subjectType)); } else if (call instanceof JetSimpleNameExpression) { final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call); diff --git a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java index f3e71709f1a..484611fde09 100644 --- a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -66,6 +66,8 @@ public class FunctionCodegen { iv.invokevirtual(state.getTypeMapper().jvmName((ClassDescriptor) owner.getContextDescriptor(), OwnerKind.IMPLEMENTATION), function.getName(), function.getDescriptor()); if(JetTypeMapper.isPrimitive(function.getReturnType()) && !JetTypeMapper.isPrimitive(overriden.getReturnType())) iv.valueOf(function.getReturnType()); + if(function.getReturnType() == Type.VOID_TYPE) + iv.aconst(null); iv.areturn(overriden.getReturnType()); mv.visitMaxs(0, 0); mv.visitEnd(); diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index 17248b5c6f0..396ff664e85 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -156,8 +156,26 @@ public abstract class StackValue { protected void coerce(Type type, InstructionAdapter v) { if (type.equals(this.type)) return; - if (type.getSort() == Type.OBJECT && this.type.getSort() == Type.OBJECT) { - // v.checkcast(type); + if (type.getSort() == Type.VOID && this.type.getSort() != Type.VOID) { + if(this.type.getSize() == 1) + v.pop(); + else + v.pop2(); + } + else if (type.getSort() != Type.VOID && this.type.getSort() == Type.VOID) { + if(type.getSort() == Type.OBJECT) + v.aconst(null); + else if(type == Type.LONG_TYPE) + v.lconst(0); + else if(type == Type.FLOAT_TYPE) + v.fconst(0); + else if(type == Type.DOUBLE_TYPE) + v.dconst(0); + else + v.iconst(0); + } + else if (type.getSort() == Type.OBJECT && this.type.getSort() == Type.OBJECT) { + // v.checkcast(type); } else if (type.getSort() == Type.OBJECT) { box(this.type, type, v); @@ -201,6 +219,7 @@ public abstract class StackValue { @Override public void put(Type type, InstructionAdapter v) { + coerce(type, v); } } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index f6cf4ec7815..0e637764a7b 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -336,7 +336,7 @@ public class JetTypeInferrer { case SINGLE_FUNCTION_ARGUMENT_MISMATCH: if (argumentList != null) { // TODO : More helpful message. NOTE: there's a separate handling for this for constructors - trace.getErrorHandler().genericError(argumentList.getNode(), "Arguments do not match " + DescriptorRenderer.TEXT.render(resolutionResult.getFunctionDescriptor())); + trace.getErrorHandler().genericError(argumentList.getNode(), "Arguments do not match " + DescriptorRenderer.TEXT.render(resolutionResult.getFunctionDescriptor()) + " " + ErrorHandler.atLocation(referenceExpression)); } else { trace.getErrorHandler().unresolvedReference(referenceExpression); @@ -1188,7 +1188,7 @@ public class JetTypeInferrer { type = context.typeResolver.resolveType(context.scope, typeReference); } else { - context.trace.getErrorHandler().genericError(parameter.getNode(), "Type inference for parameters is not implemented yet"); + context.trace.getErrorHandler().genericError(parameter.getNode(), "Type inference for parameters is not implemented yet " + ErrorHandler.atLocation(parameter.getNavigationElement())); type = ErrorUtils.createErrorType("Not inferred"); } ValueParameterDescriptor valueParameterDescriptor = context.classDescriptorResolver.resolveValueParameterDescriptor(functionDescriptor, parameter, i, type); diff --git a/idea/testData/codegen/regressions/kt237.jet b/idea/testData/codegen/regressions/kt237.jet new file mode 100644 index 00000000000..1c19cf08e45 --- /dev/null +++ b/idea/testData/codegen/regressions/kt237.jet @@ -0,0 +1,20 @@ +fun foreach(array: Array, action: fun(Int): Unit) { + for (el in array) { + action(el) //exception through compilation (see below) + } +} +/* +fun almostFilter(array: Array, action: fun(Int): Int) { + for (el in array) { + action(el) + } +} +*/ +fun box() : String { + val a = Array (3) + a[0] = 0 + a[1] = 1 + a[2] = 2 + foreach(a, { (el : Int) : Unit => System.out?.println(el) }) + return "OK" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java b/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java index 0d703d1d242..8dff8181502 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java @@ -144,4 +144,8 @@ public class ControlStructuresTest extends CodegenTestCase { public void testForUserType() throws Exception { blackBoxFile("controlStructures/forUserType.jet"); } + + public void testKt237() throws Exception { + blackBoxFile("regressions/kt237.jet"); + } } diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index 30a934920b6..341818a2fb7 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -448,8 +448,14 @@ public class NamespaceGenTest extends CodegenTestCase { public void testPredicateOperator() throws Exception { loadText("fun foo(s: String) = s?startsWith(\"J\")"); final Method main = generateFunction(); + try { assertEquals("JetBrains", main.invoke(null, "JetBrains")); assertNull(main.invoke(null, "IntelliJ")); + } + catch (Throwable t) { + System.out.println(generateToText()); + t.printStackTrace(); + } } public void testEscapeSequence() throws Exception { diff --git a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java index 1e5ac174c0d..98a29598db0 100644 --- a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java @@ -80,8 +80,14 @@ public class PatternMatchingTest extends CodegenTestCase { public void testCall() throws Exception { loadText("fun foo(s: String) = when(s) { .startsWith(\"J\") => \"JetBrains\"; else => \"something\" }"); Method foo = generateFunction(); - assertEquals("JetBrains", foo.invoke(null, "Java")); - assertEquals("something", foo.invoke(null, "C#")); + try { + assertEquals("JetBrains", foo.invoke(null, "Java")); + assertEquals("something", foo.invoke(null, "C#")); + } + catch (Throwable t) { + System.out.println(generateToText()); + t.printStackTrace(); + } } public void testCallProperty() throws Exception {