Skip to content
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

Ocamldep can miss dependencies #7470

Closed
vicuna opened this issue Jan 28, 2017 · 6 comments
Closed

Ocamldep can miss dependencies #7470

vicuna opened this issue Jan 28, 2017 · 6 comments

Comments

@vicuna
Copy link

vicuna commented Jan 28, 2017

Original bug ID: 7470
Reporter: @Octachron
Assigned to: @Octachron
Status: assigned (set by @xavierleroy on 2017-02-19T16:55:35Z)
Resolution: open
Priority: low
Severity: minor
Target version: 4.07.0+dev/beta2/rc1/rc2
Category: tools (ocaml{lex,yacc,dep,debug,...})
Related to: #8427 #4081 #4618 #5624 #5870

Bug description

Ocamldep is overly optimistic when opening or including unknown modules, which can lead to missed dependencies.

Consider this set of three files

(* a.ml *)
module M = struct module N = struct end end
open B
open M
;; N.x

(* b.ml *)
module M = struct end

(* n.ml *)
let x = 1

Running ocamldep -modules a.ml yields:

a.ml : B

whereas the correct dependencies would be

a.ml : B N

The dependency over the module N is missed, because ocamldep infers (erroneously) that the module M opened by "open M" is A.M whereas the module truly opened is B.M.

(I am not sure if this problem ever happens in real situation, but I thought it ought to be at least referenced.)

@vicuna
Copy link
Author

vicuna commented Jan 28, 2017

Comment author: @xavierleroy

I think this is a duplicate of #5870. At any rate, this is a known, long-standing, infamous limitation of ocamldep, and after two decades it is still unclear how to overcome it.

@vicuna
Copy link
Author

vicuna commented Jan 28, 2017

Comment author: @gasche

If I understand correctly, the bug could be fixed as follows: when opening a non-local module, we should forget about the previously known submodule structures, given that any previous module may have been overriden by the unknown open. The code of parsing/depend.ml currently reads:

let open_module bv lid =
match lookup_map lid bv with
| Node (s, m) ->
add_names s;
StringMap.fold StringMap.add m bv
| exception Not_found ->
add_path bv lid; bv

If I am not mistaken, this would correspond to turning the last line into something like:

| exception Not_found ->
add_path bv lid;
(* #7470: forget about known submodules
as this "open" may override them *)
StringMap.empty

Unfortunately, there is a risk of this change significantly worsening the precision of dependency computation, and thus introducing more faulty cycles if people have submodules of the name of a compilation unit.

@vicuna
Copy link
Author

vicuna commented Jan 28, 2017

Comment author: @Octachron

I would argue that this problem is quite different than #5870, since in this case, ocamldep fails to compute an over-approximation of dependencies.

@gasche: It is possible to be a little more precise by forgetting not the current submodules but the submodule structure of the current submodules, i.e in the previous example, the problem appears when the signature of M is inferred to be sig module N:sig end end whereas there is no way to know the signature of the module that was really opened.

But even in this case, fixing this problem may worsen the precision of dependency computation for non-pathological situations.

@vicuna
Copy link
Author

vicuna commented Jan 28, 2017

Comment author: @gasche

Good point.

This is a case where testing on all OPAM packages would be interesting. It's not clear that anyone will bother actually implementing a patch to experiment with that.

@vicuna
Copy link
Author

vicuna commented Feb 19, 2017

Comment author: @xavierleroy

See also https://github.com/Octachron/codept

@github-actions
Copy link

github-actions bot commented May 9, 2020

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants