Skip to content

Commit ffd4d44

Browse files
authored
fix(compiler): Inline record exception constructors (#1709)
1 parent c5cd21f commit ffd4d44

File tree

19 files changed

+151
-109
lines changed

19 files changed

+151
-109
lines changed

compiler/src/codegen/compcore.re

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3304,16 +3304,16 @@ let compile_type_metadata = (wasm_mod, env, type_metadata) => {
33043304
);
33053305
let type_metadata =
33063306
switch (exception_meta) {
3307-
| [ExceptionMetadata(id, _, _), ..._] => [
3307+
| [ExceptionMetadata(id, _, _, _), ..._] => [
33083308
ADTMeta(
33093309
id,
33103310
List.map(
33113311
meta => {
33123312
switch (meta) {
3313-
| ExceptionMetadata(_, variant, name) => (
3313+
| ExceptionMetadata(_, variant, name, cstr_type) => (
33143314
variant,
33153315
name,
3316-
TupleConstructor,
3316+
cstr_type,
33173317
)
33183318
| _ => failwith("impossible by partition")
33193319
}

compiler/src/language_server/sourcetree.re

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ module Sourcetree: Sourcetree = {
241241
Path.(
242242
switch (exp.exp_desc) {
243243
| TExpIdent(
244-
PExternal(path, _, _),
244+
PExternal(path, _),
245245
{txt: IdentExternal(IdentName({loc}), _)},
246246
desc,
247247
) =>

compiler/src/middle_end/linearize.re

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ let get_type_id = (typath, env) =>
3838
let lookup_symbol = (~env, ~allocation_type, ~repr, path) => {
3939
switch (path) {
4040
| Path.PIdent(id) => id
41-
| Path.PExternal(mod_, name, _pos) =>
41+
| Path.PExternal(mod_, name) =>
4242
let mod_map =
4343
switch (Path_tbl.find_opt(module_symbol_map, mod_)) {
4444
| Some(map) => map
@@ -1618,6 +1618,20 @@ let rec gather_type_metadata = statements => {
16181618
ty_id,
16191619
compile_constructor_tag(cstr.cstr_tag),
16201620
cstr.cstr_name,
1621+
switch (cstr.cstr_inlined) {
1622+
| None => TupleConstructor
1623+
| Some(t) =>
1624+
let label_names =
1625+
switch (t.type_kind) {
1626+
| TDataRecord(rfs) =>
1627+
List.map(rf => Ident.name(rf.Types.rf_name), rfs)
1628+
| _ =>
1629+
failwith(
1630+
"Impossible: inlined exception record constructor with non-record underlying type",
1631+
)
1632+
};
1633+
RecordConstructor(label_names);
1634+
},
16211635
),
16221636
...metadata,
16231637
];

compiler/src/parsing/ast_helper.re

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,21 @@ module Exception = {
164164
};
165165
let singleton = (~loc=?, n) => mk(~loc?, n, PConstrSingleton);
166166
let tuple = (~loc=?, n, args) => mk(~loc?, n, PConstrTuple(args));
167+
let record = (~loc=?, n, args) => {
168+
List.iter(
169+
ld =>
170+
if (ld.pld_mutable == Mutable) {
171+
raise(
172+
SyntaxError(
173+
ld.pld_loc,
174+
"A record exception constructor cannot have mutable fields.",
175+
),
176+
);
177+
},
178+
args,
179+
);
180+
mk(~loc?, n, PConstrRecord(args));
181+
};
167182
};
168183

169184
module Pattern = {

compiler/src/parsing/ast_helper.rei

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ module Exception: {
9999
let mk: (~loc: loc=?, str, constructor_arguments) => type_exception;
100100
let singleton: (~loc: loc=?, str) => type_exception;
101101
let tuple: (~loc: loc=?, str, list(parsed_type)) => type_exception;
102+
let record: (~loc: loc=?, str, list(label_declaration)) => type_exception;
102103
};
103104

104105
module Pattern: {

compiler/src/parsing/parser.mly

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ primitive_stmt:
656656
exception_stmt:
657657
| EXCEPTION type_id_str { Exception.singleton ~loc:(to_loc $loc) $2 }
658658
| EXCEPTION type_id_str lparen typs? rparen { Exception.tuple ~loc:(to_loc $loc) $2 (Option.value ~default:[] $4) }
659+
| EXCEPTION type_id_str data_labels { Exception.record ~loc:(to_loc $loc) $2 $3 }
659660

660661
module_stmt:
661662
| MODULE UIDENT lbrace toplevel_stmts RBRACE { ModuleDeclaration.mk ~loc:(to_loc $loc) (mkstr $loc($2) $2) $4 }

compiler/src/typed/ctype.re

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ let is_object_type = path => {
138138
let name =
139139
switch (path) {
140140
| Path.PIdent(id) => Ident.name(id)
141-
| Path.PExternal(_, s, _) => s
141+
| Path.PExternal(_, s) => s
142142
};
143143
name.[0] == '#';
144144
};
@@ -3331,5 +3331,5 @@ let maybe_pointer_type = (env, typ) =>
33313331
let rec lid_of_path = (~hash="") =>
33323332
fun
33333333
| Path.PIdent(id) => Identifier.IdentName(mknoloc(hash ++ Ident.name(id)))
3334-
| Path.PExternal(p1, s, _) =>
3334+
| Path.PExternal(p1, s) =>
33353335
Identifier.IdentExternal(lid_of_path(p1), mknoloc(hash ++ s));

compiler/src/typed/datarepr.re

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,7 @@ let constructor_descrs = (ty_path, decl, cstrs) => {
114114
};
115115
let cstr_name = Ident.name(cd_id);
116116
let (existentials, cstr_args, cstr_inlined) =
117-
constructor_args(
118-
cd_args,
119-
cd_res,
120-
Path.PExternal(ty_path, cstr_name, Path.nopos),
121-
);
117+
constructor_args(cd_args, cd_res, Path.PExternal(ty_path, cstr_name));
122118

123119
let cstr = {
124120
cstr_name,
@@ -141,7 +137,11 @@ let extension_descr = (path_ext, ext) => {
141137
let ty_res = newgenconstr(ext.ext_type_path, ext.ext_type_params);
142138

143139
let (existentials, cstr_args, cstr_inlined) =
144-
constructor_args(ext.ext_args, Some(ty_res), path_ext);
140+
constructor_args(
141+
ext.ext_args,
142+
Some(ty_res),
143+
Path.PExternal(path_ext, "#extension#"),
144+
);
145145

146146
let cstr_ext_type =
147147
if (cstr_args == []) {

0 commit comments

Comments
 (0)