Some progress
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CollectionLiteralResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CollectionLiteralResolver.kt
index 6502466..51bfb98 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CollectionLiteralResolver.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CollectionLiteralResolver.kt
@@ -127,10 +127,12 @@
             return ArrayFqNames.ARRAY_OF_FUNCTION
         }
 
+        val primitiveElementType = KotlinBuiltIns.getPrimitiveArrayElementType(expectedType)
+        if (primitiveElementType != null) return ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY[primitiveElementType]!!
+
         val descriptor = expectedType.constructor.declarationDescriptor ?: return ArrayFqNames.ARRAY_OF_FUNCTION
 
-        return ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayType(descriptor)]
-            ?: UnsignedTypes.unsignedArrayTypeToArrayCall[UnsignedTypes.toUnsignedArrayType(descriptor)]
+        return UnsignedTypes.unsignedArrayTypeToArrayCall[UnsignedTypes.toUnsignedArrayType(descriptor)]
             ?: ArrayFqNames.ARRAY_OF_FUNCTION
     }
 }
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt
index cb02751..1b0347d 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt
@@ -51,7 +51,6 @@
         get() = symbolTable
 
     val iterator = getClass(Name.identifier("Iterator"), "kotlin", "collections")
-    val vArrayIterator = getClass(Name.identifier("VArrayIterator"), "kotlin")
 
     val charSequence = getClass(Name.identifier("CharSequence"), "kotlin")
     val string = getClass(Name.identifier("String"), "kotlin")
@@ -134,14 +133,17 @@
     val doubleArray get() = irBuiltIns.doubleArray
     val booleanArray get() = irBuiltIns.booleanArray
 
-    val byteArrayType get() = byteArray.owner.defaultType
-    val charArrayType get() = charArray.owner.defaultType
-    val shortArrayType get() = shortArray.owner.defaultType
-    val intArrayType get() = intArray.owner.defaultType
-    val longArrayType get() = longArray.owner.defaultType
-    val floatArrayType get() = floatArray.owner.defaultType
-    val doubleArrayType get() = doubleArray.owner.defaultType
-    val booleanArrayType get() = booleanArray.owner.defaultType
+    val byteArrayType get() = primitiveArrayType(irBuiltIns.byteType, irBuiltIns.byteArray)
+    val charArrayType get() = primitiveArrayType(irBuiltIns.charType, irBuiltIns.charArray)
+    val shortArrayType get() = primitiveArrayType(irBuiltIns.shortType, irBuiltIns.shortArray)
+    val intArrayType get() = primitiveArrayType(irBuiltIns.intType, irBuiltIns.intArray)
+    val longArrayType get() = primitiveArrayType(irBuiltIns.longType, irBuiltIns.longArray)
+    val floatArrayType get() = primitiveArrayType(irBuiltIns.floatType, irBuiltIns.floatArray)
+    val doubleArrayType get() = primitiveArrayType(irBuiltIns.doubleType, irBuiltIns.doubleArray)
+    val booleanArrayType get() = primitiveArrayType(irBuiltIns.booleanType, irBuiltIns.booleanArray)
+
+    private fun primitiveArrayType(elementType: IrType, arrayClass: IrClassSymbol?) =
+        arrayClass?.owner?.defaultType ?: vArray!!.typeWith(elementType)
 
     val primitiveTypesToPrimitiveArrays get() = irBuiltIns.primitiveTypesToPrimitiveArrays
     val primitiveArraysToPrimitiveTypes get() = irBuiltIns.primitiveArraysToPrimitiveTypes
diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt
index bd3cbde..df10dbb 100644
--- a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt
+++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt
@@ -61,6 +61,7 @@
                 Key(kotlinFqn, null, "enumValueOf", listOf(stringFqn)) to EnumValueOf,
                 Key(kotlinFqn, stringFqn, "plus", listOf(anyFqn)) to StringPlus,
                 Key(kotlinReflectFqn, null, "typeOf", listOf()) to TypeOf,
+                Key(StandardNames.FqNames.vArrayIterator.toSafe(), null, "next", listOf()) to VArrayIteratorNext,
                 irBuiltIns.eqeqSymbol.toKey()!! to Equals(KtTokens.EQEQ),
                 irBuiltIns.eqeqeqSymbol.toKey()!! to Equals(KtTokens.EQEQEQ),
                 irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.floatClass]!!.toKey()!! to Ieee754Equals(Type.FLOAT_TYPE),
@@ -85,7 +86,6 @@
                 symbols.jvmDebuggerInvokeSpecialIntrinsic.toKey()!! to JvmDebuggerInvokeSpecial,
                 symbols.intPostfixIncrDecr.toKey()!! to IntIncr(isPrefix = false),
                 symbols.intPrefixIncrDecr.toKey()!! to IntIncr(isPrefix = true),
-                createKeyMapping(VArrayIteratorNext, symbols.vArrayIterator, "next"),
             ) +
                     numberConversionMethods() +
                     unaryFunForPrimitives("plus", UnaryPlus) +
diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt
index 9e850c7..d956d98 100644
--- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt
+++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt
@@ -375,14 +375,14 @@
     override val primitiveIrTypesWithComparisons = listOf(charType, byteType, shortType, intType, floatType, longType, doubleType)
     override val primitiveFloatingPointIrTypes = listOf(floatType, doubleType)
 
-    override val byteArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.BYTE).toIrSymbol()
-    override val charArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.CHAR).toIrSymbol()
-    override val shortArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.SHORT).toIrSymbol()
-    override val intArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.INT).toIrSymbol()
-    override val longArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.LONG).toIrSymbol()
-    override val floatArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.FLOAT).toIrSymbol()
-    override val doubleArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.DOUBLE).toIrSymbol()
-    override val booleanArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.BOOLEAN).toIrSymbol()
+    override val byteArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.BYTE)?.toIrSymbol()
+    override val charArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.CHAR)?.toIrSymbol()
+    override val shortArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.SHORT)?.toIrSymbol()
+    override val intArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.INT)?.toIrSymbol()
+    override val longArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.LONG)?.toIrSymbol()
+    override val floatArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.FLOAT)?.toIrSymbol()
+    override val doubleArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.DOUBLE)?.toIrSymbol()
+    override val booleanArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.BOOLEAN)?.toIrSymbol()
 
     override val primitiveArraysToPrimitiveTypes =
         PrimitiveType.values().associate { builtIns.getPrimitiveArrayClassDescriptor(it).toIrSymbol() to it }
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt
index 24e90199..74911d3 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt
@@ -101,14 +101,14 @@
     abstract val primitiveIrTypesWithComparisons: List<IrType>
     abstract val primitiveFloatingPointIrTypes: List<IrType>
 
-    abstract val byteArray: IrClassSymbol
-    abstract val charArray: IrClassSymbol
-    abstract val shortArray: IrClassSymbol
-    abstract val intArray: IrClassSymbol
-    abstract val longArray: IrClassSymbol
-    abstract val floatArray: IrClassSymbol
-    abstract val doubleArray: IrClassSymbol
-    abstract val booleanArray: IrClassSymbol
+    abstract val byteArray: IrClassSymbol?
+    abstract val charArray: IrClassSymbol?
+    abstract val shortArray: IrClassSymbol?
+    abstract val intArray: IrClassSymbol?
+    abstract val longArray: IrClassSymbol?
+    abstract val floatArray: IrClassSymbol?
+    abstract val doubleArray: IrClassSymbol?
+    abstract val booleanArray: IrClassSymbol?
 
     abstract val primitiveArraysToPrimitiveTypes: Map<IrClassSymbol, PrimitiveType>
     abstract val primitiveTypesToPrimitiveArrays: Map<PrimitiveType, IrClassSymbol>
diff --git a/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt b/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt
index 887f80a..78303e2 100644
--- a/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt
+++ b/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt
@@ -97,6 +97,7 @@
         @JvmField val string: FqNameUnsafe = fqNameUnsafe("String")
         @JvmField val array: FqNameUnsafe = fqNameUnsafe("Array")
         @JvmField val vArray: FqNameUnsafe = fqNameUnsafe("VArray")
+        @JvmField val vArrayIterator : FqNameUnsafe = fqNameUnsafe("VArrayIterator")
 
         @JvmField val _boolean: FqNameUnsafe = fqNameUnsafe("Boolean")
         @JvmField val _char: FqNameUnsafe = fqNameUnsafe("Char")
diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java
index ef28949..b752aa3 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java
+++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java
@@ -26,6 +26,7 @@
 import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
 import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull;
+import org.jetbrains.kotlin.storage.MemoizedFunctionToNullable;
 import org.jetbrains.kotlin.storage.NotNullLazyValue;
 import org.jetbrains.kotlin.storage.StorageManager;
 import org.jetbrains.kotlin.types.*;
@@ -44,7 +45,7 @@
     private final NotNullLazyValue<Primitives> primitives;
     private final NotNullLazyValue<Collection<PackageViewDescriptor>> builtInPackagesImportedByDefault;
 
-    private final MemoizedFunctionToNotNull<Name, ClassDescriptor> builtInClassesByName;
+    private final MemoizedFunctionToNullable<Name, ClassifierDescriptor> builtInClassifiersByName;
 
     private final StorageManager storageManager;
 
@@ -57,10 +58,10 @@
             @Override
             public Collection<PackageViewDescriptor> invoke() {
                 return Arrays.asList(
-                    getBuiltInsModule().getPackage(BUILT_INS_PACKAGE_FQ_NAME),
-                    getBuiltInsModule().getPackage(COLLECTIONS_PACKAGE_FQ_NAME),
-                    getBuiltInsModule().getPackage(RANGES_PACKAGE_FQ_NAME),
-                    getBuiltInsModule().getPackage(ANNOTATION_PACKAGE_FQ_NAME)
+                        getBuiltInsModule().getPackage(BUILT_INS_PACKAGE_FQ_NAME),
+                        getBuiltInsModule().getPackage(COLLECTIONS_PACKAGE_FQ_NAME),
+                        getBuiltInsModule().getPackage(RANGES_PACKAGE_FQ_NAME),
+                        getBuiltInsModule().getPackage(ANNOTATION_PACKAGE_FQ_NAME)
                 );
             }
         });
@@ -73,7 +74,7 @@
                 Map<SimpleType, SimpleType> kotlinArrayTypeToPrimitiveKotlinType = new HashMap<SimpleType, SimpleType>();
                 for (PrimitiveType primitive : PrimitiveType.values()) {
                     SimpleType type = getBuiltInTypeByClassName(primitive.getTypeName().asString());
-                    SimpleType arrayType = getBuiltInTypeByClassName(primitive.getArrayTypeName().asString());
+                    SimpleType arrayType = getBuiltInArrayType(primitive);
 
                     primitiveTypeToArrayKotlinType.put(primitive, arrayType);
                     primitiveKotlinTypeToKotlinArrayType.put(type, arrayType);
@@ -85,16 +86,13 @@
             }
         });
 
-        this.builtInClassesByName = storageManager.createMemoizedFunction(new Function1<Name, ClassDescriptor>() {
-            @Override
-            public ClassDescriptor invoke(Name name) {
-                ClassifierDescriptor classifier = getBuiltInsPackageScope().getContributedClassifier(name, NoLookupLocation.FROM_BUILTINS);
-                if (classifier != null && !(classifier instanceof ClassDescriptor)) {
-                    throw new AssertionError("Must be a class descriptor " + name + ", but was " + classifier);
-                }
-                return (ClassDescriptor) classifier;
-            }
-        });
+        this.builtInClassifiersByName =
+                storageManager.createMemoizedFunctionWithNullableValues(new Function1<Name, ClassifierDescriptor>() {
+                    @Override
+                    public ClassifierDescriptor invoke(Name name) {
+                        return getBuiltInsPackageScope().getContributedClassifier(name, NoLookupLocation.FROM_BUILTINS);
+                    }
+                });
     }
 
     protected void createBuiltInsModule(boolean isFallback) {
@@ -179,7 +177,7 @@
     /**
      * Checks if the given descriptor is declared in the deserialized built-in package fragment, i.e. if it was loaded as a part of
      * loading .kotlin_builtins definition files.
-     *
+     * <p>
      * NOTE: this method returns false for descriptors loaded from .class files or other binaries, even if they are "built-in" in some
      * other sense! For example, it returns false for the class descriptor of `kotlin.IntRange` loaded from `kotlin/IntRange.class`.
      * In case you need to check if the class is "built-in" in another sense, you should probably do it by inspecting its FQ name,
@@ -217,15 +215,35 @@
 
     @NotNull
     private ClassDescriptor getBuiltInClassByName(@NotNull String simpleName) {
-        ClassDescriptor classDescriptor = builtInClassesByName.invoke(Name.identifier(simpleName));
-        if (classDescriptor == null) {
+        ClassDescriptor descriptor = getBuiltInClassByNameOrNull(simpleName);
+        if (descriptor == null) {
             throw new AssertionError("Built-in class " + BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName)) + " is not found");
         }
-        return classDescriptor;
+        return descriptor;
+    }
+
+    @NotNull
+    private SimpleType getBuiltInArrayType(@NotNull PrimitiveType primitive) {
+        ClassifierDescriptor arrayClassifier = builtInClassifiersByName.invoke(Name.identifier(primitive.getArrayTypeName().asString()));
+        SimpleType arrayType;
+        if (arrayClassifier instanceof ClassDescriptor) {
+            arrayType = arrayClassifier.getDefaultType();
+        }
+        else if (arrayClassifier instanceof TypeAliasDescriptor) {
+            arrayType = ((TypeAliasDescriptor) arrayClassifier).getExpandedType();
+        }
+        else {
+            throw new AssertionError("Unsupported array type classifier for " + primitive + ": " + arrayClassifier);
+        }
+        return arrayType;
     }
 
     private ClassDescriptor getBuiltInClassByNameOrNull(@NotNull String simpleName) {
-        return builtInClassesByName.invoke(Name.identifier(simpleName));
+        ClassifierDescriptor classifier = builtInClassifiersByName.invoke(Name.identifier(simpleName));
+        if (classifier != null && !(classifier instanceof ClassDescriptor)) {
+            throw new AssertionError("Must be a class descriptor " + simpleName + ", but was " + classifier);
+        }
+        return (ClassDescriptor) classifier;
     }
 
     @NotNull
@@ -292,9 +310,8 @@
         return getBuiltInClassByNameOrNull("VArray");
     }
 
-    @NotNull
     public ClassDescriptor getPrimitiveArrayClassDescriptor(@NotNull PrimitiveType type) {
-        return getBuiltInClassByName(type.getArrayTypeName().asString());
+        return getBuiltInClassByNameOrNull(type.getArrayTypeName().asString());
     }
 
     @NotNull
@@ -472,7 +489,8 @@
 
     @NotNull
     public ClassDescriptor getMutableMapEntry() {
-        ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMutableMap(), "MutableEntry", NoLookupLocation.FROM_BUILTINS);
+        ClassDescriptor classDescriptor =
+                DescriptorUtils.getInnerClassByName(getMutableMap(), "MutableEntry", NoLookupLocation.FROM_BUILTINS);
         assert classDescriptor != null : "Can't find MutableMap.MutableEntry";
         return classDescriptor;
     }
@@ -584,7 +602,7 @@
 
     @NotNull
     public KotlinType getArrayElementType(@NotNull KotlinType arrayType) {
-        if (isArray(arrayType)) {
+        if (isArray(arrayType) || isVArray(arrayType)) {
             if (arrayType.getArguments().size() != 1) {
                 throw new IllegalStateException();
             }
@@ -671,6 +689,16 @@
                : null;
     }
 
+    @Nullable
+    public static PrimitiveType getPrimitiveArrayElementType(@NotNull KotlinType type) {
+        if (isPrimitiveVArray(type)) {
+            Name primitiveTypeName =
+                    type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor().getName();
+            return FqNames.fqNameToPrimitiveType.get(BUILT_INS_PACKAGE_FQ_NAME.child(primitiveTypeName).toUnsafe());
+        }
+        return getPrimitiveArrayType(type.getConstructor().getDeclarationDescriptor());
+    }
+
     @NotNull
     public SimpleType getArrayType(@NotNull Variance projectionType, @NotNull KotlinType argument, @NotNull Annotations annotations) {
         List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument));
@@ -713,15 +741,18 @@
         return isArray(type) || isPrimitiveArray(type);
     }
 
-    public static boolean isPrimitiveArray(@NotNull KotlinType type) {
-        ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
-        return descriptor != null && getPrimitiveArrayType(descriptor) != null;
+    public static boolean isPrimitiveVArray(@NotNull KotlinType type) {
+        if (isVArray(type)) {
+            TypeProjection elementType = type.getArguments().get(0);
+            return elementType.getProjectionKind() == Variance.INVARIANT && isPrimitiveType(elementType.getType());
+        }
+        return false;
     }
 
-    @Nullable
-    public static PrimitiveType getPrimitiveArrayElementType(@NotNull KotlinType type) {
+    public static boolean isPrimitiveArray(@NotNull KotlinType type) {
+        if (isPrimitiveVArray(type)) return true;
         ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
-        return descriptor == null ? null : getPrimitiveArrayType(descriptor);
+        return descriptor != null && getPrimitiveArrayType(descriptor) != null;
     }
 
     @Nullable
@@ -917,8 +948,9 @@
         assert functionReturnType != null : "Function return typed type must be resolved.";
         boolean mayReturnNonUnitValue = !isUnit(functionReturnType);
         for (FunctionDescriptor overriddenDescriptor : descriptor.getOriginal().getOverriddenDescriptors()) {
-            if (mayReturnNonUnitValue)
+            if (mayReturnNonUnitValue) {
                 break;
+            }
             KotlinType overriddenFunctionReturnType = overriddenDescriptor.getReturnType();
             assert overriddenFunctionReturnType != null : "Function return typed type must be resolved.";
             mayReturnNonUnitValue = !isUnit(overriddenFunctionReturnType);