Consolidate name resolution through PackageResolutionContext#3300
Consolidate name resolution through PackageResolutionContext#3300
Conversation
- Update namespaces_root_fallback fixture: bare Config → root.Config - Create namespaces_bare_name_rejected fixture for bare cross-ns refs - Add ignored tests: bare_name_cross_namespace_rejected, multi_segment_bare_path_rejected - Capture baseline snapshots for both fixtures
Replace split-loop (path: &[Name]) signature with explicit (namespace: &[Name], item: &Name) on PackageItems and PackageInterface. Update all ~34 call sites. Behavior-preserving — same lookups happen, just with explicit namespace/item split at the caller.
Remove the .or_else() bare fallback from lower_type_expr_in_ns — bare names from child namespaces no longer silently resolve to root. Add suggestions field to TirTypeError::UnresolvedType with namespace scan to emit "did you mean root.Config?" hints. Un-ignore Phase 1 tests.
Replace all 9 lookup_type_any_ns(unqualify(qtn)) call sites with lookup_type(qtn.namespace(), qtn.name()). Remove both unqualify functions and both lookup_type_any_ns methods.
- Remove bare-name fallback from PRC::resolve_type for non-root ns - Add root. prefix handling and dep search to PRC::resolve_value - Route resolve_name_at through PRC::resolve_value/resolve_type - Route resolve_path_at through PRC
Replace direct pkg_items.namespaces access with lookup_type(namespace, item) calls. Change resolve_in_package signature to accept pre-split (namespace, item) pair. Update all callers in resolve_qualified_key.
Use pkg_info.namespace_path instead of &[] in MIR lowering and LSP semantic token resolution. Fixes self parameter and return type resolution for functions in non-root namespaces.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughReplaces path-splitting name resolution with explicit namespace-aware lookups across HIR/PPIR/TIR/LSP: APIs changed to accept (namespace: &[Name], item: &Name), removed cross-namespace short-name scans, updated diagnostics to include suggestions, and adjusted many call sites and tests to the new model. Changes
Sequence Diagram(s)sequenceDiagram
participant Caller as Caller (lowering / ppir / tir / lsp)
participant PRC as PackageResolutionContext
participant PI as PackageInterface
participant PIItems as PackageItems
participant Deps as Dependency PackageItems
Caller->>PRC: resolve_type/resolve_value(path, ns_context)
PRC->>PI: resolve_in_own_then_deps(namespace, item)
PI->>PIItems: lookup_type(namespace, item) / lookup_value(namespace, item)
alt found in own package
PIItems-->>PI: Definition
else not found in own
PI->>Deps: lookup_type(namespace, item) / lookup_value(namespace, item)
Deps-->>PI: Definition or None
end
PI-->>PRC: ResolvedSource + Definition?
PRC-->>Caller: resolution result
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Binary size checks passed✅ 7 passed
Generated by |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
baml_language/crates/baml_lsp2_actions/src/tokens.rs (1)
409-413:⚠️ Potential issue | 🟡 MinorQualified type paths will still be highlighted incorrectly.
visit_type_expr()still resolves eachWORDin isolation, so this lookup now always probespkg_info.namespace_path. In a namespaced file,root.Configorother_ns.Foowill classifyConfig/FooasNamespaceinstead of the underlying type because the qualifier-derived namespace is discarded here. Please resolve the full path before callinglookup_type.baml_language/crates/baml_compiler2_tir/src/lower_type_expr.rs (1)
58-76:⚠️ Potential issue | 🟠 MajorHandle
root.before the generic namespace lookup.Because folder-derived namespaces can also be
["root"],root.Configis currently sent through the ordinary(namespace, item)lookup first. In a project withns_root/..., that resolves the namespaced item and the explicit-root branch never runs, soroot.*can point at the wrong definition.Suggested fix
- let resolved = if !ns_context.is_empty() { + let resolved = if segments.len() >= 2 && segments[0].as_str() == "root" { + package_items.lookup_type(&segments[1..segments.len() - 1], item) + } else if !ns_context.is_empty() { let ns: Vec<baml_base::Name> = ns_context.iter().chain(seg_ns.iter()).cloned().collect(); package_items.lookup_type(&ns, item) } else { package_items.lookup_type(seg_ns, item) };
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3999f4bd-3671-4ae5-8951-7d4f879f4c0b
⛔ Files ignored due to path filters (20)
baml_language/crates/baml_tests/snapshots/__baml_std__/baml_tests____baml_std____04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/__baml_std__/baml_tests____baml_std____06_codegen.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__01_lexer__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__01_lexer__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__02_parser__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__02_parser__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__03_hir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__04_tir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__05_diagnostics.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__06_codegen.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__10_formatter__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__10_formatter__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_basic/baml_tests__namespaces_basic__04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__01_lexer__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__02_parser__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__03_hir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__10_formatter__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/stream_types/baml_tests__stream_types__04_tir.snapis excluded by!**/*.snap
📒 Files selected for processing (20)
baml_language/crates/baml_compiler2_hir/src/package.rsbaml_language/crates/baml_compiler2_mir/src/lower.rsbaml_language/crates/baml_compiler2_ppir/src/expand.rsbaml_language/crates/baml_compiler2_tir/src/builder.rsbaml_language/crates/baml_compiler2_tir/src/infer_context.rsbaml_language/crates/baml_compiler2_tir/src/inference.rsbaml_language/crates/baml_compiler2_tir/src/lower_type_expr.rsbaml_language/crates/baml_compiler2_tir/src/package_interface.rsbaml_language/crates/baml_compiler2_tir/src/resolve.rsbaml_language/crates/baml_compiler2_tir/src/throw_inference.rsbaml_language/crates/baml_lsp2_actions/src/completions.rsbaml_language/crates/baml_lsp2_actions/src/definition.rsbaml_language/crates/baml_lsp2_actions/src/tokens.rsbaml_language/crates/baml_lsp2_actions/src/usages.rsbaml_language/crates/baml_tests/projects/namespaces_bare_name_rejected/main.bamlbaml_language/crates/baml_tests/projects/namespaces_bare_name_rejected/ns_llm/models.bamlbaml_language/crates/baml_tests/projects/namespaces_root_fallback/ns_llm/models.bamlbaml_language/crates/baml_tests/src/compiler2_hir.rsbaml_language/crates/baml_tests/src/compiler2_tir/mod.rsbaml_language/crates/baml_tests/src/compiler2_tir/phase5.rs
baml_language/crates/baml_compiler2_tir/src/package_interface.rs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
baml_language/crates/baml_compiler2_hir/src/package.rs (1)
167-181:⚠️ Potential issue | 🟠 MajorStabilize namespace enumeration before exposing
PackageItems.namespaces.
ns_pathsis collected in astd::collections::HashSet, so theFxHashMapbuilt here is still fed by process-random iteration order. Downstream scans ofpackage_items.namespaces— including the new "did you mean" builder inbaml_language/crates/baml_compiler2_tir/src/lower_type_expr.rsand LSP completion collection — will therefore keep emitting suggestions in arbitrary order. Please sort namespace paths (or expose a sorted iterator) before user-facing code consumes this map.baml_language/crates/baml_lsp2_actions/src/completions.rs (1)
372-385:⚠️ Potential issue | 🟠 MajorQualify completion inserts for out-of-namespace items.
These loops iterate
pkg.namespaces.values(), so they drop the namespace path and always insert bareConfig/UseConfignames. After this PR, accepting one of those fromns_llm/...produces an unresolved identifier whenever the target lives inrootor a sibling namespace. Iterate with(ns_path, ns_items)and emitroot.X/foo.bar.Xinsert text for anything outsidepkg_info.namespace_path.Also applies to: 808-855
baml_language/crates/baml_lsp2_actions/src/tokens.rs (1)
384-425:⚠️ Potential issue | 🟡 MinorResolve the full qualified type path before classifying the terminal token.
Even after the borrow fix,
resolve_type_namestill only looks up a bare name in the current file namespace. Inns_llm/...,root.Configwill therefore colorConfigasNamespaceinstead ofClass.visit_type_exprneeds to resolve the dotted path and classify only its last segment from that result.baml_language/crates/baml_compiler2_tir/src/lower_type_expr.rs (1)
54-76:⚠️ Potential issue | 🟠 MajorResolve explicit
root.*/ package-qualified paths before relative namespace lookup.This branch prepends
ns_contextbefore it knows whether the path is already qualified. In a namespace likefoo,root.Configwill first probefoo.root.Config, andbaml.http.Responsewill first probefoo.baml.http.Response; if either exists, the fallback never runs and the explicit reference binds to the wrong symbol.baml_language/crates/baml_compiler2_tir/src/builder.rs (1)
2952-2976:⚠️ Potential issue | 🟠 MajorForeign package classes can be shadowed by builtin stubs.
Line 2966 tries
resolve_builtin_memberfor every non-own package class before resolving against the class that was just found inpkg_items. A dependency likefoo.Arrayorfoo.media.Imagewill bind to thebamlmember if the path collides, even though the access was explicitly package-qualified.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3a0fe9c3-b1c3-4222-b45e-082d4f1754a8
⛔ Files ignored due to path filters (20)
baml_language/crates/baml_tests/snapshots/__baml_std__/baml_tests____baml_std____04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/__baml_std__/baml_tests____baml_std____06_codegen.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__01_lexer__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__01_lexer__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__02_parser__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__02_parser__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__03_hir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__04_tir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__05_diagnostics.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__06_codegen.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__10_formatter__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__10_formatter__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_basic/baml_tests__namespaces_basic__04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__01_lexer__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__02_parser__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__03_hir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_root_fallback/baml_tests__namespaces_root_fallback__10_formatter__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/stream_types/baml_tests__stream_types__04_tir.snapis excluded by!**/*.snap
📒 Files selected for processing (20)
baml_language/crates/baml_compiler2_hir/src/package.rsbaml_language/crates/baml_compiler2_mir/src/lower.rsbaml_language/crates/baml_compiler2_ppir/src/expand.rsbaml_language/crates/baml_compiler2_tir/src/builder.rsbaml_language/crates/baml_compiler2_tir/src/infer_context.rsbaml_language/crates/baml_compiler2_tir/src/inference.rsbaml_language/crates/baml_compiler2_tir/src/lower_type_expr.rsbaml_language/crates/baml_compiler2_tir/src/package_interface.rsbaml_language/crates/baml_compiler2_tir/src/resolve.rsbaml_language/crates/baml_compiler2_tir/src/throw_inference.rsbaml_language/crates/baml_lsp2_actions/src/completions.rsbaml_language/crates/baml_lsp2_actions/src/definition.rsbaml_language/crates/baml_lsp2_actions/src/tokens.rsbaml_language/crates/baml_lsp2_actions/src/usages.rsbaml_language/crates/baml_tests/projects/namespaces_bare_name_rejected/main.bamlbaml_language/crates/baml_tests/projects/namespaces_bare_name_rejected/ns_llm/models.bamlbaml_language/crates/baml_tests/projects/namespaces_root_fallback/ns_llm/models.bamlbaml_language/crates/baml_tests/src/compiler2_hir.rsbaml_language/crates/baml_tests/src/compiler2_tir/mod.rsbaml_language/crates/baml_tests/src/compiler2_tir/phase5.rs
baml_language/crates/baml_compiler2_tir/src/package_interface.rs
Outdated
Show resolved
Hide resolved
…and match patterns - builder.rs: use ns_context instead of &[] for constructor, enum variant, and type-pattern sugar lookups; add enum_name_matches() to resolve dotted enum names (e.g. "root.Status") against QualifiedTypeName in match exhaustiveness - throw_inference.rs: thread ns_context through collect_direct_throws → throw_fact_from_expr → resolve_path_to_ty so throw types resolve in namespaced files - resolve.rs: fix dep type lookup to try namespace_path then &[]; use direct pkg_items lookup for qualified paths instead of routing through PRC - package_interface.rs: filter dep class field/method lookups by package name - expand.rs: requalify_for_caller() to fix cross-namespace alias stream expansion; use alias definition's namespace when recursing into alias bodies - signature.rs: add param_type_spans for precise error span on type annotations - Add comprehensive namespaces_type_resolution test fixture (4 namespaces, same-named types, 0 diagnostics) and namespaces_stream_direct_ref fixture Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
baml_language/crates/baml_compiler2_tir/src/throw_inference.rs (1)
327-369:⚠️ Potential issue | 🟠 MajorDirect throw type resolution still skips
rootand package-qualified paths.These branches still resolve against the current package’s
pkg_itemsonly, sothrow root.MyError,throw baml.http.Request, and root-file bare cross-namespace throws still collapse toTy::Unknown. That pollutesFunctionThrowSetsand can suppress downstream throws-contract errors. Please route throw fact resolution throughPackageResolutionContext::resolve_type(or an equivalent package-aware helper) instead of treating leading segments as plain namespaces.Also applies to: 389-430
baml_language/crates/baml_compiler2_tir/src/resolve.rs (1)
105-125:⚠️ Potential issue | 🟠 Major
resolve_typesuccesses can still fall through toUnknown.Once
res_ctx.resolve_typesucceeds, the follow-up lookup only probespkg_info.namespace_pathand[]. Root-file fallback hits like bareResponse -> llm.Responsetherefore lose theirDefinitionand come backUnknown, which breaks definition/usages on exactly the names this PR still resolves. Recover theDefinitionfrom the returned qualified type instead of guessing with namespace-local lookups.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: db5b0cc1-69fe-4859-a2fd-1799833deedf
⛔ Files ignored due to path filters (34)
baml_language/crates/baml_tests/snapshots/__baml_std__/baml_tests____baml_std____04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/__baml_std__/baml_tests____baml_std____04_tir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__04_tir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_bare_name_rejected/baml_tests__namespaces_bare_name_rejected__05_diagnostics.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__01_lexer__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__01_lexer__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__02_parser__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__02_parser__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__03_hir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__04_tir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__05_diagnostics.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__06_codegen.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__10_formatter__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_stream_direct_ref/baml_tests__namespaces_stream_direct_ref__10_formatter__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__01_lexer__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__01_lexer__ns_auth_auth.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__01_lexer__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__01_lexer__ns_llm_ns_openai_client.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__02_parser__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__02_parser__ns_auth_auth.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__02_parser__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__02_parser__ns_llm_ns_openai_client.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__03_hir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__04_5_mir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__04_tir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__05_diagnostics.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__06_codegen.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__10_formatter__main.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__10_formatter__ns_auth_auth.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__10_formatter__ns_llm_models.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/namespaces_type_resolution/baml_tests__namespaces_type_resolution__10_formatter__ns_llm_ns_openai_client.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/unknown_type_error/baml_tests__unknown_type_error__04_tir.snapis excluded by!**/*.snapbaml_language/crates/baml_tests/snapshots/unknown_type_error/baml_tests__unknown_type_error__05_diagnostics.snapis excluded by!**/*.snap
📒 Files selected for processing (14)
baml_language/crates/baml_compiler2_hir/src/signature.rsbaml_language/crates/baml_compiler2_ppir/src/expand.rsbaml_language/crates/baml_compiler2_tir/src/builder.rsbaml_language/crates/baml_compiler2_tir/src/inference.rsbaml_language/crates/baml_compiler2_tir/src/package_interface.rsbaml_language/crates/baml_compiler2_tir/src/resolve.rsbaml_language/crates/baml_compiler2_tir/src/throw_inference.rsbaml_language/crates/baml_tests/projects/namespaces_stream_direct_ref/main.bamlbaml_language/crates/baml_tests/projects/namespaces_stream_direct_ref/ns_llm/models.bamlbaml_language/crates/baml_tests/projects/namespaces_type_resolution/main.bamlbaml_language/crates/baml_tests/projects/namespaces_type_resolution/ns_auth/auth.bamlbaml_language/crates/baml_tests/projects/namespaces_type_resolution/ns_llm/models.bamlbaml_language/crates/baml_tests/projects/namespaces_type_resolution/ns_llm/ns_openai/client.bamlbaml_language/crates/baml_tests/src/compiler2_tir/phase3a.rs
- expand.rs: recursively requalify map key types in requalify_for_caller - phase5.rs: assert "root.Config" suggestion text in bare_name_cross_namespace_rejected, assert "unresolved type: ns2.MyClass" in multi_segment_bare_path_rejected Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…riants Enum variants in throws type position (e.g. throws Errors.AuthError) are not yet supported in the type system. Update 4 LSP action tests to use the enum type directly (throws Errors) and document the known limitation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The InstanceOf instruction in bex_vm would call as_object_ptr on the left operand, which throws a TypeError when the value is Null (since Null maps to ObjectType::Any, not ObjectType::Instance). This caused "Function call failed: VM type error: expected instance, got any" errors in the WASM playground after PR #3300 consolidated name resolution. Instead of erroring, instanceof on null or non-instance values now correctly evaluates to false, matching standard language semantics (e.g. JavaScript's `null instanceof Foo === false`). Made-with: Cursor
## Summary - The `CmpOp::InstanceOf` instruction in `bex_vm` would call `as_object_ptr` on the left operand, which throws a `TypeError` when the value is `Null` (since `Null` maps to `ObjectType::Any`, not `ObjectType::Instance`). This caused **"Function call failed: VM type error: expected instance, got any"** errors in the WASM playground after PR #3300 consolidated name resolution. - Instead of erroring, `instanceof` on null or non-instance values now correctly evaluates to `false`, matching standard language semantics (e.g. JavaScript's `null instanceof Foo === false`). ## Root Cause The `InstanceOf` handler in `vm.rs` unconditionally called `self.as_object_ptr(&left, ObjectType::Instance)`, which returns a `TypeError` for any value that isn't an instance object. When the left operand was `Value::Null` (whose type resolves to `ObjectType::Any`), this produced the cryptic "expected instance, got any" error. This was exposed (not caused) by PR #3300's name resolution changes — the new fully-qualified name paths altered control flow so that `instanceof` checks were reached with null values that previously took a different code path. ## Fix Replaced the unconditional `as_object_ptr` call with a nested `match` that: 1. Checks if the left value is a `Value::Object` — if not, returns `false` 2. Checks if the object is an `Object::Instance` — if not, returns `false` 3. Only then performs the class pointer comparison ## Test plan - [x] `cargo test --lib` passes across all workspace crates - [x] `cargo test -p bex_vm --lib` passes - [x] `cargo test -p bex_engine --lib` passes - [x] `cargo clippy` passes (verified by pre-commit hook) - [ ] Manual verification in WASM playground that the error is resolved Made with [Cursor](https://cursor.com) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed the `instanceof` operator to properly handle non-object values and `null` by returning `false` instead of raising an error. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What problems was I solving
The BAML compiler had three independent name resolution paths that each
implemented their own namespace logic. Two of them silently fell back to
the root namespace when a name wasn't found in the current namespace —
meaning `Config` written inside `ns_llm/` would resolve to root-level
`Config` without any explicit qualification. This implicit behavior
would cause non-deterministic resolution if two namespaces defined the
same short name.
Meanwhile, `PackageResolutionContext` (PRC) was designed to be the
single authority for package-level resolution, but had zero call sites —
all three ad-hoc paths bypassed it. Additionally, `lookup_type_any_ns`
scanned all namespaces in `FxHashMap` iteration order
(non-deterministic) to find a type by short name, despite all 9 call
sites already holding a `QualifiedTypeName` with full namespace info.
After the initial consolidation, several secondary namespace bugs were
uncovered: builder.rs hardcoded `&[]` (root namespace) for constructor,
enum variant, and type-pattern lookups; match exhaustiveness couldn't
resolve dotted enum names like `root.Status.Ok`; throw inference didn't
thread namespace context; and PPIR stream alias expansion produced bare
paths unresolvable from non-root namespaces.
## What user-facing changes did I ship
- **Bare cross-namespace references now produce errors with "did you
mean" hints.** Writing `Config` from `ns_llm/` no longer silently
resolves to root — the compiler suggests `root.Config` instead.
- **LSP semantic tokens respect namespace context.** Type coloring now
uses the file's namespace path.
- **Cross-namespace enum matches work correctly.** `match (s) {
root.Status.Ok => ... }` from a non-root namespace now resolves properly
instead of producing "unreachable arm" errors.
- **Type inference in namespaced files resolves constructors and type
patterns correctly.** Object literals like `ExecutionContext { ... }` in
`baml.llm` now resolve instead of producing `unknown`.
- **Stream companion types resolve correctly for cross-namespace type
aliases.**
## How I implemented it
### Phase 1-7: Core consolidation (original commits)
- Changed `lookup_type`/`lookup_value` API from ambiguous split-loop
`(path: &[Name])` to explicit `(namespace: &[Name], item: &Name)`
- Removed `lookup_type_any_ns` and `unqualify` helpers
- Removed bare-name fallback, added "did you mean" diagnostics
- Wired `resolve_name_at`/`resolve_path_at` through PRC
- Gave `PRC::resolve_value` full parity with `resolve_type`
- Updated PPIR `resolve_in_package` to use new API
- Threaded namespace context through MIR lowering and LSP tokens
### Phase 8: Fix secondary namespace bugs (latest commit)
- **builder.rs**: Changed constructor/enum/type-pattern lookups from
`&[]` to `&self.ns_context`. Added `enum_name_matches()` to resolve
dotted enum names like `"root.Status"` or `"root.llm.Status"` against
`QualifiedTypeName` — used in `pattern_match_cases`,
`pattern_narrowed_type`, and catch-arm matching.
- **throw_inference.rs**: Threaded `ns_context` through
`collect_direct_throws` → `throw_fact_from_expr` → `resolve_path_to_ty`.
Added namespace-qualified lookup with root fallback for bare names.
- **resolve.rs**: Fixed dep type lookup to try `namespace_path` then
`&[]`. Changed `resolve_path_at` to use direct `pkg_items` lookup
instead of routing through PRC (which drops the package prefix).
- **package_interface.rs**: Filtered dep class field/method lookups by
`dep_name == class_pkg`.
- **expand.rs**: Added `requalify_for_caller()` to fix cross-namespace
type alias stream expansion — when an alias body resolves to a type in a
different namespace, the resulting path is qualified with `root.` so
`lower_type_expr_in_ns` can find it.
- **signature.rs**: Added `param_type_spans` to `SignatureSourceMap` for
precise error spans on type annotations (previously spanned the whole
`name: Type` parameter).
### Test fixtures
- **`namespaces_type_resolution`**: Comprehensive fixture with 4
namespaces (root, llm, auth, llm.openai), same-named types (`Config`,
`Error`, `Status`/`Model` enums) in each. Tests bare-name resolution,
cross-namespace `root.X`, constructors, enum matches, type aliases,
throws, stream companions, and mixed-namespace signatures. **0
diagnostics.**
- **`namespaces_stream_direct_ref`**: Captures the known limitation that
`$stream` companion types are not directly user-referenceable (future
feature).
- **`namespaces_bare_name_rejected`**: Verifies bare cross-namespace
references produce errors with suggestions.
## How to verify it
```bash
cd baml_language
cargo test -p baml_tests namespaces_type_resolution
cargo test -p baml_tests namespaces_bare_name_rejected
cargo test -p baml_tests namespaces_stream_direct_ref
cargo test -p baml_tests stream_types
cargo test -p baml_tests # full suite: 947 tests
```
## Description for the changelog
Remove implicit bare-name namespace fallback in BAML compiler;
cross-namespace references now require explicit `root.` prefix with "did
you mean" error suggestions. Fix namespace-aware type resolution for
constructors, enum matches, throw inference, and stream companion
expansion.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Bare names no longer implicitly resolve across namespaces;
cross-namespace references must be explicitly qualified.
* **Improvements**
* Name/type/value resolution consistently respects file/package
namespace context.
* Unresolved-type diagnostics now include contextual suggestions when
available.
* Semantic classifications for some type tokens are more accurate with
namespace-aware lookup.
* **Tests**
* New and updated test fixtures exercising namespace resolution,
root-prefixed references, throws semantics, and stream-companion
scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary - The `CmpOp::InstanceOf` instruction in `bex_vm` would call `as_object_ptr` on the left operand, which throws a `TypeError` when the value is `Null` (since `Null` maps to `ObjectType::Any`, not `ObjectType::Instance`). This caused **"Function call failed: VM type error: expected instance, got any"** errors in the WASM playground after PR #3300 consolidated name resolution. - Instead of erroring, `instanceof` on null or non-instance values now correctly evaluates to `false`, matching standard language semantics (e.g. JavaScript's `null instanceof Foo === false`). ## Root Cause The `InstanceOf` handler in `vm.rs` unconditionally called `self.as_object_ptr(&left, ObjectType::Instance)`, which returns a `TypeError` for any value that isn't an instance object. When the left operand was `Value::Null` (whose type resolves to `ObjectType::Any`), this produced the cryptic "expected instance, got any" error. This was exposed (not caused) by PR #3300's name resolution changes — the new fully-qualified name paths altered control flow so that `instanceof` checks were reached with null values that previously took a different code path. ## Fix Replaced the unconditional `as_object_ptr` call with a nested `match` that: 1. Checks if the left value is a `Value::Object` — if not, returns `false` 2. Checks if the object is an `Object::Instance` — if not, returns `false` 3. Only then performs the class pointer comparison ## Test plan - [x] `cargo test --lib` passes across all workspace crates - [x] `cargo test -p bex_vm --lib` passes - [x] `cargo test -p bex_engine --lib` passes - [x] `cargo clippy` passes (verified by pre-commit hook) - [ ] Manual verification in WASM playground that the error is resolved Made with [Cursor](https://cursor.com) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed the `instanceof` operator to properly handle non-object values and `null` by returning `false` instead of raising an error. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
What problems was I solving
The BAML compiler had three independent name resolution paths that each implemented their own namespace logic. Two of them silently fell back to the root namespace when a name wasn't found in the current namespace — meaning
Configwritten insidens_llm/would resolve to root-levelConfigwithout any explicit qualification. This implicit behavior would cause non-deterministic resolution if two namespaces defined the same short name.Meanwhile,
PackageResolutionContext(PRC) was designed to be the single authority for package-level resolution, but had zero call sites — all three ad-hoc paths bypassed it. Additionally,lookup_type_any_nsscanned all namespaces inFxHashMapiteration order (non-deterministic) to find a type by short name, despite all 9 call sites already holding aQualifiedTypeNamewith full namespace info.After the initial consolidation, several secondary namespace bugs were uncovered: builder.rs hardcoded
&[](root namespace) for constructor, enum variant, and type-pattern lookups; match exhaustiveness couldn't resolve dotted enum names likeroot.Status.Ok; throw inference didn't thread namespace context; and PPIR stream alias expansion produced bare paths unresolvable from non-root namespaces.What user-facing changes did I ship
Configfromns_llm/no longer silently resolves to root — the compiler suggestsroot.Configinstead.match (s) { root.Status.Ok => ... }from a non-root namespace now resolves properly instead of producing "unreachable arm" errors.ExecutionContext { ... }inbaml.llmnow resolve instead of producingunknown.How I implemented it
Phase 1-7: Core consolidation (original commits)
lookup_type/lookup_valueAPI from ambiguous split-loop(path: &[Name])to explicit(namespace: &[Name], item: &Name)lookup_type_any_nsandunqualifyhelpersresolve_name_at/resolve_path_atthrough PRCPRC::resolve_valuefull parity withresolve_typeresolve_in_packageto use new APIPhase 8: Fix secondary namespace bugs (latest commit)
&[]to&self.ns_context. Addedenum_name_matches()to resolve dotted enum names like"root.Status"or"root.llm.Status"againstQualifiedTypeName— used inpattern_match_cases,pattern_narrowed_type, and catch-arm matching.ns_contextthroughcollect_direct_throws→throw_fact_from_expr→resolve_path_to_ty. Added namespace-qualified lookup with root fallback for bare names.namespace_paththen&[]. Changedresolve_path_atto use directpkg_itemslookup instead of routing through PRC (which drops the package prefix).dep_name == class_pkg.requalify_for_caller()to fix cross-namespace type alias stream expansion — when an alias body resolves to a type in a different namespace, the resulting path is qualified withroot.solower_type_expr_in_nscan find it.param_type_spanstoSignatureSourceMapfor precise error spans on type annotations (previously spanned the wholename: Typeparameter).Test fixtures
namespaces_type_resolution: Comprehensive fixture with 4 namespaces (root, llm, auth, llm.openai), same-named types (Config,Error,Status/Modelenums) in each. Tests bare-name resolution, cross-namespaceroot.X, constructors, enum matches, type aliases, throws, stream companions, and mixed-namespace signatures. 0 diagnostics.namespaces_stream_direct_ref: Captures the known limitation that$streamcompanion types are not directly user-referenceable (future feature).namespaces_bare_name_rejected: Verifies bare cross-namespace references produce errors with suggestions.How to verify it
Description for the changelog
Remove implicit bare-name namespace fallback in BAML compiler; cross-namespace references now require explicit
root.prefix with "did you mean" error suggestions. Fix namespace-aware type resolution for constructors, enum matches, throw inference, and stream companion expansion.Summary by CodeRabbit
Bug Fixes
Improvements
Tests