@@ -187,70 +187,67 @@ let widen_for_array_get ~lhs_of_null_coalesce ~expr_pos index_expr env ty =
187187 * being a subtype of arraykey
188188 *)
189189let check_arraykey_index error env pos container_ty index_ty =
190- if TypecheckerOptions. disallow_invalid_arraykey (Env. get_tcopt env) then (
191- let (env, container_ty) = Env. expand_type env container_ty in
192- let reason =
193- match get_node container_ty with
194- | Tclass ((_ , cn ), _ , _ ) -> Reason. index_class cn
195- | _ -> Reason. index_array
196- in
197- let info_of_type ty = (get_pos ty, lazy (Typing_print. error env ty)) in
198- let container_info = info_of_type container_ty in
199- let index_info = info_of_type index_ty in
200- let ty_arraykey = MakeType. arraykey (Reason. idx_dict pos) in
201- (* If we have an error in coercion here, we will add a `Hole` indicating the
202- actual and expected type. The `Hole` may then be used in a codemod to
203- add a call to `UNSAFE_CAST` so we need to consider what type we expect.
204- There is a somewhat common pattern in older parts of www to do something like:
190+ let (env, container_ty) = Env. expand_type env container_ty in
191+ let reason =
192+ match get_node container_ty with
193+ | Tclass ((_ , cn ), _ , _ ) -> Reason. index_class cn
194+ | _ -> Reason. index_array
195+ in
196+ let info_of_type ty = (get_pos ty, lazy (Typing_print. error env ty)) in
197+ let container_info = info_of_type container_ty in
198+ let index_info = info_of_type index_ty in
199+ let ty_arraykey = MakeType. arraykey (Reason. idx_dict pos) in
200+ (* If we have an error in coercion here, we will add a `Hole` indicating the
201+ actual and expected type. The `Hole` may then be used in a codemod to
202+ add a call to `UNSAFE_CAST` so we need to consider what type we expect.
203+ There is a somewhat common pattern in older parts of www to do something like:
205204
206- ```
207- function keyset_issue(?string $x): keyset<string> {
208- $xs = keyset<string>[];
209- ...
210- /* HH_FIXME[4435] keyset values must be arraykeys */
211- $xs[] = $x;
212- return Keyset\filter_nulls($xs);
213- }
214- ```
215- (even though it is impossible for keysets to contain nulls).
205+ ```
206+ function keyset_issue(?string $x): keyset<string> {
207+ $xs = keyset<string>[];
208+ ...
209+ /* HH_FIXME[4435] keyset values must be arraykeys */
210+ $xs[] = $x;
211+ return Keyset\filter_nulls($xs);
212+ }
213+ ```
214+ (even though it is impossible for keysets to contain nulls).
216215
217- If we were to add an expected type of 'arraykey' here it would be
218- correct but adding an `UNSAFE_CAST<?string,arraykey>($x)` means we
219- get cascading errors; here, we now have the wrong return type.
216+ If we were to add an expected type of 'arraykey' here it would be
217+ correct but adding an `UNSAFE_CAST<?string,arraykey>($x)` means we
218+ get cascading errors; here, we now have the wrong return type.
220219
221- To try and prevent this, if this is an optional type where the nonnull
222- part can be coerced to arraykey, we prefer that type as our expected type.
223- *)
224- let base_error = error pos container_info index_info in
225- let (ty_actual, is_option) =
226- match deref index_ty with
227- | (_ , Toption inner_ty ) -> (inner_ty, true )
228- | _ -> (index_ty, false )
229- in
230- let (env, e1) =
231- Typing_coercion. coerce_type
232- ~coerce_for_op: true
233- pos
234- reason
235- env
236- ty_actual
237- ty_arraykey
238- Enforced
239- @@ Typing_error.Callback. always base_error
240- in
241- let (ty_mismatch, e2) =
242- match e1 with
243- | None when is_option ->
244- (Error (index_ty, ty_actual), Some (Typing_error. primary base_error))
245- | None -> (Ok index_ty, None )
246- | Some _ -> (Error (index_ty, ty_arraykey), None )
247- in
248- Option. (
249- iter ~f: (Typing_error_utils. add_typing_error ~env )
250- @@ merge e1 e2 ~f: Typing_error. both);
251- (env, ty_mismatch)
252- ) else
253- (env, Ok index_ty)
220+ To try and prevent this, if this is an optional type where the nonnull
221+ part can be coerced to arraykey, we prefer that type as our expected type.
222+ *)
223+ let base_error = error pos container_info index_info in
224+ let (ty_actual, is_option) =
225+ match deref index_ty with
226+ | (_ , Toption inner_ty ) -> (inner_ty, true )
227+ | _ -> (index_ty, false )
228+ in
229+ let (env, e1) =
230+ Typing_coercion. coerce_type
231+ ~coerce_for_op: true
232+ pos
233+ reason
234+ env
235+ ty_actual
236+ ty_arraykey
237+ Enforced
238+ @@ Typing_error.Callback. always base_error
239+ in
240+ let (ty_mismatch, e2) =
241+ match e1 with
242+ | None when is_option ->
243+ (Error (index_ty, ty_actual), Some (Typing_error. primary base_error))
244+ | None -> (Ok index_ty, None )
245+ | Some _ -> (Error (index_ty, ty_arraykey), None )
246+ in
247+ Option. (
248+ iter ~f: (Typing_error_utils. add_typing_error ~env )
249+ @@ merge e1 e2 ~f: Typing_error. both);
250+ (env, ty_mismatch)
254251
255252let check_arraykey_index_read =
256253 let mk_err pos (container_pos , container_ty_name ) (key_pos , key_ty_name ) =
0 commit comments