Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 9 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ members = [
"crates/incan_semantics_stdlib",
"crates/incan_web_macros",
"crates/rust_inspect",
"loaves/compiler/incan_emit",
"loaves/compiler/incan_format",
"loaves/compiler/incan_frontend",
"loaves/compiler/incan_ir",
"loaves/oven/oven_model",
]
exclude = ["target/incan"]
Expand Down Expand Up @@ -68,19 +70,21 @@ readme.workspace = true
default = ["cli", "std_testing", "std_async", "std_decorators"]
cli = ["dep:clap", "dep:tracing-subscriber", "rust_inspect"]
lsp = ["dep:tower-lsp", "dep:tokio", "incan_frontend/lsp"]
std_testing = ["dep:incan_semantics_stdlib", "incan_semantics_stdlib/std_testing", "incan_frontend/std_testing"]
std_async = ["dep:incan_semantics_stdlib", "incan_semantics_stdlib/std_async", "incan_frontend/std_async"]
std_decorators = ["dep:incan_semantics_stdlib", "incan_semantics_stdlib/std_decorators", "incan_frontend/std_decorators"]
std_testing = ["dep:incan_semantics_stdlib", "incan_semantics_stdlib/std_testing", "incan_frontend/std_testing", "incan_ir/std_testing", "incan_emit/std_testing"]
std_async = ["dep:incan_semantics_stdlib", "incan_semantics_stdlib/std_async", "incan_frontend/std_async", "incan_ir/std_async", "incan_emit/std_async"]
std_decorators = ["dep:incan_semantics_stdlib", "incan_semantics_stdlib/std_decorators", "incan_frontend/std_decorators", "incan_ir/std_decorators", "incan_emit/std_decorators"]
# Rust dependency inspection via rust-analyzer (`ra_ap_*`) in the `rust_inspect` crate.
# Kept optional for non-CLI/library builds; the CLI enables it so ordinary `rust::` imports can preserve
# real function/type signatures.
rust_inspect = ["rust_inspect/inspector", "incan_frontend/rust_inspect"]
rust_inspect = ["rust_inspect/inspector", "incan_frontend/rust_inspect", "incan_ir/rust_inspect", "incan_emit/rust_inspect"]

[dependencies]
# Shared language/semantic helpers (canonical vocab)
incan_core = { path = "crates/incan_core" }
incan_format = { path = "loaves/compiler/incan_format" }
incan_frontend = { path = "loaves/compiler/incan_frontend", default-features = false }
incan_ir = { path = "loaves/compiler/incan_ir", default-features = false }
incan_emit = { path = "loaves/compiler/incan_emit", default-features = false }
incan_codegraph = { path = "crates/incan_codegraph" }
incan_vocab = { path = "crates/incan_vocab" }
# Shared syntax frontend (lexer, parser, AST, diagnostics)
Expand Down Expand Up @@ -175,6 +179,7 @@ proptest = "1"
incan_stdlib = { path = "crates/incan_stdlib" }
# Temporary directories for manifest discovery tests
incan_frontend = { path = "loaves/compiler/incan_frontend", default-features = false, features = ["test_support"] }
incan_emit = { path = "loaves/compiler/incan_emit", default-features = false, features = ["test_support"] }
rust_inspect = { path = "crates/rust_inspect", default-features = false, features = ["test_fixtures"] }
tempfile = "3"
wat = "1"
Expand Down
51 changes: 51 additions & 0 deletions loaves/compiler/incan_emit/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[package]
name = "incan_emit"
version.workspace = true
edition.workspace = true
license.workspace = true
authors.workspace = true
description = "Rust emission from the Incan IR, the replacement backend and backend selection"

[lib]
name = "incan_emit"
path = "src/lib.rs"

[features]
# Mirrors the root crate's defaults without `cli`, so `cargo test -p incan_emit` sees the stdlib semantics packs; the
# root selects features explicitly and never relies on these.
default = ["rust_inspect", "std_testing", "std_async", "std_decorators"]
rust_inspect = ["incan_ir/rust_inspect", "incan_frontend/rust_inspect", "rust_inspect/inspector"]
test_support = ["dep:tempfile", "incan_frontend/test_support", "rust_inspect/test_fixtures"]
std_testing = ["incan_ir/std_testing", "incan_frontend/std_testing"]
std_async = ["incan_ir/std_async", "incan_frontend/std_async"]
std_decorators = ["incan_ir/std_decorators", "incan_frontend/std_decorators"]

[dependencies]
hex = "0.4.3"
incan_core = { path = "../../../crates/incan_core" }
incan_frontend = { path = "../incan_frontend", default-features = false }
incan_ir = { path = "../incan_ir", default-features = false }
incan_semantics_core = { path = "../../../crates/incan_semantics_core" }
incan_syntax = { path = "../../../crates/incan_syntax" }
incan_vocab = { path = "../../../crates/incan_vocab" }
oven_model = { path = "../../oven/oven_model" }
prettyplease = "0.2"
proc-macro2 = { workspace = true }
quote = { workspace = true }
regex = "1"
rust_inspect = { path = "../../../crates/rust_inspect", default-features = false }
serde = { workspace = true }
serde_json = { workspace = true }
sha2 = "0.10.9"
syn = { workspace = true, features = ["printing"] }
thiserror = { workspace = true }
tempfile = { version = "3", optional = true }
tracing = { workspace = true }

[dev-dependencies]
incan_frontend = { path = "../incan_frontend", default-features = false, features = ["test_support"] }
# The runtime crate the emitted code links; the emitter only names it in generated tokens, and links it for the
# parity tests alone, so the compiler ring never depends on the runtime it generates for.
incan_stdlib = { path = "../../../crates/incan_stdlib" }
rust_inspect = { path = "../../../crates/rust_inspect", default-features = false, features = ["test_fixtures"] }
tempfile = "3"
2 changes: 1 addition & 1 deletion loaves/compiler/incan_emit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ IR-to-Rust emission with syn/quote, conversions, prettyplease formatting, replac

Pure emission. `src/backend/project/` does NOT come here; it is Oven code (33 imports of `crate::oven`) and moves to the oven ring.

This directory is a layout skeleton. It holds no code yet; `src/` is a placeholder for the conventional crate root.
Emission, conversions, ownership, the trait-bound inference and the codegen entry point live here with the replacement backend and backend selection; `checked_program` holds the tests that drive a checked program through to Rust.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Borrowed imported enums retain constructor resolution and reference ownership (#1448).

use crate::backend::IrCodegen;
use crate::frontend::typechecker::TypeChecker;
use crate::frontend::{lexer, parser};
use crate::IrCodegen;
use incan_frontend::typechecker::TypeChecker;
use incan_frontend::{lexer, parser};

type TestResult = Result<(), Box<dyn std::error::Error>>;

Expand Down Expand Up @@ -83,11 +83,11 @@ pub def inspect(value: &Value) -> None:
/// Precise metadata and metadata-free fallback both preserve payload reference types at their use sites.
#[test]
fn borrowed_rust_enum_payload_types_preserve_reference_modes() -> TestResult {
use crate::frontend::ast::Span;
use crate::frontend::symbols::{ResolvedType, RustImportBindingKind, RustItemInfo, Symbol, SymbolKind};
use incan_core::interop::{
RustItemKind, RustItemMetadata, RustTypeInfo, RustTypeShape, RustVariantInfo, RustVisibility,
};
use incan_frontend::ast::Span;
use incan_frontend::symbols::{ResolvedType, RustImportBindingKind, RustItemInfo, Symbol, SymbolKind};
let cases = [
(None, "payload"),
(Some(RustTypeShape::Str), "payload"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! The embedded-fragment vocab pass, through lowering to the emission refusal.

use crate::frontend::ast;
use crate::frontend::library_manifest::LibraryManifest;
use crate::frontend::library_manifest_index::{
use incan_frontend::ast;
use incan_frontend::library_manifest::LibraryManifest;
use incan_frontend::library_manifest_index::{
LibraryArtifactMetadata, LibraryManifestIndex, LibraryManifestIndexEntry,
};
use crate::frontend::typechecker::TypeChecker;
use crate::frontend::vocab_desugar_pass::desugar_program_vocab_blocks;
use incan_frontend::typechecker::TypeChecker;
use incan_frontend::vocab_desugar_pass::desugar_program_vocab_blocks;
use incan_syntax::lexer;

/// Build a minimal "known library" index entry so `import pub::webkit` resolves during typecheck.
Expand All @@ -30,11 +30,11 @@ fn known_library_index(name: &str) -> LibraryManifestIndex {
)]))
}

/// Full parser -> desugar -> typecheck pipeline for one `html:`-block fixture using a hand-built descriptor
/// map (RFC 081, `#1023`), proving the `vocab_block_body_is_embedded_fragment` bypass this file adds: an
/// embedded fragment's `VocabBlockStmt` wrapper must reach typecheck as its unwrapped `Expr::Embedded`
/// directly, never through `runtime.desugar_node` (which would require a registered WASM desugarer that
/// embedded-fragment descriptors never register).
/// Full parser -> desugar -> typecheck pipeline for one `html:`-block fixture using a hand-built descriptor map (RFC
/// 081, `#1023`), proving the `vocab_block_body_is_embedded_fragment` bypass this file adds: an embedded fragment's
/// `VocabBlockStmt` wrapper must reach typecheck as its unwrapped `Expr::Embedded` directly, never through
/// `runtime.desugar_node` (which would require a registered WASM desugarer that embedded-fragment descriptors never
/// register).
#[test]
fn embedded_fragment_vocab_block_bypasses_wasm_desugar_and_typechecks() -> Result<(), Box<dyn std::error::Error>> {
let source = "import pub::webkit\n\ndef render(title: str) -> None:\n html:\n <h1>{title}</h1>\n\ndef main() -> None:\n render(\"Hello\")\n";
Expand Down Expand Up @@ -110,10 +110,10 @@ fn embedded_fragment_vocab_block_bypasses_wasm_desugar_and_typechecks() -> Resul
// `VocabBlock`/`Surface`-style contract violation) and only fail at the emission boundary, with the exact
// honest `EmitError::Unsupported` message that node's rustdoc documents -- never a panic, and never a
// silent guess at DSL-owned runtime semantics.
let mut codegen = crate::backend::IrCodegen::new();
let mut codegen = crate::IrCodegen::new();
codegen.set_library_manifest_index(known_library_index("webkit"));
let result = codegen.try_generate(&program);
let Err(crate::backend::ir::codegen::GenerationError::Emission(emit_error)) = result else {
let Err(crate::codegen::GenerationError::Emission(emit_error)) = result else {
return Err(format!(
"expected lowering to succeed and only emission to refuse the embedded fragment, got: {result:?}"
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Source-authored foreign supertraits retain their absolute Rust identities (#1427).

use crate::backend::IrCodegen;
use crate::frontend::{lexer, parser};
use crate::IrCodegen;
use incan_frontend::{lexer, parser};

type TestResult = Result<(), Box<dyn std::error::Error>>;

Expand Down Expand Up @@ -44,7 +44,7 @@ pub model Config with DecodeReady:
"#;
let tokens = lexer::lex(source).map_err(|errors| std::io::Error::other(format!("lex: {errors:?}")))?;
let ast = parser::parse(&tokens).map_err(|errors| std::io::Error::other(format!("parse: {errors:?}")))?;
let mut checker = crate::frontend::typechecker::TypeChecker::new();
let mut checker = incan_frontend::typechecker::TypeChecker::new();
checker
.check_program(&ast)
.map_err(|errors| std::io::Error::other(format!("check: {errors:?}")))?;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! Checked SDK metadata retains explicit module derive membership and backend requirements.

use crate::backend::IrCodegen;
use crate::frontend::api_metadata::{
use crate::IrCodegen;
use incan_core::lang::traits::{self as core_traits, TraitId};
use incan_frontend::api_metadata::{
CHECKED_API_METADATA_SCHEMA_VERSION, CheckedApiMetadata, CheckedApiMetadataPackage, api_declaration_public_name,
collect_checked_api_metadata,
};
use crate::frontend::library_manifest::LibraryManifest;
use crate::frontend::typechecker::TypeChecker;
use crate::frontend::{lexer, parser};
use incan_core::lang::traits::{self as core_traits, TraitId};
use incan_frontend::library_manifest::LibraryManifest;
use incan_frontend::typechecker::TypeChecker;
use incan_frontend::{lexer, parser};

type TestResult = Result<(), Box<dyn std::error::Error>>;

Expand Down Expand Up @@ -160,7 +160,7 @@ fn sdk_module_derives_missing_membership_stays_rejected() -> TestResult {
/// A public alias of a derivable trait retains the target's explicit backend requirement.
#[test]
fn sdk_module_derives_trait_alias_retains_target_macro() -> TestResult {
use crate::frontend::api_metadata::{ApiAlias, ApiDeclaration, SourceAnchor, SourceSpan};
use incan_frontend::api_metadata::{ApiAlias, ApiDeclaration, SourceAnchor, SourceSpan};
let mut facade = provider_metadata()?;
facade.module_path = vec!["bundle_facade".into()];
facade.derivable_traits = vec!["Exported".into()];
Expand Down
Loading
Loading