Pass the "external module" info along passes

This commit is contained in:
Louis Gesbert 2024-05-27 11:26:14 +02:00
parent 709b51beb6
commit f04e889173
17 changed files with 94 additions and 64 deletions

View File

@ -261,7 +261,7 @@ type modul = {
} }
type program = { type program = {
program_module_name : (ModuleName.t * Hash.t) option; program_module_name : (ModuleName.t * module_intf_id) option;
program_ctx : decl_ctx; program_ctx : decl_ctx;
program_modules : modul ModuleName.Map.t; program_modules : modul ModuleName.Map.t;
program_root : modul; program_root : modul;

View File

@ -139,7 +139,7 @@ type modul = {
} }
type program = { type program = {
program_module_name : (ModuleName.t * Hash.t) option; program_module_name : (ModuleName.t * module_intf_id) option;
program_ctx : decl_ctx; program_ctx : decl_ctx;
program_modules : modul ModuleName.Map.t; program_modules : modul ModuleName.Map.t;
(** Contains all submodules of the program, in a flattened structure *) (** Contains all submodules of the program, in a flattened structure *)

View File

@ -1742,12 +1742,14 @@ let translate_program (ctxt : Name_resolution.context) (surface : S.program) :
Ident.Map.fold Ident.Map.fold
(fun _ m acc -> (fun _ m acc ->
let mctx = ModuleName.Map.find m ctxt.Name_resolution.modules in let mctx = ModuleName.Map.find m ctxt.Name_resolution.modules in
let sub = aux mctx in let deps = aux mctx in
let mhash = snd (ModuleName.Map.find m program_modules) in let hash = snd (ModuleName.Map.find m program_modules) in
ModuleName.Map.add m (mhash, sub) acc) ModuleName.Map.add m
{ deps; intf_id = { hash; is_external = mctx.is_external } }
acc)
mctx.used_modules ModuleName.Map.empty mctx.used_modules ModuleName.Map.empty
in in
M subs subs
in in
aux ctxt.local aux ctxt.local
in in
@ -1772,12 +1774,12 @@ let translate_program (ctxt : Name_resolution.context) (surface : S.program) :
} }
in in
let program_module_name = let program_module_name =
surface.Surface.Ast.program_module_name surface.Surface.Ast.program_module
|> Option.map |> Option.map
@@ fun id -> @@ fun { Surface.Ast.module_name; module_external } ->
let mname = ModuleName.fresh id in let mname = ModuleName.fresh module_name in
let hash_placeholder = Hash.raw 0 in let hash_placeholder = Hash.raw 0 in
mname, hash_placeholder mname, { hash = hash_placeholder; is_external = module_external }
in in
let desugared = let desugared =
{ {
@ -1816,6 +1818,10 @@ let translate_program (ctxt : Name_resolution.context) (surface : S.program) :
Ast.program_module_name = Ast.program_module_name =
(desugared.Ast.program_module_name (desugared.Ast.program_module_name
|> Option.map |> Option.map
@@ fun (mname, _) -> @@ fun (mname, intf_id) ->
mname, Ast.Hash.module_binding mname desugared.Ast.program_root); ( mname,
{
intf_id with
hash = Ast.Hash.module_binding mname desugared.Ast.program_root;
} ));
} }

View File

@ -78,6 +78,7 @@ type module_context = {
between different enums *) between different enums *)
topdefs : TopdefName.t Ident.Map.t; (** Global definitions *) topdefs : TopdefName.t Ident.Map.t; (** Global definitions *)
used_modules : ModuleName.t Ident.Map.t; used_modules : ModuleName.t Ident.Map.t;
is_external : bool;
} }
(** Context for name resolution, valid within a given module *) (** Context for name resolution, valid within a given module *)
@ -770,8 +771,10 @@ let rec process_law_structure
process_code_block process_code_block
(process_item ~visibility:(if is_meta then Public else Private)) (process_item ~visibility:(if is_meta then Public else Private))
ctxt block ctxt block
| Surface.Ast.ModuleDef (_, is_external) ->
{ ctxt with local = { ctxt.local with is_external } }
| Surface.Ast.LawInclude _ | Surface.Ast.LawText _ -> ctxt | Surface.Ast.LawInclude _ | Surface.Ast.LawText _ -> ctxt
| Surface.Ast.ModuleDef _ | Surface.Ast.ModuleUse _ -> ctxt | Surface.Ast.ModuleUse _ -> ctxt
(** {1 Scope uses pass} *) (** {1 Scope uses pass} *)
@ -979,6 +982,7 @@ let empty_module_ctxt =
constructor_idmap = Ident.Map.empty; constructor_idmap = Ident.Map.empty;
topdefs = Ident.Map.empty; topdefs = Ident.Map.empty;
used_modules = Ident.Map.empty; used_modules = Ident.Map.empty;
is_external = false;
} }
let empty_ctxt = let empty_ctxt =
@ -1007,7 +1011,13 @@ let form_context (surface, mod_uses) surface_modules : context =
let ctxt = let ctxt =
{ {
ctxt with ctxt with
local = { ctxt.local with used_modules = mod_uses; path = [m] }; local =
{
ctxt.local with
used_modules = mod_uses;
path = [m];
is_external = intf.Surface.Ast.intf_modname.module_external;
};
} }
in in
let ctxt = let ctxt =

View File

@ -83,6 +83,7 @@ type module_context = {
topdefs : TopdefName.t Ident.Map.t; (** Global definitions *) topdefs : TopdefName.t Ident.Map.t; (** Global definitions *)
used_modules : ModuleName.t Ident.Map.t; used_modules : ModuleName.t Ident.Map.t;
(** Module aliases and the modules they point to *) (** Module aliases and the modules they point to *)
is_external : bool;
} }
(** Context for name resolution, valid within a given module *) (** Context for name resolution, valid within a given module *)

View File

@ -93,7 +93,7 @@ let load_module_interfaces
Surface.Parser_driver.load_interface ?default_module_name Surface.Parser_driver.load_interface ?default_module_name
(Global.FileName f) (Global.FileName f)
in in
let modname = ModuleName.fresh intf.intf_modname in let modname = ModuleName.fresh intf.intf_modname.module_name in
let seen = File.Map.add f None seen in let seen = File.Map.add f None seen in
let seen, sub_use_map = let seen, sub_use_map =
aux aux
@ -107,9 +107,9 @@ let load_module_interfaces
(seen, Ident.Map.empty) uses (seen, Ident.Map.empty) uses
in in
let seen = let seen =
match program.Surface.Ast.program_module_name with match program.Surface.Ast.program_module with
| Some m -> | Some m ->
let file = Pos.get_file (Mark.get m) in let file = Pos.get_file (Mark.get m.module_name) in
File.Map.singleton file None File.Map.singleton file None
| None -> File.Map.empty | None -> File.Map.empty
in in
@ -1022,7 +1022,7 @@ module Commands = struct
let prg = let prg =
Surface.Ast. Surface.Ast.
{ {
program_module_name = None; program_module = None;
program_items = []; program_items = [];
program_source_files = []; program_source_files = [];
program_used_modules = program_used_modules =
@ -1050,7 +1050,7 @@ module Commands = struct
in in
Format.open_hbox (); Format.open_hbox ();
Format.pp_print_list ~pp_sep:Format.pp_print_space Format.pp_print_list ~pp_sep:Format.pp_print_space
(fun ppf (m, _h) -> (fun ppf (m, _) ->
let f = Pos.get_file (Mark.get (ModuleName.get_info m)) in let f = Pos.get_file (Mark.get (ModuleName.get_info m)) in
let f = let f =
match prefix with match prefix with

View File

@ -718,14 +718,15 @@ let commands = if commands = [] then entry_scopes else commands
let check_and_reexport_used_modules fmt ~hashf modules = let check_and_reexport_used_modules fmt ~hashf modules =
List.iter List.iter
(fun (m, hash) -> (fun (m, intf_id) ->
Format.fprintf fmt Format.fprintf fmt
"@[<hv 2>let () =@ @[<hov 2>match Runtime_ocaml.Runtime.check_module \ "@[<hv 2>let () =@ @[<hov 2>match Runtime_ocaml.Runtime.check_module \
%S \"%a\"@ with@]@,\ %S \"%a\"@ with@]@,\
| Ok () -> ()@,\ | Ok () -> ()@,\
@[<hv 2>| Error h -> failwith \"Hash mismatch for module %a, it may \ @[<hv 2>| Error h -> failwith \"Hash mismatch for module %a, it may \
need recompiling\"@]@]@," need recompiling\"@]@]@,"
(ModuleName.to_string m) Hash.format (hashf hash) ModuleName.format m; (ModuleName.to_string m) Hash.format (hashf intf_id.hash)
ModuleName.format m;
Format.fprintf fmt "@[<hv 2>module %a@ = %a@]@," ModuleName.format m Format.fprintf fmt "@[<hv 2>module %a@ = %a@]@," ModuleName.format m
ModuleName.format m) ModuleName.format m)
modules modules
@ -788,8 +789,8 @@ let format_program
Format.pp_print_cut fmt (); Format.pp_print_cut fmt ();
let () = let () =
match p.module_name, exec_scope with match p.module_name, exec_scope with
| Some (modname, hash), None -> | Some (modname, intf_id), None ->
format_module_registration fmt bnd modname (hashf hash) format_module_registration fmt bnd modname (hashf intf_id.hash)
| None, Some scope_name -> | None, Some scope_name ->
let scope_body = Program.get_scope_body p scope_name in let scope_body = Program.get_scope_body p scope_name in
format_scope_exec p.decl_ctx fmt bnd scope_name scope_body format_scope_exec p.decl_ctx fmt bnd scope_name scope_body

View File

@ -121,5 +121,5 @@ type ctx = { decl_ctx : decl_ctx; modules : VarName.t ModuleName.Map.t }
type program = { type program = {
ctx : ctx; ctx : ctx;
code_items : code_item list; code_items : code_item list;
module_name : (ModuleName.t * Hash.t) option; module_name : (ModuleName.t * module_intf_id) option;
} }

View File

@ -659,7 +659,7 @@ let translate_program ~(config : translation_config) (p : 'm L.program) :
A.program = A.program =
let modules = let modules =
List.fold_left List.fold_left
(fun acc (m, _hash) -> (fun acc (m, _) ->
let vname = Mark.map (( ^ ) "Module_") (ModuleName.get_info m) in let vname = Mark.map (( ^ ) "Module_") (ModuleName.get_info m) in
(* The "Module_" prefix is a workaround name clashes for same-name (* The "Module_" prefix is a workaround name clashes for same-name
structs and modules, Python in particular mixes everything in one structs and modules, Python in particular mixes everything in one

View File

@ -67,7 +67,7 @@ type 'm scope_decl = {
} }
type 'm program = { type 'm program = {
program_module_name : (ModuleName.t * Hash.t) option; program_module_name : (ModuleName.t * module_intf_id) option;
program_ctx : decl_ctx; program_ctx : decl_ctx;
program_modules : nil scope_decl Mark.pos ScopeName.Map.t ModuleName.Map.t; program_modules : nil scope_decl Mark.pos ScopeName.Map.t ModuleName.Map.t;
program_scopes : 'm scope_decl Mark.pos ScopeName.Map.t; program_scopes : 'm scope_decl Mark.pos ScopeName.Map.t;

View File

@ -63,7 +63,7 @@ type 'm scope_decl = {
} }
type 'm program = { type 'm program = {
program_module_name : (ModuleName.t * Hash.t) option; program_module_name : (ModuleName.t * module_intf_id) option;
program_ctx : decl_ctx; program_ctx : decl_ctx;
program_modules : nil scope_decl Mark.pos ScopeName.Map.t ModuleName.Map.t; program_modules : nil scope_decl Mark.pos ScopeName.Map.t ModuleName.Map.t;
(* Using [nil] here ensure that program interfaces don't contain any (* Using [nil] here ensure that program interfaces don't contain any

View File

@ -668,9 +668,12 @@ type scope_info = {
out_struct_fields : StructField.t ScopeVar.Map.t; out_struct_fields : StructField.t ScopeVar.Map.t;
} }
type module_intf_id = { hash : Hash.t; is_external : bool }
type module_tree_node = { deps : module_tree; intf_id : module_intf_id }
and module_tree = module_tree_node ModuleName.Map.t
(** In practice, this is a DAG: beware of repeated names *) (** In practice, this is a DAG: beware of repeated names *)
type module_tree = M of (Hash.t * module_tree) ModuleName.Map.t
[@@caml.unboxed]
type visibility = Private | Public type visibility = Private | Public
@ -691,5 +694,5 @@ type 'e program = {
decl_ctx : decl_ctx; decl_ctx : decl_ctx;
code_items : 'e code_item_list; code_items : 'e code_item_list;
lang : Global.backend_lang; lang : Global.backend_lang;
module_name : (ModuleName.t * Hash.t) option; module_name : (ModuleName.t * module_intf_id) option;
} }

View File

@ -1156,16 +1156,16 @@ let interpret_program_dcalc p s : (Uid.MarkedString.info * ('a, 'm) gexpr) list
let evaluate_expr ctx lang e = evaluate_expr ctx lang (addcustom e) let evaluate_expr ctx lang e = evaluate_expr ctx lang (addcustom e)
let load_runtime_modules ~hashf prg = let load_runtime_modules ~hashf prg =
let load (m, mod_hash) = let load (mname, intf_id) =
let hash = hashf mod_hash in let hash = hashf intf_id.hash in
let obj_file = let obj_file =
Dynlink.adapt_filename Dynlink.adapt_filename
File.(Pos.get_file (Mark.get (ModuleName.get_info m)) -.- "cmo") File.(Pos.get_file (Mark.get (ModuleName.get_info mname)) -.- "cmo")
in in
(if not (Sys.file_exists obj_file) then (if not (Sys.file_exists obj_file) then
Message.error Message.error
~pos_msg:(fun ppf -> Format.pp_print_string ppf "Module defined here") ~pos_msg:(fun ppf -> Format.pp_print_string ppf "Module defined here")
~pos:(Mark.get (ModuleName.get_info m)) ~pos:(Mark.get (ModuleName.get_info mname))
"Compiled OCaml object %a@ not@ found.@ Make sure it has been \ "Compiled OCaml object %a@ not@ found.@ Make sure it has been \
suitably compiled." suitably compiled."
File.format obj_file File.format obj_file
@ -1177,13 +1177,13 @@ let load_runtime_modules ~hashf prg =
File.format obj_file Format.pp_print_text File.format obj_file Format.pp_print_text
(Dynlink.error_message dl_err)); (Dynlink.error_message dl_err));
match match
Runtime.check_module (ModuleName.to_string m) (Hash.to_string hash) Runtime.check_module (ModuleName.to_string mname) (Hash.to_string hash)
with with
| Ok () -> () | Ok () -> ()
| Error bad_hash -> | Error bad_hash ->
Message.debug Message.debug
"Module hash mismatch for %a:@ @[<v>Expected: %a@,Found: %a@]" "Module hash mismatch for %a:@ @[<v>Expected: %a@,Found: %a@]"
ModuleName.format m Hash.format hash ModuleName.format mname Hash.format hash
(fun ppf h -> (fun ppf h ->
try Hash.format ppf (Hash.of_string h) try Hash.format ppf (Hash.of_string h)
with Failure _ -> Format.pp_print_string ppf "<invalid>") with Failure _ -> Format.pp_print_string ppf "<invalid>")
@ -1191,16 +1191,16 @@ let load_runtime_modules ~hashf prg =
Message.error Message.error
"Module %a@ needs@ recompiling:@ %a@ was@ likely@ compiled@ from@ an@ \ "Module %a@ needs@ recompiling:@ %a@ was@ likely@ compiled@ from@ an@ \
older@ version@ or@ with@ incompatible@ flags." older@ version@ or@ with@ incompatible@ flags."
ModuleName.format m File.format obj_file ModuleName.format mname File.format obj_file
| exception Not_found -> | exception Not_found ->
Message.error Message.error
"Module %a@ was loaded from file %a but did not register properly, \ "Module %a@ was loaded from file %a but did not register properly, \
there is something wrong in its code." there is something wrong in its code."
ModuleName.format m File.format obj_file ModuleName.format mname File.format obj_file
in in
let modules_list_topo = Program.modules_to_list prg.decl_ctx.ctx_modules in let modules_list_topo = Program.modules_to_list prg.decl_ctx.ctx_modules in
if modules_list_topo <> [] then if modules_list_topo <> [] then
Message.debug "Loading shared modules... %a" Message.debug "Loading shared modules... %a"
(Format.pp_print_list ~pp_sep:Format.pp_print_space ModuleName.format) (Format.pp_print_list ~pp_sep:Format.pp_print_space ModuleName.format)
(List.map fst modules_list_topo); (List.map (fun (m, _) -> m) modules_list_topo);
List.iter load modules_list_topo List.iter load modules_list_topo

View File

@ -58,7 +58,7 @@ let empty_ctx =
ctx_struct_fields = Ident.Map.empty; ctx_struct_fields = Ident.Map.empty;
ctx_enum_constrs = Ident.Map.empty; ctx_enum_constrs = Ident.Map.empty;
ctx_scope_index = Ident.Map.empty; ctx_scope_index = Ident.Map.empty;
ctx_modules = M ModuleName.Map.empty; ctx_modules = ModuleName.Map.empty;
} }
let get_scope_body { code_items; _ } scope = let get_scope_body { code_items; _ } scope =
@ -87,11 +87,11 @@ let to_expr p main_scope =
res res
let modules_to_list (mt : module_tree) = let modules_to_list (mt : module_tree) =
let rec aux acc (M mtree) = let rec aux acc mtree =
ModuleName.Map.fold ModuleName.Map.fold
(fun mname (subhash, sub) acc -> (fun mname mnode acc ->
if List.exists (fun (m, _) -> ModuleName.equal m mname) acc then acc if List.exists (fun (m, _) -> ModuleName.equal m mname) acc then acc
else (mname, subhash) :: aux acc sub) else (mname, mnode.intf_id) :: aux acc mnode.deps)
mtree acc mtree acc
in in
List.rev (aux [] mt) List.rev (aux [] mt)

View File

@ -15,7 +15,6 @@
License for the specific language governing permissions and limitations under License for the specific language governing permissions and limitations under
the License. *) the License. *)
open Catala_utils
open Definitions open Definitions
(** {2 Program declaration context helpers} *) (** {2 Program declaration context helpers} *)
@ -54,5 +53,6 @@ val to_expr : ((_ any, _) gexpr as 'e) program -> ScopeName.t -> 'e boxed
val find_scope : ScopeName.t -> 'e code_item_list -> 'e scope_body val find_scope : ScopeName.t -> 'e code_item_list -> 'e scope_body
val modules_to_list : module_tree -> (ModuleName.t * Hash.t) list val modules_to_list : module_tree -> (ModuleName.t * module_intf_id) list
(** Returns a list of used modules, in topological order *) (** Returns a list of used modules, in topological order ; the boolean indicates
if the module is external *)

View File

@ -318,7 +318,7 @@ and law_structure =
| CodeBlock of code_block * source_repr * bool (* Metadata if true *) | CodeBlock of code_block * source_repr * bool (* Metadata if true *)
and interface = { and interface = {
intf_modname : uident Mark.pos; intf_modname : program_module;
intf_code : code_block; intf_code : code_block;
(** Invariant: an interface shall only contain [*Decl] elements, or (** Invariant: an interface shall only contain [*Decl] elements, or
[Topdef] elements with [topdef_expr = None] *) [Topdef] elements with [topdef_expr = None] *)
@ -330,8 +330,10 @@ and module_use = {
mod_use_alias : uident Mark.pos; mod_use_alias : uident Mark.pos;
} }
and program_module = { module_name : uident Mark.pos; module_external : bool }
and program = { and program = {
program_module_name : uident Mark.pos option; program_module : program_module option;
program_items : law_structure list; program_items : law_structure list;
program_source_files : (string[@opaque]) list; program_source_files : (string[@opaque]) list;
program_used_modules : module_use list; program_used_modules : module_use list;

View File

@ -259,18 +259,21 @@ and expand_includes (source_file : string) (commands : Ast.law_structure list) :
List.fold_left List.fold_left
(fun acc command -> (fun acc command ->
let join_module_names name_opt = let join_module_names name_opt =
match acc.Ast.program_module_name, name_opt with match acc.Ast.program_module, name_opt with
| opt, None | None, opt -> opt | opt, None | None, opt -> opt
| Some id1, Some id2 -> | Some id1, Some id2 ->
Message.error Message.error
~extra_pos:["", Mark.get id1; "", Mark.get id2] ~extra_pos:
["", Mark.get id1.module_name; "", Mark.get id2.module_name]
"Multiple definitions of the module name" "Multiple definitions of the module name"
in in
match command with match command with
| Ast.ModuleDef (id, _) -> | Ast.ModuleDef (id, is_external) ->
{ {
acc with acc with
Ast.program_module_name = join_module_names (Some id); Ast.program_module =
join_module_names
(Some { module_name = id; module_external = is_external });
Ast.program_items = command :: acc.Ast.program_items; Ast.program_items = command :: acc.Ast.program_items;
} }
| Ast.ModuleUse (mod_use_name, alias) -> | Ast.ModuleUse (mod_use_name, alias) ->
@ -288,22 +291,22 @@ and expand_includes (source_file : string) (commands : Ast.law_structure list) :
@@ fun lexbuf -> @@ fun lexbuf ->
let includ_program = parse_source lexbuf in let includ_program = parse_source lexbuf in
let () = let () =
includ_program.Ast.program_module_name includ_program.Ast.program_module
|> Option.iter |> Option.iter
@@ fun id -> @@ fun id ->
Message.error Message.error
~extra_pos: ~extra_pos:
[ [
"File include", Mark.get inc_file; "File include", Mark.get inc_file;
"Module declaration", Mark.get id; "Module declaration", Mark.get id.Ast.module_name;
] ]
"A file that declares a module cannot be used through the raw \ "A file that declares a module cannot be used through the raw \
'@{<yellow>> Include@}'@ directive.@ You should use it as a \ '@{<yellow>> Include@}'@ directive.@ You should use it as a \
module with@ '@{<yellow>> Use @{<blue>%s@}@}'@ instead." module with@ '@{<yellow>> Use @{<blue>%s@}@}'@ instead."
(Mark.remove id) (Mark.remove id.Ast.module_name)
in in
{ {
Ast.program_module_name = acc.program_module_name; Ast.program_module = acc.program_module;
Ast.program_source_files = Ast.program_source_files =
List.rev_append includ_program.program_source_files List.rev_append includ_program.program_source_files
acc.Ast.program_source_files; acc.Ast.program_source_files;
@ -316,7 +319,7 @@ and expand_includes (source_file : string) (commands : Ast.law_structure list) :
} }
| Ast.LawHeading (heading, commands') -> | Ast.LawHeading (heading, commands') ->
let { let {
Ast.program_module_name; Ast.program_module;
Ast.program_items = commands'; Ast.program_items = commands';
Ast.program_source_files = new_sources; Ast.program_source_files = new_sources;
Ast.program_used_modules = new_used_modules; Ast.program_used_modules = new_used_modules;
@ -325,7 +328,7 @@ and expand_includes (source_file : string) (commands : Ast.law_structure list) :
expand_includes source_file commands' expand_includes source_file commands'
in in
{ {
Ast.program_module_name = join_module_names program_module_name; Ast.program_module = join_module_names program_module;
Ast.program_source_files = Ast.program_source_files =
List.rev_append new_sources acc.Ast.program_source_files; List.rev_append new_sources acc.Ast.program_source_files;
Ast.program_items = Ast.program_items =
@ -336,7 +339,7 @@ and expand_includes (source_file : string) (commands : Ast.law_structure list) :
} }
| i -> { acc with Ast.program_items = i :: acc.Ast.program_items }) | i -> { acc with Ast.program_items = i :: acc.Ast.program_items })
{ {
Ast.program_module_name = None; Ast.program_module = None;
Ast.program_source_files = []; Ast.program_source_files = [];
Ast.program_items = []; Ast.program_items = [];
Ast.program_used_modules = []; Ast.program_used_modules = [];
@ -346,7 +349,7 @@ and expand_includes (source_file : string) (commands : Ast.law_structure list) :
in in
{ {
Ast.program_lang = language; Ast.program_lang = language;
Ast.program_module_name = rprg.Ast.program_module_name; Ast.program_module = rprg.Ast.program_module;
Ast.program_source_files = List.rev rprg.Ast.program_source_files; Ast.program_source_files = List.rev rprg.Ast.program_source_files;
Ast.program_items = List.rev rprg.Ast.program_items; Ast.program_items = List.rev rprg.Ast.program_items;
Ast.program_used_modules = List.rev rprg.Ast.program_used_modules; Ast.program_used_modules = List.rev rprg.Ast.program_used_modules;
@ -396,8 +399,8 @@ let with_sedlex_source source_file f =
f lexbuf f lexbuf
let check_modname program source_file = let check_modname program source_file =
match program.Ast.program_module_name, source_file with match program.Ast.program_module, source_file with
| ( Some (mname, pos), | ( Some { module_name = mname, pos; _ },
(Global.FileName file | Global.Contents (_, file) | Global.Stdin file) ) (Global.FileName file | Global.Contents (_, file) | Global.Stdin file) )
when not File.(equal mname Filename.(remove_extension (basename file))) -> when not File.(equal mname Filename.(remove_extension (basename file))) ->
Message.error ~pos Message.error ~pos
@ -413,10 +416,14 @@ let load_interface ?default_module_name source_file =
let program = with_sedlex_source source_file parse_source in let program = with_sedlex_source source_file parse_source in
check_modname program source_file; check_modname program source_file;
let modname = let modname =
match program.Ast.program_module_name, default_module_name with match program.Ast.program_module, default_module_name with
| Some mname, _ -> mname | Some mname, _ -> mname
| None, Some n -> | None, Some n ->
n, Pos.from_info (Global.input_src_file source_file) 0 0 0 0 {
module_name =
n, Pos.from_info (Global.input_src_file source_file) 0 0 0 0;
module_external = false;
}
| None, None -> | None, None ->
Message.error Message.error
"%a doesn't define a module name. It should contain a '@{<cyan>> \ "%a doesn't define a module name. It should contain a '@{<cyan>> \