Fixed type checking in the case of

val s : String = !true
This commit is contained in:
Andrey Breslav
2012-03-22 15:50:52 +01:00
parent 7341a82b0b
commit 4cef4ec170
3 changed files with 31 additions and 13 deletions
@@ -235,7 +235,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
opSet.removeAll(usedSet); opSet.removeAll(usedSet);
assert false : opSet; 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); usedSet.removeAll(opSet);
@@ -681,9 +681,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
// Type check the base expression // Type check the base expression
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
BindingTrace initialTrace = context.trace; ExpressionTypingContext contextWithTemporaryTrace = context.replaceBindingTrace(temporaryTrace);
context = context.replaceBindingTrace(temporaryTrace); JetType type = facade.getType(baseExpression, contextWithTemporaryTrace.replaceExpectedType(NO_EXPECTED_TYPE));
JetType type = facade.getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE));
if (type == null) { if (type == null) {
temporaryTrace.commit(); temporaryTrace.commit();
return null; return null;
@@ -692,7 +691,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
// Special case for expr!! // Special case for expr!!
if (operationType == JetTokens.EXCLEXCL) { if (operationType == JetTokens.EXCLEXCL) {
JetType result; JetType result;
if (isKnownToBeNotNull(baseExpression, context)) { if (isKnownToBeNotNull(baseExpression, contextWithTemporaryTrace)) {
temporaryTrace.report(UNNECESSARY_NOT_NULL_ASSERTION.on(operationSign, type)); temporaryTrace.report(UNNECESSARY_NOT_NULL_ASSERTION.on(operationSign, type));
result = 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()) // 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) { if ((operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) && baseExpression instanceof JetArrayAccessExpression) {
JetExpression stubExpression = ExpressionTypingUtils.createStubExpressionOfNecessaryType(baseExpression.getProject(), type, context.trace); JetExpression stubExpression = ExpressionTypingUtils.createStubExpressionOfNecessaryType(baseExpression.getProject(), type, contextWithTemporaryTrace.trace);
resolveArrayAccessSetMethod((JetArrayAccessExpression) baseExpression, stubExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceBindingTrace(TemporaryBindingTrace.create(initialTrace)), context.trace); resolveArrayAccessSetMethod((JetArrayAccessExpression) baseExpression,
stubExpression,
context.replaceExpectedType(NO_EXPECTED_TYPE).replaceBindingTrace(TemporaryBindingTrace.create(context.trace)),
contextWithTemporaryTrace.trace);
} }
ExpressionReceiver receiver = new ExpressionReceiver(baseExpression, type); ExpressionReceiver receiver = new ExpressionReceiver(baseExpression, type);
// Resolve the operation reference // Resolve the operation reference
OverloadResolutionResults<FunctionDescriptor> resolutionResults = context.resolveCallWithGivenNameToDescriptor( OverloadResolutionResults<FunctionDescriptor> resolutionResults = contextWithTemporaryTrace.resolveCallWithGivenNameToDescriptor(
CallMaker.makeCall(receiver, expression), CallMaker.makeCall(receiver, expression),
expression.getOperationReference(), expression.getOperationReference(),
name); name);
@@ -734,18 +736,18 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetType result; JetType result;
if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) { if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) {
if (JetTypeChecker.INSTANCE.isSubtypeOf(returnType, JetStandardClasses.getUnitType())) { if (JetTypeChecker.INSTANCE.isSubtypeOf(returnType, JetStandardClasses.getUnitType())) {
result = JetStandardClasses.getUnitType(); result = ErrorUtils.createErrorType("Unit");
context.trace.report(INC_DEC_SHOULD_NOT_RETURN_UNIT.on(operationSign)); contextWithTemporaryTrace.trace.report(INC_DEC_SHOULD_NOT_RETURN_UNIT.on(operationSign));
} }
else { else {
JetType receiverType = receiver.getType(); JetType receiverType = receiver.getType();
if (!JetTypeChecker.INSTANCE.isSubtypeOf(returnType, receiverType)) { 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 { 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? // TODO : Maybe returnType?
result = receiverType; result = receiverType;
@@ -0,0 +1,16 @@
fun main(args : Array<String>) {
val a : Int? = null;
var v = 1
val <!UNUSED_VARIABLE!>b<!> : String = <!TYPE_MISMATCH!>v<!>;
val <!UNUSED_VARIABLE!>f<!> : String = <!TYPE_MISMATCH!>a!!<!>;
val <!UNUSED_VARIABLE!>g<!> : String = <!TYPE_MISMATCH!>v++<!>;
val <!UNUSED_VARIABLE!>g1<!> : String = <!TYPE_MISMATCH!>++v<!>;
val <!UNUSED_VARIABLE!>h<!> : String = <!TYPE_MISMATCH!>v--<!>;
val <!UNUSED_VARIABLE!>h1<!> : String = <!TYPE_MISMATCH!>--v<!>;
val <!UNUSED_VARIABLE!>i<!> : String = <!TYPE_MISMATCH!>!true<!>;
val <!UNUSED_VARIABLE!>j<!> : String = <!TYPE_MISMATCH!>@foo <!ERROR_COMPILE_TIME_VALUE!>true<!><!>;
val <!UNUSED_VARIABLE!>j1<!> : String = <!TYPE_MISMATCH!>@ <!ERROR_COMPILE_TIME_VALUE!>true<!><!>;
val <!UNUSED_VARIABLE!>j2<!> : String = <!TYPE_MISMATCH!>@@ <!ERROR_COMPILE_TIME_VALUE!>true<!><!>;
val <!UNUSED_VARIABLE!>k<!> : String = <!TYPE_MISMATCH!>-1<!>;
val <!UNUSED_VARIABLE!>l<!> : String = <!TYPE_MISMATCH!>+1<!>;
}