diff --git a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizeAnnotationChecker.kt b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizeAnnotationChecker.kt
index becdf89393d..db8eff03468 100644
--- a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizeAnnotationChecker.kt
+++ b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizeAnnotationChecker.kt
@@ -5,16 +5,24 @@
package org.jetbrains.kotlin.parcelize.fir.diagnostics
+import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirAnnotationCallChecker
+import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
+import org.jetbrains.kotlin.fir.correspondingProperty
+import org.jetbrains.kotlin.fir.declarations.FirValueParameter
+import org.jetbrains.kotlin.fir.declarations.utils.fromPrimaryConstructor
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
+import org.jetbrains.kotlin.fir.expressions.classId
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
-import org.jetbrains.kotlin.fir.types.ConeClassLikeType
-import org.jetbrains.kotlin.fir.types.coneType
+import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
+import org.jetbrains.kotlin.fir.types.*
+import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.parcelize.ParcelizeNames
import org.jetbrains.kotlin.parcelize.ParcelizeNames.DEPRECATED_RUNTIME_PACKAGE
import org.jetbrains.kotlin.parcelize.ParcelizeNames.IGNORED_ON_PARCEL_CLASS_IDS
import org.jetbrains.kotlin.parcelize.ParcelizeNames.PARCELIZE_CLASS_CLASS_IDS
@@ -28,12 +36,14 @@ object FirParcelizeAnnotationChecker : FirAnnotationCallChecker() {
val resolvedAnnotationSymbol = annotationType.lookupTag.toFirRegularClassSymbol(context.session) ?: return
when (val annotationClassId = resolvedAnnotationSymbol.classId) {
in TYPE_PARCELER_CLASS_IDS -> {
- checkTypeParcelerUsage(expression, context, reporter)
- checkDeprecatedAnnotations(expression, annotationClassId, context, reporter, isForbidden = true)
+ if (checkDeprecatedAnnotations(expression, annotationClassId, context, reporter, isForbidden = true)) {
+ checkTypeParcelerUsage(expression, context, reporter)
+ }
}
in WRITE_WITH_CLASS_IDS -> {
- checkWriteWithUsage(expression, context, reporter)
- checkDeprecatedAnnotations(expression, annotationClassId, context, reporter, isForbidden = true)
+ if (checkDeprecatedAnnotations(expression, annotationClassId, context, reporter, isForbidden = true)) {
+ checkWriteWithUsage(expression, context, reporter)
+ }
}
in IGNORED_ON_PARCEL_CLASS_IDS -> {
checkDeprecatedAnnotations(expression, annotationClassId, context, reporter, isForbidden = false)
@@ -50,20 +60,83 @@ object FirParcelizeAnnotationChecker : FirAnnotationCallChecker() {
context: CheckerContext,
reporter: DiagnosticReporter,
isForbidden: Boolean
- ) {
+ ): Boolean {
if (annotationClassId.packageFqName == DEPRECATED_RUNTIME_PACKAGE) {
val factory = if (isForbidden) KtErrorsParcelize.FORBIDDEN_DEPRECATED_ANNOTATION else KtErrorsParcelize.DEPRECATED_ANNOTATION
reporter.reportOn(annotationCall.source, factory, context)
+ return false
+ }
+ return true
+ }
+
+ private fun checkTypeParcelerUsage(annotationCall: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
+ val thisMappedType = annotationCall.typeArguments.takeIf { it.size == 2 }?.first()?.toConeTypeProjection()?.type
+ ?: return
+
+ val annotationContainer = context.annotationContainers.lastOrNull()
+ val duplicatingAnnotationCount = annotationContainer
+ ?.annotations
+ ?.filter { it.classId in TYPE_PARCELER_CLASS_IDS }
+ ?.mapNotNull { it.typeArguments.takeIf { it.size == 2 }?.first()?.toConeTypeProjection()?.type }
+ ?.count { it == thisMappedType }
+
+ if (duplicatingAnnotationCount != null && duplicatingAnnotationCount > 1) {
+ val reportElement = annotationCall.typeArguments.firstOrNull()?.source ?: annotationCall.source
+ reporter.reportOn(reportElement, KtErrorsParcelize.DUPLICATING_TYPE_PARCELERS, context)
+ return
+ }
+
+ checkIfTheContainingClassIsParcelize(annotationCall, context, reporter)
+
+ // If we are looking at a parameter of the primary constructor of a class, check that the
+ // enclosing class doesn't have the same TypeParceler annotation.
+ if (annotationContainer is FirValueParameter && annotationContainer.correspondingProperty?.fromPrimaryConstructor == true) {
+ val enclosingClass = context.findClosestClassOrObject() ?: return
+
+ val annotationType = annotationCall.typeRef.coneType
+ if (enclosingClass.annotations.any { it.typeRef.coneType == annotationType }) {
+ val reportElement = annotationCall.calleeReference.source ?: annotationCall.source
+ reporter.reportOn(reportElement, KtErrorsParcelize.REDUNDANT_TYPE_PARCELER, enclosingClass.symbol, context)
+ }
}
}
- @Suppress("UNUSED_PARAMETER")
- private fun checkTypeParcelerUsage(annotationCall: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
- // TODO: this check checks type arguments of annotation which are not supported in FIR
+ private fun checkWriteWithUsage(annotationCall: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
+ checkIfTheContainingClassIsParcelize(annotationCall, context, reporter)
+
+ // For `@WriteWith
` check that `P` is an object.
+ val parcelerType = annotationCall.typeArguments.singleOrNull()?.toConeTypeProjection()?.type ?: return
+ if (parcelerType.toRegularClassSymbol(context.session)?.classKind != ClassKind.OBJECT) {
+ val reportElement = annotationCall.typeArguments.singleOrNull()?.source ?: annotationCall.source
+ reporter.reportOn(reportElement, KtErrorsParcelize.PARCELER_SHOULD_BE_OBJECT, context)
+ }
+
+ // For `@WriteWith
T` check that `P` is a subtype of `Parceler`.
+ //
+ // From the perspective of the `WriteWith` annotation call, `T` corresponds to the nearest enclosing annotation container
+ // stripped of annotations.
+ //
+ // It's safe to assume that `Parceler` refers to `kotlinx.parcelize.Parceler` rather than `kotlinx.android.parcel.Parceler`,
+ // since using the deprecated `WriteWith` annotation is an error.
+ val targetType = (context.annotationContainers.lastOrNull() as? FirTypeRef)?.coneType?.withAttributes(ConeAttributes.Empty)
+ ?: return
+ val expectedType = ConeClassLikeTypeImpl(
+ ConeClassLikeLookupTagImpl(ParcelizeNames.PARCELER_ID),
+ arrayOf(targetType),
+ isNullable = false
+ )
+ if (!parcelerType.isSubtypeOf(expectedType, context.session)) {
+ val reportElement = annotationCall.typeArguments.singleOrNull()?.source ?: annotationCall.source
+ reporter.reportOn(reportElement, KtErrorsParcelize.PARCELER_TYPE_INCOMPATIBLE, parcelerType, targetType, context)
+ }
}
- @Suppress("UNUSED_PARAMETER")
- private fun checkWriteWithUsage(annotationCall: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
- // TODO: this check checks type arguments of annotation which are not supported in FIR
+ private fun checkIfTheContainingClassIsParcelize(annotationCall: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
+ val enclosingClass = context.findClosestClassOrObject() ?: return
+
+ if (!enclosingClass.symbol.isParcelize(context.session)) {
+ val reportElement = annotationCall.calleeReference.source ?: annotationCall.source
+ reporter.reportOn(reportElement, KtErrorsParcelize.CLASS_SHOULD_BE_PARCELIZE, enclosingClass.symbol, context)
+ }
}
}
diff --git a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt
index ebffc4fdf7d..30af1fb50f9 100644
--- a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt
+++ b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt
@@ -5,7 +5,9 @@
package org.jetbrains.kotlin.parcelize.fir.diagnostics
+import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
+import org.jetbrains.kotlin.descriptors.isEnumClass
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirSession
@@ -18,12 +20,13 @@ import org.jetbrains.kotlin.fir.declarations.utils.fromPrimaryConstructor
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
+import org.jetbrains.kotlin.fir.resolve.fqName
+import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
-import org.jetbrains.kotlin.fir.types.ConeErrorType
-import org.jetbrains.kotlin.fir.types.classId
-import org.jetbrains.kotlin.fir.types.coneType
-import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
+import org.jetbrains.kotlin.fir.types.*
+import org.jetbrains.kotlin.parcelize.BuiltinParcelableTypes
+import org.jetbrains.kotlin.parcelize.ParcelizeNames
import org.jetbrains.kotlin.parcelize.ParcelizeNames.CREATOR_NAME
import org.jetbrains.kotlin.parcelize.ParcelizeNames.IGNORED_ON_PARCEL_CLASS_IDS
import org.jetbrains.kotlin.parcelize.ParcelizeNames.PARCELER_ID
@@ -55,7 +58,6 @@ object FirParcelizePropertyChecker : FirPropertyChecker() {
}
}
- @Suppress("UNUSED_PARAMETER")
private fun checkParcelableClassProperty(
property: FirProperty,
containingClassSymbol: FirRegularClassSymbol,
@@ -63,18 +65,92 @@ object FirParcelizePropertyChecker : FirPropertyChecker() {
reporter: DiagnosticReporter
) {
val type = property.returnTypeRef.coneType
- if (type is ConeErrorType || containingClassSymbol.hasCustomParceler(context.session)) return
- /*
- * TODO: abstract code from ParcelSerializer or IrParcelSerializerFactory to avoid duplication
- * of allowed types checking
- */
+ if (type is ConeErrorType || containingClassSymbol.hasCustomParceler(context.session) || property.hasIgnoredOnParcel()) {
+ return
+ }
+
+ val session = context.session
+ val customParcelerTypes = getCustomParcelerTypes(property.annotations + containingClassSymbol.annotations, session)
+ if (!checkParcelableType(type, customParcelerTypes, session)) {
+ reporter.reportOn(property.returnTypeRef.source, KtErrorsParcelize.PARCELABLE_TYPE_NOT_SUPPORTED, context)
+ }
+ }
+
+ private fun getCustomParcelerTypes(annotations: List, session: FirSession): Set =
+ annotations.mapNotNullTo(mutableSetOf()) { annotation ->
+ if (annotation.fqName(session) in ParcelizeNames.TYPE_PARCELER_FQ_NAMES && annotation.typeArguments.size == 2) {
+ annotation.typeArguments[0].toConeTypeProjection().type
+ } else {
+ null
+ }
+ }
+
+ private fun checkParcelableType(type: ConeKotlinType, customParcelerTypes: Set, session: FirSession): Boolean {
+ if (type.hasParcelerAnnotation(session) || type in customParcelerTypes) {
+ return true
+ }
+
+ val upperBound = type.getErasedUpperBound(session)
+ val symbol = upperBound?.toRegularClassSymbol(session)
+ ?: return false
+
+ if (symbol.classKind.isSingleton || symbol.classKind.isEnumClass) {
+ return true
+ }
+
+ val fqName = symbol.classId.asFqNameString()
+ if (fqName in BuiltinParcelableTypes.PARCELABLE_BASE_TYPE_FQNAMES) {
+ return true
+ }
+
+ if (fqName in BuiltinParcelableTypes.PARCELABLE_CONTAINER_FQNAMES) {
+ return upperBound.typeArguments.all { projection ->
+ projection.type?.let { checkParcelableType(it, customParcelerTypes, session) } ?: false
+ }
+ }
+
+ return with(session.typeContext) {
+ type.anySuperTypeConstructor {
+ it is ConeKotlinType &&
+ (it.classId?.asFqNameString() in BuiltinParcelableTypes.PARCELABLE_SUPERTYPE_FQNAMES ||
+ it.isBuiltinFunctionalType(session))
+ }
+ }
+ }
+
+ private fun ConeKotlinType.getErasedUpperBound(session: FirSession): ConeClassLikeType? =
+ when (this) {
+ is ConeClassLikeType ->
+ fullyExpandedType(session)
+
+ is ConeTypeParameterType -> {
+ val bounds = lookupTag.typeParameterSymbol.resolvedBounds
+ val representativeBound = bounds.firstOrNull {
+ val kind = it.coneType.toRegularClassSymbol(session)?.classKind
+ ?: return@firstOrNull false
+ kind != ClassKind.INTERFACE && kind != ClassKind.ANNOTATION_CLASS
+ } ?: bounds.first()
+ representativeBound.coneType.getErasedUpperBound(session)
+ }
+
+ else ->
+ null
+ }
+
+ private fun ConeKotlinType.hasParcelerAnnotation(session: FirSession): Boolean {
+ for (annotation in customAnnotations) {
+ val fqName = annotation.fqName(session)
+ if (fqName in ParcelizeNames.RAW_VALUE_ANNOTATION_FQ_NAMES || fqName in ParcelizeNames.WRITE_WITH_FQ_NAMES) {
+ return true
+ }
+ }
+ return false
}
private fun FirProperty.hasIgnoredOnParcel(): Boolean {
return annotations.hasIgnoredOnParcel() || (getter?.annotations?.hasIgnoredOnParcel() ?: false)
}
-
private fun List.hasIgnoredOnParcel(): Boolean {
return this.any {
if (it.annotationTypeRef.coneType.classId !in IGNORED_ON_PARCEL_CLASS_IDS) return@any false
diff --git a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/KtDefaultErrorMessagesParcelize.kt b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/KtDefaultErrorMessagesParcelize.kt
index 1cbdb321eb5..4fe91029615 100644
--- a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/KtDefaultErrorMessagesParcelize.kt
+++ b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/KtDefaultErrorMessagesParcelize.kt
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.parcelize.fir.diagnostics
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
import org.jetbrains.kotlin.diagnostics.KtDiagnosticRenderer
-import org.jetbrains.kotlin.diagnostics.rendering.Renderers.RENDER_CLASS_OR_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
+import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
import org.jetbrains.kotlin.parcelize.fir.diagnostics.KtErrorsParcelize.CLASS_SHOULD_BE_PARCELIZE
import org.jetbrains.kotlin.parcelize.fir.diagnostics.KtErrorsParcelize.CREATOR_DEFINITION_IS_NOT_ALLOWED
import org.jetbrains.kotlin.parcelize.fir.diagnostics.KtErrorsParcelize.DEPRECATED_ANNOTATION
diff --git a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/KtErrorsParcelize.kt b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/KtErrorsParcelize.kt
index 25ba24eb0d2..e3b875c9960 100644
--- a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/KtErrorsParcelize.kt
+++ b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/KtErrorsParcelize.kt
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies.DELEG
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies.INNER_MODIFIER
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies.NAME_IDENTIFIER
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies.OVERRIDE_MODIFIER
+import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.psi.KtClassOrObject
@@ -43,8 +45,8 @@ object KtErrorsParcelize {
val PARCELER_SHOULD_BE_OBJECT by error0()
val PARCELER_TYPE_INCOMPATIBLE by error2()
val DUPLICATING_TYPE_PARCELERS by error0()
- val REDUNDANT_TYPE_PARCELER by warning1()
- val CLASS_SHOULD_BE_PARCELIZE by error1()
+ val REDUNDANT_TYPE_PARCELER by warning1>()
+ val CLASS_SHOULD_BE_PARCELIZE by error1>()
val FORBIDDEN_DEPRECATED_ANNOTATION by error0()
val DEPRECATED_ANNOTATION by warning0()
val DEPRECATED_PARCELER by error0()
diff --git a/plugins/parcelize/parcelize-compiler/testData/diagnostics/customParcelers.fir.kt b/plugins/parcelize/parcelize-compiler/testData/diagnostics/customParcelers.fir.kt
index 0e856f4efa3..bca096f35d5 100644
--- a/plugins/parcelize/parcelize-compiler/testData/diagnostics/customParcelers.fir.kt
+++ b/plugins/parcelize/parcelize-compiler/testData/diagnostics/customParcelers.fir.kt
@@ -19,27 +19,27 @@ class StringClassParceler : Parceler {
override fun String.write(parcel: Parcel, flags: Int) = TODO()
}
-@TypeParceler
-class MissingParcelizeAnnotation(val a: @WriteWith String)
+@TypeParceler
+class MissingParcelizeAnnotation(val a: @WriteWith String)
@Parcelize
@TypeParceler
-class ShouldBeClass(val a: @WriteWith String) : Parcelable
+class ShouldBeClass(val a: @WriteWith<StringClassParceler> String) : Parcelable
@Parcelize
class Test(
- val a: @WriteWith Int,
+ val a: @WriteWith<StringParceler> Int,
val b: @WriteWith String,
- val c: @WriteWith CharSequence,
- val d: @WriteWith String,
+ val c: @WriteWith<StringParceler> CharSequence,
+ val d: @WriteWith<CharSequenceParceler> String,
val e: @WriteWith CharSequence
) : Parcelable
@Parcelize
@TypeParceler
-class Test2(@TypeParceler val a: String) : Parcelable
+class Test2(@TypeParceler val a: String) : Parcelable
@Parcelize
-@TypeParceler
-@TypeParceler
+@TypeParceler<String, StringParceler>
+@TypeParceler<String, CharSequenceParceler>
class Test3(val a: String) : Parcelable
diff --git a/plugins/parcelize/parcelize-compiler/testData/diagnostics/kt20062.fir.kt b/plugins/parcelize/parcelize-compiler/testData/diagnostics/kt20062.fir.kt
deleted file mode 100644
index 939b87f978b..00000000000
--- a/plugins/parcelize/parcelize-compiler/testData/diagnostics/kt20062.fir.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package test
-
-import kotlinx.parcelize.*
-import android.os.*
-
-class Box(val value: String)
-
-@Parcelize
-class Foo(val box: Box): Parcelable {
- companion object : Parceler {
- override fun create(parcel: Parcel) = Foo(Box(parcel.readString()))
-
- override fun Foo.write(parcel: Parcel, flags: Int) {
- parcel.writeString(box.value)
- }
- }
-}
-
-@Parcelize
-class Foo2(val box: Box): Parcelable
diff --git a/plugins/parcelize/parcelize-compiler/testData/diagnostics/kt20062.kt b/plugins/parcelize/parcelize-compiler/testData/diagnostics/kt20062.kt
index 36f692501ed..198d8cba6e4 100644
--- a/plugins/parcelize/parcelize-compiler/testData/diagnostics/kt20062.kt
+++ b/plugins/parcelize/parcelize-compiler/testData/diagnostics/kt20062.kt
@@ -1,3 +1,4 @@
+// FIR_IDENTICAL
package test
import kotlinx.parcelize.*
diff --git a/plugins/parcelize/parcelize-compiler/testData/diagnostics/unsupportedType.fir.kt b/plugins/parcelize/parcelize-compiler/testData/diagnostics/unsupportedType.fir.kt
deleted file mode 100644
index e1d1b2cc392..00000000000
--- a/plugins/parcelize/parcelize-compiler/testData/diagnostics/unsupportedType.fir.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package test
-
-import kotlinx.parcelize.Parcelize
-import kotlinx.parcelize.RawValue
-import android.os.Parcelable
-
-@Parcelize
-class User(
- val a: String,
- val b: Any,
- val c: Any?,
- val d: Map,
- val e: @RawValue Any?,
- val f: @RawValue Map,
- val g: Map,
- val h: Map<@RawValue Any, List<@RawValue Any>>
-) : Parcelable
diff --git a/plugins/parcelize/parcelize-compiler/testData/diagnostics/unsupportedType.kt b/plugins/parcelize/parcelize-compiler/testData/diagnostics/unsupportedType.kt
index 74956c162a1..56b5288b25a 100644
--- a/plugins/parcelize/parcelize-compiler/testData/diagnostics/unsupportedType.kt
+++ b/plugins/parcelize/parcelize-compiler/testData/diagnostics/unsupportedType.kt
@@ -1,3 +1,4 @@
+// FIR_IDENTICAL
package test
import kotlinx.parcelize.Parcelize