Incan 0.5
Readable source.Real native systems.
Build applications, libraries, workspaces, typed data tools, and native integrations with Python-shaped source and Rust-backed artifacts—without writing Rust for the ordinary application path.
- Applications
- Libraries
- Workspaces
- Native integrations
def create_report() -> Result[OrderReport, str]:
source = Path("orders.json")
.read_text("utf-8", "strict")
.map_err((error) => error.message())?
batch = OrderBatch.from_json(source)?
return Ok(build_report(batch))
Start from an outcome
Test-drive the release by building something real.
Each route ends in a concrete native artifact. Pick the one closest to the work you already do.
Model JSON, handle file failures, transform records, test the core, and ship a native report tool.
Flagship tutorial →Serve typed responses and request models without carrying a Python or JavaScript runtime into deployment.
Build the API →Build a library, preserve its public contract, and consume it through one portable dependency identity.
Build and consume →Put an established crate behind a small, readable Incan boundary instead of rewriting application logic in Rust.
Add a crate →The 0.5 shift
From evaluating a language to building a system.
Install the compiler, create a project, run it, and inspect the generated Rust.
Applications, libraries, workspaces, packages, operational APIs, and native boundaries share one checked view.
One release, three outcomes
The language, package system, and native boundary now tell one story.
Explicit failure, operational standard-library APIs, typed web boundaries, and source-owned iteration make ordinary application code viable.
Providers, features, nested namespaces, workspaces, registries, locks, and SDK components retain checked identities.
Rust crates and a bounded C ABI extend Incan without making generated Rust or ambient toolchains the application contract.
v0.5.1: Rust-interop and installed-toolchain repairs¶
Incan's first patch release does not add a new language or product surface; it carries the focused repairs tracked under #1191, validated end to end on the published toolchain artifacts: a fresh install, the starter project, a bare Bevy application built against the shipped standard-library closure, and the downstream IncQL consumer.
Repairs in this release:
- Release archives retain the Incan standard-library sources needed for installed toolchains to resolve
std.*imports during metadata inspection. - A compiler built from source can seal its vocabulary-helper closure at the explicit
incan oven bakeboundary. When a compatible compiler Loaf already seals that helper, normal and compiler-suite selection use it only after verifying the capability; generated provider Oven outputs are not re-hashed as user Cargo source, while project-output authority remains receipt-exact and no normal path gains Cargo authority. - Repeating an explicit Oven bake remains source-current across an otherwise equivalent format-1 to format-2
incan.lockmigration; the lock's decoded semantic fields, rather than its structural format number, define project authority. - Oven source-authority selection recognises the same sealed registry source archive across compatible feature selections, an initial explicit project bake may establish its first Cargo lock, and aggregate-only storage limits no longer fail because of an inherited per-domain default. The bounded aggregate store policy also leaves room for a measured IncQL/DataFusion provider-to-consumer compatibility-bake hand-off.
- Consumers of a sealed
pub::package use the provider's canonical flattened union ordering when emitting external union variants. - Crate-root union wrappers in
pub::consumers retain each provider type's exported module path instead of assuming an undeclared crate-root re-export. - Project inspection authorities preserve compatible reused direct-rustc plan receipts, so a rebake cannot publish an authority that normal
incan testmust reject. - Compound bases of
**now remain grouped before Rust power-method emission; previously, some valid programs compiled and returned a silently incorrect numeric result. - Rust interop now normalizes inspector-qualified relative paths and elides lifetime-only generic arguments when comparing imported values with inspected method parameters, allowing DataFusion read-option values to reach their Rust call boundary without weakening comparisons of real type arguments.
- Compiler: Rust generic ownership is now derived from inspected metadata rather than names or configuration: owned Rust parameters can bind mutably (#1216), publicly re-exported Rust types keep one nominal identity (#1217), public Rust tuple structs carry constructor-shape metadata (#1218),
f32arithmetic preserves its width (#1219), and mutable query-style generic payloads lower to mutable component references (#1223). The compiler proves each projection from inspected Rust implementations and observed derive-macro expansions; native Rust compilation remains the final authority, and unprovable cases fail closed. - Compiler: an imported Rust named-field constructor may omit fields when inspected metadata proves the type implements
Default; the omitted fields are filled with..Default::default()in generated Rust. - Tooling: the transient
[tool.incan.interop]manifest section that earlier v0.5.1 release candidates introduced is removed. Ownership projections are inferred from inspected metadata instead, and a manifest still carrying the section is loaded with the section ignored. - Tooling: installed toolchains retain the Rust 1.98 split-metadata
.rmetasidecars their sealed library closures depend on, so a fresh machine can bake and link projects such as a bare Bevy application against the shipped standard-library closure. - Tooling: committed
incan.lockfiles render sibling project coordinates portably (for example../producer), so locks enriched on one machine no longer churn or break on another (#1226). - Tooling: a project bake against the shipped standard-library closure now keeps every dependency the project's own compiled crates were built against. Shared third-party crates a project declares directly still resolve to the toolchain's sealed copies, so types that cross the standard-library boundary keep one identity, while a project's other dependencies coexist with the toolchain's as distinct compiled crates (#1227). Builds are additionally path-remapped for machine-independent output.
- Tooling: local
make lintand pre-commit lanes run clippy with the same flags as hosted CI, so feature-gated violations surface before a push.
The repeat-incan oven bake authority failure in #1194 is repaired: the format-1-to-format-2 migration and an unchanged rebake pass under the released control, which every release candidate repeated before this cut.
Why 0.5 exists¶
By the end of 0.4, an evaluator could install Incan, create a project, run it, inspect generated Rust, and export compiler facts. But several critical answers still depended on the path that happened to produce an artifact: analysis could be reconstructed by individual commands, SDK source could be prepared repeatedly, generated Cargo state could become an accidental authority, and native integration facts were not yet one checked contract.
0.5 tightens that system around a single idea: the compiler should know what was checked, what was selected, what was built, and what may be reused.
That idea appears throughout the release:
- Compiler commands consume one shared semantic analysis instead of rebuilding their own partial view.
- Libraries, SDK components, package features, and workspaces retain stable identities across machines and cache locations.
- Oven consumes verified Loafs through receipt-bound plans rather than silently falling back to Cargo.
- Native C integration crosses an explicit, compiler-checked boundary instead of an ambient toolchain boundary.
- New language and standard-library surfaces keep failure, ownership, and operational state visible in Incan source.
This is still a transition release. Generated Rust remains inspectable backend output, but it is not the semantic source of truth or a stable public ABI. The Hees.ai work in this cycle is a downstream proof lane for these foundations, not a Hees.ai product release.
What changes for you¶
- Application authors get more dependable iteration, error handling, environment access, file publication, hashing, web extractors, and native build behavior.
- Library authors get checked nested package namespaces, explicit field privacy, package-owned features, typed registries, and more stable compiled API identity.
- Workspace maintainers get rooted and virtual workspaces, portable locks, shared provider identities, and inspectable component and feature selection.
- Native integrators get a deliberately bounded C ABI surface with checked signatures, ownership, layouts, artifacts, and target evidence.
- Tool builders get richer diagnostics and compiler-owned provider, feature, registry, binding, and codegraph projections.
Welcome, first contributors
The community left fingerprints on the release.
Incan's early external contributions improved diagnostics, native interop, parser consistency, and the way project decisions stay public. Thank you for helping turn a language project into a shared one.
Welcome, Prince Akanso.
@princeaka140 fixed generic Rust associated constructors so receiver type arguments emit in the right place.
See contribution #807 →Welcome, Archlie and Odissei.
@Archlie and @odissei submitted and authored the repair that makes trailing commas in decorator arguments behave like ordinary multiline calls.
See contribution #1015 →Welcome, @yulinlina.
@yulinlina proposed the public Design Decision convention and authored the GPU-capability deferral preserved as DD-0001.
Read DD-0001 →Technical foundations beneath the release¶
The visible change is that Incan can build larger, more realistic programs. The machinery below is what makes that promise hold across commands, packages, native boundaries, and machines.
One compiler view¶
- Shared analysis: Executable builds, generated-Rust inspection, codegraph export, and ordinary test batches now consume
CompilationSessionanalysis. Checked lowering inputs, source-backed stdlib metadata, andSemanticModuleSnapshotfacts are produced together instead of being reconstructed by each command (#224, #225). - Backend foundation: The release records the existing backend behavior, a generated-Rust deprecation policy, stable semantic identity scaffolding, typed compiler facts, and initial HIR structures. These are foundations for the backend transition, not a claim that the cutover is complete (#646, #647, #648, #649, #650, #651).
Packages become checked inputs¶
- Providers, components, and features: Checked Incan libraries and official SDK artifacts enter compilation through one session-owned provider plan. The standard library ships as nine addressable components with
minimal,default, andfullprofiles. Package features resolve additively across optional Incan dependencies and remain distinct from private Cargo implementation features.incan inspect providersandincan inspect featuresexplain the result, while locks record the semantic closure ([RFC 114], #544). - Nested library namespaces: Published libraries preserve their checked source hierarchy as automatic
pub::package.modulenamespaces. Public declarations remain visible through exact nested imports, private declarations stay private, and existing flatsrc/lib.incnfacades remain compatible (#948). - Compact offline SDK: Toolchain archives carry relocatable, integrity-checked provider artifacts and one shared compatibility lock without provider source, mutable build targets, or repeated project-local SDK caches. Installed compilers publish selected profiles into a shared content-addressed store (#544).
- Workspaces: Rooted and virtual workspaces provide deterministic member selection, explicit shared dependency and environment inheritance, one crash-safe root lock,
incan workspace inspect, and member-scoped reports (RFC 077, #405). - Typed registries:
std.registrygives runtime loading and static tooling one declaration authority. Descriptor-backed facts travel in.incnlibartifacts and feed inspection, LSP navigation, codegraph projections, and the generated feature inventory. Start with the typed-registry tutorial, continue with the migration and inspection how-to, and use thestd.registryreference for the exact contract (RFC 113, #575).
Oven turns builds into evidence¶
- Oven Alpha (experimental): The toolchain ships complete debug and release standard-library Loaf families, while
incan oven bake --projectcan publish receipt-bound project extensions and completed library, application, and test outputs for source-current replay. Ordinaryincan build,incan test, andincan runconsume the exact compatible base, extension, output, and direct-rustcplan—or stop with actionable guidance. They never invoke Cargo as a fallback. Storage reporting separates logical artifacts, physical allocation, raw disk use, reclaimability, and active leases, while pruning protects live consumers. Read Oven Alpha for the operational model and current boundary (#1005, #975, #1046, #1054, #1056). - Generated-build transition: The cycle first bounded generated-Cargo targets and measured the storage and throughput behavior that motivated Oven. Oven is now the maintained normal backend for its documented envelope; the older cache material remains compatibility evidence rather than product authority (#876, #877, #925, #1005).
Native boundaries become checked¶
- Typed C ABI interop (experimental):
from std.interop import cactivates import-scopedbindingdeclarations for exact scalar functions, opaque resources, owned and borrowed values, output slots, bounded C strings, and compiler-paired byte orf32spans. Clang verifies declared signatures, enums, and listed plain layouts before generated Rust emits a private bridge. Ownership, mutation, and escape rules remain explicit in Incan source. Read Checked C interoperability and Declare checked C bindings for the supported surface. - Interop planning and staging: Packages can declare target-specific headers, artifacts, system capabilities, shim sources, toolchain or SDK requirements, provenance, licenses, and Android/iOS constraints under
[oven.interop].incan oven interop bakeandstageresolve only selected evidence and declared inputs into receipt-bound plans and fixed staging layouts. They do not invoke Cargo, ambient library discovery, Gradle, Xcode, signing, or physical devices. - Binding inspection:
incan inspect bindings, codegraph JSONL records, and LSP hover consume compiler-owned binding facts. They do not scrape headers or generated Rust, infer physical linking, perform native resolution, or claim a mobile build (#943).
The language gains operational building blocks¶
- Fallible iteration:
FallibleIterator[T, E]adds explicitfor item in stream?:polling, lazy adapters, and fallible terminals. Setup failures remain separate from polling failures, and retry stays owned by the domain source rather than hidden in loop syntax.BinaryReader.chunks(size)is the first Incan-authoredFallibleIterator[bytes, IoError]and powers reader-backed hashing (RFC 115, #579). - System-facing standard library:
std.environadds redacted typed environment reads;std.fsadds atomic publication, directory synchronization, and advisory locks;std.checksumadds CRC32 helpers; andstd.hashadds a storable incrementalSha256Hasher(RFC 089, RFC 112, #557, #709, #829, #969). - Source-owned iteration:
Iterator.sum()now works through the ordinary source-ownedSum[int]andSum[float]contracts, including supported validated numeric newtypes, instead of a Rust-source backend special case (#510).
Inspection and release tooling follow the same facts¶
- Codegraph and diagnostics: A runnable Incan-authored importer validates schema-v1 codegraph JSONL while preserving unknown future record kinds. Machine-readable diagnostics now include compiler origin, structured expected and actual values, and labeled related spans across
incan check, LSP, and tolerant codegraph exports (RFC 106, #771, #776). - Packaging hygiene: The npm adapter no longer emits an install-script warning. Installer and packaging tests use lock-protected named staging, reclaim abandoned work, and surface cleanup failures instead of retaining hidden release fixtures (#812, #864).
Known boundaries¶
- The HIR and semantic-identity work establishes the next backend foundation; it does not complete the full backend cutover.
- Oven Alpha covers complete standard-library and compiler-suite Loaf families plus the explicit, receipt-bound project-extension and completed-output lane. It does not claim general compatibility for arbitrary Rust workspaces, every Cargo build shape, ecosystem bake-offs, or the later RFC-defined publication model.
- Checked C bindings intentionally exclude general pointer programming and several complex calling shapes. Put those behind a governed C/C++ shim with a bounded C contract.
- Virtual Android and iOS evidence proves the declared handoff and staging shape, not Gradle/Xcode integration, signing, store publication, or physical-device support.
- The Hees.ai dependency inventory is downstream validation of Incan's foundation. It does not make Hees.ai part of the Incan 0.5 product surface.
Before you upgrade¶
The main source migration is intentional: fields on a pub model are no longer public merely because the model is public. Add pub to every field that belongs to the model's external API. Private fields remain constructible through Incan-authored factories or provider-owned defaults, not generated all-fields constructors.
Also account for these toolchain boundaries:
- Rust 1.93 is the 0.5 MSRV. The embedded Wasmtime/WASI line is pinned to the patched 36.0.13 maintenance release because the newer patched line requires Rust 1.94.
- Oven fails closed. Within its documented envelope, ordinary build, test, and run commands consume a compatible Loaf. Unsupported dependency or workspace shapes stop with guidance; they do not silently restore a Cargo backend.
- C interoperability is deliberately bounded. General pointers, callbacks, variadics, arbitrary span element types, and zero-copy returned views are not part of the 0.5 binding surface.
- Generated Rust is not a compatibility contract. Use checked Incan APIs, locks, receipts, and inspection output as the stable integration surfaces.
The long tail is the release
The headline features are backed by the unglamorous fixes that make real projects hold together.
The complete inventory below retains issue-level traceability across the compiler, standard library, workspaces, providers, native builds, diagnostics, packaging, and developer tooling.
Complete change inventory¶
The changes below are the long tail that makes the release story hold at real package, workspace, provider, and native boundaries. They remain detailed for upgrade diagnosis and issue traceability.
Open the complete fix list
- Toolchain: Incan now provisions the exact Rust release it was built against into its own
rustuphome and builds with that compiler, instead of whichever toolchain you have made your global default. A release ships prebuilt Rust libraries that load only under the compiler that produced them, so a machine with any other Rust version previously failed on its firstincan build. Your own default toolchain is never reconfigured. The release manifest now pins a concrete Rust version rather than a floatingstablechannel, and publishing refuses a manifest whose packaged hosts disagree on it. - Toolchain: On a machine with no Rust at all,
rustupis installed without a default toolchain so the compiler is downloaded once into Incan's own home rather than twice, and the installer prints how to select a default for your own use. - Toolchain: Homebrew installs prebuilt commands without running the installer, so its formula caveats now name the exact Rust release to select and the commands to select it.
- Toolchain: Linux archives are built against an older glibc, so the published binary starts on Ubuntu 22.04 LTS and Debian 12 rather than requiring a 2024-era distribution.
- Compiler: Deeply nested expressions no longer abort the compiler. A long chain of binary operators (for example a generated string concatenation of a thousand terms) previously exhausted the stack and killed the process with
fatal runtime error: stack overflowand no diagnostic; compilation now runs on a stack sized for the work, as does the language server, which typechecks on its own worker threads. - Oven Alpha: The messages you see when a project's dependencies have not been compiled yet now say that in plain terms and name the one command that fixes it, instead of describing internal receipt, closure, and envelope vocabulary.
- Oven Alpha: A consumer of a caller-owned
pub::provider that declares its own Rust registry dependencies (for example a query-engine library with its own DataFusion closure) now resolves that provider's registry dependencies against the provider's own sealed registry authority and dependency search closure instead of only the consumer's. Previously this failed closed with a confusing "no compatible receipt-bound Loaf registry leaf" error for packages the consumer never declared. - Oven Alpha: When a caller-owned provider's own registry closure resolves a shared package to a different compiled artifact than the consumer's closure already links, an executable bake now routes through one unified Cargo compilation of the generated project instead of direct-rustc composition, with a visible notice naming the conflicting package. Linking both artifacts previously produced two compiled instances of the same crate in one binary — for
tokio, a runtime "no reactor running" panic despite a fully successful build. Library bakes take the same unified-Cargo route when their dependency closure cannot be loaded as independently compiled parts. Unconflicted projects keep the direct-rustc fast path unchanged. - Oven Alpha: Release-base registry leaf substitution no longer swaps a project's own build-script-driven registry artifact (
build.rsoutput can differ despite identical declared package, version, and features) for the release base's matching one; substitution is restricted to ordinary, non-build-script leaves. - Oven Alpha: The bounded store no longer counts its own sidecar cache files toward a directory's measured physical bytes, and retained-entry admission reuses the cached measurement instead of re-walking the directory.
- Stdlib:
block_onnow reuses one process-wide Tokio runtime instead of building and dropping a fresh runtime per call, so a task or handle created in oneblock_oncall remains reachable from a later call. - Compiler:
.as_ref()results are now recognized as already-reference-shaped alongside.as_slice()/.as_str(), preventing a double borrow (&value.as_ref()) in generated Rust for external function arguments. - Compiler: Extracting a private
classfield through a constructor pattern (case Account(_secret=s): ...) now correctly receives a private-field diagnostic, matching how direct field reads already behave. Construction with a private field stays unrestricted, matching existing class semantics (#1076). - Compiler: Native Rust callback parameters typed as owned
Stringnow borrow instead of move when passed to more than one external Rust call, preventing generated Rust from failing to compile with a moved-value error (#1076). - Tooling:
incan checkandincan inspect rustno longer serve stale Rust interop metadata after editing a local path-dependency crate; the on-disk metadata cache now invalidates on path-dependency source changes, not only onCargo.toml/Cargo.lockchanges (#1076). - Compiler:
import pub::widgets.charts-style submodule imports now activate soft keywords for their full namespace path instead of only the top-level library segment, preventing a sibling namespace's vocabulary from being spuriously activated (#1076). - Packaging: Fixed a missing
toolchain-version.txtartifact entry in the npm publish workflow that would have failed the npm leg of every tagged release (#1076). - Stdlib:
std.uuidnow imports theIoErrortype required by itsstd.hash._streamingdependency closure, so UUID consumers compile through the native path. The existing native UUID regression exercises that complete closure (#1051). - Oven Alpha: An explicit public-library bake now publishes immutable package Loafs alongside its debug and release rlibs. A downstream IncQL/DataFusion consumer imports and selects that sealed provider closure during its own explicit bake, then links it without Cargo or a second DataFusion compilation. Path-dependency and provider identities now exclude local compiler, test-runner, VCS, and build output, so an unchanged warm bake no longer traverses its own caches. Project-extension schema 9 binds every direct registry alias to its exact locked package, version, registry, and checksum; packaged-library schema 6 seals checked
.incnlibmetadata and every declared provider sidecar; completed-output schema 12 retains schema 11's singular project inspection authority, isolates every declared executable by stable target identity and profile, separates canonical semantic lock authority from the derived dependency fingerprint, and carries report schema 2 for frontend-free replay through tagged project paths and opaque external-authority slots; project-inspection-authority schema 1 seals the exact Rust source metadata selected through that source-current completed output. Rust path dependencies now bind the exact[workspace.package]and[workspace.dependencies]facts they inherit instead of depending on ambient workspace interpretation.incan oven bake --projectaccepts the same Incan package-feature selection as normal commands and publishes every discovered library or declared executable target/profile pair plus the authority needed by matching dev/test dependencies. A subsequentbuild,build --lib, ortestwith the same source, semantic lock, feature, target, profile, compiler, and SDK evidence reuses that sealed project state. If only the derived dependency fingerprint is stale, a non-strict normal command warns and reuses;--lockedand--frozenreject it before selection, and any semantic input change fails closed or requires a new explicit bake. Older incomplete Loafs are deliberately rebaked. Provider and consumer targets, profiles, toolchains, and sealed ABI identities must match (#1046, #1054, #1056). - Oven Alpha: A public provider whose sealed closure is self-contained
direct_rustc_plannow composes into an explicitly baked consumer through the same receipt- and identity-checked package Loaf path as a release-base extension; consumer selection never resolves that provider closure again or falls back to Cargo (#1053). - Language: A same-signature class method alias now satisfies an adopted trait requirement during lowering and emits the required trait method while retaining the concrete target method; missing or incompatible aliases remain rejected (#1055).
- Compiler: String membership probes now borrow owned loop bindings when later generated code still uses them, rather than moving the value or adding a clone (#1057).
- Compiler: String membership now borrows the probe at its point of comparison, so a probe produced by a function call, method call, field read, or f-string is no longer handed to
AsRef::as_refby value.inandnot inagainstlist[str]andset[str]compile for every owned-string expression, not only bare variables (#1066). - Compiler: Function-call and method-call results now go through the same ownership/borrow/clone planning as every other expression at return values, struct fields, collection elements, match scrutinees, and widened call arguments. A borrowed result — for example
receiver.as_ref()or a call returning&T— is now materialized into an owned value at these sinks instead of leaking an unconverted borrow (#1066). - Language: Decorator argument lists now accept a trailing comma, matching ordinary multiline calls. This fixes valid
@describe(..., )declarations that previously stopped at the closing parenthesis with an expression parse error (#1000, #1015). - Compiler: Descriptor constants may now safely contain an empty
FrozenListof a nested descriptor model. The compiler proves the actual immutable initializer rather than rejecting it solely because the list element type is not independently const-emittable (#1001). - Registry metadata: A public registry imported from another source module retains its defining module as the canonical registry identity.
@describeattachments no longer create a competing consumer-owned catalogue entry (#1004). - Builds: Generated libraries retain a hyphenated Incan package identity while emitting the valid underscore-normalized Rust target name required by Cargo and direct
rustc(#995). - Testing: A successful Oven native test harness now reports its selected Incan test identities as passed even if libtest omits an individual outcome line from its transcript (#996).
- Workspaces: A rooted workspace whose root is a library can publish one canonical lock for its root and members without inventing a runnable script entrypoint (#997).
- Runtime dependencies: The embedded Wasmtime/WASI stack uses the patched 36.0.13 maintenance line after
RUSTSEC-2026-0222affected the 45.0.3 line. The patched 46.0.2 release requires Rust 1.94, so 36.0.13 preserves Incan 0.5's Rust 1.93 MSRV while retaining the security fix. - Compiler: A nested source module no longer silently imports itself when a same-leaf bare import collides with the module name. Use
crate::module_namefor an intended project-root import (#976). - Language: F-string interpolation retains support for direct zero-argument function calls, such as
f"enabled:{enabled()}"; parser and complete-CLI regression coverage now protect that form (#979). - Language: Built-in mutable
Set[T]values now exposeadd(value)consistently with the documented collection surface. The operation typechecks asNone, lowers toHashSet::insert, and preserves set deduplication (#963). - Compiler: Public computed properties on models and classes now travel through checked API metadata and
.incnlibcontracts, so consumers of a compiled library can typecheck property access using the published result type (#952). - SDK providers: Source SDK preparation now validates the catalog's declared compiler range before compiling any component. A stale compiler therefore reports the incompatible source-SDK requirement directly instead of emitting unrelated provider type errors later in preparation (#945).
- SDK providers: Stdlib lowering now reuses one parsed module cache across direct imports, façade re-exports, recursively loaded submodules, and source-default lookup instead of reparsing the same stdlib tree for each call. On the measured cold-provider fixture, preparation fell from 416–422 seconds to 204 seconds without changing provider identities, generated code, or test coverage (#957).
- Compiler: Type-only generic Rust declarations now retain their owner type parameters in inspection and compiled-library metadata, so associated constructors such as
Fft.new[f32](...)validate their complete signature and emit a receiver turbofish while an expectedFft[f32]result can infer the same specialization without brackets. Const-generic receivers fail with a checked diagnostic instead of emitting a misplaced Rust argument. Generated applications, compiled-package consumers, and test batches share the checked receiver decision (#961). - Compiler: Derived source traits now retain their canonical declaring module when imported directly into another source module, so method calls across compiled-library boundaries emit provider-qualified Rust paths instead of depending on an unrelated local module alias. Multi-module JSON libraries can therefore define
@derive(json)models separately fromSerialize-using helpers and publish both through a package facade (#946). - Compiler: Canonical
Iterator[T]values now retain their item type when used directly asforand comprehension sources. Source-owned adapters such aszip,take, andenumerateare polled throughIterator.__next__()without invalid Rust struct-literal loops or collection-only.iter()injection, including composed tuple-producing adapters. The builtinzip(left, right)now has the same lazyIterator[tuple[T, U]]contract asleft.iter().zip(right.iter())instead of being typed as an eager list (#950, #953). - Compiler:
set(values)andSet(values)now preserve the frontend's canonical collection-constructor decision through lowering and emit a typed RustHashSetcollection instead of an unresolved function call. A user-defined function namedsetcontinues to shadow the collection constructor normally (#951). - Lockfiles: Compiled providers now publish a digest of their authored manifest and selected Incan source inputs for canonical semantic identity, while generated Rust and host ABI metadata remain under the byte-exact physical artifact digest. Equivalent native provider builds therefore share one SDK inventory and dependency fingerprint across macOS and Linux without weakening strict locks or user-authored path dependency identity (#931).
- Compiler: Published Rust ABI metadata now excludes traits introduced only by unrelated downstream crates in the loaded inspection graph, keeping SDK provider identities and workspace dependency fingerprints stable across cache state and host platforms (#924).
- Compiler: Legacy
read_fileandwrite_filebuiltins now convert Rust filesystem errors into their declared owned Incanstrerror type, so string operations onResulterrors compile through generated Rust (#874). - Web: Route handlers now retain concrete
Query[T],Json[T], and typedPath[T]extractors in generated Rust, while source-level scalar path captures are grouped into the Axum 0.8 path extractor expected by the route. Routes preserve{capture}syntax, support multiple captures and methods, and let Axum return client errors for malformed typed request data (#867). - Tooling: Canonical lock publication now keeps its persistent cross-process guard under ignored compiler target state instead of leaving
.incan.lock.incan.lockin the project root (#912). - SDK providers: Official stdlib component packages now preserve their source-owned Apache-2.0 license in generated Cargo metadata, so downstream dependency audits no longer classify synthesized provider crates as unlicensed (#920).
- Stdlib: Cold SDK preparation now copies borrowed regex matches and capture names into owned
std.regexvalues instead of calling an unavailable&str.to_string()method (#918). - SDK providers: Compiled library artifacts now rebind SDK path dependencies to the active content-addressed provider cache, including copied support crates, so semantically identical components cannot enter one Cargo graph through conflicting cache roots (#911).
- Lockfiles: Canonical dependency fingerprints now use checked SDK provider identities instead of physical cache paths, rooted-workspace lock generation snapshots artifacts after preparation, and selected library builds re-root the aggregate Cargo resolution onto the member's exact dependency closure. Clean and relocated provider stores now converge on one lock, target-free strict member builds consume it directly, and an immediate relock stays byte-identical. Compatibility note: non-strict build and test commands still warn and leave a stale
incan.lockuntouched, but no longer use its embedded Cargo lock as authority; strict modes still reject it (#921). - Compiler: Published library Rust ABI metadata now performs complete Rust metadata extraction for the selected public ABI query paths instead of relying on the current rust-inspect prewarm cache, keeping cold and warm artifacts identical when earlier commands inspected only part of that selected surface (#922).
- Compiler: Cold library and SDK-provider builds now preserve Rust functions returning
Stringas Incanstrexpressions, so direct compound assignments use string-aware lowering without requiring an explicitly typed intermediate local (#896). - Toolchain: Prelude parsing, stdlib type metadata, testing markers, and compiled SDK-provider publication now resolve one canonical stdlib source tree.
INCAN_STDLIBandINCAN_STDLIB_DIRare true overrides, preventing a compiler in a shared Cargo target from mixing its source checkout with an older executable-adjacent stdlib. - Workspaces: Rooted workspace library artifacts now retain the selected project's identity across Cargo package, Cargo library, and
.incnlibmetadata, while removing self-dependencies even with explicit output overrides so external consumers can compile the published package (#909). - Workspaces: Root library dependency preparation now targets exactly that project and leaves canonical lock publication to its parent command, preventing fresh rooted workspaces from recursively spawning
incan build --libuntil the machine is exhausted (#908). - Workspaces: Rooted-workspace entrypoints and tests now resolve through their deepest owning member, so selected member builds retain both direct and inherited Rust dependency versions (#907).
- Workspaces: Canonical workspace locks now rebase nested package roots and feature edges into workspace-relative coordinates, keeping cross-member semantic state and fingerprints portable across checkout locations (#906).
- Compiler: Batched test modules now keep transitive dependency imports out of each other's local scopes, so separate test files can legitimately import the same public package symbols while true duplicate bindings inside one module remain rejected (#898).
- Compiler: Public types imported from compiled libraries now retain provider-qualified nominal identity across split imports, multiple local aliases, qualified module calls, nested generics, and generated test batches, without unifying same-named types from separate dependencies (#892).
- Compiler: Generated Cargo packages now preserve the authored Incan project version and SPDX license for application and library builds, keeping library
Cargo.tomlversions aligned with their.incnlibmanifests (#889). - Compiler:
std::io::stdout()now retains its stableStdoutreceiver type when sysroot metadata is unavailable, so fallible extension-trait calls such as crossterm'sExecutableCommand.execute(...)expose their nativeResultand support postfix?(#888). - Compiler: Unbound names in source type annotations now receive an Incan diagnostic before code generation instead of reaching generated Rust as undeclared types; explicit generics, forward declarations, and transparent generic aliases remain valid (#902).
- Compiler: JSON deserialization of validated newtypes now reconstructs through the canonical
from_underlyinghook or primitive constraints, including nested model and container fields, so invalid wire values returnErrinstead of creating invalid nominal values (#904). - Compiler: Class-field privacy now survives checked metadata and compiled package boundaries. Named construction through a compiled package uses an exact package-owned constructor bridge—including aliases, inherited fields, and provider-owned defaults—while later private member access receives an Incan diagnostic instead of a Rust privacy failure; older manifests without field visibility retain their compatible public behavior (#883).
- Compiler: Public classes imported from ordinary source modules now construct through the exact declaring-provider bridge when they contain private fields. Direct imports, aliases, and multi-hop public facade re-exports preserve declared field order and defaults even when sibling modules export classes with the same name, while later private member access remains an Incan type error (#886).
- Compiler: Consumer subclasses of classes imported from compiled libraries now lower the typechecker’s complete parent-first field layout into generated Rust, preserving inherited order, visibility, materializable defaults, exact Rust field types, and source-level reflection names across application builds and package test batches (#885).
- Language: Fields on public models now follow the ordinary visibility rule:
pubexposes a field, while an unmodified field is private to the declaring model. Privacy is preserved across access, construction, patterns, aliases, source facades, checked metadata, compiled libraries, generated Rust, and test batches; runtime reflection exposes public fields only, while serialization remains an explicitly adopted complete-data-shape behavior. Existing DTO-stylepub modeldeclarations must addpubto fields that remain part of their public surface (#884). - Compiler: Generated Rust libraries no longer expose public all-fields constructors for models with private inputs. Required private fields remain constructible only through Incan-authored factories, while default-backed private fields stay provider-owned behind a public-field bridge; all-public models and the distinct complete-constructor contract for classes remain unchanged (#964).
- Compiler: Expected
Result[T, E]contexts now select the exact repeated generic trait method by recursively comparing the complete result type, so typedstd.io.BinaryRead[T]calls keep their requested integral or floating width through compiled providers, generated Rust, and package test batches while calls without enough context remain ambiguous (#955). - Compiler: Absolute sibling-module imports such as
from crate.types import Decisionnow retain public model fields and enum variants across direct checks, generated builds, library builds, re-exports, and test batches (#882). - Stdlib:
std.regexreplacement and split operations now reconstruct strings with the regex engine's UTF-8 byte spans, preserving characters adjacent to non-ASCII matches while keeping public match offsets byte-based (#893). - Compiler: String literals returned from closures now materialize owned Incan
strvalues, soResult.map_errand other closure consumers generate RustStringvalues instead of borrowed&strvalues (#880). - Compiler: Imported mutable Rust trait receivers now distinguish owned values from dereferenceable guards, so calls such as
Read.by_ref(input)emit a valid direct borrow forStdinwhile stdlibRefMutreaders retain their required reborrow (#878). - Compiler: Rust interop method calls with inferred
Into-bound generic parameters now keep string literals in an inferable shape instead of generating ambiguous.into()calls (#804). - Compiler: Rust boundary metadata now preserves pointer-sized integer identity, so
usizeandisizearguments are no longer reported as mismatches against themselves (#803). - Compiler: Expression-position vocab declarations now activate their declaration-owned clause keywords, keeping parser routing and downstream syntax ownership aligned (#813).
- Compiler: Generic
Index[K, V]adoptions now retain their key and output substitutions through lowering and generated Rust, including adopters whose trait arguments useSelf(#815). - Compiler: Trait-typed receivers may call only methods available through the declared trait and its supertraits; methods belonging only to narrower subtraits now receive an Incan diagnostic (#817).
- Compiler: Rust callback metadata now preserves borrowed slice parameters in
FnMutbounds for imported functions and trait methods. Named callbacks can use borrowedlist[T]parameters, while inline closures are contextually typed from the inspected Rust bound, allowing both forms to satisfy APIs that pass&[T]or&mut [T]values (#835). - Compiler: Incomplete explicit generic arguments on inspected Rust methods are rejected during Incan typechecking with the method's required arity, instead of failing later in generated Rust compilation (#834).
- Compiler: Generic Rust function results can now be inferred from an annotated return or parameter context through
Result.unwrap(), including generated package-test builds such asserde_json::from_str(#852). - Compiler: Rust interop now preserves callable bounds such as
FnMut(&mut T, &U)when checking generic callback parameters, so by-value Incan callbacks are rejected at typecheck instead of reaching Rust codegen with an invalid borrowed callback shape (#805). - Compiler: Rust interop now preserves concrete
&Tand&mut Tmethod parameters through complete metadata extraction and generated Rust; mutable Incan bindings are required for&mut Tcalls (#861). - Compiler: Generic value-reflection bounds are preserved for impl-method-owned type parameters, and direct dependency-module generation now typechecks before lowering so root Rust trait imports stay available in generated module tests (#819, #827).
- Compiler: Rust interop now preserves inspected
&dyn Traitand&mut dyn Traitparameter shapes through typechecking, lowering, and generated Rust, including a source-level diagnostic when an exclusive borrow requires an Incanmutbinding (#832). - Compiler: Rust interop now preserves the diverging
!return type as an internal bottom type, so combining Rust and source-module imports no longer causes unrelated return-type mismatches in modules that call diverging Rust helpers (#381).