Prohibit non-const expressions through varargs in annotations

Fixes #KT-23153 for Kotlin 1.3

 The problem was in the type check of expression type against expected type. When feature `AssigningArraysToVarargsInNamedFormInAnnotations` (KT-20171) appeared, expected type could be wrong, which led to failed type check
This commit is contained in:
Mikhail Zarechenskiy
2018-03-12 02:10:25 +03:00
parent 4ebd11a7ae
commit 6086cd2cf4
12 changed files with 209 additions and 60 deletions
@@ -224,6 +224,7 @@ public interface Errors {
DiagnosticFactory0<KtExpression> ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<KtExpression> ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotatedExpression> ANNOTATIONS_ON_BLOCK_LEVEL_EXPRESSION_ON_THE_SAME_LINE = DiagnosticFactory0.create(WARNING); DiagnosticFactory0<KtAnnotatedExpression> ANNOTATIONS_ON_BLOCK_LEVEL_EXPRESSION_ON_THE_SAME_LINE = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<KtAnnotationEntry> ANNOTATION_USED_AS_ANNOTATION_ARGUMENT = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<KtAnnotationEntry> ANNOTATION_USED_AS_ANNOTATION_ARGUMENT = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtExpression> ANNOTATION_ARGUMENT_IS_NON_CONST = DiagnosticFactory0.create(WARNING);
DiagnosticFactory1<PsiElement, FqName> ILLEGAL_KOTLIN_VERSION_STRING_VALUE = DiagnosticFactory1.create(ERROR); DiagnosticFactory1<PsiElement, FqName> ILLEGAL_KOTLIN_VERSION_STRING_VALUE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, String> NEWER_VERSION_IN_SINCE_KOTLIN = DiagnosticFactory1.create(WARNING); DiagnosticFactory1<PsiElement, String> NEWER_VERSION_IN_SINCE_KOTLIN = DiagnosticFactory1.create(WARNING);
@@ -828,6 +828,7 @@ public class DefaultErrorMessages {
"Use new line if whole block-level expression must be annotated or wrap annotated expression in parentheses"); "Use new line if whole block-level expression must be annotated or wrap annotated expression in parentheses");
MAP.put(ANNOTATION_USED_AS_ANNOTATION_ARGUMENT, "An annotation can't be used as the annotations argument"); MAP.put(ANNOTATION_USED_AS_ANNOTATION_ARGUMENT, "An annotation can't be used as the annotations argument");
MAP.put(ANNOTATION_ARGUMENT_IS_NON_CONST, "An annotation argument must be a compile-time constant");
MAP.put(CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, "Const 'val' are only allowed on top level or in objects"); MAP.put(CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, "Const 'val' are only allowed on top level or in objects");
MAP.put(CONST_VAL_WITH_DELEGATE, "Const 'val' should not have a delegate"); MAP.put(CONST_VAL_WITH_DELEGATE, "Const 'val' should not have a delegate");
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* * that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.resolve.calls.callResolverUtil package org.jetbrains.kotlin.resolve.calls.callResolverUtil
@@ -22,11 +11,13 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.builtins.isSuspendFunctionType import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.lexer.KtToken import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentForExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentForExpression
@@ -36,6 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION
import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeVariables import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeVariables
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate
import org.jetbrains.kotlin.resolve.descriptorUtil.isParameterOfAnnotation import org.jetbrains.kotlin.resolve.descriptorUtil.isParameterOfAnnotation
@@ -186,41 +178,65 @@ fun getSuperCallExpression(call: Call): KtSuperExpression? {
fun getEffectiveExpectedType( fun getEffectiveExpectedType(
parameterDescriptor: ValueParameterDescriptor, parameterDescriptor: ValueParameterDescriptor,
argument: ValueArgument, resolvedArgument: ResolvedValueArgument,
context: ResolutionContext<*> languageVersionSettings: LanguageVersionSettings,
trace: BindingTrace
): KotlinType { ): KotlinType {
if (argument.getSpreadElement() != null || shouldCheckAsArray(parameterDescriptor, argument, context)) { val argument = resolvedArgument.arguments.singleOrNull()
if (parameterDescriptor.varargElementType == null) { return if (argument != null)
// Spread argument passed to a non-vararg parameter, an error is already reported by ValueArgumentsToParametersMapper getEffectiveExpectedTypeForSingleArgument(parameterDescriptor, argument, languageVersionSettings, trace)
return DONT_CARE else
} getExpectedType(parameterDescriptor)
return parameterDescriptor.type
}
val varargElementType = parameterDescriptor.varargElementType
if (varargElementType != null) {
return varargElementType
}
return parameterDescriptor.type
} }
private fun shouldCheckAsArray( fun getEffectiveExpectedType(
parameterDescriptor: ValueParameterDescriptor, parameterDescriptor: ValueParameterDescriptor,
argument: ValueArgument, argument: ValueArgument,
context: ResolutionContext<*> context: ResolutionContext<*>
): KotlinType {
return getEffectiveExpectedTypeForSingleArgument(parameterDescriptor, argument, context.languageVersionSettings, context.trace)
}
fun getEffectiveExpectedTypeForSingleArgument(
parameterDescriptor: ValueParameterDescriptor,
argument: ValueArgument,
languageVersionSettings: LanguageVersionSettings,
trace: BindingTrace
): KotlinType {
if (argument.getSpreadElement() != null) {
// Spread argument passed to a non-vararg parameter, an error is already reported by ValueArgumentsToParametersMapper
return if (parameterDescriptor.varargElementType == null) DONT_CARE else parameterDescriptor.type
}
if (arrayAssignmentToVarargInNamedFormInAnnotation(parameterDescriptor, argument, languageVersionSettings, trace)) {
return parameterDescriptor.type
}
return getExpectedType(parameterDescriptor)
}
private fun getExpectedType(parameterDescriptor: ValueParameterDescriptor): KotlinType {
return parameterDescriptor.varargElementType ?: parameterDescriptor.type
}
private fun arrayAssignmentToVarargInNamedFormInAnnotation(
parameterDescriptor: ValueParameterDescriptor,
argument: ValueArgument,
languageVersionSettings: LanguageVersionSettings,
trace: BindingTrace
): Boolean { ): Boolean {
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.AssigningArraysToVarargsInNamedFormInAnnotations)) return false if (!languageVersionSettings.supportsFeature(LanguageFeature.AssigningArraysToVarargsInNamedFormInAnnotations)) return false
if (!isParameterOfAnnotation(parameterDescriptor)) return false if (!isParameterOfAnnotation(parameterDescriptor)) return false
return argument.isNamed() && parameterDescriptor.isVararg && isArrayOrArrayLiteral(argument, context) return argument.isNamed() && parameterDescriptor.isVararg && isArrayOrArrayLiteral(argument, trace)
} }
fun isArrayOrArrayLiteral(argument: ValueArgument, context: ResolutionContext<*>): Boolean { fun isArrayOrArrayLiteral(argument: ValueArgument, trace: BindingTrace): Boolean {
val argumentExpression = argument.getArgumentExpression() ?: return false val argumentExpression = argument.getArgumentExpression() ?: return false
if (argumentExpression is KtCollectionLiteralExpression) return true if (argumentExpression is KtCollectionLiteralExpression) return true
val type = context.trace.getType(argumentExpression) ?: return false val type = trace.getType(argumentExpression) ?: return false
return KotlinBuiltIns.isArrayOrPrimitiveArray(type) return KotlinBuiltIns.isArrayOrPrimitiveArray(type)
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* * that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.resolve.calls.checkers package org.jetbrains.kotlin.resolve.calls.checkers
@@ -61,7 +50,7 @@ class AssigningNamedArgumentToVarargChecker : CallChecker {
argumentExpression: KtExpression, argumentExpression: KtExpression,
context: ResolutionContext<*> context: ResolutionContext<*>
) { ) {
if (isArrayOrArrayLiteral(argument, context)) { if (isArrayOrArrayLiteral(argument, context.trace)) {
if (argument.hasSpread()) { if (argument.hasSpread()) {
context.trace.report(Errors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION.on(argumentExpression)) context.trace.report(Errors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION.on(argumentExpression))
} }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.BindingContext.COLLECTION_LITERAL_CALL import org.jetbrains.kotlin.resolve.BindingContext.COLLECTION_LITERAL_CALL
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
@@ -86,8 +87,9 @@ class ConstantExpressionEvaluator(
val varargElementType = parameterDescriptor.varargElementType val varargElementType = parameterDescriptor.varargElementType
val argumentsAsVararg = varargElementType != null && !hasSpread(resolvedArgument) val argumentsAsVararg = varargElementType != null && !hasSpread(resolvedArgument)
val constantType = if (argumentsAsVararg) varargElementType else parameterDescriptor.type val constantType = if (argumentsAsVararg) varargElementType else parameterDescriptor.type
val compileTimeConstants = resolveAnnotationValueArguments(resolvedArgument, constantType!!, trace) val expectedType = getEffectiveExpectedType(parameterDescriptor, resolvedArgument, languageVersionSettings, trace)
val constants = compileTimeConstants.map { it.toConstantValue(constantType) } val compileTimeConstants = resolveAnnotationValueArguments(resolvedArgument, constantType!!, expectedType, trace)
val constants = compileTimeConstants.map { it.toConstantValue(expectedType) }
if (argumentsAsVararg) { if (argumentsAsVararg) {
if (isArrayPassedInNamedForm(constants, resolvedArgument)) return constants.single() if (isArrayPassedInNamedForm(constants, resolvedArgument)) return constants.single()
@@ -110,11 +112,12 @@ class ConstantExpressionEvaluator(
private fun checkCompileTimeConstant( private fun checkCompileTimeConstant(
argumentExpression: KtExpression, argumentExpression: KtExpression,
expressionType: KotlinType, expressionType: KotlinType,
trace: BindingTrace trace: BindingTrace,
useDeprecationWarning: Boolean
) { ) {
val constant = ConstantExpressionEvaluator.getConstant(argumentExpression, trace.bindingContext) val constant = ConstantExpressionEvaluator.getConstant(argumentExpression, trace.bindingContext)
if (constant != null && constant.canBeUsedInAnnotations) { if (constant != null && constant.canBeUsedInAnnotations) {
checkInnerPartsOfCompileTimeConstant(constant, trace, argumentExpression) checkInnerPartsOfCompileTimeConstant(constant, trace, argumentExpression, useDeprecationWarning)
return return
} }
@@ -125,13 +128,17 @@ class ConstantExpressionEvaluator(
else -> Errors.ANNOTATION_ARGUMENT_MUST_BE_CONST else -> Errors.ANNOTATION_ARGUMENT_MUST_BE_CONST
} }
trace.report(diagnosticFactory.on(argumentExpression)) if (useDeprecationWarning)
reportDeprecationWarningOnNonConst(argumentExpression, trace)
else
trace.report(diagnosticFactory.on(argumentExpression))
} }
private fun checkInnerPartsOfCompileTimeConstant( private fun checkInnerPartsOfCompileTimeConstant(
constant: CompileTimeConstant<*>, constant: CompileTimeConstant<*>,
trace: BindingTrace, trace: BindingTrace,
argumentExpression: KtExpression argumentExpression: KtExpression,
useDeprecationWarning: Boolean
) { ) {
// array(1, <!>null<!>, 3) - error should be reported on inner expression // array(1, <!>null<!>, 3) - error should be reported on inner expression
val callArguments = when (argumentExpression) { val callArguments = when (argumentExpression) {
@@ -143,12 +150,17 @@ class ConstantExpressionEvaluator(
if (callArguments != null) { if (callArguments != null) {
for (argument in callArguments) { for (argument in callArguments) {
val type = trace.getType(argument) ?: continue val type = trace.getType(argument) ?: continue
checkCompileTimeConstant(argument, type, trace) checkCompileTimeConstant(argument, type, trace, useDeprecationWarning)
} }
} }
if (constant.usesNonConstValAsConstant) { if (constant.usesNonConstValAsConstant) {
trace.report(Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.on(argumentExpression)) if (useDeprecationWarning) {
reportDeprecationWarningOnNonConst(argumentExpression, trace)
} else {
trace.report(Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.on(argumentExpression))
}
} }
if (argumentExpression is KtClassLiteralExpression) { if (argumentExpression is KtClassLiteralExpression) {
@@ -156,12 +168,20 @@ class ConstantExpressionEvaluator(
if (lhsExpression != null) { if (lhsExpression != null) {
val doubleColonLhs = trace.bindingContext.get(BindingContext.DOUBLE_COLON_LHS, lhsExpression) val doubleColonLhs = trace.bindingContext.get(BindingContext.DOUBLE_COLON_LHS, lhsExpression)
if (doubleColonLhs is DoubleColonLHS.Expression && !doubleColonLhs.isObjectQualifier) { if (doubleColonLhs is DoubleColonLHS.Expression && !doubleColonLhs.isObjectQualifier) {
trace.report(Errors.ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL.on(argumentExpression)) if (useDeprecationWarning) {
reportDeprecationWarningOnNonConst(argumentExpression, trace)
} else {
trace.report(Errors.ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL.on(argumentExpression))
}
} }
} }
} }
} }
private fun reportDeprecationWarningOnNonConst(expression: KtExpression, trace: BindingTrace) {
trace.report(Errors.ANNOTATION_ARGUMENT_IS_NON_CONST.on(expression))
}
private fun getArgumentExpressionsForArrayCall( private fun getArgumentExpressionsForArrayCall(
expression: KtCallExpression, expression: KtCallExpression,
trace: BindingTrace trace: BindingTrace
@@ -203,6 +223,7 @@ class ConstantExpressionEvaluator(
private fun resolveAnnotationValueArguments( private fun resolveAnnotationValueArguments(
resolvedValueArgument: ResolvedValueArgument, resolvedValueArgument: ResolvedValueArgument,
deprecatedExpectedType: KotlinType,
expectedType: KotlinType, expectedType: KotlinType,
trace: BindingTrace trace: BindingTrace
): List<CompileTimeConstant<*>> { ): List<CompileTimeConstant<*>> {
@@ -220,12 +241,18 @@ class ConstantExpressionEvaluator(
val expressionType = trace.getType(argumentExpression) ?: continue val expressionType = trace.getType(argumentExpression) ?: continue
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(expressionType, expectedType)) { // this type check should not used as it can introduce subtle bugs when type checking rules against expected type are changing
// TYPE_MISMATCH should be reported otherwise if (!languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonConstValuesAsVarargsInAnnotations) &&
continue !KotlinTypeChecker.DEFAULT.isSubtypeOf(expressionType, deprecatedExpectedType)
) {
if (KotlinTypeChecker.DEFAULT.isSubtypeOf(expressionType, expectedType)) {
checkCompileTimeConstant(argumentExpression, expressionType, trace, useDeprecationWarning = true)
}
continue // TYPE_MISMATCH should be reported otherwise
} }
checkCompileTimeConstant(argumentExpression, expressionType, trace) checkCompileTimeConstant(argumentExpression, expressionType, trace, useDeprecationWarning = false)
} }
return constants return constants
} }
@@ -0,0 +1,26 @@
// !LANGUAGE: -ProhibitNonConstValuesAsVarargsInAnnotations
val nonConstArray = longArrayOf(0)
fun nonConstFun(): LongArray = TODO()
fun nonConstLong(): Long = TODO()
annotation class Anno(vararg val value: Long)
@Anno(value = <!ANNOTATION_ARGUMENT_IS_NON_CONST!>nonConstArray<!>)
fun foo1() {}
@Anno(value = <!ANNOTATION_ARGUMENT_IS_NON_CONST!>nonConstFun()<!>)
fun foo2() {}
@Anno(value = <!ANNOTATION_ARGUMENT_IS_NON_CONST!>longArrayOf(<!ANNOTATION_ARGUMENT_IS_NON_CONST!>nonConstLong()<!>)<!>)
fun foo3() {}
@Anno(value = <!ANNOTATION_ARGUMENT_IS_NON_CONST!>[<!ANNOTATION_ARGUMENT_IS_NON_CONST!>nonConstLong()<!>]<!>)
fun foo4() {}
@Anno(value = *<!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION, ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
fun bar1() {}
@Anno(*<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
fun bar2() {}
@@ -0,0 +1,19 @@
package
public val nonConstArray: kotlin.LongArray
@Anno public fun bar1(): kotlin.Unit
@Anno public fun bar2(): kotlin.Unit
@Anno(value = {}) public fun foo1(): kotlin.Unit
@Anno(value = {}) public fun foo2(): kotlin.Unit
@Anno(value = {}) public fun foo3(): kotlin.Unit
@Anno(value = {}) public fun foo4(): kotlin.Unit
public fun nonConstFun(): kotlin.LongArray
public fun nonConstLong(): kotlin.Long
public final annotation class Anno : kotlin.Annotation {
public constructor Anno(/*0*/ vararg value: kotlin.Long /*kotlin.LongArray*/)
public final val value: kotlin.LongArray
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
}
@@ -0,0 +1,26 @@
// !LANGUAGE: +ProhibitNonConstValuesAsVarargsInAnnotations
val nonConstArray = longArrayOf(0)
fun nonConstFun(): LongArray = TODO()
fun nonConstLong(): Long = TODO()
annotation class Anno(vararg val value: Long)
@Anno(value = <!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
fun foo1() {}
@Anno(value = <!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstFun()<!>)
fun foo2() {}
@Anno(value = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>longArrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstLong()<!>)<!>)
fun foo3() {}
@Anno(value = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>[<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstLong()<!>]<!>)
fun foo4() {}
@Anno(value = *<!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION, ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
fun bar1() {}
@Anno(*<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
fun bar2() {}
@@ -0,0 +1,19 @@
package
public val nonConstArray: kotlin.LongArray
@Anno public fun bar1(): kotlin.Unit
@Anno public fun bar2(): kotlin.Unit
@Anno(value = {}) public fun foo1(): kotlin.Unit
@Anno(value = {}) public fun foo2(): kotlin.Unit
@Anno(value = {}) public fun foo3(): kotlin.Unit
@Anno(value = {}) public fun foo4(): kotlin.Unit
public fun nonConstFun(): kotlin.LongArray
public fun nonConstLong(): kotlin.Long
public final annotation class Anno : kotlin.Annotation {
public constructor Anno(/*0*/ vararg value: kotlin.Long /*kotlin.LongArray*/)
public final val value: kotlin.LongArray
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
}
@@ -24536,6 +24536,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("assignNonConstSingleArrayElementAsVarargInAnnotation.kt")
public void testAssignNonConstSingleArrayElementAsVarargInAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotation.kt");
doTest(fileName);
}
@TestMetadata("assignNonConstSingleArrayElementAsVarargInAnnotationError.kt")
public void testAssignNonConstSingleArrayElementAsVarargInAnnotationError() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.kt");
doTest(fileName);
}
@TestMetadata("assigningArraysToVarargsInAnnotations.kt") @TestMetadata("assigningArraysToVarargsInAnnotations.kt")
public void testAssigningArraysToVarargsInAnnotations() throws Exception { public void testAssigningArraysToVarargsInAnnotations() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/assigningArraysToVarargsInAnnotations.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/assigningArraysToVarargsInAnnotations.kt");
@@ -24536,6 +24536,18 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
doTest(fileName); doTest(fileName);
} }
@TestMetadata("assignNonConstSingleArrayElementAsVarargInAnnotation.kt")
public void testAssignNonConstSingleArrayElementAsVarargInAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotation.kt");
doTest(fileName);
}
@TestMetadata("assignNonConstSingleArrayElementAsVarargInAnnotationError.kt")
public void testAssignNonConstSingleArrayElementAsVarargInAnnotationError() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.kt");
doTest(fileName);
}
@TestMetadata("assigningArraysToVarargsInAnnotations.kt") @TestMetadata("assigningArraysToVarargsInAnnotations.kt")
public void testAssigningArraysToVarargsInAnnotations() throws Exception { public void testAssigningArraysToVarargsInAnnotations() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/assigningArraysToVarargsInAnnotations.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/varargs/assigningArraysToVarargsInAnnotations.kt");
@@ -67,6 +67,7 @@ enum class LanguageFeature(
JvmStaticInInterface(KOTLIN_1_3), JvmStaticInInterface(KOTLIN_1_3),
InlineClasses(KOTLIN_1_3), InlineClasses(KOTLIN_1_3),
ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion(KOTLIN_1_3), ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion(KOTLIN_1_3),
ProhibitNonConstValuesAsVarargsInAnnotations(KOTLIN_1_3),
StrictJavaNullabilityAssertions(sinceVersion = null, defaultState = State.DISABLED), StrictJavaNullabilityAssertions(sinceVersion = null, defaultState = State.DISABLED),
ProperIeee754Comparisons(sinceVersion = null, defaultState = State.DISABLED), ProperIeee754Comparisons(sinceVersion = null, defaultState = State.DISABLED),