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:
+22
-3
@@ -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()<!>
|
||||
}
|
||||
Reference in New Issue
Block a user