Skip to content

Commit 751f66c

Browse files
committed
Report warning on generic type as argument for reified parameter
#KT-6484 Fixed
1 parent ae6c62d commit 751f66c

File tree

8 files changed

+44
-1
lines changed

8 files changed

+44
-1
lines changed

compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ enum BadNamedArgumentsTarget {
510510

511511
DiagnosticFactory1<PsiElement, TypeParameterDescriptor> TYPE_PARAMETER_AS_REIFIED = DiagnosticFactory1.create(ERROR);
512512
DiagnosticFactory1<PsiElement, KotlinType> REIFIED_TYPE_FORBIDDEN_SUBSTITUTION = DiagnosticFactory1.create(ERROR);
513+
DiagnosticFactory1<PsiElement, KotlinType> REIFIED_TYPE_UNSAFE_SUBSTITUTION = DiagnosticFactory1.create(WARNING);
513514

514515
// Type inference
515516

compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ public String render(@NotNull Boolean hasValueParameters) {
664664
MAP.put(TYPE_PARAMETER_AS_REIFIED, "Cannot use ''{0}'' as reified type parameter. Use a class instead.", NAME);
665665
MAP.put(REIFIED_TYPE_PARAMETER_NO_INLINE, "Only type parameters of inline functions can be reified");
666666
MAP.put(REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, "Cannot use ''{0}'' as reified type parameter", RENDER_TYPE);
667+
MAP.put(REIFIED_TYPE_UNSAFE_SUBSTITUTION, "It may be not safe to use ''{0}'' as an argument for a reified type parameter. Use a non-generic type or * if possible", RENDER_TYPE);
667668
MAP.put(TYPE_PARAMETERS_NOT_ALLOWED, "Type parameters are not allowed here");
668669

669670
MAP.put(TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER, "Type parameter of a property must be used in its receiver type");

compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReifiedTypeParameterSubstitutionChecker.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ else if (TypeUtilsKt.cannotBeReified(argument)) {
5353
context.trace.report(
5454
Errors.REIFIED_TYPE_FORBIDDEN_SUBSTITUTION.on(getElementToReport(context, parameter.getIndex()), argument));
5555
}
56+
else if (TypeUtilsKt.unsafeAsReifiedArgument(argument)) {
57+
context.trace.report(
58+
Errors.REIFIED_TYPE_UNSAFE_SUBSTITUTION.on(getElementToReport(context, parameter.getIndex()), argument));
59+
}
5660
}
5761
}
5862
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// !DIAGNOSTICS: -UNUSED_PARAMETER
2+
3+
inline fun <reified T> foo() {}
4+
5+
inline fun <reified F> bar() {
6+
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>Array<F><!>>()
7+
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>List<F><!>>()
8+
}
9+
10+
inline fun <reified E> baz(x: E) {}
11+
12+
fun test(x: Array<String>, y: Array<*>) {
13+
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>List<String><!>>()
14+
foo<List<*>>()
15+
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>Map<*, String><!>>()
16+
foo<Map<*, *>>()
17+
18+
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>Array<String><!>>()
19+
foo<Array<*>>()
20+
21+
<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>baz<!>(x)
22+
baz(y)
23+
}
24+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package
2+
3+
public inline fun </*0*/ reified F> bar(): kotlin.Unit
4+
public inline fun </*0*/ reified E> baz(/*0*/ x: E): kotlin.Unit
5+
public inline fun </*0*/ reified T> foo(): kotlin.Unit
6+
public fun test(/*0*/ x: kotlin.Array<kotlin.String>, /*1*/ y: kotlin.Array<*>): kotlin.Unit
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// !CHECK_TYPE
22

33
fun test() {
4-
val array = arrayOf(arrayOf(1))
4+
val array = <!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>arrayOf<!>(arrayOf(1))
55
array checkType { _<Array<Array<Int>>>() }
66
}

compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7382,6 +7382,12 @@ public void testConventions() throws Exception {
73827382
doTest(fileName);
73837383
}
73847384

7385+
@TestMetadata("GenericAsReifiedArgument.kt")
7386+
public void testGenericAsReifiedArgument() throws Exception {
7387+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/tpAsReified/GenericAsReifiedArgument.kt");
7388+
doTest(fileName);
7389+
}
7390+
73857391
@TestMetadata("InConstructor.kt")
73867392
public void testInConstructor() throws Exception {
73877393
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/tpAsReified/InConstructor.kt");

core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ fun KotlinType?.isArrayOfNothing(): Boolean {
6767
fun KotlinType.isSubtypeOf(superType: KotlinType): Boolean = KotlinTypeChecker.DEFAULT.isSubtypeOf(this, superType)
6868

6969
fun KotlinType.cannotBeReified(): Boolean = KotlinBuiltIns.isNothingOrNullableNothing(this) || this.isDynamic()
70+
fun KotlinType.unsafeAsReifiedArgument(): Boolean = arguments.any { !it.isStarProjection }
7071

7172
fun TypeProjection.substitute(doSubstitute: (KotlinType) -> KotlinType): TypeProjection {
7273
return if (isStarProjection)

0 commit comments

Comments
 (0)