GROOVY-10720: STC: primitive array incompatible with non-primitive array
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 4fccd42..6ca999c 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -467,8 +467,9 @@
         if (NUMBER_TYPES.containsKey(type.redirect()) && NUMBER_TYPES.containsKey(toBeAssignedTo.redirect())) {
             return NUMBER_TYPES.get(type.redirect()) <= NUMBER_TYPES.get(toBeAssignedTo.redirect());
         }
-        if (type.isArray() && toBeAssignedTo.isArray()) {
-            return isAssignableTo(type.getComponentType(), toBeAssignedTo.getComponentType());
+        if (type.isArray() && toBeAssignedTo.isArray()) { // GROOVY-10720: check primitive to/from non-primitive
+            ClassNode sourceComponent = type.getComponentType(), targetComponent = toBeAssignedTo.getComponentType();
+            return (isPrimitiveType(sourceComponent) == isPrimitiveType(targetComponent)) && isAssignableTo(sourceComponent, targetComponent);
         }
         if (type.isDerivedFrom(GSTRING_TYPE) && isStringType(toBeAssignedTo)) {
             return true;
@@ -671,7 +672,10 @@
 
         if (left.isArray()) {
             if (right.isArray()) {
-                return checkCompatibleAssignmentTypes(left.getComponentType(), right.getComponentType(), rightExpression, false);
+                ClassNode leftComponent = left.getComponentType();
+                ClassNode rightComponent = right.getComponentType();
+                if (isPrimitiveType(leftComponent) != isPrimitiveType(rightComponent)) return false;
+                return checkCompatibleAssignmentTypes(leftComponent, rightComponent, rightExpression, false);
             }
             if (GeneralUtils.isOrImplements(right, Collection_TYPE) && !(rightExpression instanceof ListExpression)) {
                 GenericsType elementType = GenericsUtils.parameterizeType(right, Collection_TYPE).getGenericsTypes()[0];
diff --git a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
index 4c56749..9d0e598 100644
--- a/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ArraysAndCollectionsSTCTest.groovy
@@ -37,26 +37,33 @@
         shouldFailWithMessages '''
             String[] strings = ['a','b','c']
             int str = strings[0]
-        ''', 'Cannot assign value of type java.lang.String to variable of type int'
+        ''',
+        'Cannot assign value of type java.lang.String to variable of type int'
     }
 
     void testWrongComponentTypeInArray() {
         shouldFailWithMessages '''
             int[] intArray = ['a']
-        ''', 'Cannot assign value of type java.lang.String into array of type int[]'
+        ''',
+        'Cannot assign value of type java.lang.String into array of type int[]'
     }
 
     // GROOVY-9985, GROOVY-9994
     void testWrongComponentTypeInArrayInitializer() {
         shouldFailWithMessages '''
             new int['a']
-        ''', 'Cannot convert from java.lang.String to int'
+        ''',
+        'Cannot convert from java.lang.String to int'
+
         shouldFailWithMessages '''
             new int[]{'a'}
-        ''', 'Cannot convert from java.lang.String to int'
+        ''',
+        'Cannot convert from java.lang.String to int'
+
         shouldFailWithMessages '''
             new Integer[]{new Object(),1}
-        ''', 'Cannot convert from java.lang.Object to java.lang.Integer'
+        ''',
+        'Cannot convert from java.lang.Object to java.lang.Integer'
     }
 
     // GROOVY-10111
@@ -89,7 +96,8 @@
         shouldFailWithMessages '''
             int[] arr2 = [1, 2, 3]
             arr2[1] = "One"
-        ''', 'Cannot assign value of type java.lang.String to variable of type int'
+        ''',
+        'Cannot assign value of type java.lang.String to variable of type int'
     }
 
     void testBidimensionalArray() {
@@ -102,14 +110,16 @@
     void testBidimensionalArrayWithInitializer() {
         shouldFailWithMessages '''
             int[][] arr2 = new Object[1][]
-        ''', 'Cannot assign value of type java.lang.Object[][] to variable of type int[][]'
+        ''',
+        'Cannot assign value of type java.lang.Object[][] to variable of type int[][]'
     }
 
     void testBidimensionalArrayWithWrongSubArrayType() {
         shouldFailWithMessages '''
             int[][] arr2 = new int[1][]
             arr2[0] = ['1']
-        ''', 'Cannot assign value of type java.lang.String into array of type int[]'
+        ''',
+        'Cannot assign value of type java.lang.String into array of type int[]'
     }
 
     void testForLoopWithArrayAndUntypedVariable() {
@@ -123,7 +133,8 @@
         shouldFailWithMessages '''
             String[] arr = ['1','2','3']
             for (int i in arr) { }
-        ''', 'Cannot loop with element of type int with collection of type java.lang.String[]'
+        ''',
+        'Cannot loop with element of type int with collection of type java.lang.String[]'
     }
 
     void testJava5StyleForLoopWithArray() {
@@ -137,7 +148,8 @@
         shouldFailWithMessages '''
             String[] arr = ['1','2','3']
             for (int i : arr) { }
-        ''', 'Cannot loop with element of type int with collection of type java.lang.String[]'
+        ''',
+        'Cannot loop with element of type int with collection of type java.lang.String[]'
     }
 
     void testForEachLoopOnString() {
@@ -151,17 +163,17 @@
 
     void testSliceInference() {
         assertScript '''
-        List<String> foos = ['aa','bb','cc']
-        foos[0].substring(1)
-        def bars = foos[0..1]
-        println bars[0].substring(1)
+            List<String> foos = ['aa','bb','cc']
+            foos[0].substring(1)
+            def bars = foos[0..1]
+            println bars[0].substring(1)
         '''
 
         assertScript '''
-        def foos = ['aa','bb','cc']
-        foos[0].substring(1)
-        def bars = foos[0..1]
-        println bars[0].substring(1)
+            def foos = ['aa','bb','cc']
+            foos[0].substring(1)
+            def bars = foos[0..1]
+            println bars[0].substring(1)
         '''
 
         // GROOVY-5608
@@ -177,7 +189,7 @@
             List<Integer> b = a[1..2]
 
             List<Integer> c = (List<Integer>)a[1..2]
-         '''
+        '''
 
         // check that it also works for custom getAt methods
         assertScript '''
@@ -334,7 +346,7 @@
         assertScript '''
             int n = 10
             for (int i in 1..n) {
-                @ASTTest(phase=INSTRUCTION_SELECTION, value= {
+                @ASTTest(phase=INSTRUCTION_SELECTION, value={
                     assert node.getNodeMetaData(DECLARATION_INFERRED_TYPE) == int_TYPE
                 })
                 def k = i
@@ -346,7 +358,7 @@
         assertScript '''
             int n = 10
             for (int i in 1..(n-1)) {
-                @ASTTest(phase=INSTRUCTION_SELECTION, value= {
+                @ASTTest(phase=INSTRUCTION_SELECTION, value={
                     assert node.getNodeMetaData(DECLARATION_INFERRED_TYPE) == int_TYPE
                 })
                 def k = i
@@ -358,7 +370,7 @@
         assertScript '''
             int n = 10
             for (int i in [-1,1]) {
-                @ASTTest(phase=INSTRUCTION_SELECTION, value= {
+                @ASTTest(phase=INSTRUCTION_SELECTION, value={
                     assert node.getNodeMetaData(DECLARATION_INFERRED_TYPE) == int_TYPE
                 })
                 def k = i
@@ -410,7 +422,8 @@
             }
             class FooAnother {
             }
-        ''', 'Cannot assign value of type Foo[] to variable of type FooAnother'
+        ''',
+        'Cannot assign value of type Foo[] to variable of type FooAnother'
     }
 
     // GROOVY-8984
@@ -418,35 +431,54 @@
         shouldFailWithMessages '''
             List<String> m() { }
             Number[] array = m()
-        ''', 'Cannot assign value of type java.util.List<java.lang.String> to variable of type java.lang.Number[]'
+        ''',
+        'Cannot assign value of type java.util.List<java.lang.String> to variable of type java.lang.Number[]'
 
         shouldFailWithMessages '''
             void test(Set<String> set) {
                 Number[] array = set
             }
-        ''', 'Cannot assign value of type java.util.Set<java.lang.String> to variable of type java.lang.Number[]'
+        ''',
+        'Cannot assign value of type java.util.Set<java.lang.String> to variable of type java.lang.Number[]'
 
         shouldFailWithMessages '''
             List<? super CharSequence> m() { }
             CharSequence[] array = m()
-        ''', 'Cannot assign value of type java.util.List<? super java.lang.CharSequence> to variable of type java.lang.CharSequence[]'
+        ''',
+        'Cannot assign value of type java.util.List<? super java.lang.CharSequence> to variable of type java.lang.CharSequence[]'
 
         shouldFailWithMessages '''
             void test(Set<? super CharSequence> set) {
                 CharSequence[] array = set
             }
-        ''', 'Cannot assign value of type java.util.Set<? super java.lang.CharSequence> to variable of type java.lang.CharSequence[]'
+        ''',
+        'Cannot assign value of type java.util.Set<? super java.lang.CharSequence> to variable of type java.lang.CharSequence[]'
 
         shouldFailWithMessages '''
             List<? super Runnable> m() { }
             Runnable[] array = m()
-        ''', 'Cannot assign value of type java.util.List<? super java.lang.Runnable> to variable of type java.lang.Runnable[]'
+        ''',
+        'Cannot assign value of type java.util.List<? super java.lang.Runnable> to variable of type java.lang.Runnable[]'
 
         shouldFailWithMessages '''
             void test(List<? super Runnable> list) {
                 Runnable[] array = list
             }
-        ''', 'Cannot assign value of type java.util.List<? super java.lang.Runnable> to variable of type java.lang.Runnable[]'
+        ''',
+        'Cannot assign value of type java.util.List<? super java.lang.Runnable> to variable of type java.lang.Runnable[]'
+    }
+
+    // GROOVY-10720
+    void testShouldNotAllowArrayAssignment3() {
+        shouldFailWithMessages '''
+            int[] array = new Integer[0]
+        ''',
+        'Cannot assign value of type java.lang.Integer[] to variable of type int[]'
+
+        shouldFailWithMessages '''
+            double[] array = new Double[0]
+        ''',
+        'Cannot assign value of type java.lang.Double[] to variable of type double[]'
     }
 
     // GROOVY-8983
@@ -550,6 +582,16 @@
         '''
     }
 
+    void testShouldAllowArrayAssignment5() {
+        assertScript '''
+            Object[] array = new Double[0]
+        '''
+
+        assertScript '''
+            int[] array = new long[0] // ?
+        '''
+    }
+
     void testListPlusEquals() {
         assertScript '''
             List<String> list = ['a','b']
@@ -657,24 +699,25 @@
     }
 
     void testInferredTypeWithListAndFind() {
-        assertScript '''List<Integer> list = [ 1, 2, 3, 4 ]
+        assertScript '''
+            List<Integer> list = [ 1, 2, 3, 4 ]
 
-        @ASTTest(phase=INSTRUCTION_SELECTION, value= {
-            assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
-        })
-        Integer j = org.codehaus.groovy.runtime.DefaultGroovyMethods.find(list) { int it -> it%2 == 0 }
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
+            })
+            Integer j = org.codehaus.groovy.runtime.DefaultGroovyMethods.find(list) { int it -> it%2 == 0 }
 
-        @ASTTest(phase=INSTRUCTION_SELECTION, value= {
-            assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
-        })
-        Integer i = list.find { int it -> it % 2 == 0 }
+            @ASTTest(phase=INSTRUCTION_SELECTION, value= {
+                assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
+            })
+            Integer i = list.find { int it -> it % 2 == 0 }
         '''
     }
 
     // GROOVY-5573
     void testArrayNewInstance() {
         assertScript '''import java.lang.reflect.Array
-            @ASTTest(phase=INSTRUCTION_SELECTION, value= {
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
                 assert node.rightExpression.getNodeMetaData(INFERRED_TYPE) == OBJECT_TYPE
             })
             def object = Array.newInstance(Integer.class, 10)
@@ -717,12 +760,12 @@
     // GROOVY-5797
     void testShouldAllowExpressionAsMapPropertyKey() {
         assertScript '''
-        def m( Map param ) {
-          def map = [ tim:4 ]
-          map[ param.key ]
-        }
+            def m( Map param ) {
+                def map = [ tim:4 ]
+                map[ param.key ]
+            }
 
-        assert m( [ key: 'tim' ] ) == 4
+            assert m( [ key: 'tim' ] ) == 4
         '''
     }
 
@@ -743,7 +786,8 @@
                 int[] array = [ null, null ]
                 return array
             }
-        ''', 'Cannot assign value of type java.lang.Object into array of type int[]'
+        ''',
+        'Cannot assign value of type java.lang.Object into array of type int[]'
     }
 
     // GROOVY-6131
@@ -755,7 +799,8 @@
             def list = ['a']
             addToCollection(list, 0, 'b')
             assert list == ['b']
-        ''', 'Cannot find matching method java.util.Collection#putAt(int, java.lang.Object)'
+        ''',
+        'Cannot find matching method java.util.Collection#putAt(int, java.lang.Object)'
     }
 
     // GROOVY-6266
@@ -863,7 +908,8 @@
                 A(int n) {}
             }
             A a = [1]
-        ''', 'Cannot assign value of type java.util.List<java.lang.Integer> to variable of type A'
+        ''',
+        'Cannot assign value of type java.util.List<java.lang.Integer> to variable of type A'
     }
 
     // GROOVY-6912
@@ -887,7 +933,8 @@
 
         shouldFailWithMessages '''
             ArrayList<String> strings = [1,2,3]
-        ''', 'Incompatible generic argument types. Cannot assign java.util.ArrayList<java.lang.Integer> to: java.util.ArrayList<java.lang.String>'
+        ''',
+        'Incompatible generic argument types. Cannot assign java.util.ArrayList<java.lang.Integer> to: java.util.ArrayList<java.lang.String>'
     }
 
     // GROOVY-6912
@@ -917,7 +964,8 @@
 
         shouldFailWithMessages '''
             LinkedHashSet<String> strings = [1,2,3]
-        ''', 'Incompatible generic argument types. Cannot assign java.util.LinkedHashSet<java.lang.Integer> to: java.util.LinkedHashSet<java.lang.String>'
+        ''',
+        'Incompatible generic argument types. Cannot assign java.util.LinkedHashSet<java.lang.Integer> to: java.util.LinkedHashSet<java.lang.String>'
     }
 
     void testCollectionTypesInitializedByListLiteral1() {
@@ -959,31 +1007,38 @@
     void testCollectionTypesInitializedByListLiteral3() {
         shouldFailWithMessages '''
             List<String> list = ['a','b',3]
-        ''', 'Cannot assign java.util.ArrayList<java.io.Serializable'
+        ''',
+        'Cannot assign java.util.ArrayList<java.io.Serializable'
 
         shouldFailWithMessages '''
             Set<String> set = [1,2,3]
-        ''', 'Cannot assign java.util.LinkedHashSet<java.lang.Integer> to: java.util.Set<java.lang.String>'
+        ''',
+        'Cannot assign java.util.LinkedHashSet<java.lang.Integer> to: java.util.Set<java.lang.String>'
 
         shouldFailWithMessages '''
             Iterable<String> iter = [1,2,3]
-        ''', 'Cannot assign java.util.ArrayList<java.lang.Integer> to: java.lang.Iterable<java.lang.String>'
+        ''',
+        'Cannot assign java.util.ArrayList<java.lang.Integer> to: java.lang.Iterable<java.lang.String>'
 
         shouldFailWithMessages '''
             Collection<String> coll = [1,2,3]
-        ''', 'Cannot assign java.util.ArrayList<java.lang.Integer> to: java.util.Collection<java.lang.String>'
+        ''',
+        'Cannot assign java.util.ArrayList<java.lang.Integer> to: java.util.Collection<java.lang.String>'
 
         shouldFailWithMessages '''
             Deque<String> deque = []
-        ''', 'Cannot assign value of type java.util.List<E> to variable of type java.util.Deque<java.lang.String>'
+        ''',
+        'Cannot assign value of type java.util.List<E> to variable of type java.util.Deque<java.lang.String>'
 
         shouldFailWithMessages '''
             Queue<String> queue = []
-        ''', 'Cannot assign value of type java.util.List<E> to variable of type java.util.Queue<java.lang.String>'
+        ''',
+        'Cannot assign value of type java.util.List<E> to variable of type java.util.Queue<java.lang.String>'
 
         shouldFailWithMessages '''
             Deque<String> deque = [""]
-        ''', 'Cannot assign value of type java.util.List<java.lang.String> to variable of type java.util.Deque<java.lang.String>'
+        ''',
+        'Cannot assign value of type java.util.List<java.lang.String> to variable of type java.util.Deque<java.lang.String>'
     }
 
     // GROOVY-7128
@@ -1030,6 +1085,7 @@
 
         shouldFailWithMessages '''
             Map<String,Integer> map = [1:2]
-        ''', 'Cannot assign java.util.LinkedHashMap<java.lang.Integer, java.lang.Integer> to: java.util.Map<java.lang.String, java.lang.Integer>'
+        ''',
+        'Cannot assign java.util.LinkedHashMap<java.lang.Integer, java.lang.Integer> to: java.util.Map<java.lang.String, java.lang.Integer>'
     }
 }
diff --git a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
index dde7baa..f159e0f 100644
--- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -1561,6 +1561,15 @@
         '''
     }
 
+    // GROOVY-10720
+    void testOverloadedMethodWithArray() {
+        assertScript '''
+            Double[] array = new Double[1]
+            def stream = Arrays.stream(array) //stream(T[])
+            assert stream.map(d -> 'string')[0] == 'string'
+        '''
+    }
+
     // GROOVY-5883, GROOVY-6270
     void testClosureUpperBound() {
         assertScript '''