Fix false "useless cast" when target type is flexible

#KT-17820 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2017-05-15 11:24:05 +03:00
parent a8f1e32dec
commit ac8fbce249
5 changed files with 50 additions and 4 deletions
@@ -213,13 +213,14 @@ object CastDiagnosticsUtil {
return isRefinementUseless(possibleTypes, refinedTargetType, typeChecker, shouldCheckForExactType(expression, context.expectedType))
}
// It is a warning "useless cast" for `as` and a warning "redundant is" for `is`
fun isRefinementUseless(
possibleTypes: Collection<KotlinType>,
targetType: KotlinType,
typeChecker: KotlinTypeChecker,
shouldCheckForExactType: Boolean
): Boolean {
val intersectedType = TypeIntersector.intersectTypes(typeChecker, possibleTypes) ?: return false
val intersectedType = TypeIntersector.intersectTypes(typeChecker, possibleTypes.map { it.upperIfFlexible() }) ?: return false
return if (shouldCheckForExactType)
isExactTypeCast(intersectedType, targetType)
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.*
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo
import org.jetbrains.kotlin.types.typeUtil.containsError
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import java.util.*
class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTypingInternals) : ExpressionTypingVisitor(facade) {
@@ -464,8 +463,7 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
if (subjectType.containsError() || targetType.containsError()) return
val possibleTypes = DataFlowAnalyzer.getAllPossibleTypes(subjectType, context, subjectDataFlowValue)
val intersection = TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, possibleTypes.map { it.upperIfFlexible() })
if (intersection?.isSubtypeOf(targetType) ?: false) {
if (CastDiagnosticsUtil.isRefinementUseless(possibleTypes, targetType, KotlinTypeChecker.DEFAULT, false)) {
context.trace.report(Errors.USELESS_IS_CHECK.on(isCheck, !negated))
}
}