Skip to content

Commit 4f5b4f5

Browse files
authored
Fixed subtype checking for record types with "@as" attributes (#6163)
See #6158
1 parent c0bd807 commit 4f5b4f5

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
- Disable warning on `@inline` attibute on uncurried functions. https://github.com/rescript-lang/rescript-compiler/pull/6152
2121
- Support doc comments on arguments of function types. https://github.com/rescript-lang/rescript-compiler/pull/6161
2222
- Fix issue with record type coercion and unboxed. https://github.com/rescript-lang/rescript-compiler/issues/6158
23+
- Fixed subtype checking for record types with "@as" attributes: The subtype relationship now takes into account the compatibility of "@as" attributes between corresponding fields, ensuring correctness in runtime representation.
24+
https://github.com/rescript-lang/rescript-compiler/issues/6158
25+
2326

2427
# 11.0.0-alpha.3
2528

jscomp/ml/ctype.ml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3967,11 +3967,18 @@ let rec subtype_rec env trace t1 t2 cstrs =
39673967
| _ -> false in
39683968
let violation = ref false in
39693969
let label_decl_sub (acc1, acc2) ld2 =
3970-
match fields1 |> List.find_opt (fun ld1 -> Ident.name ld1.ld_id = Ident.name ld2.ld_id) with
3970+
match Ext_list.find_first fields1 (fun ld1 -> ld1.ld_id.name = ld2.ld_id.name) with
39713971
| Some ld1 ->
39723972
if field_is_optional ld1.ld_id repr1 && not (field_is_optional ld2.ld_id repr2) then
39733973
(* optional field can't be cast to non-optional one *)
39743974
violation := true;
3975+
let get_as (({txt}, payload) : Parsetree.attribute) =
3976+
if txt = "as" then Ast_payload.is_single_string payload
3977+
else None in
3978+
let get_as_name ld = match Ext_list.filter_map ld.ld_attributes get_as with
3979+
| [] -> ld.ld_id.name
3980+
| (s,_)::_ -> s in
3981+
if get_as_name ld1 <> get_as_name ld2 then violation := true;
39753982
ld1.ld_type :: acc1, ld2.ld_type :: acc2
39763983
| None ->
39773984
(* field must be present *)

0 commit comments

Comments
 (0)