[FE 1.0] Report errors due to inferred empty intersection on those candidates which were already previously discriminated by CompatibilityOfTypeVariableAsIntersectionTypePart
This commit is contained in:
committed by
teamcity
parent
38913b68b2
commit
12a39d0330
+11
-2
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.types.error.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.*
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -880,6 +881,13 @@ internal object CheckContextReceiversResolutionPart : ResolutionPart() {
|
||||
}
|
||||
|
||||
internal object CheckIncompatibleTypeVariableUpperBounds : ResolutionPart() {
|
||||
/*
|
||||
* Check if the candidate was already discriminated by `CompatibilityOfTypeVariableAsIntersectionTypePart` resolution part
|
||||
* If it's true we shouldn't mark the candidate with warning, but should mark with error, to repeat the existing proper behaviour
|
||||
*/
|
||||
private fun ResolutionCandidate.wasPreviouslyDiscriminated(upperTypes: List<KotlinTypeMarker>) =
|
||||
callComponents.statelessCallbacks.isOldIntersectionIsEmpty(upperTypes.cast())
|
||||
|
||||
override fun ResolutionCandidate.process(workIndex: Int) = with(getSystem().asConstraintSystemCompleterContext()) {
|
||||
for (variableWithConstraints in getSystem().getBuilder().currentStorage().notFixedTypeVariables.values) {
|
||||
val upperTypes = variableWithConstraints.constraints.extractUpperTypesToCheckIntersectionEmptiness()
|
||||
@@ -888,8 +896,9 @@ internal object CheckIncompatibleTypeVariableUpperBounds : ResolutionPart() {
|
||||
val isInferredEmptyIntersectionForbidden =
|
||||
callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ForbidInferringTypeVariablesIntoEmptyIntersection)
|
||||
|
||||
val errorFactory =
|
||||
if (isInferredEmptyIntersectionForbidden) ::InferredEmptyIntersectionError else ::InferredEmptyIntersectionWarning
|
||||
val errorFactory = if (isInferredEmptyIntersectionForbidden || wasPreviouslyDiscriminated(upperTypes))
|
||||
::InferredEmptyIntersectionError
|
||||
else ::InferredEmptyIntersectionWarning
|
||||
addError(errorFactory(upperTypes, variableWithConstraints.typeVariable))
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,5 +11,5 @@ interface B
|
||||
|
||||
fun <K : Inv<A>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<Inv<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
Bar<Inv<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,5 +11,5 @@ interface B<K> : A<Int>
|
||||
|
||||
fun <K : Out<A<String>>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<Out<B<String>>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
Bar<Out<B<String>>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,5 +11,5 @@ interface B : A<Int>
|
||||
|
||||
fun <K : Out<A<String>>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<Out<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
Bar<Out<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,5 +12,5 @@ interface C : A<String>
|
||||
|
||||
fun <K : Out<C>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<Out<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
Bar<Out<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,5 +12,5 @@ class C : A<String>
|
||||
|
||||
fun <K : <!FINAL_UPPER_BOUND!>Out<C><!>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<Out<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
Bar<Out<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,5 +11,5 @@ class B : A<Int>
|
||||
|
||||
fun <K : Out<A<String>>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<Out<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
Bar<Out<B>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
|
||||
+1
-1
@@ -53,5 +53,5 @@ fun main() {
|
||||
|
||||
select(id(::foo5), id { x: A -> }, id { x: B -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> })
|
||||
|
||||
val x2: (Int) -> Unit = selectNumber(id(::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>foo6<!>), id { x -> <!DEBUG_INFO_EXPRESSION_TYPE("{Comparable<*> & Number}")!>x<!> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("{Comparable<*> & Number}")!>it<!> })
|
||||
val x2: (Int) -> Unit = selectNumber(id(::foo6), id { x -> <!DEBUG_INFO_EXPRESSION_TYPE("{Comparable<*> & Number}")!>x<!> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("{Comparable<*> & Number}")!>it<!> })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user