[FIR] Use ConeKotlinType to represent vararg's element type
We are using `ConeKotlinType` instead of `FirTypeRef` to represent that element type of vararg doesn't have any source. It has a type that was inferred. If we try to specify a source, then we could end up with the incorrect place for diagnostic. #KT-59682 Fixed
This commit is contained in:
+7
@@ -131,6 +131,13 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
reportFirDiagnostic(diagnostic, thisReference.source, data)
|
reportFirDiagnostic(diagnostic, thisReference.source, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitVarargArgumentsExpression(varargArgumentsExpression: FirVarargArgumentsExpression, data: CheckerContext) {
|
||||||
|
val elementType = varargArgumentsExpression.coneElementTypeOrNull ?: return
|
||||||
|
if (elementType is ConeErrorType) {
|
||||||
|
reportFirDiagnostic(elementType.diagnostic, varargArgumentsExpression.source, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun reportFirDiagnostic(
|
private fun reportFirDiagnostic(
|
||||||
diagnostic: ConeDiagnostic,
|
diagnostic: ConeDiagnostic,
|
||||||
source: KtSourceElement?,
|
source: KtSourceElement?,
|
||||||
|
|||||||
@@ -540,7 +540,8 @@ class Fir2IrVisitor(
|
|||||||
startOffset,
|
startOffset,
|
||||||
endOffset,
|
endOffset,
|
||||||
varargArgumentsExpression.resolvedType.toIrType(),
|
varargArgumentsExpression.resolvedType.toIrType(),
|
||||||
varargArgumentsExpression.varargElementType.toIrType(),
|
varargArgumentsExpression.coneElementTypeOrNull?.toIrType()
|
||||||
|
?: error("Vararg expression has incorrect type"),
|
||||||
varargArgumentsExpression.arguments.map { it.convertToIrVarargElement() }
|
varargArgumentsExpression.arguments.map { it.convertToIrVarargElement() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,9 +222,7 @@ private fun List<JavaAnnotationArgument>.mapJavaTargetArguments(session: FirSess
|
|||||||
ConeAttributes.Empty
|
ConeAttributes.Empty
|
||||||
)
|
)
|
||||||
coneTypeOrNull = elementConeType
|
coneTypeOrNull = elementConeType
|
||||||
varargElementType = buildResolvedTypeRef {
|
coneElementTypeOrNull = elementConeType.createOutArrayType()
|
||||||
type = elementConeType.createOutArrayType()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
|
|||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fakeElement
|
import org.jetbrains.kotlin.fakeElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.copyWithNewSource
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
@@ -38,15 +39,13 @@ internal fun remapArgumentsWithVararg(
|
|||||||
// Create a FirVarargArgumentExpression for the vararg arguments.
|
// Create a FirVarargArgumentExpression for the vararg arguments.
|
||||||
// The order of arguments in the mapping must be preserved for FIR2IR, hence we have to find where the vararg arguments end.
|
// The order of arguments in the mapping must be preserved for FIR2IR, hence we have to find where the vararg arguments end.
|
||||||
// FIR2IR uses the mapping order to determine if arguments need to be reordered.
|
// FIR2IR uses the mapping order to determine if arguments need to be reordered.
|
||||||
val varargParameterTypeRef = varargParameter.returnTypeRef
|
|
||||||
val varargElementType = varargArrayType.arrayElementType()?.approximateIntegerLiteralType()
|
val varargElementType = varargArrayType.arrayElementType()?.approximateIntegerLiteralType()
|
||||||
val argumentList = argumentMapping.keys.toList()
|
val argumentList = argumentMapping.keys.toList()
|
||||||
var indexAfterVarargs = argumentList.size
|
var indexAfterVarargs = argumentList.size
|
||||||
val newArgumentMapping = linkedMapOf<FirExpression, FirValueParameter>()
|
val newArgumentMapping = linkedMapOf<FirExpression, FirValueParameter>()
|
||||||
val varargArgument = buildVarargArgumentsExpression {
|
val varargArgument = buildVarargArgumentsExpression {
|
||||||
// TODO: ideally we should use here a source from the use-site and not from the declaration-site, KT-59682
|
coneElementTypeOrNull = varargElementType
|
||||||
this.varargElementType = varargParameterTypeRef.withReplacedConeType(varargElementType, KtFakeSourceElementKind.VarargArgument)
|
coneTypeOrNull = varargArrayType
|
||||||
this.coneTypeOrNull = varargArrayType
|
|
||||||
var startOffset = Int.MAX_VALUE
|
var startOffset = Int.MAX_VALUE
|
||||||
var endOffset = 0
|
var endOffset = 0
|
||||||
var firstVarargElementSource: KtSourceElement? = null
|
var firstVarargElementSource: KtSourceElement? = null
|
||||||
|
|||||||
+1
-1
@@ -1600,7 +1600,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
i += varargSize
|
i += varargSize
|
||||||
source = argument.source
|
source = argument.source
|
||||||
coneTypeOrNull = argument.resolvedType
|
coneTypeOrNull = argument.resolvedType
|
||||||
varargElementType = argument.varargElementType
|
coneElementTypeOrNull = argument.coneElementTypeOrNull
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
indicesQualifiedAccessForGet[i++]
|
indicesQualifiedAccessForGet[i++]
|
||||||
|
|||||||
+1
-2
@@ -11,7 +11,6 @@ package org.jetbrains.kotlin.fir.expressions
|
|||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
|
|
||||||
@@ -24,7 +23,7 @@ abstract class FirVarargArgumentsExpression : FirExpression() {
|
|||||||
abstract override val coneTypeOrNull: ConeKotlinType?
|
abstract override val coneTypeOrNull: ConeKotlinType?
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract val arguments: List<FirExpression>
|
abstract val arguments: List<FirExpression>
|
||||||
abstract val varargElementType: FirTypeRef
|
abstract val coneElementTypeOrNull: ConeKotlinType?
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||||
visitor.visitVarargArgumentsExpression(this, data)
|
visitor.visitVarargArgumentsExpression(this, data)
|
||||||
|
|||||||
+3
-4
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
|
import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirVarargArgumentsExpressionImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirVarargArgumentsExpressionImpl
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|
||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
class FirVarargArgumentsExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
|
class FirVarargArgumentsExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||||
@@ -28,7 +27,7 @@ class FirVarargArgumentsExpressionBuilder : FirAnnotationContainerBuilder, FirEx
|
|||||||
override var coneTypeOrNull: ConeKotlinType? = null
|
override var coneTypeOrNull: ConeKotlinType? = null
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
val arguments: MutableList<FirExpression> = mutableListOf()
|
val arguments: MutableList<FirExpression> = mutableListOf()
|
||||||
lateinit var varargElementType: FirTypeRef
|
var coneElementTypeOrNull: ConeKotlinType? = null
|
||||||
|
|
||||||
override fun build(): FirVarargArgumentsExpression {
|
override fun build(): FirVarargArgumentsExpression {
|
||||||
return FirVarargArgumentsExpressionImpl(
|
return FirVarargArgumentsExpressionImpl(
|
||||||
@@ -36,14 +35,14 @@ class FirVarargArgumentsExpressionBuilder : FirAnnotationContainerBuilder, FirEx
|
|||||||
coneTypeOrNull,
|
coneTypeOrNull,
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
arguments,
|
arguments,
|
||||||
varargElementType,
|
coneElementTypeOrNull,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
inline fun buildVarargArgumentsExpression(init: FirVarargArgumentsExpressionBuilder.() -> Unit): FirVarargArgumentsExpression {
|
inline fun buildVarargArgumentsExpression(init: FirVarargArgumentsExpressionBuilder.() -> Unit = {}): FirVarargArgumentsExpression {
|
||||||
contract {
|
contract {
|
||||||
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
|
import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.UnresolvedExpressionTypeAccess
|
import org.jetbrains.kotlin.fir.expressions.UnresolvedExpressionTypeAccess
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformInplace
|
import org.jetbrains.kotlin.fir.visitors.transformInplace
|
||||||
@@ -30,19 +29,17 @@ internal class FirVarargArgumentsExpressionImpl(
|
|||||||
override var coneTypeOrNull: ConeKotlinType?,
|
override var coneTypeOrNull: ConeKotlinType?,
|
||||||
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
||||||
override val arguments: MutableList<FirExpression>,
|
override val arguments: MutableList<FirExpression>,
|
||||||
override var varargElementType: FirTypeRef,
|
override val coneElementTypeOrNull: ConeKotlinType?,
|
||||||
) : FirVarargArgumentsExpression() {
|
) : FirVarargArgumentsExpression() {
|
||||||
|
|
||||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||||
annotations.forEach { it.accept(visitor, data) }
|
annotations.forEach { it.accept(visitor, data) }
|
||||||
arguments.forEach { it.accept(visitor, data) }
|
arguments.forEach { it.accept(visitor, data) }
|
||||||
varargElementType.accept(visitor, data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirVarargArgumentsExpressionImpl {
|
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirVarargArgumentsExpressionImpl {
|
||||||
transformAnnotations(transformer, data)
|
transformAnnotations(transformer, data)
|
||||||
arguments.transformInplace(transformer, data)
|
arguments.transformInplace(transformer, data)
|
||||||
varargElementType = varargElementType.transform(transformer, data)
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -616,7 +616,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
|||||||
|
|
||||||
varargArgumentsExpression.configure {
|
varargArgumentsExpression.configure {
|
||||||
+fieldList("arguments", expression)
|
+fieldList("arguments", expression)
|
||||||
+field("varargElementType", typeRef)
|
+field("coneElementTypeOrNull", coneKotlinTypeType, nullable = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
samConversionExpression.configure {
|
samConversionExpression.configure {
|
||||||
|
|||||||
+4
-3
@@ -1,13 +1,14 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
||||||
|
// COMPARE_WITH_LIGHT_TREE
|
||||||
|
|
||||||
fun <T> select(vararg x: <!CANNOT_INFER_PARAMETER_TYPE, CANNOT_INFER_PARAMETER_TYPE!>T<!>) = x[0]
|
fun <T> select(vararg x: T) = x[0]
|
||||||
fun <K> id(x: K) = x
|
fun <K> id(x: K) = x
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val x1 = select<Any?>(id { x, y -> }, { x: Int, y -> })
|
val x1 = select<Any?>(id { x, y -> }, { x: Int, y -> })
|
||||||
val x2 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id<!> { x, <!CANNOT_INFER_PARAMETER_TYPE!>y<!> -> }, { x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!> -> })
|
val x2 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(<!CANNOT_INFER_PARAMETER_TYPE{LT}!><!CANNOT_INFER_PARAMETER_TYPE{PSI}!><!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id<!> { x, <!CANNOT_INFER_PARAMETER_TYPE!>y<!> -> }<!>, { x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!> -> }<!>)
|
||||||
|
|
||||||
val x3 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id<!>(fun (x, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {}), fun (x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {})
|
val x3 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(<!CANNOT_INFER_PARAMETER_TYPE{LT}!><!CANNOT_INFER_PARAMETER_TYPE{PSI}!><!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id<!>(fun (x, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {})<!>, fun (x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {}<!>)
|
||||||
|
|
||||||
val x4 = select<Any?>((fun (x, y) {}), fun (x: Int, y) {})
|
val x4 = select<Any?>((fun (x, y) {}), fun (x: Int, y) {})
|
||||||
val x5 = select<Any?>(id(fun (<!CANNOT_INFER_PARAMETER_TYPE!>x<!>, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {}), fun (x: Int, y) {})
|
val x5 = select<Any?>(id(fun (<!CANNOT_INFER_PARAMETER_TYPE!>x<!>, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {}), fun (x: Int, y) {})
|
||||||
|
|||||||
+1
@@ -1,4 +1,5 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
||||||
|
// COMPARE_WITH_LIGHT_TREE
|
||||||
|
|
||||||
fun <T> select(vararg x: T) = x[0]
|
fun <T> select(vararg x: T) = x[0]
|
||||||
fun <K> id(x: K) = x
|
fun <K> id(x: K) = x
|
||||||
|
|||||||
Vendored
+5
-4
@@ -1,10 +1,11 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
// !CHECK_TYPE
|
// !CHECK_TYPE
|
||||||
|
// COMPARE_WITH_LIGHT_TREE
|
||||||
|
|
||||||
class Inv<I>
|
class Inv<I>
|
||||||
fun <T> materialize(): Inv<T> = TODO()
|
fun <T> materialize(): Inv<T> = TODO()
|
||||||
fun <K> id(arg: K) = arg
|
fun <K> id(arg: K) = arg
|
||||||
fun <S> select(vararg args: <!CANNOT_INFER_PARAMETER_TYPE, CANNOT_INFER_PARAMETER_TYPE!>S<!>): S = TODO()
|
fun <S> select(vararg args: S): S = TODO()
|
||||||
|
|
||||||
fun test1(b: Boolean?) {
|
fun test1(b: Boolean?) {
|
||||||
val v = when(b) {
|
val v = when(b) {
|
||||||
@@ -17,7 +18,7 @@ fun test1(b: Boolean?) {
|
|||||||
|
|
||||||
fun test2() {
|
fun test2() {
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(
|
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>()
|
<!CANNOT_INFER_PARAMETER_TYPE!><!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>()<!>
|
||||||
)
|
)
|
||||||
select(materialize(), materialize<String>())
|
select(materialize(), materialize<String>())
|
||||||
select(materialize(), null, Inv<String>())
|
select(materialize(), null, Inv<String>())
|
||||||
@@ -26,8 +27,8 @@ fun test2() {
|
|||||||
null
|
null
|
||||||
)<!>
|
)<!>
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(
|
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>(),
|
<!CANNOT_INFER_PARAMETER_TYPE{LT}!><!CANNOT_INFER_PARAMETER_TYPE{PSI}!><!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>()<!>,
|
||||||
materialize()
|
materialize()<!>
|
||||||
)
|
)
|
||||||
select(
|
select(
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>(),
|
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>(),
|
||||||
|
|||||||
Vendored
+1
@@ -1,5 +1,6 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
// !CHECK_TYPE
|
// !CHECK_TYPE
|
||||||
|
// COMPARE_WITH_LIGHT_TREE
|
||||||
|
|
||||||
class Inv<I>
|
class Inv<I>
|
||||||
fun <T> materialize(): Inv<T> = TODO()
|
fun <T> materialize(): Inv<T> = TODO()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ package n
|
|||||||
import checkSubtype
|
import checkSubtype
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val a = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>array<!>(array())
|
val a = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>array<!>(<!CANNOT_INFER_PARAMETER_TYPE!>array()<!>)
|
||||||
val a0 : Array<Array<Int>> = array(array())
|
val a0 : Array<Array<Int>> = array(array())
|
||||||
val a1 = array(array<Int>())
|
val a1 = array(array<Int>())
|
||||||
checkSubtype<Array<Array<Int>>>(a1)
|
checkSubtype<Array<Array<Int>>>(a1)
|
||||||
@@ -15,4 +15,4 @@ fun main() {
|
|||||||
|
|
||||||
//from library
|
//from library
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <T> array(vararg t : <!CANNOT_INFER_PARAMETER_TYPE!>T<!>) : Array<T> = t as Array<T>
|
fun <T> array(vararg t : T) : Array<T> = t as Array<T>
|
||||||
|
|||||||
Reference in New Issue
Block a user