diff --git a/compiler/src/codegen/compcore.re b/compiler/src/codegen/compcore.re index 37962cd85d..e996050ce2 100644 --- a/compiler/src/codegen/compcore.re +++ b/compiler/src/codegen/compcore.re @@ -3304,16 +3304,16 @@ let compile_type_metadata = (wasm_mod, env, type_metadata) => { ); let type_metadata = switch (exception_meta) { - | [ExceptionMetadata(id, _, _), ..._] => [ + | [ExceptionMetadata(id, _, _, _), ..._] => [ ADTMeta( id, List.map( meta => { switch (meta) { - | ExceptionMetadata(_, variant, name) => ( + | ExceptionMetadata(_, variant, name, cstr_type) => ( variant, name, - TupleConstructor, + cstr_type, ) | _ => failwith("impossible by partition") } diff --git a/compiler/src/language_server/sourcetree.re b/compiler/src/language_server/sourcetree.re index 9f806e64d1..d36bd437aa 100644 --- a/compiler/src/language_server/sourcetree.re +++ b/compiler/src/language_server/sourcetree.re @@ -241,7 +241,7 @@ module Sourcetree: Sourcetree = { Path.( switch (exp.exp_desc) { | TExpIdent( - PExternal(path, _, _), + PExternal(path, _), {txt: IdentExternal(IdentName({loc}), _)}, desc, ) => diff --git a/compiler/src/middle_end/linearize.re b/compiler/src/middle_end/linearize.re index 0d34e21465..7441facb66 100644 --- a/compiler/src/middle_end/linearize.re +++ b/compiler/src/middle_end/linearize.re @@ -38,7 +38,7 @@ let get_type_id = (typath, env) => let lookup_symbol = (~env, ~allocation_type, ~repr, path) => { switch (path) { | Path.PIdent(id) => id - | Path.PExternal(mod_, name, _pos) => + | Path.PExternal(mod_, name) => let mod_map = switch (Path_tbl.find_opt(module_symbol_map, mod_)) { | Some(map) => map @@ -1618,6 +1618,20 @@ let rec gather_type_metadata = statements => { ty_id, compile_constructor_tag(cstr.cstr_tag), cstr.cstr_name, + switch (cstr.cstr_inlined) { + | None => TupleConstructor + | Some(t) => + let label_names = + switch (t.type_kind) { + | TDataRecord(rfs) => + List.map(rf => Ident.name(rf.Types.rf_name), rfs) + | _ => + failwith( + "Impossible: inlined exception record constructor with non-record underlying type", + ) + }; + RecordConstructor(label_names); + }, ), ...metadata, ]; diff --git a/compiler/src/parsing/ast_helper.re b/compiler/src/parsing/ast_helper.re index 9adc900b8e..212f75d22a 100644 --- a/compiler/src/parsing/ast_helper.re +++ b/compiler/src/parsing/ast_helper.re @@ -164,6 +164,21 @@ module Exception = { }; let singleton = (~loc=?, n) => mk(~loc?, n, PConstrSingleton); let tuple = (~loc=?, n, args) => mk(~loc?, n, PConstrTuple(args)); + let record = (~loc=?, n, args) => { + List.iter( + ld => + if (ld.pld_mutable == Mutable) { + raise( + SyntaxError( + ld.pld_loc, + "A record exception constructor cannot have mutable fields.", + ), + ); + }, + args, + ); + mk(~loc?, n, PConstrRecord(args)); + }; }; module Pattern = { diff --git a/compiler/src/parsing/ast_helper.rei b/compiler/src/parsing/ast_helper.rei index 5cb51a1a47..a541aae86a 100644 --- a/compiler/src/parsing/ast_helper.rei +++ b/compiler/src/parsing/ast_helper.rei @@ -99,6 +99,7 @@ module Exception: { let mk: (~loc: loc=?, str, constructor_arguments) => type_exception; let singleton: (~loc: loc=?, str) => type_exception; let tuple: (~loc: loc=?, str, list(parsed_type)) => type_exception; + let record: (~loc: loc=?, str, list(label_declaration)) => type_exception; }; module Pattern: { diff --git a/compiler/src/parsing/parser.mly b/compiler/src/parsing/parser.mly index 63bb1c7b16..0fd908fbfd 100644 --- a/compiler/src/parsing/parser.mly +++ b/compiler/src/parsing/parser.mly @@ -656,6 +656,7 @@ primitive_stmt: exception_stmt: | EXCEPTION type_id_str { Exception.singleton ~loc:(to_loc $loc) $2 } | EXCEPTION type_id_str lparen typs? rparen { Exception.tuple ~loc:(to_loc $loc) $2 (Option.value ~default:[] $4) } + | EXCEPTION type_id_str data_labels { Exception.record ~loc:(to_loc $loc) $2 $3 } module_stmt: | MODULE UIDENT lbrace toplevel_stmts RBRACE { ModuleDeclaration.mk ~loc:(to_loc $loc) (mkstr $loc($2) $2) $4 } diff --git a/compiler/src/typed/ctype.re b/compiler/src/typed/ctype.re index 6dd0598115..85d45d6937 100644 --- a/compiler/src/typed/ctype.re +++ b/compiler/src/typed/ctype.re @@ -138,7 +138,7 @@ let is_object_type = path => { let name = switch (path) { | Path.PIdent(id) => Ident.name(id) - | Path.PExternal(_, s, _) => s + | Path.PExternal(_, s) => s }; name.[0] == '#'; }; @@ -3331,5 +3331,5 @@ let maybe_pointer_type = (env, typ) => let rec lid_of_path = (~hash="") => fun | Path.PIdent(id) => Identifier.IdentName(mknoloc(hash ++ Ident.name(id))) - | Path.PExternal(p1, s, _) => + | Path.PExternal(p1, s) => Identifier.IdentExternal(lid_of_path(p1), mknoloc(hash ++ s)); diff --git a/compiler/src/typed/datarepr.re b/compiler/src/typed/datarepr.re index db0563535c..1454e6c37d 100644 --- a/compiler/src/typed/datarepr.re +++ b/compiler/src/typed/datarepr.re @@ -114,11 +114,7 @@ let constructor_descrs = (ty_path, decl, cstrs) => { }; let cstr_name = Ident.name(cd_id); let (existentials, cstr_args, cstr_inlined) = - constructor_args( - cd_args, - cd_res, - Path.PExternal(ty_path, cstr_name, Path.nopos), - ); + constructor_args(cd_args, cd_res, Path.PExternal(ty_path, cstr_name)); let cstr = { cstr_name, @@ -141,7 +137,11 @@ let extension_descr = (path_ext, ext) => { let ty_res = newgenconstr(ext.ext_type_path, ext.ext_type_params); let (existentials, cstr_args, cstr_inlined) = - constructor_args(ext.ext_args, Some(ty_res), path_ext); + constructor_args( + ext.ext_args, + Some(ty_res), + Path.PExternal(path_ext, "#extension#"), + ); let cstr_ext_type = if (cstr_args == []) { diff --git a/compiler/src/typed/env.re b/compiler/src/typed/env.re index 5df467fc05..966f22ffda 100644 --- a/compiler/src/typed/env.re +++ b/compiler/src/typed/env.re @@ -374,7 +374,7 @@ module IdTbl = { | Some({using, root, next, components}) => try({ let (descr, pos) = Tbl.find(name, components); - let res = (PExternal(root, name, pos), descr); + let res = (PExternal(root, name), descr); if (mark) { switch (using) { | None => () @@ -427,7 +427,7 @@ module IdTbl = { | Some({root, using: _, next, components}) => try({ let (desc, pos) = Tbl.find(name, components); - [(PExternal(root, name, pos), desc), ...find_all(name, next)]; + [(PExternal(root, name), desc), ...find_all(name, next)]; }) { | Not_found => find_all(name, next) } @@ -445,8 +445,7 @@ module IdTbl = { | Some({root, using: _, next, components}) => acc |> Tbl.fold( - (name, (desc, pos)) => - f(name, (PExternal(root, name, pos), desc)), + (name, (desc, pos)) => f(name, (PExternal(root, name), desc)), components, ) |> fold_name(f, next) @@ -471,7 +470,7 @@ module IdTbl = { (s, (x, pos)) => f( Ident.hide(Ident.create(s) /* ??? */), - (PExternal(root, s, pos), x), + (PExternal(root, s), x), ), components, ); @@ -980,7 +979,7 @@ let rec find_module_descr = (path, filename, env) => { | _ => raise(Not_found) }; } - | PExternal(m, s, pos) => + | PExternal(m, s) => let c = get_components(find_module_descr(m, filename, env)); let (descr, _pos) = Tbl.find(s, c.comp_components); descr; @@ -990,7 +989,7 @@ let rec find_module_descr = (path, filename, env) => { let find = (proj1, proj2, path, env) => switch (path) { | PIdent(id) => IdTbl.find_same(id, proj1(env)) - | PExternal(m, n, _pos) => + | PExternal(m, n) => let c = get_components(find_module_descr(m, None, env)); let (data, _pos) = Tbl.find(n, proj2(c)); data; @@ -999,7 +998,7 @@ let find = (proj1, proj2, path, env) => let find_tycomp = (proj1, proj2, path, env) => switch (path) { | PIdent(id) => TycompTbl.find_same(id, proj1(env)) - | PExternal(m, n, _pos) => + | PExternal(m, n) => let c = get_components(find_module_descr(m, None, env)); switch (Tbl.find(n, proj2(c))) { | [cstr, ..._] => cstr @@ -1031,18 +1030,40 @@ let type_of_cstr = path => | _ => failwith("Impossible: Env.type_of_cstr called on non-record constructor"); +let find_extension_full = (path, env) => { + switch (path) { + | PIdent(id) => TycompTbl.find_same(id, env.constructors) + | PExternal(p, s) => + let comps = get_components(find_module_descr(p, None, env)); + let cstrs = Tbl.find(s, comps.comp_constrs); + List.find( + cstr => + switch (cstr.cstr_tag) { + | CstrExtension(_) => true + | _ => false + }, + cstrs, + ); + }; +}; + let rec find_type_full = (path, env) => switch (path) { | PIdent(_) => try((PathMap.find(path, env.local_constraints), ([], []))) { | Not_found => find_type_data(path, env) } - | PExternal(p, name, pos) => - try({ - let cstr = find_cstr(p, name, env); + | PExternal(p, name) => + if (name == "#extension#") { + let cstr = find_extension_full(p, env); type_of_cstr(path, cstr); - }) { - | Not_found => find_type_data(path, env) + } else { + try({ + let cstr = find_cstr(p, name, env); + type_of_cstr(path, cstr); + }) { + | Not_found => find_type_data(path, env) + }; } } @@ -1077,7 +1098,7 @@ let find_module = (path, filename, env) => raise(Not_found); }; } - | PExternal(m, n, _pos) => + | PExternal(m, n) => let c = get_components(find_module_descr(m, filename, env)); let (data, _pos) = Tbl.find(n, c.comp_modules); EnvLazy.force(subst_modtype_maker, data); @@ -1092,7 +1113,7 @@ let find_module_chain = (path, env) => { [EnvLazy.force(subst_modtype_maker, data)], IdTbl.find_same(id, env.components), ); - | PExternal(m, s, pos) => + | PExternal(m, s) => let (data, components) = find(m, env); let c = get_components(components); let (decl, _pos) = Tbl.find(s, c.comp_modules); @@ -1107,12 +1128,12 @@ let find_module_chain = (path, env) => { let rec normalize_path = (lax, env, path) => switch (path) { | PIdent(id) when lax && Ident.persistent(id) => path - | PExternal(p, s, pos) => + | PExternal(p, s) => let p' = normalize_path(lax, env, p); if (p == p') { expand_path(lax, env, path); } else { - expand_path(lax, env, PExternal(p', s, pos)); + expand_path(lax, env, PExternal(p', s)); }; | PIdent(_) => expand_path(lax, env, path) } @@ -1148,7 +1169,7 @@ let normalize_path = (oloc, env, path) => let normalize_path_prefix = (oloc, env, path) => switch (path) { - | PExternal(p, s, pos) => PExternal(normalize_path(oloc, env, p), s, pos) + | PExternal(p, s) => PExternal(normalize_path(oloc, env, p), s) | PIdent(_) => path }; /*| PApply _ -> assert false*/ @@ -1210,7 +1231,7 @@ let rec lookup_module_descr_aux = (~mark, id, env) => | IdentExternal(m, {txt: n}) => let (p, descr) = lookup_module_descr(~mark, m, env); let (descr, pos) = Tbl.find(n, get_components(descr).comp_components); - (PExternal(p, n, pos), descr); + (PExternal(p, n), descr); } ) @@ -1257,12 +1278,11 @@ and lookup_module = (~loc=?, ~load, ~mark, id, filename, env): Path.t => | Identifier.IdentExternal(l, {txt: s}) => let (p, descr) = lookup_module_descr(~mark, l, env); let c = get_components(descr); - let (_data, pos) = Tbl.find(s, c.comp_modules); let (comps, _) = Tbl.find(s, c.comp_components); if (mark) { mark_module_used(env, s, comps.loc); }; - let p = PExternal(p, s, pos); + let p = PExternal(p, s); p; }; @@ -1273,7 +1293,7 @@ let lookup_idtbl = (~mark, proj1, proj2, id, env) => | IdentExternal(m, {txt: n}) => let (p, desc) = lookup_module_descr(~mark, m, env); let (data, pos) = Tbl.find(n, proj2(get_components(desc))); - (PExternal(p, n, pos), data); + (PExternal(p, n), data); } ); @@ -1428,17 +1448,12 @@ let iter_env = (proj1, proj2, f, env, ()) => { } else { let comps = get_components(mcomps); Tbl.iter( - (s, (d, n)) => - f(PExternal(path, s, n), (PExternal(path', s, n), d)), + (s, (d, n)) => f(PExternal(path, s), (PExternal(path', s), d)), proj2(comps), ); Tbl.iter( (s, (c, n)) => - iter_components( - PExternal(path, s, n), - PExternal(path', s, n), - c, - ), + iter_components(PExternal(path, s), PExternal(path', s), c), comps.comp_components, ); }; @@ -1491,7 +1506,7 @@ let find_all_comps = (proj, s, (p, mcomps)) => { let comps = get_components(mcomps); try({ let (c, n) = Tbl.find(s, proj(comps)); - [(PExternal(p, s, n), c)]; + [(PExternal(p, s), c)]; }) { | Not_found => [] }; @@ -1500,7 +1515,7 @@ let find_all_comps = (proj, s, (p, mcomps)) => { let rec find_shadowed_comps = (path, env) => switch (path) { | PIdent(id) => IdTbl.find_all(Ident.name(id), env.components) - | PExternal(p, s, _) => + | PExternal(p, s) => let l = find_shadowed_comps(p, env); let l' = List.map(find_all_comps(comps => comps.comp_components, s), l); List.flatten(l'); @@ -1509,7 +1524,7 @@ let rec find_shadowed_comps = (path, env) => let find_shadowed = (proj1, proj2, path, env) => switch (path) { | PIdent(id) => IdTbl.find_all(Ident.name(id), proj1(env)) - | PExternal(p, s, _) => + | PExternal(p, s) => let l = find_shadowed_comps(p, env); let l' = List.map(find_all_comps(proj2, s), l); List.flatten(l'); @@ -1538,7 +1553,7 @@ let rec prefix_idents = (root, pos, sub) => fun | [] => ([], sub) | [TSigValue(id, decl), ...rem] => { - let p = PExternal(root, Ident.name(id), pos); + let p = PExternal(root, Ident.name(id)); let nextpos = switch (decl.val_kind) { | TValPrim(_) => pos @@ -1548,25 +1563,25 @@ let rec prefix_idents = (root, pos, sub) => ([p, ...pl], final_sub); } | [TSigType(id, _, _), ...rem] => { - let p = PExternal(root, Ident.name(id), nopos); + let p = PExternal(root, Ident.name(id)); let (pl, final_sub) = prefix_idents(root, pos, Subst.add_type(id, p, sub), rem); ([p, ...pl], final_sub); } | [TSigTypeExt(id, ec, es), ...rem] => { - let p = PExternal(root, Ident.name(id), pos); + let p = PExternal(root, Ident.name(id)); let (pl, final_sub) = prefix_idents(root, pos, Subst.add_type(id, p, sub), rem); ([p, ...pl], final_sub); } | [TSigModule(id, _, _), ...rem] => { - let p = PExternal(root, Ident.name(id), pos); + let p = PExternal(root, Ident.name(id)); let (pl, final_sub) = prefix_idents(root, pos + 1, Subst.add_module(id, p, sub), rem); ([p, ...pl], final_sub); } | [TSigModType(id, _), ...rem] => { - let p = PExternal(root, Ident.name(id), nopos); + let p = PExternal(root, Ident.name(id)); let (pl, final_sub) = prefix_idents( root, @@ -1690,7 +1705,7 @@ and components_of_module_maker = ((env, sub, path, mty)) => let get_path = name => switch (path) { | PIdent(_) => PIdent(Ident.create(name)) - | PExternal(p, _, level) => PExternal(p, name, level) + | PExternal(p, _) => PExternal(p, name) }; let path = get_path(desc.cstr_name); let val_desc = { @@ -1753,7 +1768,7 @@ and components_of_module_maker = ((env, sub, path, mty)) => let get_path = name => switch (path) { | PIdent(_) => PIdent(Ident.create(name)) - | PExternal(p, _, level) => PExternal(p, name, level) + | PExternal(p, _) => PExternal(p, name) }; let path = get_path(desc.cstr_name); let val_desc = { @@ -2390,7 +2405,7 @@ let find_all = (proj1, proj2, f, lid, env, acc) => let (p, desc) = lookup_module_descr(~mark=true, l, env); let c = get_components(desc); Tbl.fold( - (s, (data, pos), acc) => f(s, PExternal(p, s, pos), data, acc), + (s, (data, pos), acc) => f(s, PExternal(p, s), data, acc), proj2(c), acc, ); @@ -2443,7 +2458,7 @@ let fold_modules = (f, lid, env, acc) => (s, (data, pos), acc) => f( s, - PExternal(p, s, pos), + PExternal(p, s), EnvLazy.force(subst_modtype_maker, data), acc, ), diff --git a/compiler/src/typed/includemod.re b/compiler/src/typed/includemod.re index ec49383b0b..e300c2c407 100644 --- a/compiler/src/typed/includemod.re +++ b/compiler/src/typed/includemod.re @@ -905,7 +905,7 @@ let path_of_context = fun | [] => path | [Module(id), ...rem] => - subm(PExternal(path, Ident.name(id), -1), rem) + subm(PExternal(path, Ident.name(id)), rem) | _ => assert(false) ); subm(PIdent(id), rem); diff --git a/compiler/src/typed/mtype.re b/compiler/src/typed/mtype.re index 63febbe971..29a87d1528 100644 --- a/compiler/src/typed/mtype.re +++ b/compiler/src/typed/mtype.re @@ -67,7 +67,7 @@ and strengthen_sig = (~aliasable, env, sg, p, pos) => Some( Btype.newgenty( TTyConstr( - PExternal(p, Ident.name(id), nopos), + PExternal(p, Ident.name(id)), decl.type_params, ref(TMemNil), ), @@ -90,12 +90,7 @@ and strengthen_sig = (~aliasable, env, sg, p, pos) => ] | [TSigModule(id, md, rs), ...rem] => let str = - strengthen_decl( - ~aliasable, - env, - md, - PExternal(p, Ident.name(id), pos), - ); + strengthen_decl(~aliasable, env, md, PExternal(p, Ident.name(id))); [ TSigModule(id, str, rs), @@ -113,7 +108,7 @@ and strengthen_sig = (~aliasable, env, sg, p, pos) => switch (decl.mtd_type) { | None => { ...decl, - mtd_type: Some(TModIdent(PExternal(p, Ident.name(id), nopos))), + mtd_type: Some(TModIdent(PExternal(p, Ident.name(id)))), } | Some(_) => decl }; @@ -320,7 +315,7 @@ and enrich_item = (env, p) => | TSigType(id, decl, rs) => TSigType( id, - enrich_typedecl(env, PExternal(p, Ident.name(id), nopos), id, decl), + enrich_typedecl(env, PExternal(p, Ident.name(id)), id, decl), rs, ) | TSigModule(id, md, rs) => @@ -329,11 +324,7 @@ and enrich_item = (env, p) => { ...md, md_type: - enrich_modtype( - env, - PExternal(p, Ident.name(id), nopos), - md.md_type, - ), + enrich_modtype(env, PExternal(p, Ident.name(id)), md.md_type), }, rs, ) @@ -358,11 +349,11 @@ and type_paths_sig = (env, p, pos, sg) => }; type_paths_sig(env, p, pos', rem); | [TSigType(id, _decl, _), ...rem] => [ - PExternal(p, Ident.name(id), nopos), + PExternal(p, Ident.name(id)), ...type_paths_sig(env, p, pos, rem), ] | [TSigModule(id, md, _), ...rem] => - type_paths(env, PExternal(p, Ident.name(id), pos), md.md_type) + type_paths(env, PExternal(p, Ident.name(id)), md.md_type) @ type_paths_sig( Env.add_module_declaration(~check=false, id, md, env), p, @@ -462,14 +453,14 @@ module PathMap = Map.Make(Path); let rec get_prefixes = fun | PIdent(_) => PathSet.empty - | PExternal(p, _, _) => + | PExternal(p, _) => /*| Papply (p, _)*/ PathSet.add(p, get_prefixes(p)); let rec get_arg_paths = fun | PIdent(_) => PathSet.empty - | PExternal(p, _, _) => get_arg_paths(p); + | PExternal(p, _) => get_arg_paths(p); /*| Papply (p1, p2) -> PathSet.add p2 (PathSet.union (get_prefixes p2) @@ -480,12 +471,12 @@ let rec rollback_path = (subst, p) => | Not_found => switch (p) { | PIdent(_) /*| Papply _*/ => p - | PExternal(p1, s, n) => + | PExternal(p1, s) => let p1' = rollback_path(subst, p1); if (Path.same(p1, p1')) { p; } else { - rollback_path(subst, PExternal(p1', s, n)); + rollback_path(subst, PExternal(p1', s)); }; } }; @@ -521,7 +512,7 @@ let collect_arg_paths = mty => { | TSigModule(id', _, _) => subst := PathMap.add( - PExternal(PIdent(id), Ident.name(id'), -1), + PExternal(PIdent(id), Ident.name(id')), id', subst^, ) diff --git a/compiler/src/typed/path.re b/compiler/src/typed/path.re index 6131f521c2..56cedd23f7 100644 --- a/compiler/src/typed/path.re +++ b/compiler/src/typed/path.re @@ -4,14 +4,14 @@ open Sexplib.Conv; [@deriving (sexp, yojson)] type t = | PIdent(Ident.t) - | PExternal(t, string, int); + | PExternal(t, string); let nopos = (-1); let rec same = (p1, p2) => switch (p1, p2) { | (PIdent(id1), PIdent(id2)) => Ident.same(id1, id2) - | (PExternal(mod1, s1, _), PExternal(mod2, s2, _)) => + | (PExternal(mod1, s1), PExternal(mod2, s2)) => s1 == s2 && same(mod1, mod2) | _ => false }; @@ -19,7 +19,7 @@ let rec same = (p1, p2) => let rec compare = (p1, p2) => switch (p1, p2) { | (PIdent(id1), PIdent(id2)) => Ident.compare(id1, id2) - | (PExternal(mod1, s1, _), PExternal(mod2, s2, _)) => + | (PExternal(mod1, s1), PExternal(mod2, s2)) => let s_comp = String.compare(s1, s2); if (s_comp != 0) { s_comp; @@ -33,41 +33,41 @@ let rec compare = (p1, p2) => let rec find_free_opt = ids => fun | PIdent(id) => List.find_opt(Ident.same(id), ids) - | PExternal(p, _, _) => find_free_opt(ids, p); + | PExternal(p, _) => find_free_opt(ids, p); let rec isfree = id => fun | PIdent(id') => Ident.same(id, id') - | PExternal(m, _, _) => isfree(id, m); + | PExternal(m, _) => isfree(id, m); let rec binding_time = fun | PIdent(id) => Ident.binding_time(id) - | PExternal(m, _, _) => binding_time(m); + | PExternal(m, _) => binding_time(m); let flatten = { let rec flatten = acc => fun | PIdent(id) => (id, acc) - | PExternal(m, s, _) => flatten([s, ...acc], m); + | PExternal(m, s) => flatten([s, ...acc], m); flatten([]); }; let rec name = fun | PIdent(id) => Ident.name(id) - | PExternal(m, s, _) => name(m) ++ "." ++ s; + | PExternal(m, s) => name(m) ++ "." ++ s; let rec head = fun | PIdent(id) => id - | PExternal(m, _, _) => head(m); + | PExternal(m, _) => head(m); let heads = p => { let rec heads = (p, acc) => switch (p) { | PIdent(id) => [id, ...acc] - | PExternal(m, _, _) => heads(m, acc) + | PExternal(m, _) => heads(m, acc) }; heads(p, []); }; @@ -75,9 +75,9 @@ let heads = p => { let rec last = fun | PIdent(id) => Ident.name(id) - | PExternal(_, s, _) => s; + | PExternal(_, s) => s; let rec stamp = fun | PIdent(id) => id.stamp - | PExternal(p, _, _) => stamp(p); + | PExternal(p, _) => stamp(p); diff --git a/compiler/src/typed/path.rei b/compiler/src/typed/path.rei index fefa82c578..7ba2b6af4d 100644 --- a/compiler/src/typed/path.rei +++ b/compiler/src/typed/path.rei @@ -3,7 +3,7 @@ [@deriving (sexp, yojson)] type t = | PIdent(Ident.t) - | PExternal(t, string, int); + | PExternal(t, string); let same: (t, t) => bool; let compare: (t, t) => int; diff --git a/compiler/src/typed/printtyp.re b/compiler/src/typed/printtyp.re index 079693ff93..dc97631b35 100644 --- a/compiler/src/typed/printtyp.re +++ b/compiler/src/typed/printtyp.re @@ -48,7 +48,7 @@ let ident_pervasives = Ident.create_persistent("Stdlib"); let printing_env = ref(Env.empty); let non_shadowed_pervasive = fun - | PExternal(PIdent(id), s, _pos) as path => + | PExternal(PIdent(id), s) as path => Ident.same(id, ident_pervasives) && ( try( @@ -65,16 +65,16 @@ let non_shadowed_pervasive = let rec tree_of_path = fun | PIdent(id) => Oide_ident(ident_name(id)) - | PExternal(_, s, _pos) as path when non_shadowed_pervasive(path) => + | PExternal(_, s) as path when non_shadowed_pervasive(path) => Oide_ident(s) - | PExternal(p, s, _pos) => Oide_dot(tree_of_path(p), s); + | PExternal(p, s) => Oide_dot(tree_of_path(p), s); let rec path = ppf => fun | PIdent(id) => ident(ppf, id) - | PExternal(_, s, _pos) as path when non_shadowed_pervasive(path) => + | PExternal(_, s) as path when non_shadowed_pervasive(path) => pp_print_string(ppf, s) - | PExternal(p, s, _pos) => { + | PExternal(p, s) => { path(ppf, p); pp_print_string(ppf, "::"); pp_print_string(ppf, s); @@ -316,7 +316,7 @@ let penalty = s => let rec path_size = fun | PIdent(id) => (penalty(Ident.name(id)), - Ident.binding_time(id)) - | PExternal(p, _, _) => { + | PExternal(p, _) => { let (l, b) = path_size(p); (1 + l, b); }; @@ -1454,7 +1454,7 @@ let ident_same_name = (id1, id2) => let rec path_same_name = (p1, p2) => switch (p1, p2) { | (PIdent(id1), PIdent(id2)) => ident_same_name(id1, id2) - | (PExternal(p1, s1, _), PExternal(p2, s2, _)) when s1 == s2 => + | (PExternal(p1, s1), PExternal(p2, s2)) when s1 == s2 => path_same_name(p1, p2) | _ => () }; diff --git a/compiler/src/typed/subst.re b/compiler/src/typed/subst.re index 4f09c344b4..c547af197f 100644 --- a/compiler/src/typed/subst.re +++ b/compiler/src/typed/subst.re @@ -76,7 +76,7 @@ let rec module_path = (s, path) => | Not_found => switch (path) { | PIdent(_) => path - | PExternal(p, n, pos) => PExternal(module_path(s, p), n, pos) + | PExternal(p, n) => PExternal(module_path(s, p), n) } }; @@ -91,7 +91,7 @@ let modtype_path = s => ) { | Not_found => p } - | PExternal(p, n, pos) => PExternal(module_path(s, p), n, pos); + | PExternal(p, n) => PExternal(module_path(s, p), n); let type_path = (s, path) => switch (PathMap.find(path, s.types)) { @@ -100,7 +100,7 @@ let type_path = (s, path) => | exception Not_found => switch (path) { | PIdent(_) => path - | PExternal(p, n, pos) => PExternal(module_path(s, p), n, pos) + | PExternal(p, n) => PExternal(module_path(s, p), n) } }; @@ -314,8 +314,7 @@ let rec modtype = s => try(Tbl.find(id, s.modtypes)) { | Not_found => mty } - | PExternal(p, n, pos) => - TModIdent(PExternal(module_path(s, p), n, pos)) + | PExternal(p, n) => TModIdent(PExternal(module_path(s, p), n)) } | TModSignature(sg) => TModSignature(signature(s, sg)) diff --git a/compiler/src/typed/typed_well_formedness.re b/compiler/src/typed/typed_well_formedness.re index 87f51d90d2..b204a7bbea 100644 --- a/compiler/src/typed/typed_well_formedness.re +++ b/compiler/src/typed/typed_well_formedness.re @@ -218,7 +218,7 @@ module WellFormednessArg: TypedtreeIter.IteratorArgument = { { exp_desc: TExpIdent( - Path.PExternal(Path.PIdent({name: "Pervasives"}), func, _), + Path.PExternal(Path.PIdent({name: "Pervasives"}), func), _, _, ), @@ -240,11 +240,7 @@ module WellFormednessArg: TypedtreeIter.IteratorArgument = { { exp_desc: TExpIdent( - Path.PExternal( - Path.PIdent({name: modname}), - "fromNumber", - _, - ), + Path.PExternal(Path.PIdent({name: modname}), "fromNumber"), _, _, ), diff --git a/compiler/src/typed/typemod.re b/compiler/src/typed/typemod.re index 14fe449725..94de1cd785 100644 --- a/compiler/src/typed/typemod.re +++ b/compiler/src/typed/typemod.re @@ -311,7 +311,7 @@ let enrich_type_decls = (anchor, decls, oldenv, newenv) => (e, info) => { let id = info.data_id; let info' = { - let p = PExternal(p, Ident.name(id), nopos); + let p = PExternal(p, Ident.name(id)); let decl = info.data_type; switch (decl.type_manifest) { | Some(_) => decl diff --git a/compiler/src/typed/types.re b/compiler/src/typed/types.re index a97bb942a4..ea3e8c8dea 100644 --- a/compiler/src/typed/types.re +++ b/compiler/src/typed/types.re @@ -179,7 +179,7 @@ type adt_constructor_type = type type_metadata = | ADTMetadata(int, list((int, string, adt_constructor_type))) | RecordMetadata(int, list(string)) - | ExceptionMetadata(int, int, string); + | ExceptionMetadata(int, int, string, adt_constructor_type); [@deriving (sexp, yojson)] type value_kind = diff --git a/compiler/test/suites/exceptions.re b/compiler/test/suites/exceptions.re index df93978592..a6eeb6e97a 100644 --- a/compiler/test/suites/exceptions.re +++ b/compiler/test/suites/exceptions.re @@ -52,4 +52,14 @@ describe("exceptions", ({test, testSkip}) => { |}, "Spooky error 2", ); + assertRun( + "record_exception_1", + {|exception Foo { msg: String, bar: Number }; print(Foo{msg: "Oops", bar: 1})|}, + "Foo{\n msg: \"Oops\",\n bar: 1\n}\n", + ); + assertRunError( + "record_exception_2", + {|include "exception"; exception Foo { msg: String, bar: Number }; Exception.registerPrinter(e => match (e) { Foo { msg, bar } => Some(msg ++ toString(bar)), _ => None }); let _ = throw Foo{msg: "Oops", bar: 1}|}, + "Oops1", + ); });