GROOVY-7774: Collection addAll fails CompileStatic type checking when adding a collection of subtypes (same treatment for some Map methods) (closes #376)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/a0aee5b3 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/a0aee5b3 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/a0aee5b3 Branch: refs/heads/master Commit: a0aee5b31d140f64641c96c31ab9df78e4458c03 Parents: ce246e6 Author: paulk <pa...@asert.com.au> Authored: Sun Jul 31 17:29:59 2016 +1000 Committer: paulk <pa...@asert.com.au> Committed: Tue Aug 2 09:12:42 2016 +1000 ---------------------------------------------------------------------- .../groovy/runtime/DefaultGroovyMethods.java | 10 ++++--- .../groovy/transform/stc/Groovy7774Bug.groovy | 30 ++++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/a0aee5b3/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java index 23e67b3..e952f0d 100644 --- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java +++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java @@ -5176,7 +5176,9 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport { G key = outer.getKey(); List<Map.Entry<K, V>> entries = outer.getValue(); Map<K, V> target = createSimilarMap(self); - putAll(target, entries); + for (Map.Entry<K, V> entry : entries) { + target.put(entry.getKey(), entry.getValue()); + } answer.put(key, target); } return answer; @@ -8903,8 +8905,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport { * @return the same map, after the items have been added to it. * @since 1.6.1 */ - public static <K, V> Map<K, V> putAll(Map<K, V> self, Collection<Map.Entry<K, V>> entries) { - for (Map.Entry<K, V> entry : entries) { + public static <K, V> Map<K, V> putAll(Map<K, V> self, Collection<Map.Entry<? extends K, ? extends V>> entries) { + for (Map.Entry<? extends K, ? extends V> entry : entries) { self.put(entry.getKey(), entry.getValue()); } return self; @@ -8923,7 +8925,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport { * @return a new Map containing all key, value pairs from self and entries * @since 1.6.1 */ - public static <K, V> Map<K, V> plus(Map<K, V> self, Collection<Map.Entry<K, V>> entries) { + public static <K, V> Map<K, V> plus(Map<K, V> self, Collection<Map.Entry<? extends K, ? extends V>> entries) { Map<K, V> map = cloneSimilarMap(self); putAll(map, entries); return map; http://git-wip-us.apache.org/repos/asf/groovy/blob/a0aee5b3/src/test/groovy/transform/stc/Groovy7774Bug.groovy ---------------------------------------------------------------------- diff --git a/src/test/groovy/transform/stc/Groovy7774Bug.groovy b/src/test/groovy/transform/stc/Groovy7774Bug.groovy index ca9b1ab..96b3c7f 100644 --- a/src/test/groovy/transform/stc/Groovy7774Bug.groovy +++ b/src/test/groovy/transform/stc/Groovy7774Bug.groovy @@ -26,17 +26,31 @@ class Groovy7774Bug extends StaticTypeCheckingTestCase { class Y extends X{} def create() { - Set<X> set = new HashSet<X>() - List<Y> addIterable = [new Y()] - Iterator<Y> addIterator = [new Y()].iterator() - Y[] addArray = [new Y()] - set.addAll(addIterable) - set.addAll(addIterator) - set.addAll(addArray) - assert set.size() == 3 + Set<X> set = new HashSet<X>() + List<Y> addIterable = [new Y()] + Iterator<Y> addIterator = [new Y()].iterator() + Y[] addArray = [new Y()] + set.addAll(addIterable) + set.addAll(addIterator) + set.addAll(addArray) + assert set.size() == 3 } create() ''' } + + void testMapPutAllShouldHonorInheritance() { + assertScript ''' + class X{} + class Y extends X{} + + def create() { + Map<X, X> items = new HashMap<X, X>() + List<Map.Entry<Y, Y>> addEntries = new ArrayList<Map.Entry<Y, Y>>() + items.putAll(addEntries) + } + create() + ''' + } }