Merge pull request #84 from udalov/kt2176
KT-2176 non-nullability is not inferred after !! or "as"
This commit is contained in:
+10
-5
@@ -193,17 +193,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetTypeInfo visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context) {
|
public JetTypeInfo visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context) {
|
||||||
|
JetExpression left = expression.getLeft();
|
||||||
JetTypeReference right = expression.getRight();
|
JetTypeReference right = expression.getRight();
|
||||||
JetType result = null;
|
JetType result = null;
|
||||||
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
||||||
if (right != null) {
|
if (right != null) {
|
||||||
JetType targetType = context.expressionTypingServices.getTypeResolver().resolveType(context.scope, right, context.trace, true);
|
JetType targetType = context.expressionTypingServices.getTypeResolver().resolveType(context.scope, right, context.trace, true);
|
||||||
|
IElementType operationType = expression.getOperationSign().getReferencedNameElementType();
|
||||||
|
|
||||||
boolean tryWithNoExpectedType = true;
|
boolean tryWithNoExpectedType = true;
|
||||||
if (isTypeFlexible(expression.getLeft()) || expression.getOperationSign().getReferencedNameElementType() == JetTokens.COLON) {
|
if (isTypeFlexible(left) || operationType == JetTokens.COLON) {
|
||||||
TemporaryBindingTrace temporaryTraceWithExpectedType = TemporaryBindingTrace.create(context.trace);
|
TemporaryBindingTrace temporaryTraceWithExpectedType = TemporaryBindingTrace.create(context.trace);
|
||||||
ExpressionTypingContext contextWithTemporaryTrace = context.replaceBindingTrace(temporaryTraceWithExpectedType).replaceExpectedType(targetType);
|
ExpressionTypingContext contextWithTemporaryTrace = context.replaceBindingTrace(temporaryTraceWithExpectedType).replaceExpectedType(targetType);
|
||||||
JetTypeInfo typeInfo = facade.getTypeInfo(expression.getLeft(), contextWithTemporaryTrace);
|
JetTypeInfo typeInfo = facade.getTypeInfo(left, contextWithTemporaryTrace);
|
||||||
if (typeInfo.getType() != null && checkBinaryWithTypeRHS(expression, contextWithTemporaryTrace, targetType, typeInfo.getType())) {
|
if (typeInfo.getType() != null && checkBinaryWithTypeRHS(expression, contextWithTemporaryTrace, targetType, typeInfo.getType())) {
|
||||||
temporaryTraceWithExpectedType.commit();
|
temporaryTraceWithExpectedType.commit();
|
||||||
dataFlowInfo = typeInfo.getDataFlowInfo();
|
dataFlowInfo = typeInfo.getDataFlowInfo();
|
||||||
@@ -213,18 +215,21 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
if (tryWithNoExpectedType) {
|
if (tryWithNoExpectedType) {
|
||||||
ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE);
|
ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE);
|
||||||
JetTypeInfo typeInfo = facade.getTypeInfo(expression.getLeft(), contextWithNoExpectedType);
|
JetTypeInfo typeInfo = facade.getTypeInfo(left, contextWithNoExpectedType);
|
||||||
if (typeInfo.getType() != null) {
|
if (typeInfo.getType() != null) {
|
||||||
checkBinaryWithTypeRHS(expression, contextWithNoExpectedType, targetType, typeInfo.getType());
|
checkBinaryWithTypeRHS(expression, contextWithNoExpectedType, targetType, typeInfo.getType());
|
||||||
dataFlowInfo = typeInfo.getDataFlowInfo();
|
dataFlowInfo = typeInfo.getDataFlowInfo();
|
||||||
|
if (operationType == JetTokens.AS_KEYWORD) {
|
||||||
|
DataFlowValue value = DataFlowValueFactory.INSTANCE.createDataFlowValue(left, typeInfo.getType(), context.trace.getBindingContext());
|
||||||
|
dataFlowInfo = dataFlowInfo.establishSubtyping(new DataFlowValue[]{value}, targetType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IElementType operationType = expression.getOperationSign().getReferencedNameElementType();
|
|
||||||
result = operationType == JetTokens.AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType;
|
result = operationType == JetTokens.AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dataFlowInfo = facade.getTypeInfo(expression.getLeft(), context.replaceExpectedType(NO_EXPECTED_TYPE)).getDataFlowInfo();
|
dataFlowInfo = facade.getTypeInfo(left, context.replaceExpectedType(NO_EXPECTED_TYPE)).getDataFlowInfo();
|
||||||
}
|
}
|
||||||
return DataFlowUtils.checkType(result, expression, context, dataFlowInfo);
|
return DataFlowUtils.checkType(result, expression, context, dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
//KT-2176 non-nullability is not inferred after !! or "as"
|
||||||
|
package kt2176
|
||||||
|
|
||||||
|
fun f1(a: String?) {
|
||||||
|
a!!
|
||||||
|
a: String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f2(a: String) {
|
||||||
|
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||||
|
a: String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f3(a: Any?) {
|
||||||
|
a as String
|
||||||
|
a: String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f4(a: Any) {
|
||||||
|
a as String
|
||||||
|
a: String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f5(a: String) {
|
||||||
|
a <!USELESS_CAST_STATIC_ASSERT_IS_FINE!>as<!> Any?
|
||||||
|
a: String
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user