From 093485072f4e798059a27806af913ed9f069661d Mon Sep 17 00:00:00 2001 From: Raphael Amorim Date: Fri, 24 Jul 2026 23:54:31 +0200 Subject: [PATCH] externs and consts resolve through import handles --- crates/jam-sema/src/astgen.rs | 33 ++++++++++++++++++++++-- tests/unit/mod_handle_access.jam | 5 ++++ tests/unit/test_import_handle_access.jam | 18 +++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 tests/unit/mod_handle_access.jam create mode 100644 tests/unit/test_import_handle_access.jam diff --git a/crates/jam-sema/src/astgen.rs b/crates/jam-sema/src/astgen.rs index 581703e..e6a0383 100644 --- a/crates/jam-sema/src/astgen.rs +++ b/crates/jam-sema/src/astgen.rs @@ -4808,9 +4808,18 @@ fn astgen_dotted_call( } // 2. Prefix as an IMPORT HANDLE (`const lib = import("m"); lib.fn()`) -> the - // free function `m.fn`. + // free function `m.fn`. Externs/exports register under their bare C name + // only (module_path stays empty so the symbol isn't mangled), so a handle + // spelling like `objc.objc_getClass` falls back to the bare lookup. if let Some(module) = gctx.ctx.import_handle_module(prefix) - && let Some(method) = gctx.ctx.get_function_ast(&format!("{module}.{suffix}")) + && let Some(method) = gctx + .ctx + .get_function_ast(&format!("{module}.{suffix}")) + .or_else(|| { + gctx.ctx + .get_function_ast(suffix) + .filter(|f| f.is_extern || f.is_export) + }) { // Privacy: a non-`pub` function reached through a module handle is not // exported. `extern`/`export` libc bare names stay accessible. @@ -6999,6 +7008,26 @@ fn astgen_member_access(gctx: &mut AstGenCtx, n: &AstNode) -> Result