Forbid dynamic on the RHS of is and as

This commit is contained in:
Andrey Breslav
2014-11-13 04:21:27 +02:00
parent 645d931a9e
commit c8029307fa
8 changed files with 62 additions and 6 deletions
@@ -533,6 +533,7 @@ public interface Errors {
DiagnosticFactory0<JetSimpleNameExpression> USELESS_CAST_STATIC_ASSERT_IS_FINE = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<JetSimpleNameExpression> USELESS_CAST = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<JetSimpleNameExpression> CAST_NEVER_SUCCEEDS = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<JetTypeReference> DYNAMIC_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<JetExpression, JetType> IMPLICIT_CAST_TO_UNIT_OR_ANY = DiagnosticFactory1.create(WARNING);
@@ -259,6 +259,7 @@ public class DefaultErrorMessages {
MAP.put(USELESS_CAST_STATIC_ASSERT_IS_FINE, "No cast needed. You can use ':' if you need a cast to a super type");
MAP.put(USELESS_CAST, "No cast needed");
MAP.put(CAST_NEVER_SUCCEEDS, "This cast can never succeed");
MAP.put(DYNAMIC_NOT_ALLOWED, "Dynamic types are not allowed in this position");
MAP.put(USELESS_NULLABLE_CHECK, "Non-null type is checked for instance of nullable type");
MAP.put(WRONG_SETTER_PARAMETER_TYPE, "Setter parameter type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
MAP.put(WRONG_GETTER_RETURN_TYPE, "Getter return type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
@@ -209,6 +209,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
) {
if (actualType == null || noExpectedType(targetType)) return;
if (TypesPackage.isDynamic(targetType)) {
JetTypeReference right = expression.getRight();
assert right != null : "We know target is dynamic, but RHS is missing";
context.trace.report(DYNAMIC_NOT_ALLOWED.on(right));
return;
}
if (!CastDiagnosticsUtil.isCastPossible(actualType, targetType, components.platformToKotlinClassMap)) {
context.trace.report(CAST_NEVER_SUCCEEDS.on(expression.getOperationReference()));
return;
@@ -283,18 +283,23 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
}
TypeResolutionContext typeResolutionContext = new TypeResolutionContext(context.scope, context.trace, true, /*allowBareTypes=*/ true);
PossiblyBareType possiblyBareTarget = components.expressionTypingServices.getTypeResolver().resolvePossiblyBareType(typeResolutionContext, typeReferenceAfterIs);
JetType type = TypeReconstructionUtil.reconstructBareType(typeReferenceAfterIs, possiblyBareTarget, subjectType, context.trace);
if (!subjectType.isNullable() && type.isNullable()) {
JetType targetType = TypeReconstructionUtil.reconstructBareType(typeReferenceAfterIs, possiblyBareTarget, subjectType, context.trace);
if (TypesPackage.isDynamic(targetType)) {
context.trace.report(DYNAMIC_NOT_ALLOWED.on(typeReferenceAfterIs));
}
if (!subjectType.isNullable() && targetType.isNullable()) {
JetTypeElement element = typeReferenceAfterIs.getTypeElement();
assert element instanceof JetNullableType : "element must be instance of " + JetNullableType.class.getName();
JetNullableType nullableType = (JetNullableType) element;
context.trace.report(Errors.USELESS_NULLABLE_CHECK.on(nullableType));
}
checkTypeCompatibility(context, type, subjectType, typeReferenceAfterIs);
if (CastDiagnosticsUtil.isCastErased(subjectType, type, JetTypeChecker.DEFAULT)) {
context.trace.report(Errors.CANNOT_CHECK_FOR_ERASED.on(typeReferenceAfterIs, type));
checkTypeCompatibility(context, targetType, subjectType, typeReferenceAfterIs);
if (CastDiagnosticsUtil.isCastErased(subjectType, targetType, JetTypeChecker.DEFAULT)) {
context.trace.report(Errors.CANNOT_CHECK_FOR_ERASED.on(typeReferenceAfterIs, targetType));
}
return new DataFlowInfos(context.dataFlowInfo.establishSubtyping(subjectDataFlowValue, type), context.dataFlowInfo);
return new DataFlowInfos(context.dataFlowInfo.establishSubtyping(subjectDataFlowValue, targetType), context.dataFlowInfo);
}
private static DataFlowInfos noChange(ExpressionTypingContext context) {