Skip to content

Commit 95c52fd

Browse files
authored
Print variant runtime repr in error messages, and fix inclusion check. (#6669)
* POC print variant runtime repr As in `type t = @as(undefined) A` Triggered in error message: ```res Type declarations do not match: type t = @as(undefined) A is not included in type t = @as(null) A ``` * Print @unboxed for variants and check inclusion correctly. - Print `@unboxed` in the variant type declaration in the outcome printer. - Fix issue where attributes such as `@unboxed` were printed twice. - Fix issue where inconsistency in `@unboxed` in variant declarations between implementation and interface was not chedked. * snake case * Changelog and test. * Bump rescript-core for playground bundling.
1 parent e4439c9 commit 95c52fd

File tree

10 files changed

+103
-37
lines changed

10 files changed

+103
-37
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
- Reactivate unused attribute check for `@int`. https://github.com/rescript-lang/rescript-compiler/pull/6802
3434
- Fix issue where optional labels were not taken into account when disambiguating record value construction. https://github.com/rescript-lang/rescript-compiler/pull/6798
3535
- Fix issue in gentype when type `Jsx.element` surfaces to the user. https://github.com/rescript-lang/rescript-compiler/pull/6808
36+
- Fix inclusion check (impl vs interface) for untagged variants, and fix the outcome printer to show tags. https://github.com/rescript-lang/rescript-compiler/pull/6669
3637

3738
#### :house: Internal
3839

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/UntaggedImplIntf.res:3:5-5:1
4+
5+
1 │ module M: {
6+
2 │ @unboxed type t = | @as(null) A
7+
3 │ } = {
8+
4 │  type t = | @as(null) A
9+
5 │ }
10+
11+
Signature mismatch:
12+
Modules do not match:
13+
{
14+
type t = @as(null) A
15+
}
16+
is not included in
17+
{
18+
@unboxed type t = @as(null) A
19+
}
20+
Type declarations do not match:
21+
type t = @as(null) A
22+
is not included in
23+
@unboxed type t = @as(null) A
24+
/.../fixtures/UntaggedImplIntf.res:2:12-33:
25+
Expected declaration
26+
/.../fixtures/UntaggedImplIntf.res:4:3-24:
27+
Actual declaration
28+
Their internal representations differ:
29+
the second declaration uses unboxed representation.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module M: {
2+
@unboxed type t = | @as(null) A
3+
} = {
4+
type t = | @as(null) A
5+
}

jscomp/ml/includecore.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,10 @@ let type_declarations ?(equality = false) ~loc env name decl1 id decl2 =
328328
in
329329
if err <> [] then err else
330330
let err =
331-
match (decl2.type_kind, decl1.type_unboxed.unboxed,
332-
decl2.type_unboxed.unboxed) with
331+
let untagged1 = Ast_untagged_variants.process_untagged decl1.type_attributes in
332+
let untagged2 = Ast_untagged_variants.process_untagged decl2.type_attributes in
333+
match (decl2.type_kind, decl1.type_unboxed.unboxed || untagged1,
334+
decl2.type_unboxed.unboxed || untagged2) with
333335
| Type_abstract, _, _ -> []
334336
| _, true, false -> [Unboxed_representation false]
335337
| _, false, true -> [Unboxed_representation true]

jscomp/ml/oprint.ml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -499,13 +499,13 @@ and print_out_signature ppf =
499499
match items with
500500
Osig_typext(ext, Oext_next) :: items ->
501501
gather_extensions
502-
((ext.oext_name, ext.oext_args, ext.oext_ret_type) :: acc)
502+
((ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr) :: acc)
503503
items
504504
| _ -> (List.rev acc, items)
505505
in
506506
let exts, items =
507507
gather_extensions
508-
[(ext.oext_name, ext.oext_args, ext.oext_ret_type)]
508+
[(ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr)]
509509
items
510510
in
511511
let te =
@@ -531,7 +531,7 @@ and print_out_sig_item ppf =
531531
name !out_class_type clt
532532
| Osig_typext (ext, Oext_exception) ->
533533
fprintf ppf "@[<2>exception %a@]"
534-
print_out_constr (ext.oext_name, ext.oext_args, ext.oext_ret_type)
534+
print_out_constr (ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr)
535535
| Osig_typext (ext, _es) ->
536536
print_out_extension_constructor ppf ext
537537
| Osig_modtype (name, Omty_abstract) ->
@@ -639,7 +639,10 @@ and print_out_type_decl kwd ppf td =
639639
print_immediate
640640
print_unboxed
641641

642-
and print_out_constr ppf (name, tyl,ret_type_opt) =
642+
and print_out_constr ppf (name, tyl, ret_type_opt, repr) =
643+
let () = match repr with
644+
| None -> ()
645+
| Some s -> pp_print_string ppf s in
643646
let name =
644647
match name with
645648
| "::" -> "(::)" (* #7200 *)
@@ -686,7 +689,7 @@ and print_out_extension_constructor ppf ext =
686689
fprintf ppf "@[<hv 2>type %t +=%s@;<1 2>%a@]"
687690
print_extended_type
688691
(if ext.oext_private = Asttypes.Private then " private" else "")
689-
print_out_constr (ext.oext_name, ext.oext_args, ext.oext_ret_type)
692+
print_out_constr (ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr)
690693

691694
and print_out_type_extension ppf te =
692695
let print_extended_type ppf =
@@ -736,13 +739,13 @@ let rec print_items ppf =
736739
match items with
737740
(Osig_typext(ext, Oext_next), None) :: items ->
738741
gather_extensions
739-
((ext.oext_name, ext.oext_args, ext.oext_ret_type) :: acc)
742+
((ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr) :: acc)
740743
items
741744
| _ -> (List.rev acc, items)
742745
in
743746
let exts, items =
744747
gather_extensions
745-
[(ext.oext_name, ext.oext_args, ext.oext_ret_type)]
748+
[(ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr)]
746749
items
747750
in
748751
let te =

jscomp/ml/outcometree.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ type out_type =
6363
| Otyp_object of (string * out_type) list * bool option
6464
| Otyp_record of (string * bool * bool * out_type) list
6565
| Otyp_stuff of string
66-
| Otyp_sum of (string * out_type list * out_type option) list
66+
| Otyp_sum of (string * out_type list * out_type option * string option) list
6767
| Otyp_tuple of out_type list
6868
| Otyp_var of bool * string
6969
| Otyp_variant of
@@ -118,11 +118,12 @@ and out_extension_constructor =
118118
oext_type_params: string list;
119119
oext_args: out_type list;
120120
oext_ret_type: out_type option;
121+
oext_repr: string option;
121122
oext_private: Asttypes.private_flag }
122123
and out_type_extension =
123124
{ otyext_name: string;
124125
otyext_params: string list;
125-
otyext_constructors: (string * out_type list * out_type option) list;
126+
otyext_constructors: (string * out_type list * out_type option * string option) list;
126127
otyext_private: Asttypes.private_flag }
127128
and out_val_decl =
128129
{ oval_name: string;

jscomp/ml/printtyp.ml

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ let rec tree_of_type_decl id decl =
881881
in
882882
let (name, args) = type_defined decl in
883883
let constraints = tree_of_constraints params in
884+
let untagged = ref false in
884885
let ty, priv =
885886
match decl.type_kind with
886887
| Type_abstract ->
@@ -890,6 +891,7 @@ let rec tree_of_type_decl id decl =
890891
tree_of_typexp false ty, decl.type_private
891892
end
892893
| Type_variant cstrs ->
894+
untagged := Ast_untagged_variants.process_untagged decl.type_attributes;
893895
tree_of_manifest (Otyp_sum (List.map tree_of_constructor cstrs)),
894896
decl.type_private
895897
| Type_record(lbls, _rep) ->
@@ -907,7 +909,7 @@ let rec tree_of_type_decl id decl =
907909
otype_type = ty;
908910
otype_private = priv;
909911
otype_immediate = immediate;
910-
otype_unboxed = decl.type_unboxed.unboxed;
912+
otype_unboxed = decl.type_unboxed.unboxed || !untagged;
911913
otype_cstrs = constraints ;
912914
}
913915

@@ -917,16 +919,29 @@ and tree_of_constructor_arguments = function
917919

918920
and tree_of_constructor cd =
919921
let name = Ident.name cd.cd_id in
922+
let nullary = Ast_untagged_variants.is_nullary_variant cd.cd_args in
923+
let repr =
924+
if not nullary then None
925+
else match Ast_untagged_variants.process_tag_type cd.cd_attributes with
926+
| Some Null -> Some "@as(null)"
927+
| Some Undefined -> Some "@as(undefined)"
928+
| Some (String s) -> Some (Printf.sprintf "@as(%S)" s)
929+
| Some (Int i) -> Some (Printf.sprintf "@as(%d)" i)
930+
| Some (Float f) -> Some (Printf.sprintf "@as(%s)" f)
931+
| Some (Bool b) -> Some (Printf.sprintf "@as(%b)" b)
932+
| Some (BigInt s) -> Some (Printf.sprintf "@as(%sn)" s)
933+
| Some (Untagged _) (* should never happen *)
934+
| None -> None in
920935
let arg () = tree_of_constructor_arguments cd.cd_args in
921936
match cd.cd_res with
922-
| None -> (name, arg (), None)
937+
| None -> (name, arg (), None, repr)
923938
| Some res ->
924939
let nm = !names in
925940
names := [];
926941
let ret = tree_of_typexp false res in
927942
let args = arg () in
928943
names := nm;
929-
(name, args, Some ret)
944+
(name, args, Some ret, repr)
930945

931946
and tree_of_label l =
932947
let opt = l.ld_attributes |> List.exists (fun ({txt}, _) -> txt = "ns.optional" || txt = "res.optional") in
@@ -982,6 +997,7 @@ let tree_of_extension_constructor id ext es =
982997
oext_type_params = ty_params;
983998
oext_args = args;
984999
oext_ret_type = ret;
1000+
oext_repr = None;
9851001
oext_private = ext.ext_private }
9861002
in
9871003
let es =

jscomp/syntax/src/res_outcome_printer.ml

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,12 @@ and print_out_constructors_doc constructors =
429429
constructors);
430430
]))
431431

432-
and print_out_constructor_doc (name, args, gadt) =
432+
and print_out_constructor_doc (name, args, gadt, repr) =
433+
let repr_doc =
434+
match repr with
435+
| None -> Doc.nil
436+
| Some s -> Doc.text (s ^ " ")
437+
in
433438
let gadt_doc =
434439
match gadt with
435440
| Some out_type -> Doc.concat [Doc.text ": "; print_out_type_doc out_type]
@@ -469,7 +474,7 @@ and print_out_constructor_doc (name, args, gadt) =
469474
Doc.rparen;
470475
])
471476
in
472-
Doc.group (Doc.concat [Doc.text name; args_doc; gadt_doc])
477+
Doc.group (Doc.concat [repr_doc; Doc.text name; args_doc; gadt_doc])
473478

474479
and print_record_decl_row_doc (name, mut, opt, arg) =
475480
Doc.group
@@ -678,7 +683,6 @@ let rec print_out_sig_item_doc ?(print_name_as_is = false)
678683
Doc.group
679684
(Doc.concat
680685
[
681-
attrs;
682686
kw;
683687
(if print_name_as_is then Doc.text out_type_decl.otype_name
684688
else
@@ -758,13 +762,14 @@ and print_out_signature_doc (signature : Outcometree.out_sig_item list) =
758762
match items with
759763
| Outcometree.Osig_typext (ext, Oext_next) :: items ->
760764
gather_extensions
761-
((ext.oext_name, ext.oext_args, ext.oext_ret_type) :: acc)
765+
((ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr)
766+
:: acc)
762767
items
763768
| _ -> (List.rev acc, items)
764769
in
765770
let exts, items =
766771
gather_extensions
767-
[(ext.oext_name, ext.oext_args, ext.oext_ret_type)]
772+
[(ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr)]
768773
items
769774
in
770775
let te =
@@ -822,7 +827,10 @@ and print_out_extension_constructor_doc
822827
(if out_ext.oext_private = Asttypes.Private then Doc.text "private "
823828
else Doc.nil);
824829
print_out_constructor_doc
825-
(out_ext.oext_name, out_ext.oext_args, out_ext.oext_ret_type);
830+
( out_ext.oext_name,
831+
out_ext.oext_args,
832+
out_ext.oext_ret_type,
833+
out_ext.oext_repr );
826834
])
827835

828836
and print_out_type_extension_doc
@@ -1035,13 +1043,14 @@ let print_out_phrase_signature signature =
10351043
match items with
10361044
| (Outcometree.Osig_typext (ext, Oext_next), None) :: items ->
10371045
gather_extensions
1038-
((ext.oext_name, ext.oext_args, ext.oext_ret_type) :: acc)
1046+
((ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr)
1047+
:: acc)
10391048
items
10401049
| _ -> (List.rev acc, items)
10411050
in
10421051
let exts, signature =
10431052
gather_extensions
1044-
[(ext.oext_name, ext.oext_args, ext.oext_ret_type)]
1053+
[(ext.oext_name, ext.oext_args, ext.oext_ret_type, ext.oext_repr)]
10451054
signature
10461055
in
10471056
let te =

packages/playground-bundling/package-lock.json

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/playground-bundling/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"author": "",
1212
"license": "ISC",
1313
"dependencies": {
14-
"@rescript/core": "^1.1.0",
14+
"@rescript/core": "^1.5.0",
1515
"@rescript/react": "^0.12.1"
1616
}
1717
}

0 commit comments

Comments
 (0)