@@ -66,16 +66,49 @@ interface SimpleConstraintSystem {
66
66
val constraintSystemMarker: ConstraintSystemMarker
67
67
}
68
68
69
- private fun <T > SimpleConstraintSystem.isValueParameterTypeEquallyOrMoreSpecific (
69
+ class FlatSignatureComparisonState (
70
+ private val cs : SimpleConstraintSystem ,
71
+ private val typeParameters : Collection <TypeParameterMarker >,
72
+ private val typeSubstitutor : TypeSubstitutorMarker ,
73
+ private val callbacks : SpecificityComparisonCallbacks ,
74
+ private val specificityComparator : TypeSpecificityComparator ,
75
+ ) {
76
+ fun isLessSpecific (specificType : KotlinTypeMarker , generalType : KotlinTypeMarker ): Boolean {
77
+ if (specificityComparator.isDefinitelyLessSpecific(specificType, generalType)) {
78
+ return true
79
+ } else if (typeParameters.isEmpty() || ! generalType.dependsOnTypeParameters(cs.context, typeParameters)) {
80
+ if (! AbstractTypeChecker .isSubtypeOf(cs.context, specificType, generalType)) {
81
+ if (! callbacks.isNonSubtypeEquallyOrMoreSpecific(specificType, generalType)) {
82
+ return true
83
+ }
84
+ }
85
+ } else {
86
+ val substitutedGeneralType = typeSubstitutor.safeSubstitute(cs.context, generalType)
87
+
88
+ /* *
89
+ * Example:
90
+ * fun <X> Array<out X>.sort(): Unit {}
91
+ * fun <Y: Comparable<Y>> Array<out Y>.sort(): Unit {}
92
+ * Here, when we try solve this CS(Y is variables) then Array<out X> <: Array<out Y> and this system impossible to solve,
93
+ * so we capture types from receiver and value parameters.
94
+ */
95
+ val specificCapturedType = AbstractTypeChecker .prepareType(cs.context, specificType)
96
+ .let { if (cs.captureFromArgument) cs.context.captureFromExpression(it) ? : it else it }
97
+ cs.addSubtypeConstraint(specificCapturedType, substitutedGeneralType)
98
+ if (cs.hasContradiction()) {
99
+ return true
100
+ }
101
+ }
102
+
103
+ return false
104
+ }
105
+ }
106
+
107
+ private fun <T > FlatSignatureComparisonState.isValueParameterTypeEquallyOrMoreSpecific (
70
108
specific : FlatSignature <T >,
71
109
general : FlatSignature <T >,
72
- callbacks : SpecificityComparisonCallbacks ,
73
- specificityComparator : TypeSpecificityComparator ,
74
- typeKindSelector : (TypeWithConversion ? ) -> KotlinTypeMarker ?
110
+ typeKindSelector : (TypeWithConversion ? ) -> KotlinTypeMarker ? ,
75
111
): Boolean {
76
- val typeParameters = general.typeParameters
77
- val typeSubstitutor = registerTypeVariables(typeParameters)
78
-
79
112
val specificContextReceiverCount = specific.contextReceiverCount
80
113
val generalContextReceiverCount = general.contextReceiverCount
81
114
@@ -91,57 +124,44 @@ private fun <T> SimpleConstraintSystem.isValueParameterTypeEquallyOrMoreSpecific
91
124
val specificType = typeKindSelector(specificValueParameterTypes[index]) ? : continue
92
125
val generalType = typeKindSelector(generalValueParameterTypes[index]) ? : continue
93
126
94
- if (specificityComparator.isDefinitelyLessSpecific(specificType, generalType)) {
95
- return false
96
- }
97
-
98
- if (typeParameters.isEmpty() || ! generalType.dependsOnTypeParameters(context, typeParameters)) {
99
- if (! AbstractTypeChecker .isSubtypeOf(context, specificType, generalType)) {
100
- if (! callbacks.isNonSubtypeEquallyOrMoreSpecific(specificType, generalType)) {
101
- return false
102
- }
103
- }
104
- } else {
105
- val substitutedGeneralType = typeSubstitutor.safeSubstitute(context, generalType)
106
-
107
- /* *
108
- * Example:
109
- * fun <X> Array<out X>.sort(): Unit {}
110
- * fun <Y: Comparable<Y>> Array<out Y>.sort(): Unit {}
111
- * Here, when we try solve this CS(Y is variables) then Array<out X> <: Array<out Y> and this system impossible to solve,
112
- * so we capture types from receiver and value parameters.
113
- */
114
- val specificCapturedType = AbstractTypeChecker .prepareType(context, specificType)
115
- .let { if (captureFromArgument) context.captureFromExpression(it) ? : it else it }
116
- addSubtypeConstraint(specificCapturedType, substitutedGeneralType)
117
- }
127
+ if (isLessSpecific(specificType, generalType)) return false
118
128
}
119
129
120
130
return true
121
131
}
122
132
123
- fun <T > SimpleConstraintSystem.isSignatureEquallyOrMoreSpecific (
133
+ fun <T > SimpleConstraintSystem.signatureComparisonStateIfEquallyOrMoreSpecific (
124
134
specific : FlatSignature <T >,
125
135
general : FlatSignature <T >,
126
136
callbacks : SpecificityComparisonCallbacks ,
127
137
specificityComparator : TypeSpecificityComparator ,
128
- useOriginalSamTypes : Boolean = false
129
- ): Boolean {
130
- if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return false
131
- if (specific.contextReceiverCount > general.contextReceiverCount) return false
138
+ useOriginalSamTypes : Boolean = false,
139
+ ): FlatSignatureComparisonState ? {
140
+ if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return null
141
+ if (specific.contextReceiverCount > general.contextReceiverCount) return null
132
142
if (specific.valueParameterTypes.size - specific.contextReceiverCount != general.valueParameterTypes.size - general.contextReceiverCount)
133
- return false
143
+ return null
134
144
135
- if (! isValueParameterTypeEquallyOrMoreSpecific(specific, general, callbacks, specificityComparator) { it?.resultType }) {
136
- return false
145
+ val typeSubstitutor = registerTypeVariables(general.typeParameters)
146
+ val state = FlatSignatureComparisonState (this , general.typeParameters, typeSubstitutor, callbacks, specificityComparator)
147
+
148
+ if (! state.isValueParameterTypeEquallyOrMoreSpecific(specific, general) { it?.resultType }) {
149
+ return null
137
150
}
138
151
139
- if (useOriginalSamTypes && ! isValueParameterTypeEquallyOrMoreSpecific(
140
- specific, general, callbacks, specificityComparator
141
- ) { it?.originalTypeIfWasConverted }
142
- ) {
143
- return false
152
+ if (useOriginalSamTypes && ! state.isValueParameterTypeEquallyOrMoreSpecific(specific, general) { it?.originalTypeIfWasConverted }) {
153
+ return null
144
154
}
145
155
146
- return ! hasContradiction()
156
+ return state
157
+ }
158
+
159
+ fun <T > SimpleConstraintSystem.isSignatureEquallyOrMoreSpecific (
160
+ specific : FlatSignature <T >,
161
+ general : FlatSignature <T >,
162
+ callbacks : SpecificityComparisonCallbacks ,
163
+ specificityComparator : TypeSpecificityComparator ,
164
+ useOriginalSamTypes : Boolean = false
165
+ ): Boolean {
166
+ return signatureComparisonStateIfEquallyOrMoreSpecific(specific, general, callbacks, specificityComparator, useOriginalSamTypes) != null
147
167
}
0 commit comments