apple/swift
Embedded Swift
Active contributors: kubamracek, kavon
Purpose
Embedded Swift is a dialect of the language tailored for bare-metal and resource-constrained environments. Goals:
- No runtime allocator, no heap (or a very small heap that the user provides).
- No standard library features that depend on dynamic features (existentials, dynamic casting, reflection, autoreleasing).
- Predictable code size (whole-module specialization, dead-code elimination).
- Suitable for kernels, firmware, microcontrollers, and OS bootloaders.
It is a subset of Swift, not a separate language. Code is compiled with -enable-experimental-feature Embedded.
Directory layout
stdlib/public/EmbeddedPlatform/ # platform shims for embedded targets
stdlib/public/SwiftDirectRuntime/ # a minimal runtime alternative (no ARC for some configs)
stdlib/toolchain/ # statically-linkable runtime variants
docs/EmbeddedSwift/ # user-facing docs
├── EmbeddedSwiftStatus.md
├── ExistentialModule.md
├── EmbeddedSwiftMain.md
└── ...
test/embedded/ # 588+ commits in the last yearThe Swift compiler enforces embedded-mode restrictions in lib/Sema/ and a dedicated mandatory pass in SwiftCompilerSources/Sources/Optimizer/ModulePasses/EmbeddedSwiftDiagnostics.swift.
How it works
graph LR
Source["Swift source"] --> Frontend["swift-frontend -enable-experimental-feature Embedded"]
Frontend --> Sema["Sema (Embedded checks)"]
Sema --> SILGen
SILGen --> SILOpt["SIL optimizer (mandatory + perf)"]
SILOpt --> Diags["EmbeddedSwiftDiagnostics module pass"]
SILOpt --> IRGen
IRGen --> ObjectFile[".o for bare-metal target"]Diagnostics
A dedicated SIL module pass (EmbeddedSwiftDiagnostics.swift) walks all SIL after the optimizer has had a chance to specialize / inline, then complains about any operations that should never appear in embedded code:
- Allocations of class instances that escape across module boundaries (no global heap).
- Dynamic dispatch through existentials (
any P). - Calls into the full standard library that depend on heap.
try?, throwing functions that allocateErrorboxes (without explicit suppression).
Errors point back at the user's source thanks to retained SourceLocs.
Standard library subset
The Embedded build of the stdlib disables features incompatible with the embedded model:
- No
Array,Dictionary,Setby default (the user can opt into a stripped-downArray). Stringis severely limited or unavailable.- Many of the floating-point conformances are gated by Foundation, which is not available in Embedded.
The exact subset is described in docs/EmbeddedSwift/EmbeddedSwiftStatus.md.
Runtimes
SwiftDirectRuntime-- a stripped-down runtime usable when the embedded program is willing to write a small allocator. ARC is still available forclasstypes, but type metadata caches are pre-built.EmbeddedPlatform-- platform-shim Swift module that provides minimalprint/assertglue.
Integration points
- Compiler driver / frontend -- the
-enable-experimental-feature Embeddedflag flips numerous knobs (whole-module by default, no resilience, etc.). - SIL optimizer -- a mandatory pass enforces embedded restrictions.
- Stdlib build -- when configured for embedded, the build emits a different
Swiftmodule with the limited subset. - Macros -- macros work in Embedded because they run in the host compiler's
swift-plugin-server, not in the embedded program.
Entry points for modification
- New embedded restriction: extend
EmbeddedSwiftDiagnostics.swiftinSwiftCompilerSources/Sources/Optimizer/ModulePasses/. - Adding a feature to the Embedded stdlib subset: gate it with
#if !$Embedded(or#if hasFeature(...)) instdlib/public/core/. - Tests live in
test/embedded/.
Related pages
- SwiftCompilerSources -- where the embedded diagnostics pass lives.
- Standard library -- the build configuration.
- Runtimes -- the alternate stdlib build that supports Embedded.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.