Skip to main content

native_source_root

Function native_source_root 

Source
pub fn native_source_root(entry: &Path) -> PathBuf
Expand description

Resolve a project’s source root from an entry file’s path: the directory containing the nearest brink.toml found by walking up from the entry (brink-project-config’s discovery), or — if none exists — the entry’s own directory (decision-log 2026-07-22 “native module identity … source root”: the explicit, documented single-file-project mode, not a silent fallback).

Despite the name, this is no longer native-only: prepare_driver (brink-compiler/src/driver.rs) also calls it for an .ink entry, to register ProjectDb::set_ink_root (issue #1696) — the same root discovery a native compile already used, reused so hir:: root_content_scope_path’s qualifier is a root-relative key rather than the entry’s raw spelling.

A relative multi-component entry_dir like chapters has Path::parent return Some("") — not None — once the walk-up inside brink_project_config::find_config reaches it, so find_config can return a bare brink.toml (found relative to the process cwd, e.g. PathBuf::from("brink.toml")) whose own .parent() is that same empty path. Naively filtering that empty parent out and falling back to entry_dir (as this function used to) silently discards a config that was found — so brink ide check -e chapters/story.ink, run from a cwd containing brink.toml, missed the config and mis-rooted at chapters instead of the true root (review finding on #1403/PR #1412). An empty parent always means “found in the directory the walk started from” — i.e. the current directory — so it maps to Path::new(".") instead of being discarded.

A relative entry_dir still can’t see past the process’s cwd, though, even after that fix: find_config’s walk-up is Path::parent, which is purely lexical — for a relative path it bottoms out at "" (cwd itself) and has no way to synthesize a ".." to keep climbing, unlike an absolute entry_dir, whose Path::parent chain walks all the way to the filesystem root for free. So brink compile story.ink, run from a cwd whose brink.toml lives one directory above cwd (not in cwd itself), never even attempts that ancestor — entry_dir is ".", find_config checks "./brink.toml" and the bare "brink.toml" (both resolve to the same cwd-relative candidate) and then has nowhere lexical left to go, so it returns None and this function falls back to entry_dir itself, mis-rooting at cwd instead of the true project root (issue #1413) — even though the identical project laid out with an absolute or chapters/-nested entry resolves correctly. When the relative walk comes up empty, retry once from an absolutized entry_dir so a brink.toml above cwd is still found, exactly as it would be for an absolute-path entry. The retry is skipped whenever absolutizing entry_dir changes nothing (i.e. entry_dir was already absolute and already normalized — the first pass already walked to the filesystem root, so a byte-identical second walk would be wasted work) and never runs when the relative walk already found an answer — so the fast, already-correct relative result (including the "."-for-cwd spelling GitRev::repo_relative’s shortcut depends on, per the #1403/PR #1412 trap) is untouched in the common case.

Neither pass climbs past a workspace/git boundary (#1425): brink_project_config::find_config itself now stops ascending once it passes a directory containing a .git entry, so this function can never resolve root to somewhere outside the repository the entry lives in — closing the gap the absolutized retry above opened (an absolute walk used to reach the filesystem root “for free,” which meant a stray brink.toml anywhere above the repo — even in $HOME — could get picked up). A brink.toml sitting outside a repository entirely (as opposed to merely above entry_dir but still inside it) is now treated exactly like no brink.toml at all: this function falls back to entry_dir. And even a VCS-less tree, which has no .git boundary to stop at, no longer climbs “to the filesystem root for free” as the absolute-path reasoning above describes: find_config’s MAX_ANCESTOR_DEPTH cap (#1435) bounds every walk — relative-retry or absolute — regardless of whether a .git is ever found.