By Pavel Talanov: KT-618 overloaded assignment operators should not allow for returning types other than Unit of Subtypes or the type where they are defined

This commit is contained in:
Andrey Breslav
2011-11-25 18:32:03 +03:00
parent ae6e87ef5a
commit a7eada71ce
2 changed files with 50 additions and 3 deletions
@@ -20,11 +20,12 @@ import org.jetbrains.jet.lexer.JetTokens;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_SET;
import static org.jetbrains.jet.lang.resolve.BindingContext.VARIABLE_REASSIGNMENT;
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.getExpressionReceiver;
/**
* @author abreslav
*/
* @author abreslav
*/
public class ExpressionTypingVisitorForStatements extends BasicExpressionTypingVisitor {
private final WritableScope scope;
@@ -138,17 +139,35 @@ public class ExpressionTypingVisitorForStatements extends BasicExpressionTypingV
}
assignmentOperationType = getTypeForBinaryCall(scope, counterpartName, context, expression);
if (assignmentOperationType != null) {
context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression);
context.trace.record(VARIABLE_REASSIGNMENT, expression);
ExpressionTypingUtils.checkWrappingInRef(expression.getLeft(), context);
}
}
else {
temporaryBindingTrace.commit();
checkReassignment(expression, context, assignmentOperationType, left);
}
checkLValue(context.trace, expression.getLeft());
return checkAssignmentType(assignmentOperationType, expression, contextWithExpectedType);
}
private void checkReassignment(@NotNull JetBinaryExpression expression, @NotNull ExpressionTypingContext context,
@NotNull JetType assignmentOperationType, @Nullable JetExpression left) {
if (left == null) return;
JetType leftType = facade.getType(left, context.replaceScope(scope));
if (leftType == null) return;
boolean isUnit = context.semanticServices.getTypeChecker().
isSubtypeOf(assignmentOperationType, JetStandardClasses.getUnitType());
if (isUnit) return;
if (context.semanticServices.getTypeChecker().isSubtypeOf(assignmentOperationType, leftType)) {
context.trace.record(VARIABLE_REASSIGNMENT, expression);
}
else {
context.trace.report(TYPE_MISMATCH.on(expression, leftType, assignmentOperationType));
}
}
@Override
protected JetType visitAssignment(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceExpectedReturnType(TypeUtils.NO_EXPECTED_TYPE);
@@ -0,0 +1,28 @@
namespace lol
class B() {
fun plusAssign(other : B) : String {
return "s"
}
fun minusAssign(other : B) : String {
return "s"
}
fun modAssign(other : B) : String {
return "s"
}
fun divAssign(other : B) : String {
return "s"
}
fun timesAssign(other : B) : String {
return "s"
}
}
fun main(args : Array<String>) {
var c = B()
<!TYPE_MISMATCH!>c += B()<!>
<!TYPE_MISMATCH!>c *= B()<!>
<!TYPE_MISMATCH!>c /= B()<!>
<!TYPE_MISMATCH!>c -= B()<!>
<!TYPE_MISMATCH!>c %= B()<!>
}