@@ -2085,6 +2085,43 @@ public function inferTemplateTypes(Type $receivedType): TemplateTypeMap
20852085 $ typeMap = $ typeMap ->union ($ valueType ->inferTemplateTypes ($ receivedValueType ));
20862086 }
20872087
2088+ $ unsealed = $ this ->getUnsealedTypes ();
2089+ if ($ unsealed !== null ) {
2090+ [$ unsealedKeyType , $ unsealedValueType ] = $ unsealed ;
2091+
2092+ // Received's explicit keys not in $this's explicit keys are
2093+ // candidates for matching $this's unsealed extras pattern.
2094+ // Only contribute when the key type matches; mismatched explicit
2095+ // keys are extra entries the parameter wouldn't accept anyway,
2096+ // surfaced by the regular argument-type check.
2097+ $ receivedKeyTypes = $ receivedType ->getKeyTypes ();
2098+ $ receivedValueTypes = $ receivedType ->getValueTypes ();
2099+ foreach ($ receivedKeyTypes as $ j => $ receivedKeyType ) {
2100+ if ($ this ->hasOffsetValueType ($ receivedKeyType )->yes ()) {
2101+ continue ;
2102+ }
2103+ if (!$ unsealedKeyType ->isSuperTypeOf ($ receivedKeyType )->yes ()) {
2104+ continue ;
2105+ }
2106+ $ typeMap = $ typeMap ->union ($ unsealedKeyType ->inferTemplateTypes ($ receivedKeyType ));
2107+ $ typeMap = $ typeMap ->union ($ unsealedValueType ->inferTemplateTypes ($ receivedValueTypes [$ j ]));
2108+ }
2109+
2110+ // Received's own unsealed extras describe "all the rest" — when
2111+ // the key type doesn't fit $this's unsealed key pattern there
2112+ // is no valid template assignment, so force NEVER.
2113+ $ receivedUnsealed = $ receivedType ->getUnsealedTypes ();
2114+ if ($ receivedUnsealed !== null ) {
2115+ [$ receivedUnsealedKey , $ receivedUnsealedValue ] = $ receivedUnsealed ;
2116+ if ($ unsealedKeyType ->isSuperTypeOf ($ receivedUnsealedKey )->no ()) {
2117+ $ typeMap = $ typeMap ->union ($ unsealedValueType ->inferTemplateTypes (new NeverType ()));
2118+ } else {
2119+ $ typeMap = $ typeMap ->union ($ unsealedKeyType ->inferTemplateTypes ($ receivedUnsealedKey ));
2120+ $ typeMap = $ typeMap ->union ($ unsealedValueType ->inferTemplateTypes ($ receivedUnsealedValue ));
2121+ }
2122+ }
2123+ }
2124+
20882125 return $ typeMap ;
20892126 }
20902127
0 commit comments