From e8c05899c98308f52e0e0486a2e137f9ee7a3daa Mon Sep 17 00:00:00 2001 From: Davis Vaughan Date: Mon, 29 Jun 2026 14:04:08 -0400 Subject: [PATCH] Allow `Package::resolve()` to skip the namespace export check for `base` --- crates/oak_db/src/package_resolve.rs | 4 ++++ crates/oak_db/src/tests/package_resolve.rs | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/crates/oak_db/src/package_resolve.rs b/crates/oak_db/src/package_resolve.rs index bc1cef139e..19afb24488 100644 --- a/crates/oak_db/src/package_resolve.rs +++ b/crates/oak_db/src/package_resolve.rs @@ -55,7 +55,11 @@ impl<'db> Package { name: Name<'db>, visibility: PackageVisibility, ) -> Vec> { + // When resolving an export, the `name` must be present in the `NAMESPACE` + // exports. If the package is `base`, there is no `NAMESPACE`, but all top-level + // bindings in `base` are visible by construction, so we skip this check entirely. if visibility == PackageVisibility::Exported && + self.name(db) != "base" && !self .namespace(db) .exports diff --git a/crates/oak_db/src/tests/package_resolve.rs b/crates/oak_db/src/tests/package_resolve.rs index 4471e0083c..f40eb703bb 100644 --- a/crates/oak_db/src/tests/package_resolve.rs +++ b/crates/oak_db/src/tests/package_resolve.rs @@ -273,3 +273,23 @@ fn test_same_name_defined_in_multiple_files_returns_each() { assert!(target_files.contains(&files[0])); assert!(target_files.contains(&files[1])); } + +#[test] +fn test_base_exports_every_top_level_binding() { + // `base` doesn't have a `NAMESPACE`, so there are no namespace exports for it. + // Instead, `PackageVisibility::Exported` lookups on `base` skip the export check and + // fall straight through to looking for a top-level binding anywhere in the `base` + // source files. + // + // Note that this won't find primitives! These have no top-level binding. + let mut db = TestDb::new(); + let (pkg, files) = setup_package(&mut db, "base", &[], &[( + "workspace/base/R/a.R", + "foo <- function() 1\n", + )]); + + let defs = pkg.resolve(&db, name(&db, "foo"), PackageVisibility::Exported); + assert_eq!(defs.len(), 1); + assert_eq!(defs[0].file(&db), files[0]); + assert_eq!(defs[0].name(&db).text(&db).as_str(), "foo"); +}