79f6cb7985
The question is premature, and measuring says why. El's partition is a
FILESYSTEM PATH, not a neighbourhood, and there is no namespacing at all.
MEASURED
import is textual inlining (resolve_imports), guarded against double
inclusion by a __elc_imp__:<path> state key
when a .elh header exists the header is inlined instead and the .el is marked
seen, so symbols resolve at C link time -- so linking IS real, delegated to C
two modules defining `helper` emit two C functions into one translation unit
So linking barely survives the PATH partition. Whether it survives a
neighbourhood partition cannot be asked yet.
A DIAGNOSTIC REGRESSION I CAUSED, found by asking this question. cc does catch
the collision, but reports:
error: redefinition of '__el_body_helper'
error: redefinition of '__env_helper'
error: redefinition of '__thunk_helper'
error: redefinition of 'helper'
The user's own function is FOURTH. The first three are generated symbols
introduced by the unconditional-wrapper pass earlier today -- before it, there
was one clear message. Repaired by catching the collision at El level instead:
duplicate definition: 'helper' is defined 2 times — El has no namespacing,
so imported modules share one global scope
LIMIT, stated rather than hidden: textual inlining destroys file provenance. By
the time codegen runs there is one source string, so the message can say WHICH
name collides but not which files. Naming a.el and b.el needs provenance
threaded through resolve_imports.
104/104 native, 4/4 definitions_query.sh, the compiler itself reports clean,
fixpoint ok.
26 lines
1.4 KiB
Bash
Executable File
26 lines
1.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Control for duplicate-definition detection.
|
|
#
|
|
# El has no namespacing: import is textual inlining, so two modules defining the
|
|
# same name emit two C functions into one translation unit.
|
|
set -uo pipefail
|
|
ELC="${1:?usage: definitions_query.sh <elc>}"
|
|
LANG_DIR="${2:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
W=$(mktemp -d); trap 'rm -rf "$W"' EXIT; F=0
|
|
chk(){ [ "$2" = "$3" ] && printf ' ok %s\n' "$1" || { printf ' FAIL %s\n expected %s got %s\n' "$1" "$2" "$3"; F=$((F+1)); }; }
|
|
|
|
printf 'fn helper() -> Int { return 1 }\n' > "$W/a.el"
|
|
printf 'fn helper() -> Int { return 2 }\n' > "$W/b.el"
|
|
printf 'import "a.el"\nimport "b.el"\nfn main() { println(int_to_str(helper())) }\n' > "$W/m.el"
|
|
EL_RELATIONS_OUT="$W/r.txt" "$ELC" "$W/m.el" >/dev/null 2>&1
|
|
out=$("$LANG_DIR/tools/check/definitions.sh" "$W/r.txt" 2>&1); rc=$?
|
|
chk "a collision across modules is caught at El level" "1" "$rc"
|
|
chk "the colliding name is reported" "1" "$(echo "$out" | grep -c "'helper' is defined 2 times")"
|
|
chk "and the reason is given" "1" "$(echo "$out" | grep -c 'no namespacing')"
|
|
|
|
printf 'fn only_once() -> Int { return 1 }\nfn main() { println(int_to_str(only_once())) }\n' > "$W/c.el"
|
|
EL_RELATIONS_OUT="$W/r2.txt" "$ELC" "$W/c.el" >/dev/null 2>&1
|
|
"$LANG_DIR/tools/check/definitions.sh" "$W/r2.txt" >/dev/null 2>&1
|
|
chk "a clean program exits 0" "0" "$?"
|
|
echo; echo " 4 assertions, $((4-F)) passed, $F failed"; exit $F
|