Ignis is a general-purpose, statically typed language that compiles Ignis source to C and links native binaries via GCC. The repository is a Rust workspace containing compiler crates, LSP support, standard library sources, and a C runtime.
- Languages: Rust (compiler, LSP), Ignis (
.ignsources, standard library), C (runtime, generated output). - Tooling: Cargo workspace, GCC for C compilation/linking,
arfor static archives,makefor runtime rebuilds. - Testing:
instafor snapshot tests,proptestfor property-based tests,tempfilefor compilation sandboxes, nativeignis testfor language-level tests. - LSP:
tower-lspwith Tokio async runtime. - CLI:
clapwith derive macros and typed subcommands.
crates/
ignis/ # CLI entry point
src/main.rs # Subcommand routing, config resolution
src/cli.rs # Clap CLI definition
tests/test_command.rs # CLI integration tests for `ignis test`
ignis_driver/ # Build pipeline orchestration
src/pipeline.rs # Full pipeline: analysis → mono → LIR → codegen → link
src/context.rs # Module discovery, import resolution, per-module parsing
src/link.rs # GCC compilation, archive creation, executable linking
tests/native_test_runner.rs # Project + single-file native test runner integration tests
tests/e2e_ok.rs # E2E tests (compile + run)
tests/e2e_err.rs # E2E error tests (runtime failures)
tests/common/mod.rs # Shared test helpers
ignis_parser/ # Lexer + parser
src/lexer/ # Token scanner
src/parser/mod.rs # Parser core, delimited list helpers
src/parser/declarations.rs # Functions, records, enums, imports, attributes
src/parser/expression.rs # Pratt-precedence expression parsing
src/parser/statement.rs # Statement parsing
src/parser/type_syntax.rs # Type annotation parsing
src/parser/recovery.rs # Error recovery strategies
ignis_analyzer/ # Semantic analysis (7 phases)
src/lib.rs # Analyzer struct, phase dispatch, entry points
src/binder.rs # Phase 1: definition creation (two-pass)
src/resolver.rs # Phase 2: name resolution, scope building
src/typeck.rs # Phase 3: type inference and checking
src/const_eval.rs # Phase 4: compile-time constant evaluation
src/checks.rs # Phase 5: extra semantic checks (control flow, etc.)
src/lint.rs # Phase 6: lint warnings
src/lowering.rs # AST → HIR conversion
src/mono.rs # Monomorphization (generic specialization)
src/scope.rs # Scope tree (Global, Function, Block, Generic, Loop)
src/imports.rs # Module import/export handling
src/modules.rs # Module graph management, cycle detection
src/capture.rs # Closure capture analysis (what closures capture and how)
src/escape.rs # Escape analysis (whether closures outlive their scope)
src/borrowck_hir.rs # HIR-level borrow checking
src/ownership_hir.rs # HirOwnershipChecker, drop schedule generation
src/dump.rs # Debug dump utilities for types and definitions
tests/golden_ok.rs # Analyzer snapshot tests (valid programs)
tests/golden_err.rs # Analyzer snapshot tests (error programs)
tests/golden_hir.rs # HIR output snapshots
tests/fixtures.rs # Tests from test_cases/ .ign files
tests/diagnostics.rs # Error code + line number assertions
tests/properties.rs # Property-based fuzz tests (proptest)
ignis_hir/ # High-level IR
src/lib.rs # HIRNode, HIRKind, HIR store
src/pattern.rs # HIRPattern, HIRMatchArm (match, if let, let else)
src/statement.rs # Loop condition types
src/operation.rs # BinaryOperation, UnaryOperation
src/drop_schedule.rs # DropSchedules, ExitKey
src/display.rs # HIR pretty printer
ignis_lir/ # Low-level IR (TAC / basic blocks)
src/instr.rs # Instruction types (Load, Store, BinOp, Call, etc.)
src/operand.rs # Operand types (Immediate, Temporary, Local, FunctionRef)
src/block.rs # Block, Terminator (Jump, CondJump, Return, Unreachable)
src/program.rs # FunctionLir, LirProgram, LocalData, TempData
src/lowering/mod.rs # LoweringContext: HIR → LIR conversion
src/lowering/builder.rs # FunctionBuilder: block/instruction emission
src/verify.rs # LIR verification
ignis_codegen_c/ # C code generation
src/emit.rs # CEmitter: LIR → C source code
src/classify.rs # Definition classification (User/Std/Runtime)
tests/golden_c.rs # C codegen snapshot tests
ignis_ast/ # AST node types
src/statements/mod.rs # ASTStatement enum (Variable, Function, Record, Enum, Trait, LetElse, etc.)
src/expressions/mod.rs # ASTExpression enum (Binary, Call, Match, LetCondition, etc.)
src/type_.rs # IgnisTypeSyntax (parsed type annotations)
src/pattern.rs # ASTPattern (Wildcard, Literal, Path, Tuple, Or)
src/attribute.rs # ASTAttribute, ASTAttributeArg
src/metadata.rs # ASTMetadata bitflags (STATIC, MUTABLE, EXPORT, etc.)
src/generics.rs # ASTGenericParams, ASTGenericParam
ignis_type/ # Type system and definitions
src/types.rs # Type enum, TypeId, TypeStore, Substitution
src/definition.rs # Definition, DefinitionKind (incl. Trait), DefinitionId, DefinitionStore
src/symbol.rs # SymbolId, SymbolTable (interned identifiers)
src/attribute.rs # RecordAttr, FunctionAttr, FieldAttr, ParamAttr, NamespaceAttr
src/lint.rs # LintId, LintLevel
src/span.rs # Source locations
src/module.rs # ModuleId, ModulePath, ModuleStore
src/namespace.rs # NamespaceId, NamespaceStore
src/value.rs # Literal values (IgnisLiteralValue)
ignis_token/ # Token types
src/token_types.rs # Token enum (keywords, punctuation, literals)
ignis_data_type/ # Legacy data type enum (used by ignis_token)
ignis_config/ # Build configuration types
src/lib.rs # IgnisSTDManifest, CHeader, StdToolchainConfig, StdLinkingInfo
ignis_formatter/ # Canonical source formatter
src/api.rs # format_text/format_file entry points, safety + idempotence integration
src/config.rs # Formatter config loading, CLI override precedence
src/layout.rs # AST-guided layout engine + source-preserving fallbacks
src/printer.rs # Final trivia-aware emission
src/safety.rs # Parse-back, token-shape, comment-ownership validation
ignis_diagnostics/ # Error reporting
src/message.rs # DiagnosticMessage enum (450+ variants)
src/diagnostic_report.rs # Diagnostic, Severity, Label
ignis_log/ # Build output formatting
src/lib.rs # cmd_header!, phase_log!, cmd_ok!, cmd_fail! macros
ignis_lsp/ # Language Server
src/lib.rs # Async server setup (Tokio + tower-lsp)
src/server.rs # LanguageServer trait impl (hover, goto-def, refs, etc.)
src/state.rs # Document state, project caching (RwLock)
src/completion.rs # Token-based completion (works without valid AST)
src/at_items.rs # Registry of @-prefixed builtins and directives
src/type_format.rs # Type formatting for LSP hover/display
src/convert.rs # UTF-16 position conversion
src/semantic.rs # Semantic token classification
src/inlay.rs # Parameter name inlay hints
src/project.rs # ignis.toml discovery and project caching
std/ # Ignis standard library
manifest.toml # Module registry and linking configuration
io/mod.ign # Print functions (println, print, eprintln, eprint) + IoError
io/error.ign # ErrorKind enum and IoError record
string/mod.ign # String utilities (length, concat, forEach, map, etc.)
memory/mod.ign # Allocation (allocate, free, reallocate, copy, move)
memory/align.ign # Alignment utilities
memory/layout.ign # Memory layout
vector/mod.ign # Vector<T> (growable array with push, pop, at, etc.)
math/mod.ign # Math functions (sin, cos, sqrt, pow, floor, ceil, etc.)
number/mod.ign # Numeric helpers (abs, toFixed, round, floor, ceil)
types/mod.ign # Runtime type IDs
option/mod.ign # Option<S> (SOME/NONE)
result/mod.ign # Result<T, E> (OK/ERROR)
rc/mod.ign # Rc<T> and Weak<T> (reference-counted pointers)
libc/mod.ign # C standard library wrappers (9 submodules)
ptr/mod.ign # Pointer utilities
ffi/mod.ign # FFI utilities (CString)
fs/mod.ign # Filesystem (readToString, writeString, Dir, File, Metadata)
path/mod.ign # Path manipulation utilities
test/mod.ign # `std::test::Test` assertions and snapshot helpers
runtime/ # C runtime implementation
ignis_rt.h # Runtime API header (types, strings, Rc, memory)
libignis_rt.a # Precompiled runtime archive
Makefile # Runtime build system
internal/rt_memory.c # malloc/free/realloc wrappers
internal/rt_string.c # IgnisString operations
internal/rt_io.c # stdout/stderr printing
internal/rt_rc.c # Reference counting (Rc/Weak)
test_cases/analyzer/ # Ignis fixture files organized by feature
borrows/ # Borrow checking tests
casts/ # Cast validation tests
extern/ # Extern block tests
for_of/ # For-of iteration tests
generics/ # Generic type tests
lang_traits/ # Drop, Clone, Copy trait validation
missing_return/ # Return path analysis tests
mutability/ # Mutability checks
overloads/ # Function overloading tests
ownership/ # Ownership transfer tests
type_errors/ # Type error tests
unreachable/ # Unreachable code tests
example/ # Example Ignis programs
docs/ # Language reference and ABI docs
Entry: crates/ignis/src/main.rs
Parses commands via clap, resolves compile input (project ignis.toml or single file), and builds IgnisConfig with CLI overrides (opt_level, debug, out_dir, std_path, cc, emit).
Subcommands: build, check, fmt, test, build-std, check-std, check-runtime, lsp.
Entry: crates/ignis_formatter/src/api.rs and crates/ignis/src/main.rs → run_fmt()
The formatter is a parser-aware, safety-validated canonical rewriter for Ignis source.
- Input modes: project, single file, multiple explicit files, and NDJSON batch stdin.
- Canonical empty high-level blocks emit inline (
namespace Foo {}). - Trailing commas are layout-driven: multiline call/initializer lists gain a final comma, single-line canonical output drops it.
namespaceandexternbodies containing raw compile-time directives use source-preserving fallback instead of reparsing branch-selected AST.- Safety validation checks parse-back, token-shape stability, comment ownership, directive structure, trailing whitespace, final newline, and idempotence.
- Import sorting is opt-in only via formatter config or
--sort-imports.
Entry: crates/ignis_driver/src/pipeline.rs → compile_project()
Orchestrates the full compilation pipeline. Two codegen paths:
- Module-based (when precompiled std archive exists): per-module header generation, per-module C emission with fingerprint-based caching, user archive creation, final linking.
- Legacy single-file: all code emitted to one C file, compiled directly.
Caching uses stamp files with BuildFingerprint (compiler version + ABI version + source hashes) to skip recompilation of unchanged modules.
Entries: crates/ignis_driver/src/pipeline.rs → run_project_tests() / run_single_file_tests()
The native test runner reuses the normal analysis → mono → LIR → codegen → link pipeline, but swaps the normal entry wrapper for a generated test harness. The harness executes discovered @test functions one by one, preserves deterministic ordering, continues after failures, and forwards snapshot context through environment variables.
Runner responsibilities:
- discover
@testfunctions from analyzed modules - build deterministic fully-qualified test names
- support project-mode and single-file mode
- execute tests through a harness binary
- expose snapshot context (
IGNIS_TEST_NAME,IGNIS_TEST_SNAPSHOT_DIR,IGNIS_TEST_UPDATE_SNAPSHOTS) - report failures with bounded stderr/stdout detail
Entry: crates/ignis_driver/src/context.rs → CompilationContext
discover_modules()builds a module dependency graph starting from the entry file.discover_recursive()follows imports to discover transitive dependencies.discover_std_module()resolvesstd::module_nameviamanifest.toml.parse_file()runs lexer → parser for each discovered file.- Modules are analyzed in topological order (dependencies first).
Entry: crates/ignis_parser/src/parser/
Recursive-descent parser with Pratt-style operator precedence for expressions.
- Pratt parsing: uses binding power tuples
(lbp, rbp)where low = low precedence. - Type argument disambiguation: lookahead heuristic to distinguish
<as comparison vs generic args. - Attribute collection:
@nameand@name(args)parsed intopending_attrs, consumed by the next declaration. - Error recovery: synchronizes to declaration boundaries on parse errors.
- Recursion safety:
MAX_RECURSION_DEPTH = 500prevents stack overflow.
Entry: crates/ignis_analyzer/src/lib.rs → Analyzer::analyze_with_shared_stores()
Seven sequential phases over the AST:
| Phase | File | Purpose |
|---|---|---|
| 1. Binding | binder.rs |
Two-pass: predeclare types (pass 1), then complete all definitions (pass 2). Enables forward references. |
| 2. Resolution | resolver.rs |
Resolve identifiers to DefinitionId via scope lookup. Build scope tree. |
| 3. Type Checking | typeck.rs |
Bidirectional type inference. Propagates expected types downward via InferContext. Handles overload resolution. |
| 4. Const Eval | const_eval.rs |
Evaluate constant expressions at compile time. Populate ConstantDefinition::value. |
| 5. Extra Checks | checks.rs |
Control flow analysis (missing returns, unreachable code, never-typed expressions). |
| 6. Lints | lint.rs |
UnusedVariable, UnusedImport, UnusedMut, Deprecated. Respects @allow/@warn/@deny directives. |
After all phases, lower_to_hir() converts the typed AST into HIR. This stage also runs capture analysis (capture.rs) and escape analysis (escape.rs) for closures.
Output: AnalyzerOutput containing TypeStore, DefinitionStore, HIR, diagnostics, and lookup maps (node_defs, node_types, node_spans, resolved_calls) used by the LSP.
Entry: crates/ignis_analyzer/src/mono.rs → Monomorphizer
Transforms generic HIR into concrete HIR with all type parameters resolved:
- Discovery — scan HIR for generic instantiations (calls with type args, record inits, method calls).
- Shell creation — create
DefinitionIdentries with mangled names for each concrete instance. - Body substitution — clone generic bodies, replacing
Type::Paramwith concrete types viaSubstitution. - Fixpoint — repeat until no new instantiations are discovered.
Invariant: post-mono, no Type::Param or Type::Instance should exist. Debug builds verify with verify_no_generics().
Entry: crates/ignis_analyzer/src/borrowck_hir.rs → HirBorrowChecker
Runs on monomorphized HIR. Tracks borrow states per variable (None, Imm(count), Mut), validates that mutable borrows are exclusive, and detects use-after-move and conflicting borrows. Borrow lifetimes are scope-based.
Entry: crates/ignis_analyzer/src/ownership_hir.rs → HirOwnershipChecker
Runs on monomorphized HIR after borrow checking. Validates move semantics and reference rules. Produces DropSchedules that map HIR nodes to their exit points where cleanup code should be emitted (end of block, break, continue, return).
Location: crates/ignis_hir/src/
Tree-based intermediate representation preserving program structure. Each HIRNode has a HIRKind (operation), Span (source location), and TypeId (inferred type). Uses DefinitionId references instead of names.
Key HIRKind categories:
- Expressions:
Literal,Variable,Binary,Unary,Call,CallClosure,Cast,BitCast,Reference,Dereference,Index,VectorLiteral,FieldAccess,MethodCall,EnumVariant,RecordInit,Match,StaticAccess,Closure. - Statements:
Let,LetElse,Assign,Block,If,Loop,Break,Continue,Return,Defer,ExpressionStatement. - Patterns:
HIRPattern(Wildcard, Literal, Binding, Variant, Tuple, Or, Constant) used byMatch,LetElse, and let-conditions inIf/Loop. - Builtins:
SizeOf,AlignOf,MaxOf,MinOf,Panic,Trap,BuiltinUnreachable,BuiltinLoad,BuiltinStore,BuiltinDropInPlace,BuiltinDropGlue. - Closures:
HIRKind::Closurecarries params, captures (HIRCapture), thunk/drop definitions, escape flag, and capture mode overrides.
Location: crates/ignis_lir/src/
Three-address code (TAC) with basic block structure. Each instruction has at most one operation with results stored in temporaries (TempId) or locals (LocalId).
- Instructions:
Load,Store,LoadPtr,StorePtr,BuiltinLoad,BuiltinStore,Copy,BinOp,UnaryOp,Cast,BitCast,Call,RuntimeCall,GetElementPtr,InitVector,InitRecord,InitEnumVariant,EnumGetTag,EnumGetPayloadField,GetFieldPtr,SizeOf,AlignOf,MaxOf,MinOf,AddrOfLocal,Drop,DropInPlace,DropGlue,Trap,PanicMessage,MakeClosure,CallClosure,DropClosure,TypeIdOf,Nop. - Terminators:
Goto,Branch,Return,Unreachable. - Program structure:
LirProgramcontainsHashMap<DefinitionId, FunctionLir>. EachFunctionLirhas an entry block, a store ofBlocks,LocalData, andTempData.
Lowering: LoweringContext (in lowering/mod.rs) converts HIR to LIR, managing block creation, control flow, drop scheduling, and temporary allocation. FunctionBuilder (in lowering/builder.rs) emits instructions into blocks.
Verification: verify.rs checks LIR well-formedness after lowering.
Entry: crates/ignis_codegen_c/src/emit.rs → CEmitter
Emission pipeline:
emit_implicit_headers()— stdio, math, string as needed.emit_headers()— user-provided C headers fromLinkPlan.emit_type_forward_declarations()— forward struct/enum declarations.emit_type_definitions()— full struct and tagged union definitions.emit_static_constants()— global constants.emit_extern_declarations()— external C function prototypes.emit_forward_declarations()— function prototypes.emit_functions()— function implementations.
Type representation in C:
- Records → named structs with mangled names.
- Enums → tagged unions (tag field + payload union). Each variant gets a
#define TAG_VARIANT value. - Generic types → only fully monomorphized instances emitted.
Classification: classify.rs determines whether a definition is User, Std, or Runtime code. Emission targets (EmitTarget) control which definitions are included: User, StdModule(name), UserModule(ModuleId), or All.
Attribute mapping to C:
@packed→__attribute__((packed))@aligned(N)→__attribute__((aligned(N)))@cold→__attribute__((cold))@inline(always)→__attribute__((always_inline)) inline@inline(never)→__attribute__((noinline))@externName("name")→ uses the specified C symbol name.
Entry: crates/ignis_driver/src/link.rs
Three stages:
- Object compilation:
gcc -c <input.c> -o <output.o> -I <include_dirs>. - Archive creation:
ar rcs <archive.a> <obj1.o> <obj2.o> .... - Executable linking:
gcc <objects> <user.a> <std.a> <runtime_objects> -o binary -l<libs>.
Link order is critical: user objects → user archive → std archive → runtime objects → external libraries.
LinkPlan carries headers, objects, archives, libs, and include dirs through the pipeline.
Entry: crates/ignis_lsp/src/
Capabilities: diagnostics, hover (type info + docs), go-to-definition, find references, completions, semantic tokens, inlay hints (parameter names), workspace symbols, document symbols, file watching.
Key design decisions:
- Token-based completion (
completion.rs): detects context from tokens (after.,::, in imports, in record init) without requiring a valid AST. Works even when the file has parse errors. - Panic safety: analysis wrapped in
catch_unwind()to prevent server crashes. - Caching: analysis results cached per document version. Last good analysis preserved for incomplete code.
- File overrides: open file content collected from LSP state, overriding disk content for analysis.
Registry: std/manifest.toml maps module names to .ign files and declares linking requirements (headers, archives, -l flags).
Key modules:
| Module | Provides |
|---|---|
io |
println, print, eprintln, eprint, IoError, ErrorKind |
string |
length, concat, substring, contains, forEach, map, toUpperCase, toLowerCase, toString overloads |
memory |
allocate<T>, free<T>, reallocate<T>, copy<T>, move<T>, Layout, Align |
vector |
Vector<T> with init, push, pop, at, clear, shrink (implements Drop) |
math |
sin, cos, sqrt, pow, floor, ceil, round, constants (PI, E, TAU) |
number |
Numeric helpers (abs, toFixed, rounding wrappers via extensions) |
types |
Runtime type IDs |
option |
Option<S> with SOME/NONE, helpers (isSome, isNone, unwrap, unwrapOr) |
result |
Result<T, E> with OK/ERROR, helpers (isOk, isError, unwrap, unwrapOr) |
rc |
Rc<T> (shared ownership), Weak<T> (non-owning observer) |
test |
std::test::Test namespace: generic assertions and snapshot helpers |
libc |
C standard library wrappers (memory, string, process, io, stdio, errno, misc, primitives) |
ptr |
Pointer utilities |
ffi |
FFI utilities: CString (owned NUL-terminated C string) |
fs |
Filesystem: readToString, writeString, Dir, File, Metadata (returns Result<T, Io::IoError>) |
path |
Path manipulation utilities |
Auto-loaded modules (always available without explicit import): string, number, vector, types, option, result.
Std modules use extern namespace declarations backed by C runtime functions.
The canonical equality contract behind generic test assertions is std::hash::Eq. Generic Test::assertEq<T> / assertNe<T> route through builtin @eq<T> after analyzer validation, and unsupported equality must be rejected before codegen.
Location: std/runtime/
Provides:
- Memory:
ignis_alloc,ignis_free,ignis_realloc,ignis_calloc,ignis_memcpy,ignis_memmove. - Strings:
IgnisStringheap type withignis_string_new,ignis_string_from_cstr,ignis_string_concat,ignis_string_substring, etc. Output-pointer_init_variants for safe struct return. - I/O:
ignis_print,ignis_eprint. - Reference counting:
IgnisRcBoxwithignis_rc_alloc,ignis_rc_retain,ignis_rc_release,ignis_rc_get, weak references. - Type conversions:
ignis_i32_to_string,ignis_f64_to_string, etc. - Atoms:
ignis_atom_t(u32) type alias.
Built via Makefile → libignis_rt.a.
CLI args → IgnisConfig
↓
CompilationContext
discover_modules() → ModuleGraph + ParsedModules (AST per file)
↓
Analyzer (per module, topological order)
bind_phase() → DefinitionStore
resolve_phase() → node_defs, ScopeTree
typecheck_phase() → node_types, TypeStore
const_eval_phase() → ConstantDefinition::value
extra_checks_phase() → control flow diagnostics
lint_phase() → lint diagnostics
lower_to_hir() → HIR
↓
AnalyzerOutput (types, defs, hir, diagnostics, lookup maps)
↓
Monomorphizer::run() → concrete HIR (no Type::Param/Instance)
↓
HirBorrowChecker::check() → borrow diagnostics
↓
HirOwnershipChecker::check() → DropSchedules
↓
lower_and_verify() → LirProgram (basic blocks, TAC)
↓
CEmitter::emit_*() → C source (.c) + headers (.h)
↓
gcc -c → object files (.o)
ar rcs → archives (.a)
gcc link → executable binary
build/
bin/ # Linked executables
obj/ # Object files
c/ # Generated C source
build/std/ # Precompiled standard library (ignis build-std)
include/ # ignis_std.h + per-module .h files
lib/ # libignis_std.a
obj/ # Per-module .o files
src/ # Per-module .c files
build/user/ # User modules (module-based compilation)
include/ # Per-module .h files
lib/ # libignis_user.a
obj/ # Per-module .o files
src/ # Per-module .c files
The compiler generates a C main() wrapper around the user's main function:
- User
mainis emitted as__ignis_user_main. - The wrapper calls it and handles the return value.
Supported signatures:
main(): i32— exit code returned directly.main(): void— wrapper returns 0.main(): Result<i32, E>— OK unwraps the exit code; ERROR prints a panic message and callsexit(101).main(argc: i32, argv: *str)— argc/argv forwarded from C main.
| Type | Representation | C equivalent |
|---|---|---|
char |
Single byte (u8) |
u8 |
str |
UTF-8 NUL-terminated byte slice | const char* |
String |
Heap-backed UTF-8 byte buffer (data + len + cap) | IgnisString |
Char literals ('a') accept only single-byte ASCII or byte-range escapes (\u{00}–\u{FF}). Multi-byte char literals produce a compile error.
Closures compile through a multi-stage pipeline:
- Capture analysis (
capture.rs) — determines which outer variables a closure captures and the capture mode (by ref, by move, by ref-mut). - Escape analysis (
escape.rs) — determines if a closure outlives its defining scope.@noescapeon parameters prevents escape propagation. - HIR —
HIRKind::Closurecarries captures, thunk/drop definition IDs, and anescapesflag. - LIR —
MakeClosure(captures → env struct),CallClosure(indirect call through thunk),DropClosure(cleanup). - C codegen — non-escaping closures use stack-allocated env; escaping closures use heap-allocated env. Closure values are structs with
call(thunk fn ptr),drop(optional drop fn ptr), andenv(opaque*u8).
| File | Purpose |
|---|---|
Cargo.toml |
Workspace members, shared dependencies |
ignis.toml |
Project config: std_path, source_dir, target, optimize, out_dir |
std/manifest.toml |
Std module registry, linking config (headers, archives, -l flags) |
IGNIS_STD_PATH env |
Overrides standard library root path |
.rustfmt.toml |
2-space indent, 120 width, no import reorder, vertical params |
.editorconfig |
LF line endings, 2-space indent |