API Reference
Macros
TypeContracts.@contract Macro
@contract AbstractType begin
method1(::Self, ::ArgType)
method2(::Self) :: ReturnType
:optional
method3(::Self)
end
@contract AbstractType{T,N} begin
method1(::Self, ::Int) :: T
method2(::Self, ::T, ::Int)
endRegister a method contract for a type. Type parameters (T, N, …) declared in the header can be used anywhere in the method signatures — they are resolved at check time from the concrete type's supertype chain.
Methods before :optional are mandatory (enforced by @verify). Methods after :optional are recorded but not enforced at compile time.
Auto-generation: if the abstract type or any unqualified function name is not yet defined in the calling module, @contract defines it automatically. This means the common boilerplate (abstract type T end, function f end) is no longer required. Define the abstract type explicitly beforehand only when you need a supertype constraint (e.g. abstract type Animal <: LivingThing end).
Documentation
An optional interface description and per-method descriptions are folded into the type's ?-visible documentation (and describe). They work for owned types and for retroactive contracts on foreign types (e.g. Base.AbstractArray):
@contract AbstractShape "A 2-D geometric shape." begin
area(::Self)::Float64 => "area enclosed by the shape"
perimeter(::Self)::Float64 => "length of the boundary"
:optional
name(::Self)::String => "human-readable name"
end?AbstractShape then shows the contract section alongside any existing docstring.
TypeContracts.@verify Macro
@verify ConcreteType
@verify ConcreteType trim_compat=true
@verify AbstractType subtypes=true
@verify AbstractType subtypes=true trim_compat=true
@verify ConcreteType for_contract=InterfaceType
@verify ConcreteType for_contract=InterfaceType trim_compat=trueAssert at module-load / precompile time that a type satisfies all mandatory contracts for its supertype chain. Checks both method existence and declared return types (via Base.return_types).
juliac / trim binaries: @verify at module top level is safe. It runs during Julia's precompilation step (before the native binary is produced) and is not re-executed at binary runtime. The trimmer eliminates it automatically because it is unreachable from any entry point. Do not call @verify (or check_contract) inside a function that runs at binary runtime — that would embed a Base.return_types call in the runtime call graph.
With trim_compat=true, also runs check_trim_compat to scan the typed IR of each mandatory method for known trim-unsafe calls (Base.return_types, invokelatest, etc.) and emits @warn for any found. This is a shallow, heuristic check — use TrimCheck.@validate for exhaustive verification.
With subtypes=true, verifies every concrete subtype of the given abstract type rather than the type itself. Equivalent to calling @verify on each concrete subtype individually, and self-maintaining as new subtypes are added.
With for_contract=I, performs a structural check against the contract registered for I without requiring T <: I. Useful for Holy Trait / structural protocols where user types satisfy a contract's method signatures but do not and cannot subtype the interface type. Combining with trim_compat=true also checks that T's implementations of I's methods are juliac --trim compatible.
Must be placed after all type and method definitions.
TypeContracts.@verify_all Macro
@verify_all
@verify_all trim_compat=trueAssert at module-load / precompile time that every concrete subtype of a registered contract type, defined in the calling module, satisfies its mandatory contracts.
Place once at the end of your module, after all type and method definitions. Replaces the need for individual @verify T calls.
With trim_compat=true, also runs check_trim_compat on each type (see @verify for details on what is checked).
Example
module Shapes
using TypeContracts
abstract type AbstractShape end
@contract AbstractShape begin
area(::Self)
end
struct Circle <: AbstractShape ... end
area(c::Circle) = ...
struct Square <: AbstractShape ... end
area(s::Square) = ...
@verify_all # checks Circle AND Square
endTypeContracts.@invariants Macro
@invariants AbstractType begin
"description" => x -> predicate(x)
:optional
"optional check" => x -> other_check(x)
endRegister behavioral invariants for a type. These are tested at test time via test_behavior, not at compile time. The :optional separator works the same as in @contract.
TypeContracts.@delegate Macro
@delegate WrapperType :field InterfaceTypeGenerate forwarding methods for every mandatory method in InterfaceType's contract, routing calls to getfield(wrapper, :field). Equivalent to writing each forwarding method manually, but driven by the registered @contract.
After emitting the forwarders, satisfies(WrapperType, InterfaceType) is called automatically and throws InterfaceError on failure.
The generated forwarding methods are plain concrete method definitions — no closures, no runtime dispatch on abstract types. They are fully trim-safe and pass juliac --trim.
Example
using TypeContracts, BaseTypeContracts
struct LoggedArray{T} <: AbstractArray{T,1}
data::Vector{T}
n_reads::Ref{Int}
end
LoggedArray(v::Vector{T}) where T = LoggedArray{T}(v, Ref(0))
# Replaces explicit size/getindex/setindex! forwarding:
@delegate LoggedArray :data AbstractArray
LoggedArray([1, 2, 3])[2] # 2
satisfies(LoggedArray{Int}, AbstractArray) # (satisfied = true, ...)Limitations
Only methods in
@contract InterfaceTypeare forwarded. Add to the contract first.@contract(orusingthe package that registers it) must precede@delegate.Arguments typed as interface type parameters are forwarded untyped (
Anydispatch).
Structural checks
TypeContracts.check_contract Method
check_contract(T::Type) -> NamedTuple{(:type, :contracts, :passed)}Verify that T satisfies all mandatory contracts for its supertype chain. Checks both method existence and declared return types (via Julia's type inferencer). Optional methods are skipped. Throws InterfaceError on failure.
Uses Base.return_types internally. Do not call from functions that run at binary runtime — use @verify / @verify_all at module top level instead, where the trimmer eliminates it before the binary is produced.
TypeContracts.check_contract Method
check_contract(T::Type, I::Type) -> NamedTuple{(:type, :contracts, :passed)}Structural variant: verify that T satisfies the mandatory contract for I without requiring T <: I. Useful for structural (Holy Trait) protocols where the implementing type does not and cannot subtype the interface type.
Throws InterfaceError on failure. Uses Base.return_types — precompile-time only.
TypeContracts.check_trim_compat Method
check_trim_compat(T::Type) -> NamedTuple{(:type, :contracts, :issues, :passed)}Precompile-time check that inspects the typed IR of each mandatory contract method for T and warns if any known trim-unsafe functions are called directly in the method body (e.g. Base.return_types, invokelatest, Base.which).
This is a shallow, heuristic scan — it detects obvious reflection in the top-level method body but does not recurse into callees. Use TrimCheck.@validate for exhaustive trim verification.
Emits @warn for each finding; does not throw. Call after check_contract or @verify so method existence is already guaranteed.
TypeContracts.check_trim_compat Method
check_trim_compat(T::Type, I::Type) -> NamedTuple{(:type, :contracts, :issues, :passed)}Structural variant of check_trim_compat: scan the typed IR of each mandatory method of contract I implemented by T, without requiring T <: I. Useful for structural (Holy Trait) protocols where user types never subtype the interface type — check_trim_compat(T) is a no-op in that case because I is absent from supertypes(T).
Emits @warn for each finding; does not throw. Call after check_contract(T, I) so method existence is already guaranteed.
TypeContracts.satisfies Function
satisfies(T::Type, S::Type) -> NamedTupleNon-throwing check. Returns (satisfied, missing_methods, missing_optional). satisfied is true when all mandatory methods are present and return types match.
Uses Base.return_types — do not call from functions that run at binary runtime.
TypeContracts.list_contract Method
list_contract(T::Type) -> Vector{MethodSpec}Return method specs registered directly for type T.
TypeContracts.list_contract Method
list_contract(T::Type, Val(:all)) -> Dict{Type, Vector{MethodSpec}}Return all contracts applicable to T via its supertype chain.
TypeContracts.registered_contracts Function
registered_contracts() -> Dict{Type, Vector{MethodSpec}}Return every abstract type that has a registered @contract, mapped to its Vector{MethodSpec}. Implemented via method introspection; intended for interactive use.
Testing helpers
TypeContracts.implements Method
implements(T::Type, S::Type; include_optional::Bool=false) -> BoolReturn true if T satisfies the structural contract for S (method existence and return types). Errors if S has no registered contract. Designed for direct use with @test:
@test implements(Circle, AbstractShape)
@test implements(Circle, AbstractShape; include_optional=true)Pass include_optional=true to also require all optional methods.
See also: satisfies for the full diagnostic result, implements(T) to check all applicable contracts at once.
TypeContracts.implements Method
implements(T::Type; include_optional::Bool=false) -> BoolReturn true if T satisfies all contracts in its supertype chain. Errors if no contracts are found (likely a wrong type or a missing @contract call):
@test implements(Circle)
@test implements(Circle; include_optional=true)Pass include_optional=true to also require all optional methods across every applicable contract.
See also: implements(T, S) for a single contract, check_contract for the compile-time throwing version.
TypeContracts.behavior_passes Function
behavior_passes(T::Type, objects; S=nothing, include_optional=false) -> BoolReturn true if all mandatory behavioral invariants for T's supertype chain pass against objects. Designed for direct use with @test:
@test behavior_passes(Counter, [Counter(0), Counter(5)])
@test behavior_passes(Counter, [Counter(0)]; S=AbstractCounter)
@test behavior_passes(Counter, [Counter(0)]; include_optional=true)Pass S to test only the invariants registered for a specific interface. Pass include_optional=true to require optional invariants as well.
TypeContracts.@test_implements Macro
@test_implements T SAssert that T satisfies the structural contract for S, integrating with the active Test.@testset. On failure, prints the list of missing methods before recording the test failure. Requires using Test at the call site.
using Test, TypeContracts
@test_implements Circle AbstractShapeTypeContracts.@test_behavior_passes Macro
@test_behavior_passes T objectsAssert that all mandatory behavioral invariants for T's supertype chain pass against objects, integrating with the active Test.@testset. On failure, prints which invariants failed before recording the test failure. Requires using Test at the call site.
using Test, TypeContracts
@test_behavior_passes Counter [Counter(0), Counter(5)]Behavioral testing
TypeContracts.test_behavior Method
test_behavior(T::Type, objects) -> NamedTupleRun all behavioral invariants registered for T's supertype chain against deepcopy'd test objects. Returns (passed, results, mandatory_failures).
passed is true when all mandatory invariants hold for all objects.
TypeContracts.test_behavior Method
test_behavior(T::Type, S::Type, objects) -> NamedTupleRun behavioral invariants registered for S specifically against objects of type T.
TypeContracts.list_behaviors Function
list_behaviors(T::Type) -> Vector{BehaviorSpec}Return behavioral invariants registered directly for type T.
TypeContracts.registered_behaviors Function
registered_behaviors() -> Dict{Type, Vector{BehaviorSpec}}Return every type that has registered @invariants, mapped to its Vector{BehaviorSpec}. Implemented via method introspection; intended for interactive use.
Trait dispatch
TypeContracts.interface_trait Function
interface_trait(::Type{I}, ::Type{T}) -> Implemented{I} | NotImplemented{I}Check if T satisfies the mandatory contract for I (method existence only). Returns a singleton trait type suitable for dispatch.
Trim/juliac-compatible. @contract I generates a concrete method interface_trait(::Type{I}, ::Type{T}) where {T} whose body is a fixed conjunction of concrete hasmethod(f, Tuple{…}) calls — no runtime registry lookup, no abstractly-typed Function, no dynamically-built signature. Because the method is emitted by @contract (ordinary method definition, not a Dict mutation), it is serialized into the registering package's precompile cache and survives precompilation and package reloads. hasmethod is a method-table lookup that runs without the JIT or type inferencer, so the result is statically resolvable and passes juliac --trim.
Interfaces with no registered contract fall through to the method below and return NotImplemented{I}().
Example
process(x) = _process(interface_trait(AbstractShape, typeof(x)), x)
_process(::Implemented{AbstractShape}, x) = area(x)
_process(::NotImplemented{AbstractShape}, x) = error("not a shape")TypeContracts.verified_trait Function
verified_trait(::Type{I}, ::Type{T}) -> Implemented{I} | NotImplemented{I}Check whether T has been verified against the full contract for I — method existence and declared return types — via @verify, @verify_all, or @delegate. Unlike interface_trait, which checks method existence only, verified_trait reflects the complete check_contract/satisfies result at the moment verification succeeded.
Returns NotImplemented{I}() for any (I, T) pair that has not been explicitly verified — even if T would in fact satisfy the contract structurally. This is a nominal, opt-in guarantee (like Rust's impl Trait for T), not a structural one: @verify/@verify_all/@delegate are what seal it in.
Trim/juliac-compatible: sealing emits one concrete, singleton-returning method per verified (I, T) pair at verification time (module load / precompile) — strictly more specific than the generic fallback below, so dispatch resolves it statically. No runtime check, no allocation, no registry lookup, same as interface_trait.
Revise caveat: redefining an implementation method after @verify leaves the sealed method in place until T is re-verified; the Revise extension's live re-check warns on a contract violation but does not automatically unseal verified_trait.
Example
@verify Circle # after this succeeds, verified_trait(Shape, Circle) === Implemented{Shape}()
process(x) = _process(verified_trait(Shape, typeof(x)), x)
_process(::Implemented{Shape}, x) = area(x)
_process(::NotImplemented{Shape}, x) = error("not a verified shape")TypeContracts.Implemented Type
Implemented{I}Singleton trait type returned by interface_trait when a type satisfies all mandatory methods of interface I. Used as a dispatch key.
_process(::Implemented{AbstractShape}, x) = area(x)TypeContracts.NotImplemented Type
NotImplemented{I}Singleton trait type returned by interface_trait when a type does not satisfy all mandatory methods of interface I. Used as a dispatch key.
_process(::NotImplemented{AbstractShape}, x) = error("not a shape")Introspection
TypeContracts.describe Method
describe(T::Type; io::IO=stdout, all::Bool=!isabstracttype(T))Pretty-print the contract for T.
all=true— walks the full supertype chain and shows every inherited contract (equivalent todescribe(T, Val(:all))).all=false— shows only whatTitself registers: the methods and invariants declared directly in@contract Tand@invariants T.
The default is true for concrete types (since contracts live on abstract supertypes, not on the concrete type itself) and false for abstract types (showing only what that level adds). Pass all=true on an abstract type to see the full chain:
describe(AbstractFloat) # own invariants only
describe(AbstractFloat; all=true) # + Real + Number
describe(Float64) # full chain (default for concrete)
describe(Float64; all=false) # (no contract registered)TypeContracts.describe Method
describe(T::Type, Val(:all); io::IO=stdout)Pretty-print contracts for T's full supertype chain. Equivalent to describe(T; all=true).
Note
describe(T) on a concrete type automatically shows the full supertype chain. describe(T, Val(:all)) on an abstract type additionally walks upward through its own supertypes.
Documenter integration
TypeContracts.contract_md_string Function
contract_md_string(T::Type) -> StringReturn a Markdown-formatted string describing the contract and behavioral invariants registered for T. Suitable for Documenter @eval blocks — a String return value is rendered as Markdown by Documenter.
Returns an empty string when no contract or invariants are registered for T.
TypeContracts.contract_md Function
contract_md(T::Type)Return a Markdown.MD object for the contract registered on T. Requires the TypeContractsDocumenterExt extension, which loads automatically when using Documenter is in scope. Returns nothing when the extension is absent.
Trim diagnostics
Proactive pre-build scan and reactive juliac output translation. See the trim diagnostics guide for examples.
TypeContracts.trim_report Function
trim_report(f, sig::Type{<:Tuple}) -> TrimReportStatically scan the optimized, type-inferred IR of f called with argument tuple-type sig for patterns juliac --trim=safe rejects — dynamic dispatch (a call whose result infers to Any) and reflection (return_types, invokelatest, which, methods).
This is a fast, advisory pre-build check, not a substitute for juliac's verifier: it inspects one function's IR (after inlining, so many transitive issues surface) but does not run the whole-program trim analysis. Treat findings as warnings.
trim_report(myfunc, Tuple{Int64}) # → TrimReport(...; passed=true/false)TypeContracts.TrimReport Type
TrimReport(entry, findings, passed)Result of trim_report: entry describes the scanned function, findings are human-readable likely-trim-unsafe sites (empty when clean), and passed is their absence. TrimReport <: Exception so it can be thrown with a styled showerror when desired.
TypeContracts.TrimDiagnostics.explain_trim_failure Function
explain_trim_failure(output; entry_path="", source_files=String[]) -> TrimFailureParse juliac --trim verifier output into a TrimFailure with a readable, source-mapped showerror. entry_path and source_files let the parser map findings to the user's own code (vs. generated wrappers). If the output is not in the recognised verifier format, the result still carries raw and renders a trimmed dump.
TypeContracts.TrimDiagnostics.TrimFailure Type
TrimFailure(sites, raw; recognized, entry_path, source_files)A parsed juliac --trim failure. sites are the deduplicated findings; raw is the original verifier output; recognized is false when the output did not match the known format (then showerror falls back to a trimmed raw dump so nothing is hidden). entry_path/source_files identify generated vs. user code for frame selection.
Types
TypeContracts.Self Type
SelfSentinel type used in @contract declarations as a placeholder for the concrete implementing type. At verification time, Self is substituted with the actual type being checked.
TypeContracts.TypeParamRef Type
TypeParamRefReference to a type parameter of a parametric abstract type. Used in @contract AbstractType{T,N} blocks to refer to T or N in method signatures and return types.
At check time, resolved by extracting the corresponding parameter from the concrete type's supertype chain.
Juliac-compatible: plain data struct, no closures.
TypeContracts.InterfaceError Type
InterfaceError <: ExceptionThrown when a type does not satisfy its registered interface contract.
TypeContracts.MethodSpec Type
MethodSpecA single method requirement within an interface contract.
Fields
f::Function— the function objectarg_types::Vector{Any}— argument types (Self,TypeParamRef, or concreteType)return_type::Type— annotated return type for display (Anyif unspecified or parametric)return_type_spec::Union{Type,TypeParamRef}— used for actual return type checkingdescription::String— human-readable signature for error messagesoptional::Bool— whether this method is optionaldoc::String— optional prose description (""if none); shown in?-docs anddescribe
TypeContracts.BehaviorSpec Type
BehaviorSpecA behavioral invariant tested against real objects at test time.
Fields
description::String— human-readable descriptionpredicate::Function—x -> Bool, takes a test objectoptional::Bool— whether this invariant is optional