Report warning on generic type as argument for reified parameter
#KT-6484 Fixed
This commit is contained in:
@@ -510,6 +510,7 @@ public interface Errors {
|
||||
|
||||
DiagnosticFactory1<PsiElement, TypeParameterDescriptor> TYPE_PARAMETER_AS_REIFIED = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, KotlinType> REIFIED_TYPE_FORBIDDEN_SUBSTITUTION = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, KotlinType> REIFIED_TYPE_UNSAFE_SUBSTITUTION = DiagnosticFactory1.create(WARNING);
|
||||
|
||||
// Type inference
|
||||
|
||||
|
||||
+1
@@ -664,6 +664,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(TYPE_PARAMETER_AS_REIFIED, "Cannot use ''{0}'' as reified type parameter. Use a class instead.", NAME);
|
||||
MAP.put(REIFIED_TYPE_PARAMETER_NO_INLINE, "Only type parameters of inline functions can be reified");
|
||||
MAP.put(REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, "Cannot use ''{0}'' as reified type parameter", RENDER_TYPE);
|
||||
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);
|
||||
MAP.put(TYPE_PARAMETERS_NOT_ALLOWED, "Type parameters are not allowed here");
|
||||
|
||||
MAP.put(TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER, "Type parameter of a property must be used in its receiver type");
|
||||
|
||||
+4
@@ -53,6 +53,10 @@ public class ReifiedTypeParameterSubstitutionChecker implements CallChecker {
|
||||
context.trace.report(
|
||||
Errors.REIFIED_TYPE_FORBIDDEN_SUBSTITUTION.on(getElementToReport(context, parameter.getIndex()), argument));
|
||||
}
|
||||
else if (TypeUtilsKt.unsafeAsReifiedArgument(argument)) {
|
||||
context.trace.report(
|
||||
Errors.REIFIED_TYPE_UNSAFE_SUBSTITUTION.on(getElementToReport(context, parameter.getIndex()), argument));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
inline fun <reified T> foo() {}
|
||||
|
||||
inline fun <reified F> bar() {
|
||||
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>Array<F><!>>()
|
||||
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>List<F><!>>()
|
||||
}
|
||||
|
||||
inline fun <reified E> baz(x: E) {}
|
||||
|
||||
fun test(x: Array<String>, y: Array<*>) {
|
||||
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>List<String><!>>()
|
||||
foo<List<*>>()
|
||||
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>Map<*, String><!>>()
|
||||
foo<Map<*, *>>()
|
||||
|
||||
foo<<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>Array<String><!>>()
|
||||
foo<Array<*>>()
|
||||
|
||||
<!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>baz<!>(x)
|
||||
baz(y)
|
||||
}
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package
|
||||
|
||||
public inline fun </*0*/ reified F> bar(): kotlin.Unit
|
||||
public inline fun </*0*/ reified E> baz(/*0*/ x: E): kotlin.Unit
|
||||
public inline fun </*0*/ reified T> foo(): kotlin.Unit
|
||||
public fun test(/*0*/ x: kotlin.Array<kotlin.String>, /*1*/ y: kotlin.Array<*>): kotlin.Unit
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// !CHECK_TYPE
|
||||
|
||||
fun test() {
|
||||
val array = arrayOf(arrayOf(1))
|
||||
val array = <!REIFIED_TYPE_UNSAFE_SUBSTITUTION!>arrayOf<!>(arrayOf(1))
|
||||
array checkType { _<Array<Array<Int>>>() }
|
||||
}
|
||||
@@ -7382,6 +7382,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GenericAsReifiedArgument.kt")
|
||||
public void testGenericAsReifiedArgument() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/tpAsReified/GenericAsReifiedArgument.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InConstructor.kt")
|
||||
public void testInConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/tpAsReified/InConstructor.kt");
|
||||
|
||||
@@ -67,6 +67,7 @@ fun KotlinType?.isArrayOfNothing(): Boolean {
|
||||
fun KotlinType.isSubtypeOf(superType: KotlinType): Boolean = KotlinTypeChecker.DEFAULT.isSubtypeOf(this, superType)
|
||||
|
||||
fun KotlinType.cannotBeReified(): Boolean = KotlinBuiltIns.isNothingOrNullableNothing(this) || this.isDynamic()
|
||||
fun KotlinType.unsafeAsReifiedArgument(): Boolean = arguments.any { !it.isStarProjection }
|
||||
|
||||
fun TypeProjection.substitute(doSubstitute: (KotlinType) -> KotlinType): TypeProjection {
|
||||
return if (isStarProjection)
|
||||
|
||||
Reference in New Issue
Block a user