@@ -692,12 +692,22 @@ public static <K, V> ImmutableMap<K, V> copyOf(Map<? extends K, ? extends V> map
692692 return kvMap ;
693693 }
694694 } else if (map instanceof EnumMap ) {
695- @ SuppressWarnings ("unchecked" ) // safe since map is not writable
696- ImmutableMap <K , V > kvMap =
697- (ImmutableMap <K , V >)
698- copyOfEnumMap (
699- (EnumMap <?, ? extends V >) map ); // hide K (violates bounds) from J2KT, preserve V.
700- return kvMap ;
695+ EnumMap <?, ? extends V > clone = ((EnumMap <?, ? extends V >) map ).clone ();
696+ for (Entry <?, ?> entry : clone .entrySet ()) {
697+ checkEntryNotNull (entry .getKey (), entry .getValue ());
698+ }
699+ ImmutableMap <?, ? extends V > untypedResult = ImmutableEnumMap .asImmutable (clone );
700+ /*
701+ * The result has the same type argument we started with. We just couldn't express EnumMap<K,
702+ * ...> or ImmutableEnumMap<K, ...> along the way because our own <K> isn't <K extends
703+ * Enum<K>>.
704+ *
705+ * We are also performing a covariant cast, potentially from ImmutableMap<K, Sub> to
706+ * ImmutableMap<K, Super>. That is safe because no one can add elements to the map.
707+ */
708+ @ SuppressWarnings ("unchecked" )
709+ ImmutableMap <K , V > result = (ImmutableMap <K , V >) untypedResult ;
710+ return result ;
701711 }
702712 return copyOf (map .entrySet ());
703713 }
@@ -730,16 +740,6 @@ public static <K, V> ImmutableMap<K, V> copyOf(
730740 }
731741 }
732742
733- private static <K extends Enum <K >, V > ImmutableMap <K , ? extends V > copyOfEnumMap (
734- EnumMap <?, ? extends V > original ) {
735- @ SuppressWarnings ("unchecked" ) // the best we could do to make copyOf(Map) compile
736- EnumMap <K , V > copy = new EnumMap <>((EnumMap <K , ? extends V >) original );
737- for (Entry <K , V > entry : copy .entrySet ()) {
738- checkEntryNotNull (entry .getKey (), entry .getValue ());
739- }
740- return ImmutableEnumMap .asImmutable (copy );
741- }
742-
743743 static final Entry <?, ?>[] EMPTY_ENTRY_ARRAY = new Entry <?, ?>[0 ];
744744
745745 abstract static class IteratorBasedImmutableMap <K , V > extends ImmutableMap <K , V > {
0 commit comments