diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 08b9f477d45..5a9b88570cc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -500,6 +500,8 @@ public interface Errors { DiagnosticFactory0 MULTIPLE_VARARG_PARAMETERS = DiagnosticFactory0.create(ERROR, PARAMETER_VARARG_MODIFIER); + DiagnosticFactory1 FORBIDDEN_VARARG_PARAMETER_TYPE = DiagnosticFactory1.create(ERROR, PARAMETER_VARARG_MODIFIER); + // Named parameters DiagnosticFactory0 DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE = DiagnosticFactory0.create(ERROR, PARAMETER_DEFAULT_VALUE); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 13fcad38d5f..5fd2b9d3637 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -267,6 +267,7 @@ public class DefaultErrorMessages { MAP.put(ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE, "An anonymous function is not allowed to specify default values for its parameters"); MAP.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless"); MAP.put(MULTIPLE_VARARG_PARAMETERS, "Multiple vararg-parameters are prohibited"); + MAP.put(FORBIDDEN_VARARG_PARAMETER_TYPE, "Forbidden vararg parameter type: {0}", RENDER_TYPE); MAP.put(HEADER_DECLARATION_WITH_BODY, "Header declaration must not have a body"); MAP.put(HEADER_DECLARATION_WITH_DEFAULT_PARAMETER, "Header declaration cannot have parameters with default values"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index e6815327a82..848e065f7d9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.resolve.BindingContext.* import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeChecker @@ -891,15 +892,21 @@ class DeclarationsChecker( } private fun checkVarargParameters(trace: BindingTrace, callableDescriptor: CallableDescriptor) { - val numberOfVarargParameters = callableDescriptor.valueParameters.count { it.varargElementType != null } - if (numberOfVarargParameters > 1) { - for (parameter in callableDescriptor.valueParameters) { - if (parameter.varargElementType != null) { - val parameterDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(parameter) - if (parameterDeclaration is KtParameter) { - trace.report(MULTIPLE_VARARG_PARAMETERS.on(parameterDeclaration)) - } - } + val varargParameters = callableDescriptor.valueParameters.filter { it.varargElementType != null } + + if (varargParameters.size > 1) { + for (parameter in varargParameters) { + val parameterDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(parameter) as? KtParameter ?: continue + trace.report(MULTIPLE_VARARG_PARAMETERS.on(parameterDeclaration)) + } + } + + val nullableNothing = callableDescriptor.builtIns.nullableNothingType + for (parameter in varargParameters) { + val varargElementType = parameter.varargElementType!!.upperIfFlexible() + if (KotlinTypeChecker.DEFAULT.isSubtypeOf(varargElementType, nullableNothing)) { + val parameterDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(parameter) as? KtParameter ?: continue + trace.report(FORBIDDEN_VARARG_PARAMETER_TYPE.on(parameterDeclaration, varargElementType)) } } } diff --git a/compiler/testData/diagnostics/tests/varargs/varargOfNothing.kt b/compiler/testData/diagnostics/tests/varargs/varargOfNothing.kt new file mode 100644 index 00000000000..97afb147da5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/varargs/varargOfNothing.kt @@ -0,0 +1,15 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun testVarargOfNothing(vararg v: Nothing) {} + +fun testVarargOfNNothing(vararg v: Nothing?) {} + +fun testVarargOfT(vararg v: T) {} + +fun outer() { + fun testVarargOfNothing(vararg v: Nothing) {} + + fun testVarargOfNNothing(vararg v: Nothing?) {} + + fun testVarargOfT(vararg v: T) {} +} diff --git a/compiler/testData/diagnostics/tests/varargs/varargOfNothing.txt b/compiler/testData/diagnostics/tests/varargs/varargOfNothing.txt new file mode 100644 index 00000000000..2eb7f37c44c --- /dev/null +++ b/compiler/testData/diagnostics/tests/varargs/varargOfNothing.txt @@ -0,0 +1,6 @@ +package + +public fun outer(): kotlin.Unit +public fun testVarargOfNNothing(/*0*/ vararg v: kotlin.Nothing? /*kotlin.Array*/): kotlin.Unit +public fun testVarargOfNothing(/*0*/ vararg v: kotlin.Nothing /*kotlin.Array*/): kotlin.Unit +public fun testVarargOfT(/*0*/ vararg v: T /*kotlin.Array*/): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 75929d674e7..b8c949dde09 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -22627,6 +22627,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("varargOfNothing.kt") + public void testVarargOfNothing() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/varargOfNothing.kt"); + doTest(fileName); + } + @TestMetadata("varargsAndFunctionLiterals.kt") public void testVarargsAndFunctionLiterals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/varargsAndFunctionLiterals.kt");