Mercury Bugs - mercury
View Issue Details
0000489mercuryBugpublic2020-01-09 14:312020-01-15 19:54
Reporterwangp 
Assigned Towangp 
PrioritynormalSeverityminorReproducibilityalways
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0000489: mmc --make gets confused by source files with same name as standard library module
Descriptionmmc --make gets confused by a source file in the current directory that matches the name of a standard library module, e.g. in the attached test case, lexer.m contains the sub-module `test.lexer'.


Test 1 - tries to make lexer.mih from lexer.m
---------------------------------------------
% mmc -s hlc.gc -m test -v
Making Mercury/mihs/lexer.mih
Invoking self `mmc [...] lexer' <-- not test.lexer
...
lexer.m:010: In module `lexer': error:
lexer.m:010: the absence of an `:- import_module' or `:- use_module'
lexer.m:010: declaration for `test' prevents access to the `:- import_module'
lexer.m:010: declaration for its child module `test.other'.



Test 2 - likewise for .opt files
--------------------------------
% mmc -s asm_fast.gc --intermod-opt -m test
Making Mercury/opts/test.opt
Making Mercury/opts/test.lexer.opt
Making Mercury/opts/test.other.opt
Making Mercury/opts/lexer.opt
lexer.m:010: In module `lexer': error:
lexer.m:010: the absence of an `:- import_module' or `:- use_module'
lexer.m:010: declaration for `test' prevents access to the `:- import_module'
lexer.m:010: declaration for its child module `test.other'.
** Error making `Mercury/opts/lexer.opt'.
TagsNo tags attached.
Attached Filesgz mmc_make_source_filename_confusion.tar.gz (10,240) 2020-01-09 14:31
https://bugs.mercurylang.org/file_download.php?file_id=294&type=bug

Notes
(0001056)
wangp   
2020-01-09 16:23   
Notes:

do_get_module_dependencies assumes the SourceFileName returned by module_name_to_file_name can only be the source file for the given ModuleName, so the solution may require reading the `:- module` item before proceeding with make_module_dependencies.

If a source file map is present, it may be helpful to rule out the default source file name: if "lexer.m" is mapped to `test.lexer' then it cannot be the source file for module `lexer'.
(0001057)
zs   
2020-01-09 21:18   
The documentation of the -f option states:

"Output the module name to file name mapping for the list of source files given as non-option arguments to ‘mmc’ to Mercury.modules. This must be done before ‘mmc --generate-dependencies’ if there are any modules for which the file name does not match the module name. If there are no such modules the mapping need not be generated."

So if there is NO source file map present, mmc --make is *allowed* to assume that lexer.m
contains a module named "lexer", and *not* a module named "test.lexer".

The error message it generates could of course be improved, e.g. by drawing attention
to this fact, but in this case, I don't think the compiler is confused; more like it is misled,
which is not its fault.

Or am I missing something?
(0001058)
wangp   
2020-01-09 21:53   
The section on separate sub-modules states:

"For a module named ‘foo.bar.baz’, The University of Melbourne Mercury implementation requires the source to be located in a file named foo.bar.baz.m, bar.baz.m, or baz.m."
(0001059)
zs   
2020-01-11 18:57   
We have two endpoints of a spectrum where the answer to the question
"should you have to run mmc -f *.m?" is clear-cut.

Endpoint A: every module is in a file whose name is the fully qualified module name.

Endpoint B: every module is a file whose name has no relationship to the module name.

It is clear that at Endpoint A, the answer is "no", while at endpoint B, it is "yes".

At the moment, the answer is also "no" if every module is in a file whose name is either
the fully qualified module name *or a subsequence* of the fully qualified sequence.
The code that implements that check, in read_first_module_decl in parse_module.m,
already has an XXX, on code that accepts module A.B.C not just as being in file A.C.m,
but also as being in file A.D.B.C.m. And your bug report demonstrates another problem
with the existing code.

There are two ways to fix this bug. One is to change this code to require the expected
module name and the actual module name to be identical. Without mmc -f, this would mean
that the answer is "yes" everywhere except at Endpoint A. This would be a change from
the current situation, and would require a change in the manual, but the rule would be simple
and easy to obey: always use mmc -f. The other possible approach to the fix, which I read
your initial note as supporting, would require the compiler to look for a known module name
(test.lexer) in one file name after another (all being subsequences of the fully qualified
module name) until it found one whose :- module declaration had the looked-for name.
(In this case, we would need to look in just two places, test.lexer.m and lexer.m, but in
general, the list could be a lot longer). In effect, this approach would require mmc
--generate-dependencies to do a significant part of the job of mmc -f. I, for one,
would find that solution more complex than necessary, from the user's point of view
as well as from an implementor's.
(0001060)
wangp   
2020-01-12 12:08   
The current rules have always seemed oddly lax to me, and I think most larger Mercury project would be using mmc -f for one reason or another, so I have no problem with changing the compiler's behaviour such that modules must be in a file whose names is the fully qualified module name (.m), or else listed in the source file map.
(0001061)
zs   
2020-01-12 12:14   
In that case, I will post a proposed diff for doing this later today.

I also propose that this change be part of 20.01. Any objections?
(0001062)
juliensf   
2020-01-12 12:55   
There are definitely some larger Mercury projects that do *not* use mmc -f; Opturion's runtime library is an example. That's not an objection since the fix is trivial, but the proposed change is going to break some things.

No objections to including this in 20.01 for me.
(0001063)
zs   
2020-01-12 22:28   
Fix committed 2020 jan 12.
(0001064)
wangp   
2020-01-13 10:49   
A file listed in the source file map needs to be not returned as the source file for some different module. (assigning to self; Mantis only has a "Request feedback" button)

Issue History
2020-01-09 14:31wangpNew Issue
2020-01-09 14:31wangpFile Added: mmc_make_source_filename_confusion.tar.gz
2020-01-09 16:23wangpNote Added: 0001056
2020-01-09 21:18zsNote Added: 0001057
2020-01-09 21:53wangpNote Added: 0001058
2020-01-11 18:57zsNote Added: 0001059
2020-01-12 12:08wangpNote Added: 0001060
2020-01-12 12:14zsNote Added: 0001061
2020-01-12 12:55juliensfNote Added: 0001062
2020-01-12 22:28zsAssigned To => zs
2020-01-12 22:28zsStatusnew => resolved
2020-01-12 22:28zsResolutionopen => fixed
2020-01-12 22:28zsNote Added: 0001063
2020-01-13 10:49wangpAssigned Tozs => wangp
2020-01-13 10:49wangpStatusresolved => feedback
2020-01-13 10:49wangpResolutionfixed => reopened
2020-01-13 10:49wangpNote Added: 0001064
2020-01-15 19:54wangpStatusfeedback => resolved
2020-01-15 19:54wangpResolutionreopened => fixed