@@ -8,8 +8,6 @@ package org.jetbrains.kotlin.resolve.calls.tower
8
8
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
9
9
import org.jetbrains.kotlin.descriptors.*
10
10
import org.jetbrains.kotlin.descriptors.annotations.Annotations
11
- import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
12
- import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
13
11
import org.jetbrains.kotlin.diagnostics.Diagnostic
14
12
import org.jetbrains.kotlin.diagnostics.Errors
15
13
import org.jetbrains.kotlin.psi.*
@@ -25,13 +23,12 @@ import org.jetbrains.kotlin.resolve.calls.components.AdditionalDiagnosticReporte
25
23
import org.jetbrains.kotlin.resolve.calls.components.isVararg
26
24
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
27
25
import org.jetbrains.kotlin.resolve.calls.context.CallPosition
28
- import org.jetbrains.kotlin.resolve.calls.inference.approximateCapturedTypes
29
26
import org.jetbrains.kotlin.resolve.calls.inference.buildResultingSubstitutor
30
27
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
31
28
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
32
29
import org.jetbrains.kotlin.resolve.calls.inference.model.*
33
30
import org.jetbrains.kotlin.resolve.calls.inference.substitute
34
- import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateIntegerLiteralTypes
31
+ import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateCapturedTypes
35
32
import org.jetbrains.kotlin.resolve.calls.model.*
36
33
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.makeNullableTypeIfSafeReceiver
37
34
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
@@ -41,13 +38,14 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
41
38
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
42
39
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
43
40
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
41
+ import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
44
42
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
45
43
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
46
- import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
47
44
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
48
45
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
49
46
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
50
47
import org.jetbrains.kotlin.types.*
48
+ import org.jetbrains.kotlin.types.checker.NewCapturedType
51
49
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
52
50
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
53
51
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
@@ -295,14 +293,15 @@ class KotlinToResolvedCallTransformer(
295
293
// todo external argument
296
294
297
295
val argumentExpression = valueArgument.getArgumentExpression() ? : continue
298
- updateRecordedType(argumentExpression, parameter, newContext)
296
+ updateRecordedType(argumentExpression, parameter, newContext, resolvedCall.isReallySuccess() )
299
297
}
300
298
}
301
299
302
300
fun updateRecordedType (
303
301
expression : KtExpression ,
304
302
parameter : ValueParameterDescriptor ? ,
305
- context : BasicCallResolutionContext
303
+ context : BasicCallResolutionContext ,
304
+ reportErrorForTypeMismatch : Boolean
306
305
): KotlinType ? {
307
306
val deparenthesized = expression.let {
308
307
KtPsiUtil .getLastElementDeparenthesized(it, context.statementFilter)
@@ -319,6 +318,9 @@ class KotlinToResolvedCallTransformer(
319
318
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, deparenthesized) ? : updatedType
320
319
}
321
320
321
+
322
+ var reportErrorDuringTypeCheck = reportErrorForTypeMismatch
323
+
322
324
if (parameter != null && ImplicitIntegerCoercion .isEnabledForParameter(parameter)) {
323
325
val argumentCompileTimeValue = context.trace[BindingContext .COMPILE_TIME_VALUE , deparenthesized]
324
326
if (argumentCompileTimeValue != null && argumentCompileTimeValue.parameters.isConvertableConstVal) {
@@ -327,14 +329,15 @@ class KotlinToResolvedCallTransformer(
327
329
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(
328
330
context.trace, context.statementFilter, context.expectedType, generalNumberType, expression
329
331
)
332
+ reportErrorDuringTypeCheck = true
330
333
}
331
334
332
335
}
333
336
}
334
337
335
338
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context)
336
339
337
- dataFlowAnalyzer.checkType(updatedType, deparenthesized, context, false )
340
+ dataFlowAnalyzer.checkType(updatedType, deparenthesized, context, reportErrorDuringTypeCheck )
338
341
339
342
return updatedType
340
343
}
@@ -687,44 +690,32 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
687
690
@Suppress(" UNCHECKED_CAST" )
688
691
resultingDescriptor = run {
689
692
val candidateDescriptor = resolvedCallAtom.candidateDescriptor
690
- val containsIntegerLiteralTypes = resolvedCallAtom.candidateDescriptor.returnType?.contains {
691
- it.constructor is IntegerLiteralTypeConstructor
692
- } ? : false
693
+ val containsCapturedTypes = resolvedCallAtom.candidateDescriptor.returnType?.contains { it is NewCapturedType } ? : false
694
+ val containsIntegerLiteralTypes = resolvedCallAtom.candidateDescriptor.returnType?.contains { it.constructor is IntegerLiteralTypeConstructor } ? : false
693
695
694
696
when {
695
697
candidateDescriptor is FunctionDescriptor ||
696
- (candidateDescriptor is PropertyDescriptor && candidateDescriptor.typeParameters.isNotEmpty() || containsIntegerLiteralTypes) ->
698
+ (candidateDescriptor is PropertyDescriptor && ( candidateDescriptor.typeParameters.isNotEmpty() || containsCapturedTypes || containsIntegerLiteralTypes) ) ->
697
699
// this code is very suspicious. Now it is very useful for BE, because they cannot do nothing with captured types,
698
700
// but it seems like temporary solution.
699
- candidateDescriptor.substituteAndApproximateIntegerLiteralTypes(resolvedCallAtom.substitutor).let {
700
- if (substitutor != null ) {
701
- it.substitute(substitutor)
702
- } else {
703
- it
704
- }
705
- }
706
-
701
+ candidateDescriptor.substitute(resolvedCallAtom.substitutor).substituteAndApproximateCapturedTypes(
702
+ substitutor ? : FreshVariableNewTypeSubstitutor .Empty
703
+ )
707
704
else ->
708
705
candidateDescriptor
709
706
}
710
707
} as D
711
708
712
709
typeArguments = resolvedCallAtom.substitutor.freshVariables.map {
713
- (substitutor ? : FreshVariableNewTypeSubstitutor .Empty ).safeSubstitute(it.defaultType)
710
+ val substituted = (substitutor ? : FreshVariableNewTypeSubstitutor .Empty ).safeSubstitute(it.defaultType)
711
+ TypeApproximator (substituted.constructor .builtIns)
712
+ .approximateToSuperType(substituted, TypeApproximatorConfiguration .IntegerLiteralsTypesApproximation )
713
+ ? : substituted
714
714
}
715
715
716
716
calculateExpectedTypeForSamConvertedArgumentMap(substitutor)
717
717
}
718
718
719
- fun approximateCapturedTypesAndHackSetters () {
720
- val approximator = TypeApproximator (resultingDescriptor.builtIns)
721
- resultingDescriptor = resultingDescriptor.hackSettersAccordingToCapturedOutTypes()
722
- resultingDescriptor = resultingDescriptor.approximateCapturedTypes()
723
- typeArguments = typeArguments.map {
724
- approximator.approximateToSuperType(it, TypeApproximatorConfiguration .CapturedAndIntegerLiteralsTypesApproximation ) ? : it
725
- }
726
- }
727
-
728
719
fun getExpectedTypeForSamConvertedArgument (valueArgument : ValueArgument ): UnwrappedType ? =
729
720
expedtedTypeForSamConvertedArgumentMap?.get(valueArgument)
730
721
@@ -817,41 +808,3 @@ fun NewResolvedCallImpl<*>.hasInferredReturnType(): Boolean {
817
808
val returnType = this .resultingDescriptor.returnType ? : return false
818
809
return ! returnType.contains { ErrorUtils .isUninferredParameter(it) }
819
810
}
820
-
821
- fun ResolvedCall <* >.approximateCapturedTypesAndHackSetters () {
822
- when (this ) {
823
- is NewResolvedCallImpl <* > -> approximateCapturedTypesAndHackSetters()
824
- is NewVariableAsFunctionResolvedCallImpl -> {
825
- functionCall.approximateCapturedTypesAndHackSetters()
826
- variableCall.approximateCapturedTypesAndHackSetters()
827
- }
828
- else -> throw UnsupportedOperationException (" Illegal resolved call: $this " )
829
- }
830
- }
831
-
832
- fun <D : CallableDescriptor > D.hackSettersAccordingToCapturedOutTypes (): D {
833
- return when (this ) {
834
- is PropertyDescriptorImpl -> hackSettersAccordingToCapturedOutTypes() as D
835
- else -> this
836
- }
837
- }
838
-
839
- private fun PropertyDescriptorImpl.hackSettersAccordingToCapturedOutTypes (): PropertyDescriptor {
840
- val setter = setter ? : return this
841
- val valueParameter = setter.valueParameters.first()
842
- val inputType = valueParameter.type
843
- val approximatedType = TypeApproximator (builtIns).approximateToSubType(
844
- inputType.unwrap(),
845
- TypeApproximatorConfiguration .CapturedAndIntegerLiteralsTypesApproximation
846
- ) ? : return this
847
-
848
- val newProperty = newCopyBuilder().setOriginal(original).build() as PropertyDescriptorImpl
849
-
850
- val newSetter = with (setter) {
851
- PropertySetterDescriptorImpl (newProperty, annotations, modality, visibility, isDefault, isExternal, isInline, kind, original, source)
852
- }
853
- newSetter.initialize(PropertySetterDescriptorImpl .createSetterParameter(newSetter, approximatedType, setter.annotations))
854
- newProperty.initialize(getter, newSetter, backingField, delegateField)
855
- newProperty.isSetterProjectedOut = true
856
- return newProperty
857
- }
0 commit comments