[m-rev.] for post-commit review: start on diagnostic for missing interface files

Julien Fischer jfischer at opturion.com
Sun Jul 5 15:13:00 AEST 2026


On Fri, 3 Jul 2026 at 06:47, Zoltan Somogyi <zoltan.somogyi at runbox.com> wrote:

> A start on diagnostics for missing interface files ...
>
> ... for command lines such as "mmc a.m b.m c.m".

...

> diff --git a/compiler/error_spec.m b/compiler/error_spec.m
> index b64e9e2f7..5497e0b6a 100644
> --- a/compiler/error_spec.m
> +++ b/compiler/error_spec.m
> @@ -25,6 +25,7 @@
>  :- import_module mdbcomp.
>  :- import_module mdbcomp.prim_data.
>  :- import_module mdbcomp.sym_name.
> +:- import_module parse_tree.file_names.
>  :- import_module parse_tree.prog_data.
>  :- import_module parse_tree.var_table.
>
> @@ -153,12 +154,24 @@
>      ;       phase_check_libs
>      ;       phase_make_target
>      ;       phase_make_int
> -    ;       phase_find_files(string)
> -            % The name of the file we tried to find, but failed.
> +    ;       phase_find_files(string, maybe(module_file_id))
> +            % The first argument is name of the file we tried but failed
> +            % to open for reading, possibly after a search.
>              % The intention is to make it possible to use this info
>              % to replace several messages that all report failures
>              % to find files with a single, shorter message to that effect.
> +            %
> +            % If the file we wanted to open for reading is module.ext
> +            % for some module name and extension, then we record this fact
> +            % in the second argument. (Note that source files do not have
> +            % a representation in the ext type.)
>      ;       phase_read_files
> +            % We use this phase to report both failed attempts to read files
> +            % after having opened them, and both parse errors and semantic
> +            % errors that were discovered while reading the file.

That's awkwardly worded, I suggest:

   We use this phase to report failed attempts to read files, as well as
   parse errors and semantic errors discovered while reading the file.


> +    ;       phase_write_files
> +            % We use this phase to report failed attempts to open files
> +            % for writing.
>      ;       phase_module_name
>      ;       phase_t2pt              % short for "term to parse tree"
>      % The "tim" in the next few phase names is short for "type inst mode".

...


> diff --git a/compiler/mercury_compile_main.m b/compiler/mercury_compile_main.m
> index 9c7ca8154..4e9619974 100644
> --- a/compiler/mercury_compile_main.m
> +++ b/compiler/mercury_compile_main.m
> @@ -438,26 +438,53 @@ do_op_mode_args(ProgressStream, ErrorStream, Globals, OpModeArgs,
>          % Print all remaining module-specific error_specs,
>          % as well as the ones generated just above.
>          write_error_specs(ErrorStream, Globals, !.Specs, !IO),
> -        maybe_print_delayed_error_messages(ErrorStream, Globals, !IO),
> -
>          io.get_exit_status(ExitStatus, !IO),
> -        ( if ExitStatus = 0 then
> +        ( if
> +            OpModeArgs = opma_augment(opmau_front_and_middle(
> +                opfam_target_object_and_executable)),
>              ModulesToLink = cord.list(ModulesToLinkCord),
> -            ExtraObjFiles = cord.list(ExtraObjFilesCord),
> +            ModulesToLink = [FirstModule | _]
> +        then
>              ( if
> -                OpModeArgs = opma_augment(opmau_front_and_middle(
> -                    opfam_target_object_and_executable)),
> -                ModulesToLink = [FirstModule | _]
> +                ExitStatus = 0
>              then
> +                ExtraObjFiles = cord.list(ExtraObjFilesCord),
>                  generate_executable(ProgressStream, ErrorStream, Globals,
>                      InvokedByMmcMake, Params,
>                      FirstModule, ModulesToLink, ExtraObjFiles, !IO)
> +            else if
> +                all_args_end_in_dot_m(Args) = yes,
> +                % XXX We should test not only !.Specs, but ALL the
> +                % error_specs we have already printed *before* the call
> +                % to write_error_specs above.
> +                could_not_read_some_int_file(!.Specs) = yes
> +            then
> +                % Should we add the condition that all words in Args
> +                % end with ".m"?
> +                Pieces = [words("You can invoke the Mercury compiler"),
> +                    words("with a list of Mercury source files to compile")] ++
> +                    color_as_incorrect([words("only")]) ++
> +                    [words("if you have previously built"),
> +                    words("all the interface files they need, and,"),
> +                    words("if intermodule is enabled,"),

s/intermodule/intermodule optimization/

We could just look to see if intermodule optimization has been enabled by
the user and only include that part of the message if it is.

> +                    words("all the optimization interface files they need."),
> +                    words("Since arranging all this by hand is tedious,"),
> +                    words("you should consider using either"),
> +                    quote("mmc --make"), words("or"), quote("mmake"),
> +                    words("as a build system."), nl],
> +                % The severity option and phase are not appropriate, but
> +                % (a) we do not have an appropriate option or phase, and
> +                % (b) we do not need them.
> +                Severity = severity_informational(warn_dodgy_simple_code),
> +                Spec = no_ctxt_spec($pred, Severity, phase_style, Pieces),
> +                !:Specs = [Spec | !.Specs]

That looks fine otherwise.

Julien.


More information about the reviews mailing list