Skip to content

Commit 8ae3391

Browse files
committed
baml-language: set up ppir
1 parent e10ef7c commit 8ae3391

14 files changed

Lines changed: 143 additions & 31 deletions

File tree

baml_language/Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

baml_language/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ baml_codegen_types = { path = "crates/baml_codegen_types" }
3333
baml_compiler_analysis = { path = "crates/baml_compiler_analysis" }
3434
baml_compiler2_ast = { path = "crates/baml_compiler2_ast" }
3535
baml_compiler2_hir = { path = "crates/baml_compiler2_hir" }
36+
baml_compiler2_ppir = { path = "crates/baml_compiler2_ppir" }
3637
baml_compiler2_tir = { path = "crates/baml_compiler2_tir" }
3738
baml_compiler2_mir = { path = "crates/baml_compiler2_mir" }
3839
baml_compiler2_emit = { path = "crates/baml_compiler2_emit" }

baml_language/crates/baml_compiler2_hir/src/builder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::{
2929
semantic_index::{DefinitionSite, FileSemanticIndex, ScopeBindings, SemanticIndexExtra},
3030
};
3131

32-
pub(crate) struct SemanticIndexBuilder<'db> {
32+
pub struct SemanticIndexBuilder<'db> {
3333
db: &'db dyn crate::Db,
3434
file: SourceFile,
3535

@@ -51,7 +51,7 @@ pub(crate) struct SemanticIndexBuilder<'db> {
5151
}
5252

5353
impl<'db> SemanticIndexBuilder<'db> {
54-
pub(crate) fn new(db: &'db dyn crate::Db, file: SourceFile) -> Self {
54+
pub fn new(db: &'db dyn crate::Db, file: SourceFile) -> Self {
5555
Self {
5656
db,
5757
file,
@@ -71,7 +71,7 @@ impl<'db> SemanticIndexBuilder<'db> {
7171
///
7272
/// `file_range` is the full text range of the file (used for
7373
/// Project/Package/Namespace/File scopes).
74-
pub(crate) fn build(
74+
pub fn build(
7575
mut self,
7676
items: Vec<ast::Item>,
7777
file_range: TextRange,

baml_language/crates/baml_compiler2_hir/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//! - Cross-file aggregation: `namespace_items`, `package_items`
1414
1515
pub mod body;
16-
mod builder;
16+
pub mod builder;
1717
pub mod contributions;
1818
pub mod diagnostic;
1919
pub mod file_package;
@@ -30,8 +30,9 @@ use std::sync::Arc;
3030

3131
use baml_base::SourceFile;
3232

33+
pub use builder::SemanticIndexBuilder;
34+
3335
use crate::{
34-
builder::SemanticIndexBuilder,
3536
contributions::FileSymbolContributions,
3637
item_tree::ItemTree,
3738
semantic_index::{FileSemanticIndex, ScopeBindings},
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "baml_compiler2_ppir"
3+
version.workspace = true
4+
edition.workspace = true
5+
6+
[lints]
7+
workspace = true
8+
9+
[dependencies]
10+
baml_base = { workspace = true }
11+
baml_compiler_parser = { workspace = true }
12+
baml_compiler2_ast = { workspace = true }
13+
baml_compiler2_hir = { workspace = true }
14+
baml_workspace = { workspace = true }
15+
rustc-hash = { workspace = true }
16+
salsa = { workspace = true }
17+
smol_str = { workspace = true }
18+
text-size = { workspace = true }
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//! Pre-Processed Intermediate Representation (PPIR) for compiler2.
2+
//!
3+
//! Pipeline: CST -> AST -> HIR (raw) -> PPIR (expansion + canonical) -> TIR.
4+
//!
5+
//! PPIR uses HIR's `package_items` for symbol classification (class vs enum vs alias),
6+
//! then synthesizes `stream_*` AST items and provides canonical queries that include
7+
//! both original and synthetic items.
8+
//!
9+
//! **No union simplification in PPIR.** Deferred to TIR.
10+
//!
11+
//! Currently a passthrough scaffold — all queries delegate directly to HIR.
12+
13+
use std::sync::Arc;
14+
15+
use baml_base::SourceFile;
16+
use baml_compiler2_hir::{
17+
contributions::FileSymbolContributions,
18+
item_tree::ItemTree,
19+
namespace::NamespaceId,
20+
package::{PackageId, PackageItems},
21+
scope::ScopeId,
22+
semantic_index::{FileSemanticIndex, ScopeBindings},
23+
};
24+
25+
// -- Db trait -----------------------------------------------------------------
26+
27+
#[salsa::db]
28+
pub trait Db: baml_compiler2_hir::Db {}
29+
30+
// -- Canonical queries (passthrough to HIR) -----------------------------------
31+
32+
/// Canonical file_semantic_index — currently delegates to HIR.
33+
/// Will later merge synthetic stream_* items into the index.
34+
pub fn file_semantic_index<'db>(
35+
db: &'db dyn Db,
36+
file: SourceFile,
37+
) -> &'db FileSemanticIndex<'db> {
38+
baml_compiler2_hir::file_semantic_index(db, file)
39+
}
40+
41+
/// Canonical file_item_tree — currently delegates to HIR.
42+
pub fn file_item_tree(db: &dyn Db, file: SourceFile) -> Arc<ItemTree> {
43+
baml_compiler2_hir::file_item_tree(db, file)
44+
}
45+
46+
/// Canonical symbol contributions — currently delegates to HIR.
47+
pub fn file_symbol_contributions<'db>(
48+
db: &'db dyn Db,
49+
file: SourceFile,
50+
) -> Arc<FileSymbolContributions<'db>> {
51+
baml_compiler2_hir::file_symbol_contributions(db, file)
52+
}
53+
54+
/// Canonical scope_bindings_query — currently delegates to HIR.
55+
pub fn scope_bindings_query<'db>(db: &'db dyn Db, scope_id: ScopeId<'db>) -> ScopeBindings {
56+
baml_compiler2_hir::scope_bindings_query(db, scope_id)
57+
}
58+
59+
/// Canonical namespace_items — currently delegates to HIR.
60+
pub fn namespace_items<'db>(
61+
db: &'db dyn Db,
62+
namespace_id: NamespaceId<'db>,
63+
) -> &'db baml_compiler2_hir::namespace::NamespaceItems<'db> {
64+
baml_compiler2_hir::namespace::namespace_items(db, namespace_id)
65+
}
66+
67+
/// Canonical package_items — currently delegates to HIR.
68+
pub fn package_items<'db>(db: &'db dyn Db, package_id: PackageId<'db>) -> &'db PackageItems<'db> {
69+
baml_compiler2_hir::package::package_items(db, package_id)
70+
}

baml_language/crates/baml_compiler2_tir/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ workspace = true
1010
baml_base = { workspace = true }
1111
baml_compiler2_ast = { workspace = true }
1212
baml_compiler2_hir = { workspace = true }
13+
baml_compiler2_ppir = { workspace = true }
1314
baml_compiler_analysis = { workspace = true }
1415
baml_compiler_diagnostics = { workspace = true }
1516
baml_workspace = { workspace = true }

baml_language/crates/baml_compiler2_tir/src/builder.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,7 +2023,7 @@ impl<'db> TypeInferenceBuilder<'db> {
20232023
first.clone()
20242024
};
20252025
let pkg_id = baml_compiler2_hir::package::PackageId::new(db, pkg_name);
2026-
let pkg_items = baml_compiler2_hir::package::package_items(db, pkg_id);
2026+
let pkg_items = baml_compiler2_ppir::package_items(db, pkg_id);
20272027

20282028
if pkg_items.namespaces.is_empty() {
20292029
return Ty::Unknown;
@@ -2247,7 +2247,7 @@ impl<'db> TypeInferenceBuilder<'db> {
22472247
let db = self.context.db();
22482248
let pkg_info =
22492249
baml_compiler2_hir::file_package::file_package(db, class_loc.file(db));
2250-
let item_tree = baml_compiler2_hir::file_item_tree(db, class_loc.file(db));
2250+
let item_tree = baml_compiler2_ppir::file_item_tree(db, class_loc.file(db));
22512251
let class_data = &item_tree[class_loc.id(db)];
22522252
self.resolutions.insert(
22532253
at,
@@ -2504,7 +2504,7 @@ impl<'db> TypeInferenceBuilder<'db> {
25042504
let ns_context =
25052505
baml_compiler2_hir::file_package::file_package(self.context.db(), file)
25062506
.namespace_path;
2507-
let item_tree = baml_compiler2_hir::file_item_tree(self.context.db(), file);
2507+
let item_tree = baml_compiler2_ppir::file_item_tree(self.context.db(), file);
25082508
let class_data = &item_tree[class_loc.id(self.context.db())];
25092509
for field in &class_data.fields {
25102510
let mut diags = Vec::new();
@@ -2547,7 +2547,7 @@ impl<'db> TypeInferenceBuilder<'db> {
25472547
self.package_items
25482548
} else {
25492549
let foreign_pkg_id = baml_compiler2_hir::package::PackageId::new(db, class_pkg.clone());
2550-
baml_compiler2_hir::package::package_items(db, foreign_pkg_id)
2550+
baml_compiler2_ppir::package_items(db, foreign_pkg_id)
25512551
}
25522552
}
25532553

@@ -2575,7 +2575,7 @@ impl<'db> TypeInferenceBuilder<'db> {
25752575
let db = self.context.db();
25762576
let file = class_loc.file(db);
25772577
let ns_context = baml_compiler2_hir::file_package::file_package(db, file).namespace_path;
2578-
let item_tree = baml_compiler2_hir::file_item_tree(db, file);
2578+
let item_tree = baml_compiler2_ppir::file_item_tree(db, file);
25792579
let class_data = &item_tree[class_loc.id(db)];
25802580

25812581
for &method_id in &class_data.methods {
@@ -2700,7 +2700,7 @@ impl<'db> TypeInferenceBuilder<'db> {
27002700
first.clone()
27012701
};
27022702
let pkg_id = baml_compiler2_hir::package::PackageId::new(db, resolved_pkg_name);
2703-
let pkg_items = baml_compiler2_hir::package::package_items(db, pkg_id);
2703+
let pkg_items = baml_compiler2_ppir::package_items(db, pkg_id);
27042704

27052705
// Check that this package actually has items (non-empty = real package)
27062706
if pkg_items.namespaces.is_empty() {
@@ -2840,7 +2840,7 @@ impl<'db> TypeInferenceBuilder<'db> {
28402840
let db = self.context.db();
28412841
let pkg_info =
28422842
baml_compiler2_hir::file_package::file_package(db, class_loc.file(db));
2843-
let item_tree = baml_compiler2_hir::file_item_tree(db, class_loc.file(db));
2843+
let item_tree = baml_compiler2_ppir::file_item_tree(db, class_loc.file(db));
28442844
let class_data = &item_tree[class_loc.id(db)];
28452845
self.resolutions.insert(
28462846
at,
@@ -2868,7 +2868,7 @@ impl<'db> TypeInferenceBuilder<'db> {
28682868
let db = self.context.db();
28692869
let baml_pkg_id =
28702870
baml_compiler2_hir::package::PackageId::new(db, baml_base::Name::new("baml"));
2871-
let baml_items = baml_compiler2_hir::package::package_items(db, baml_pkg_id);
2871+
let baml_items = baml_compiler2_ppir::package_items(db, baml_pkg_id);
28722872

28732873
// Look up the class by path (e.g. &["Array"] or &["media", "Image"]).
28742874
let path: Vec<Name> = class_path.iter().map(|s| baml_base::Name::new(s)).collect();
@@ -2880,7 +2880,7 @@ impl<'db> TypeInferenceBuilder<'db> {
28802880
let file = class_loc.file(db);
28812881
let stub_pkg = baml_compiler2_hir::file_package::file_package(db, file);
28822882
let stub_ns: &[Name] = &stub_pkg.namespace_path;
2883-
let item_tree = baml_compiler2_hir::file_item_tree(db, file);
2883+
let item_tree = baml_compiler2_ppir::file_item_tree(db, file);
28842884
let class_data = &item_tree[class_loc.id(db)];
28852885

28862886
// Bind generic type variables: e.g. {T → int} for Array<int>.
@@ -3031,7 +3031,7 @@ impl<'db> TypeInferenceBuilder<'db> {
30313031
// Cross-package enum: look it up in the enum's own package.
30323032
let pkg_id =
30333033
baml_compiler2_hir::package::PackageId::new(db, enum_name.package().clone());
3034-
Some(baml_compiler2_hir::package::package_items(db, pkg_id))
3034+
Some(baml_compiler2_ppir::package_items(db, pkg_id))
30353035
};
30363036

30373037
// Build the lookup path: namespace segments + enum name.
@@ -3042,7 +3042,7 @@ impl<'db> TypeInferenceBuilder<'db> {
30423042
if let Some(def) = items.lookup_type(&lookup_path) {
30433043
if let Definition::Enum(enum_loc) = def {
30443044
let file = enum_loc.file(db);
3045-
let item_tree = baml_compiler2_hir::file_item_tree(db, file);
3045+
let item_tree = baml_compiler2_ppir::file_item_tree(db, file);
30463046
let enum_data = &item_tree[enum_loc.id(db)];
30473047
return enum_data.variants.iter().map(|v| v.name.clone()).collect();
30483048
}

baml_language/crates/baml_compiler2_tir/src/inference.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ pub fn infer_scope_types<'db>(
193193
) -> ScopeInference<'db> {
194194
let file = scope_id.file(db);
195195
let file_scope = scope_id.file_scope_id(db);
196-
let index = baml_compiler2_hir::file_semantic_index(db, file);
196+
let index = baml_compiler2_ppir::file_semantic_index(db, file);
197197
let scope = &index.scopes[file_scope.index() as usize];
198198

199199
// Get package items for cross-file resolution
@@ -211,7 +211,7 @@ pub fn infer_scope_types<'db>(
211211
// Find the function by matching scope range AND name against item_tree functions.
212212
// Both checks are required to disambiguate companion functions that
213213
// share the parent's span.
214-
let item_tree = baml_compiler2_hir::file_item_tree(db, file);
214+
let item_tree = baml_compiler2_ppir::file_item_tree(db, file);
215215
let mut found = false;
216216
for (local_id, func_data) in &item_tree.functions {
217217
if func_data.span == scope.range && scope.name.as_ref() == Some(&func_data.name) {
@@ -360,7 +360,7 @@ pub fn infer_scope_types<'db>(
360360
ScopeKind::Let => {
361361
// Top-level let binding — find the matching let in the item tree
362362
// and type-infer its initializer expression.
363-
let item_tree = baml_compiler2_hir::file_item_tree(db, file);
363+
let item_tree = baml_compiler2_ppir::file_item_tree(db, file);
364364
for (local_id, let_data) in &item_tree.lets {
365365
if let_data.span == scope.range && scope.name.as_ref() == Some(&let_data.name) {
366366
let let_loc = LetLoc::new(db, file, *local_id);
@@ -532,7 +532,7 @@ pub fn resolve_class_fields<'db>(
532532
class_loc: ClassLoc<'db>,
533533
) -> Arc<ResolvedClassFields> {
534534
let file = class_loc.file(db);
535-
let item_tree = baml_compiler2_hir::file_item_tree(db, file);
535+
let item_tree = baml_compiler2_ppir::file_item_tree(db, file);
536536
let pkg_info = baml_compiler2_hir::file_package::file_package(db, file);
537537
let pkg_id = PackageId::new(db, pkg_info.package.clone());
538538
let pkg_items = package_items(db, pkg_id);
@@ -581,7 +581,7 @@ pub fn resolve_type_alias<'db>(
581581
alias_loc: TypeAliasLoc<'db>,
582582
) -> Arc<ResolvedTypeAlias> {
583583
let file = alias_loc.file(db);
584-
let item_tree = baml_compiler2_hir::file_item_tree(db, file);
584+
let item_tree = baml_compiler2_ppir::file_item_tree(db, file);
585585
let pkg_info = baml_compiler2_hir::file_package::file_package(db, file);
586586
let pkg_id = PackageId::new(db, pkg_info.package.clone());
587587
let pkg_items = package_items(db, pkg_id);
@@ -635,9 +635,9 @@ pub fn render_scope_diagnostics<'db>(
635635
// Find the source map by matching scope range against item_tree functions.
636636
let file = scope_id.file(db);
637637
let file_scope = scope_id.file_scope_id(db);
638-
let index = baml_compiler2_hir::file_semantic_index(db, file);
638+
let index = baml_compiler2_ppir::file_semantic_index(db, file);
639639
let scope = &index.scopes[file_scope.index() as usize];
640-
let item_tree = baml_compiler2_hir::file_item_tree(db, file);
640+
let item_tree = baml_compiler2_ppir::file_item_tree(db, file);
641641

642642
let source_map = item_tree
643643
.functions
@@ -675,7 +675,7 @@ pub fn collect_file_diagnostics<'db>(
675675
db: &'db dyn crate::Db,
676676
file: baml_base::SourceFile,
677677
) -> TypeCheckDiagnostics<'db> {
678-
let index = baml_compiler2_hir::file_semantic_index(db, file);
678+
let index = baml_compiler2_ppir::file_semantic_index(db, file);
679679
let mut all_diagnostics = TypeCheckDiagnostics::default();
680680

681681
for scope_id in &index.scope_ids {

baml_language/crates/baml_compiler2_tir/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ pub mod ty;
3535
/// Extends `baml_compiler2_hir::Db`. Use `infer_scope_types` for type
3636
/// inference queries, `resolve_name_at` for name resolution.
3737
#[salsa::db]
38-
pub trait Db: baml_compiler2_hir::Db {}
38+
pub trait Db: baml_compiler2_ppir::Db {}

0 commit comments

Comments
 (0)