Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changes/qualified-own-namespace-dependency.fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Make a module reached only as `Namespace.Module` from inside its own
namespace a dependency, so it builds first and its changes rebuild the user.
9 changes: 8 additions & 1 deletion compiler/ml/depend.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ let add_names s =
let rec add_path bv ?(p = []) = function
| Lident s ->
let free =
try lookup_free (s :: p) bv with Not_found -> String_set.singleton s
try lookup_free (s :: p) bv
with Not_found -> (
(* Also record [S.M] for a qualified free path: when [S] is the
namespace of the module's own package, the build system resolves
[M] in that namespace, which [S] alone cannot tell it. *)
match p with
| [] -> String_set.singleton s
| m :: _ -> String_set.of_list [s; s ^ "." ^ m])
in
add_names free
| Ldot (l, s) -> add_path bv ~p:(s :: p) l
Expand Down
57 changes: 57 additions & 0 deletions rewatch/tests/compile/22-qualified-own-namespace-dependency.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

cd $(dirname $0)
source "../utils.sh"

bold "Test: A module reached only through its own namespace is a dependency"

fixture=$(mktemp -d 2>/dev/null || mktemp -d -t rewatch-qualified-own-namespace)
trap "rm -rf '$fixture'" EXIT

mkdir -p "$fixture/src"

cat > "$fixture/rescript.json" <<'JSON'
{
"name": "rewatch-qualified-own-namespace",
"namespace": "Ns",
"sources": { "dir": "src" },
"package-specs": { "module": "esmodule", "in-source": true },
"suffix": ".mjs"
}
JSON

# User names Target only as Ns.Target, so its AST header must say so: the
# bare namespace does not tell the build system which module to wait for.
cat > "$fixture/src/Target.res" <<'RES'
let value = 1
RES

cat > "$fixture/src/User.res" <<'RES'
let value = Ns.Target.value + 1
RES

cd "$fixture"
if ! compiler_output=$("$REWATCH_EXECUTABLE" build 2>&1); then
error "Clean build compiled User before Target"
printf "%s\n" "$compiler_output" >&2
exit 1
fi

# Changing Target must recompile User and report its new type error.
cat > src/Target.res <<'RES'
let value = "not an int"
RES

if compiler_output=$("$REWATCH_EXECUTABLE" build 2>&1); then
error "Incremental build did not recompile User after Target changed"
printf "%s\n" "$compiler_output" >&2
exit 1
fi

if ! printf '%s\n' "$compiler_output" | grep -q "User.res"; then
error "Incremental build did not report the error in User"
printf "%s\n" "$compiler_output" >&2
exit 1
fi

success "Modules reached through their own namespace are dependencies"
1 change: 1 addition & 0 deletions rewatch/tests/suite.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ fi
./compile/19-utf8-warning.sh &&
./compile/20-schedule-independent-modules-after-error.sh &&
./compile/21-rebuild-dependency-for-package-specs.sh &&
./compile/22-qualified-own-namespace-dependency.sh &&
./compile/14-no-testrepo-changes.sh &&
./compile/15-no-new-files.sh &&
./compile/16-snapshots-unchanged.sh &&
Expand Down
Loading