Skip to content

Commit 7457cb1

Browse files
cristianocclaude
andcommitted
Convert hoisted export names for nested dynamic imports too
The cmj hoisted metadata stores the raw flattened compiler name (Operator$+ for a hoisted Operator.\"+"); export printing applies Ext_ident.convert afterward, emitting Operator$$plus. The nested dynamic-import branch passed the raw cmj name to the then-access, so the promise resolved to undefined. Apply the same ML-export-name conversion as the single-segment case. Pinned by an import2.res case against the existing hoisted operator fixture. Signed-Off-By: Cristiano Calcagno <ccrisccris@gmail.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PCtQiaDijUqA2fujQXvKUw
1 parent 5d2068f commit 7457cb1

3 files changed

Lines changed: 13 additions & 4 deletions

File tree

compiler/core/lam_compile_primitive.ml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,10 @@ let translate output_prefix loc (cxt : Lam_compile_context.t)
132132
Lam_compile_env.register_ml_module ~dynamic_import:true module_;
133133
let import = import_of_path (import_path oid) in
134134
(* a ReScript module's JS export names go through the same identifier
135-
conversion js_dump applies to qualified access (e.g. a binding
136-
named [case] is exported as [$$case]); hoisted export names from
137-
the cmj are already the emitted flat identifiers *)
135+
conversion js_dump applies to qualified access and export lists:
136+
a binding named [case] is exported as [$$case], and a hoisted
137+
[Operator.\"+"] whose cmj metadata stores the raw flattened name
138+
[Operator$+] is exported as [Operator$$plus] *)
138139
let ml_export_name name =
139140
if name = Js_dump_import_export.default_export then name
140141
else Ext_ident.convert name
@@ -149,7 +150,7 @@ let translate output_prefix loc (cxt : Lam_compile_context.t)
149150
Lam_compile_env.find_hoisted_external_export ~dynamic_import:true
150151
module_ path
151152
with
152-
| Some hoisted_name -> wrap_then import hoisted_name
153+
| Some hoisted_name -> wrap_then import (ml_export_name hoisted_name)
153154
| None ->
154155
Location.raise_errorf ~loc
155156
"Invalid argument: Dynamic import requires a module or module \

tests/tests/src/import2.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ let b = A;
88

99
let c = import("./export_keyword.mjs").then(m => m.$$case);
1010

11+
let d = import("./hoisted_function_attr.mjs").then(m => m.Operator$$plus);
12+
1113
export {
1214
a,
1315
b,
1416
c,
17+
d,
1518
}
1619
/* b Not a pure module */

tests/tests/src/import2.res

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@ let b = Import_external.makeA
44
/* the imported export name goes through JS identifier conversion, matching
55
the emitted export (`case` is exported as `$$case`) */
66
let c = import(Export_keyword.case)
7+
8+
/* hoisted export names also go through JS identifier conversion:
9+
the cmj stores the raw flattened name (Operator$+), the module exports
10+
the converted one (Operator$$plus) */
11+
let d = import(Hoisted_function_attr.Operator.\"+")

0 commit comments

Comments
 (0)