From 4cef4ec1709c764952029710ffa48f2b020aee50 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 22 Mar 2012 15:50:52 +0100 Subject: [PATCH] Fixed type checking in the case of val s : String = !true --- .../lang/parsing/JetExpressionParsing.java | 2 +- .../BasicExpressionTypingVisitor.java | 26 ++++++++++--------- .../TypeMismatchOnUnaryOperations.jet | 16 ++++++++++++ 3 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index 301b719e26c..c26a4602b9e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -235,7 +235,7 @@ public class JetExpressionParsing extends AbstractJetParsing { opSet.removeAll(usedSet); assert false : opSet; } - assert usedSet.size() == opSet.size() : "Either some operations are unused, or something that's not an operation is used"; + assert usedSet.size() == opSet.size() : "Either some ops are unused, or something a non-op is used"; usedSet.removeAll(opSet); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 6e52b10a73f..dceace41d84 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -681,9 +681,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { // Type check the base expression TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); - BindingTrace initialTrace = context.trace; - context = context.replaceBindingTrace(temporaryTrace); - JetType type = facade.getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE)); + ExpressionTypingContext contextWithTemporaryTrace = context.replaceBindingTrace(temporaryTrace); + JetType type = facade.getType(baseExpression, contextWithTemporaryTrace.replaceExpectedType(NO_EXPECTED_TYPE)); if (type == null) { temporaryTrace.commit(); return null; @@ -692,7 +691,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { // Special case for expr!! if (operationType == JetTokens.EXCLEXCL) { JetType result; - if (isKnownToBeNotNull(baseExpression, context)) { + if (isKnownToBeNotNull(baseExpression, contextWithTemporaryTrace)) { temporaryTrace.report(UNNECESSARY_NOT_NULL_ASSERTION.on(operationSign, type)); result = type; } @@ -712,14 +711,17 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { // a[i]++/-- takes special treatment because it is actually let j = i, arr = a in arr.set(j, a.get(j).inc()) if ((operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) && baseExpression instanceof JetArrayAccessExpression) { - JetExpression stubExpression = ExpressionTypingUtils.createStubExpressionOfNecessaryType(baseExpression.getProject(), type, context.trace); - resolveArrayAccessSetMethod((JetArrayAccessExpression) baseExpression, stubExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceBindingTrace(TemporaryBindingTrace.create(initialTrace)), context.trace); + JetExpression stubExpression = ExpressionTypingUtils.createStubExpressionOfNecessaryType(baseExpression.getProject(), type, contextWithTemporaryTrace.trace); + resolveArrayAccessSetMethod((JetArrayAccessExpression) baseExpression, + stubExpression, + context.replaceExpectedType(NO_EXPECTED_TYPE).replaceBindingTrace(TemporaryBindingTrace.create(context.trace)), + contextWithTemporaryTrace.trace); } ExpressionReceiver receiver = new ExpressionReceiver(baseExpression, type); // Resolve the operation reference - OverloadResolutionResults resolutionResults = context.resolveCallWithGivenNameToDescriptor( + OverloadResolutionResults resolutionResults = contextWithTemporaryTrace.resolveCallWithGivenNameToDescriptor( CallMaker.makeCall(receiver, expression), expression.getOperationReference(), name); @@ -734,18 +736,18 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetType result; if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) { if (JetTypeChecker.INSTANCE.isSubtypeOf(returnType, JetStandardClasses.getUnitType())) { - result = JetStandardClasses.getUnitType(); - context.trace.report(INC_DEC_SHOULD_NOT_RETURN_UNIT.on(operationSign)); + result = ErrorUtils.createErrorType("Unit"); + contextWithTemporaryTrace.trace.report(INC_DEC_SHOULD_NOT_RETURN_UNIT.on(operationSign)); } else { JetType receiverType = receiver.getType(); if (!JetTypeChecker.INSTANCE.isSubtypeOf(returnType, receiverType)) { - context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name, receiverType, returnType)); + contextWithTemporaryTrace.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name, receiverType, returnType)); } else { - context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression); + contextWithTemporaryTrace.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression); - checkLValue(context.trace, baseExpression); + checkLValue(contextWithTemporaryTrace.trace, baseExpression); } // TODO : Maybe returnType? result = receiverType; diff --git a/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.jet b/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.jet new file mode 100644 index 00000000000..c1800e156d4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.jet @@ -0,0 +1,16 @@ +fun main(args : Array) { + val a : Int? = null; + var v = 1 + val b : String = v; + val f : String = a!!; + val g : String = v++; + val g1 : String = ++v; + val h : String = v--; + val h1 : String = --v; + val i : String = !true; + val j : String = @foo true; + val j1 : String = @ true; + val j2 : String = @@ true; + val k : String = -1; + val l : String = +1; +} \ No newline at end of file