New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Turn warning 31 (Module_linked_twice) into a hard error #11635
Conversation
cc @gasche |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the issues linked, there seems to be consensus for making this change, and I think the code change does what's intended.
I tested the behavior of this change with the script at the bottom of this comment, and it works fine but I observe error messages that are a bit worse:
4.14:
native:
File "_none_", line 1:
Error: Files 2/a.cmx and 1/a.cmx both define a module named A
bytecode:
File "2/a.cmo", line 1:
Error (warning 31 [module-linked-twice]): files 2/a.cmo and 1/a.cmo both define a module named A
File "2/b.cmo", line 1:
Error (warning 31 [module-linked-twice]): files 2/b.cmo and 1/b.cmo both define a module named B
this PR:
native:
File "_none_", line 1:
Error: Files 2/a.cmx and 1/a.cmx
make inconsistent assumptions over interface A
bytecode:
File "_none_", line 1:
Error: Files 2/a.cmo and 1/a.cmo
make inconsistent assumptions over interface A
Not the end of the world when the build system ensures uniqueness of compilation units, but I think it's trivial to fix (as I indicated in an inline comment), so may as well.
Other than addressing the review comments, please do the usual rebase, adding a Changes entry (and maybe squash the commits? not sure what's expected).
The test script:
#!/bin/bash
set -e -u -o pipefail
which ocamlopt
which ocamlc
rm -rf /tmp/test
mkdir /tmp/test
cd /tmp/test
mkdir 1 2
echo "type t = int" > 1/a.ml
echo "Printf.printf \"%d\\n\" (1 : A.t)" > 1/b.ml
echo "type t = string" > 2/a.ml
echo "Printf.printf \"%s\\n\" (\"qwerty\" : A.t)" > 2/b.ml
echo "native:"
(cd 1; ocamlopt -c {a,b}.ml)
(cd 2; ocamlopt -c {a,b}.ml)
ocamlopt 1/{a,b}.cmx 2/{a,b}.cmx || true
echo "bytecode:"
(cd 1; ocamlc -c {a,b}.ml)
(cd 2; ocamlc -c {a,b}.ml)
ocamlc 1/{a,b}.cmo 2/{a,b}.cmo
asmcomp/asmlink.ml
Outdated
@@ -90,7 +87,7 @@ let check_consistency file_name unit crc = | |||
with Not_found -> () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on my test script, I think we should move the raise (Error(Multiple_definition ...))
above at the top of the function, so the errors are improved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
bytecomp/bytelink.ml
Outdated
| Module_linked_twice (modname, file1, file2) -> | ||
fprintf ppf "Files %a and %a both define a module named %s" | ||
Location.print_filename file1 | ||
Location.print_filename file2 | ||
modname | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use the same code as in asmlink.ml (more format boxes than here), and in fact let's use the same constructor name as well (Multiple_definition
), for easier comparison between bytelink.ml and asmlink.ml.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
bytecomp/bytelink.ml
Outdated
(Warnings.Module_linked_twice(cu.cu_name, | ||
Location.show_filename file_name, | ||
Location.show_filename source)) | ||
raise (Error (Module_linked_twice(cu.cu_name, file_name, source))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing as in asmlink.ml: I think we should move the check to the top of the function, for better error messages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
188e8b9
to
96b8ebf
Compare
Thanks for the review @sliquister. I meant to add a new test in the testsuite but my few attempts weren't successful.
Running more tests, I noticed that, when linking a library that contain units also present elsewhere on the command line, we don't fail/warn if theses units don't end up being linked. The behavior seems fine but it means that adding |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, modulo the Changes entry.
Changes
Outdated
@@ -219,6 +219,9 @@ Working version | |||
modules with mismatching -for-pack | |||
(Pierre Chambart and Vincent Laviron, review by Mark Shinwell) | |||
|
|||
- #11635: Turn warning 31 (Module_linked_twice) into a hard error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please list the issues as well, not just the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
The appveyor failure looks spurious.
Yeah, that behavior seems fine, although a stricter behavior would probably also make sense. |
{ number = 31; | ||
names = ["module-linked-twice"]; | ||
description = "A module is linked twice in the same executable."; | ||
since = since 4 0 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to understand well what is going on with the warning from a compatibility perspective:
- what happens if a user manually specifies this warning, on the command-line or in an attribute, by number or by name?
- what is shown in
-warn-help
?
My current understanding is as follows:
- Warning modifiers are interpreted by mutating dense flag arrays of all warning numbers.
- Using a number-based modifier
-31
or+31
will modify the flag array and do nothing else (as the warning is never raised anymore). In practice this is silently ignored, which is probably fine. - Using
-module-linked-twice
will result in a lookup failure because thedescription
entry is removed here, which will eventually result in a confusingocaml_deprecated_cli
alert. This is not good. - The warning will not appear in
-warn-help
anymore, because the description entry is removed.
I think that we should do this instead: keep the description entry, but extend the description to say that the warning is now ignored and replaced by a hard error.
My understanding is that we would then get the following behavior:
- specifying the warning by number or by name is ignored
- the warning shows up in
-warn-help
, with a mention that it is ignored
I think that this new behavior would be reasonable, a better default.
One may think of something even more informative (if users try to disable the warning, letting them know that this does not work anymore through... another warning?), but I think that it would not be worth the implementation and conceptual complexity.
Minor note: the definition of defaults_warn_error
further down still mentions +31
, it should be removed I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've kept the description entry, updated defaults_warn_error
and updated manual and man pages.
I'm not super happy with the updated description.
31 [module-linked-twice] Ignored: now a hard error (since 5.0).
A module is linked twice in the same executable.
I've tried to follow what was done for number 25
25 Ignored: now part of warning 8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed it to
31 [module-linked-twice] A module is linked twice in the same executable.
Ignored: now a hard error (since 5.0).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine with me, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5.1 rather than 5.0 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Octachron, fixed thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i agree with @sliquister that this is a good implementation of the proposed change. I am in favor of merging once the commits have been rebased/fixupped by @hhugo as he prefers, and the CI is green.
Thanks a lot @sliquister for your careful review. I don't think that I would have had the energy to look at this by myself without your contribution.
b2d6bb0
to
22568bf
Compare
I've squashed the commits and rebased. |
Looks like the warning changes are breaking |
Indeed. This test checks that every constructor of the sum type has a corresponding textual mnemonic, and vice-versa. This fails because the mnemonic for warning 31 does not have a corresponding constructor. The simplest workaround is to add a hard-coded list of deprecated warnings to this test (for which there is no associated constructor). |
I've pushed a fix for the tests/warnings/mnemonics.mll test following @nojb suggestion |
The appveyor failure is due to #11853 |
Merged, thanks! |
Fix #5461
Fix #10564