Summary
collect_top_level_extern_decls builds a program-wide name -> DefId map with last-file-wins, so at most one external fn of a given bare name can be bound anywhere in a multi-file program. An unrelated, never-called declaration in a sibling file breaks a working call in another file, with the calling file's source unchanged.
Reproduction
main.inf declares external fn f(...) and binds it with use { f } from mathlib;, then calls it. A024 passes.
- Add a sibling file containing an unrelated
external fn f(...) that is never called and never bound.
main.inf's own call now fails A024, with byte-identical source in main.inf.
Why it matters
The failure is non-local and the diagnostic points at the calling file, which is correct in neither the cause nor the fix. It also makes the binding depend on file iteration order rather than on scope.
The natural fix is to key the map on the declaration's DefId (or on (module_path, name)) rather than the bare name — the same identity distinction #363 needed for resolving a bound extern in a spec obligation, where a name-keyed lookup would hand a spec-inner declaration the top-level one's origin.
Scope
Pre-existing and independent of the #363 linker-envelope work; found and reproduced while implementing it.
Summary
collect_top_level_extern_declsbuilds a program-widename -> DefIdmap with last-file-wins, so at most oneexternal fnof a given bare name can be bound anywhere in a multi-file program. An unrelated, never-called declaration in a sibling file breaks a working call in another file, with the calling file's source unchanged.Reproduction
main.infdeclaresexternal fn f(...)and binds it withuse { f } from mathlib;, then calls it. A024 passes.external fn f(...)that is never called and never bound.main.inf's own call now fails A024, with byte-identical source inmain.inf.Why it matters
The failure is non-local and the diagnostic points at the calling file, which is correct in neither the cause nor the fix. It also makes the binding depend on file iteration order rather than on scope.
The natural fix is to key the map on the declaration's
DefId(or on(module_path, name)) rather than the bare name — the same identity distinction #363 needed for resolving a bound extern in a spec obligation, where a name-keyed lookup would hand a spec-inner declaration the top-level one's origin.Scope
Pre-existing and independent of the #363 linker-envelope work; found and reproduced while implementing it.