Update variadic declaration checker

Add check for errors, caused by incorrect combination of vararg modifiers on type variable, value parameter and value parameter's type.
Remove old generators after moving Tuple to stdlib, update and regenerate tests.
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java
index 8aa89ed..9b5f229 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java
@@ -691,6 +691,8 @@
 
     DiagnosticFactory0<KtExpression> VARARG_OUTSIDE_PARENTHESES = DiagnosticFactory0.create(ERROR);
     DiagnosticFactory0<LeafPsiElement> NON_VARARG_SPREAD = DiagnosticFactory0.create(ERROR);
+    DiagnosticFactory0<KtTupleType> NON_VARIADIC_SPREAD = DiagnosticFactory0.create(ERROR);
+    DiagnosticFactory0<KtTypeReference> NO_SPREAD_FOR_VARIADIC_PARAMETER = DiagnosticFactory0.create(ERROR);
     DiagnosticFactory0<LeafPsiElement> SPREAD_OF_NULLABLE = DiagnosticFactory0.create(ERROR);
     DiagnosticFactory0<LeafPsiElement> SPREAD_OF_LAMBDA_OR_CALLABLE_REFERENCE = DiagnosticFactory0.create(ERROR);
 
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 07b88d2..43c7b23d 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java
@@ -199,6 +199,8 @@
 
         MAP.put(VARARG_OUTSIDE_PARENTHESES, "Passing value as a vararg is only allowed inside a parenthesized argument list");
         MAP.put(NON_VARARG_SPREAD, "The spread operator (*foo) may only be applied in a vararg position");
+        MAP.put(NON_VARIADIC_SPREAD, "The spread operator (*) may only be used in type for vararg argument in conjunction with variadic type variable");
+        MAP.put(NO_SPREAD_FOR_VARIADIC_PARAMETER, "The variadic type parameter should be referenced in type declaration with spread (*)");
         MAP.put(SPREAD_OF_NULLABLE, "The spread operator (*foo) may not be applied to an argument of nullable type");
         MAP.put(SPREAD_OF_LAMBDA_OR_CALLABLE_REFERENCE, "The spread operator (*foo) cannot be applied to lambda argument or callable reference");
 
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/VariadicDeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/VariadicDeclarationsChecker.kt
index a72c8f2..87de78e 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/VariadicDeclarationsChecker.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/VariadicDeclarationsChecker.kt
@@ -5,11 +5,18 @@
 
 package org.jetbrains.kotlin.resolve.checkers
 
+import org.jetbrains.kotlin.config.LanguageFeature
 import org.jetbrains.kotlin.descriptors.*
 import org.jetbrains.kotlin.diagnostics.Errors
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.KtDeclaration
-import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
+import org.jetbrains.kotlin.lexer.*
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
+import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
+import org.jetbrains.kotlin.resolve.calls.components.isVararg
+import org.jetbrains.kotlin.resolve.source.getPsi
+import org.jetbrains.kotlin.types.typeUtil.contains
+import org.jetbrains.kotlin.types.typeUtil.isVariadic
+import org.jetbrains.kotlin.utils.addToStdlib.safeAs
 
 class VariadicDeclarationsChecker : DeclarationChecker {
     private val unsupportedFunctionModifiers = setOf(
@@ -27,9 +34,18 @@
         context: DeclarationCheckerContext
     ) {
         if (declaration !is KtTypeParameterListOwner) return
+
+        if (!context.languageVersionSettings.supportsFeature(LanguageFeature.VariadicGenerics)) {
+            reportUnsupportedOnVararg(declaration, context)
+            return
+        }
+
         when (descriptor) {
-            is SimpleFunctionDescriptor -> checkFunctionTypeParameters(declaration, descriptor, context)
-            else -> checkClassifierTypeParameters(declaration, context)
+            is SimpleFunctionDescriptor -> {
+                checkFunctionTypeParameters(declaration, descriptor, context)
+                checkFunctionParameters(descriptor, context)
+            }
+            else -> checkTypeParametersOnNonVariadicDeclaration(declaration, context)
         }
     }
 
@@ -42,6 +58,19 @@
         if (variadicParameters.isEmpty())
             return
 
+        if (variadicParameters.size > 1) {
+            for (ktTypeParameter in declaration.typeParameters) {
+                context.trace.report(Errors.MULTIPLE_VARARG_PARAMETERS.on(ktTypeParameter))
+            }
+        }
+
+        checkUnsupprotedModifiers(declaration, context)
+    }
+
+    private fun checkUnsupprotedModifiers(
+        declaration: KtTypeParameterListOwner,
+        context: DeclarationCheckerContext
+    ) {
         unsupportedFunctionModifiers.forEach { modifier ->
             declaration.modifierList?.getModifier(modifier)?.let { reportOn ->
                 context.trace.report(
@@ -53,15 +82,50 @@
                 )
             }
         }
+    }
 
-        if (variadicParameters.size > 1) {
-            for (ktTypeParameter in declaration.typeParameters) {
-                context.trace.report(Errors.MULTIPLE_VARARG_PARAMETERS.on(ktTypeParameter))
+    private fun checkFunctionParameters(
+        functionDescriptor: SimpleFunctionDescriptor,
+        context: DeclarationCheckerContext
+    ) {
+        for (parameter in functionDescriptor.valueParameters) {
+            val psiParameter = parameter.source.getPsi().safeAs<KtParameter>() ?: continue
+            val typeReference = psiParameter.getChildOfType<KtTypeReference>() ?: continue
+            val outerTupleType = typeReference.getChildOfType<KtTupleType>()
+
+            val isVararg = parameter.isVararg
+            val tupleTypes = psiParameter.collectDescendantsOfType<KtTupleType>()
+            val dependsOnVariadicType = parameter.type.contains { it.isVariadic }
+
+            if (tupleTypes.count() > 1) {
+                context.trace.report(
+                    Errors.UNSUPPORTED.on(typeReference, "Multiple spread (*) operators in single type are not supported")
+                )
+                continue
+            }
+            if (outerTupleType != null
+                && (!isVararg || !dependsOnVariadicType)
+            ) {
+                context.trace.report(Errors.NON_VARIADIC_SPREAD.on(outerTupleType))
+                continue
+            }
+            if (dependsOnVariadicType && tupleTypes.count() == 0) {
+                context.trace.report(Errors.NO_SPREAD_FOR_VARIADIC_PARAMETER.on(typeReference))
             }
         }
     }
 
-    private fun checkClassifierTypeParameters(
+    private fun reportUnsupportedOnVararg(declaration: KtTypeParameterListOwner, context: DeclarationCheckerContext) {
+        for (ktTypeParameter in declaration.typeParameters) {
+            val ktVarargKeyword = ktTypeParameter.modifierList?.getModifier(KtTokens.VARARG_KEYWORD)
+                ?: continue
+            context.trace.report(
+                Errors.UNSUPPORTED.on(ktVarargKeyword, "'vararg' modifier on type parameter is not supported")
+            )
+        }
+    }
+
+    private fun checkTypeParametersOnNonVariadicDeclaration(
         declaration: KtTypeParameterListOwner,
         context: DeclarationCheckerContext
     ) {
diff --git a/compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectArguments.kt b/compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectArguments.kt
new file mode 100644
index 0000000..0c6010a
--- /dev/null
+++ b/compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectArguments.kt
@@ -0,0 +1,15 @@
+// !LANGUAGE: +NewInference +VariadicGenerics
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+class Box<T>
+
+fun <Ts> v0(args: Ts) {}
+fun <Ts> v1(args: <!NON_VARIADIC_SPREAD!>*Ts<!>) {}
+fun <Ts> v2(vararg args: Ts) {}
+fun <Ts> v3(vararg args: <!NON_VARIADIC_SPREAD!>*Ts<!>) {}
+fun <vararg Ts> v4(args: <!NO_SPREAD_FOR_VARIADIC_PARAMETER!>Ts<!>) {}
+fun <vararg Ts> v5(args: <!NON_VARIADIC_SPREAD!>*Ts<!>) {}
+fun <vararg Ts> v6(vararg args: <!NO_SPREAD_FOR_VARIADIC_PARAMETER!>Ts<!>) {}
+fun <vararg Ts> v7(vararg args: *Ts) {}
+fun <vararg Ts> v8(vararg args: <!UNSUPPORTED!>*Box<*Ts><!>) {}
+fun <vararg Ts> v9(vararg args: <!NO_SPREAD_FOR_VARIADIC_PARAMETER!>Box<Ts><!>) {}
diff --git a/compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectArguments.txt b/compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectArguments.txt
new file mode 100644
index 0000000..05be51a
--- /dev/null
+++ b/compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectArguments.txt
@@ -0,0 +1,19 @@
+package
+
+public fun </*0*/ Ts> v0(/*0*/ args: Ts): kotlin.Unit
+public fun </*0*/ Ts> v1(/*0*/ args: kotlin.Tuple<Ts>): kotlin.Unit
+public fun </*0*/ Ts> v2(/*0*/ vararg args: Ts /*kotlin.Array<out Ts>*/): kotlin.Unit
+public fun </*0*/ Ts> v3(/*0*/ vararg args: Ts /*kotlin.Tuple<Ts>*/): kotlin.Unit
+public fun </*0*/ Ts> v4(/*0*/ args: Ts): kotlin.Unit
+public fun </*0*/ Ts> v5(/*0*/ args: kotlin.Tuple<Ts>): kotlin.Unit
+public fun </*0*/ Ts> v6(/*0*/ vararg args: Ts /*kotlin.Array<out Ts>*/): kotlin.Unit
+public fun </*0*/ Ts> v7(/*0*/ vararg args: Ts /*kotlin.Tuple<Ts>*/): kotlin.Unit
+public fun </*0*/ Ts> v8(/*0*/ vararg args: Box<kotlin.Tuple<Ts>> /*kotlin.Tuple<Box<kotlin.Tuple<Ts>>>*/): kotlin.Unit
+public fun </*0*/ Ts> v9(/*0*/ vararg args: Box<Ts> /*kotlin.Array<out Box<Ts>>*/): kotlin.Unit
+
+public final class Box</*0*/ T> {
+    public constructor Box</*0*/ T>()
+    public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+    public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+    public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+}
diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java
index a9180c4..843a62a 100644
--- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java
@@ -3553,6 +3553,11 @@
             runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/errorNoWrapper.kt");
         }
 
+        @TestMetadata("incorrectArguments.kt")
+        public void testIncorrectArguments() throws Exception {
+            runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectArguments.kt");
+        }
+
         @TestMetadata("incorrectCalls.kt")
         public void testIncorrectCalls() throws Exception {
             runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectCalls.kt");
@@ -3573,6 +3578,11 @@
             runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/suspendLambda.kt");
         }
 
+        @TestMetadata("unsupported.kt")
+        public void testUnsupported() throws Exception {
+            runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/unsupported.kt");
+        }
+
         @TestMetadata("varargDeclarations.kt")
         public void testVarargDeclarations() throws Exception {
             runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/varargDeclarations.kt");
diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
index 34326c1..42e2486 100644
--- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
@@ -3553,6 +3553,11 @@
             runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/errorNoWrapper.kt");
         }
 
+        @TestMetadata("incorrectArguments.kt")
+        public void testIncorrectArguments() throws Exception {
+            runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectArguments.kt");
+        }
+
         @TestMetadata("incorrectCalls.kt")
         public void testIncorrectCalls() throws Exception {
             runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/incorrectCalls.kt");
@@ -3573,6 +3578,11 @@
             runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/suspendLambda.kt");
         }
 
+        @TestMetadata("unsupported.kt")
+        public void testUnsupported() throws Exception {
+            runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/unsupported.kt");
+        }
+
         @TestMetadata("varargDeclarations.kt")
         public void testVarargDeclarations() throws Exception {
             runTest("compiler/testData/diagnostics/testsWithStdLib/variadicGenerics/varargDeclarations.kt");
diff --git a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt
index 271eeba..02f8387 100644
--- a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt
+++ b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt
@@ -83,10 +83,6 @@
             model("diagnostics/testsWithStdLib")
         }
 
-        testClass<AbstractDiagnosticsTestWithVariadicGenerics> {
-            model("diagnostics/testsWithVariadicGenerics")
-        }
-
         testClass<AbstractDiagnosticsTestWithStdLibUsingJavac> {
             model("diagnostics/testsWithStdLib")
         }
@@ -296,10 +292,6 @@
             model("writeSignature")
         }
 
-        testClass<AbstractWriteSignatureTestWithVariadicGenerics> {
-            model("writeSignatureWithVariadicGenerics")
-        }
-
         testClass<AbstractCliTest> {
             model("cli/jvm", extension = "args", testMethod = "doJvmTest", recursive = false)
             model("cli/js", extension = "args", testMethod = "doJsTest", recursive = false)