Don't recognize nullable function types as inlinable

#KT-19679 Fixed
This commit is contained in:
Mikhael Bogdanov
2017-08-16 12:51:28 +02:00
parent 1b2e28d467
commit 79ecc7fd5c
17 changed files with 177 additions and 15 deletions
@@ -51,7 +51,7 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
private val isEffectivelyPrivateApiFunction = descriptor.isEffectivelyPrivateApi
private val inlinableParameters = descriptor.valueParameters.filter { isInlinableParameter(it) }
private val inlinableParameters = descriptor.valueParameters.filter { InlineUtil.isInlineParameter(it) }
private val inlinableKtParameters = inlinableParameters.mapNotNull { (it.source as? KotlinSourceElement)?.psi }
@@ -132,7 +132,7 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
when {
!checkNotInDefaultParameter(context, argumentCallee, argumentExpression) -> { /*error*/ }
InlineUtil.isInline(targetDescriptor) && isInlinableParameter(targetParameterDescriptor) ->
InlineUtil.isInline(targetDescriptor) && InlineUtil.isInlineParameter(targetParameterDescriptor) ->
if (allowsNonLocalReturns(argumentCallee) && !allowsNonLocalReturns(targetParameterDescriptor)) {
context.trace.report(NON_LOCAL_RETURN_NOT_ALLOWED.on(argumentExpression, argumentExpression))
}
@@ -219,10 +219,6 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
}
}
private fun isInlinableParameter(descriptor: ParameterDescriptor): Boolean {
return InlineUtil.isInlineLambdaParameter(descriptor) && !descriptor.type.isMarkedNullable
}
private fun isInvokeOrInlineExtension(descriptor: CallableDescriptor): Boolean {
if (descriptor !is SimpleFunctionDescriptor) {
return false
@@ -154,9 +154,12 @@ class InlineAnalyzerExtension(
}
private fun checkHasInlinableAndNullability(functionDescriptor: FunctionDescriptor, function: KtFunction, trace: BindingTrace) {
for ((parameter, descriptor) in function.valueParameters.zip(functionDescriptor.valueParameters)) {
if (checkInlinableParameter(descriptor, parameter, functionDescriptor, trace)) return
var hasInlineArgs = false
function.valueParameters.zip(functionDescriptor.valueParameters).forEach {
(parameter, descriptor) ->
hasInlineArgs = hasInlineArgs or checkInlinableParameter(descriptor, parameter, functionDescriptor, trace)
}
if (hasInlineArgs) return
if (functionDescriptor.isInlineOnlyOrReifiable() || functionDescriptor.isHeader) return
@@ -171,7 +174,7 @@ class InlineAnalyzerExtension(
expression: KtElement,
functionDescriptor: CallableDescriptor,
trace: BindingTrace?): Boolean {
if (InlineUtil.isInlineLambdaParameter(parameter)) {
if (InlineUtil.isInlineParameterExceptNullability(parameter)) {
if (parameter.type.isMarkedNullable) {
trace?.report(Errors.NULLABLE_INLINE_PARAMETER.on(expression, expression, functionDescriptor))
}
@@ -32,12 +32,18 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
public class InlineUtil {
public static boolean isInlineLambdaParameter(@NotNull ParameterDescriptor valueParameterOrReceiver) {
public static boolean isInlineParameterExceptNullability(@NotNull ParameterDescriptor valueParameterOrReceiver) {
return !(valueParameterOrReceiver instanceof ValueParameterDescriptor
&& ((ValueParameterDescriptor) valueParameterOrReceiver).isNoinline()) &&
FunctionTypesKt.isFunctionType(valueParameterOrReceiver.getOriginal().getType());
}
public static boolean isInlineParameter(@NotNull ParameterDescriptor valueParameterOrReceiver) {
return isInlineParameterExceptNullability(valueParameterOrReceiver) &&
!valueParameterOrReceiver.getOriginal().getType().isMarkedNullable();
}
public static boolean isInline(@Nullable DeclarationDescriptor descriptor) {
return descriptor instanceof FunctionDescriptor && getInlineStrategy((FunctionDescriptor) descriptor).isInline();
}
@@ -152,7 +158,7 @@ public class InlineUtil {
if (!(mapping instanceof ArgumentMatch)) return null;
ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter();
return isInlineLambdaParameter(parameter) ? parameter : null;
return isInlineParameter(parameter) ? parameter : null;
}
public static boolean canBeInlineArgument(@Nullable PsiElement functionalExpression) {