Structural Satisfaction Reflection¶
Accepted
Accepted for the V1 structural satisfaction predicate and metadata APIs.
Structural satisfaction reflection describes whether one concrete type satisfies one inspectable structural constraint Type in one lookup scope.
T.satisfaction(Shape, scope) Type.Satisfaction!Type.SatisfactionError
This answers:
- whether concrete type
Thas the visible fields and functions required byShape - which concrete declarations matched each requirement
- which requirements failed, and why
- which scope controlled visibility
It does not run arbitrary user-defined comptime predicates, prove semantic contracts, expose runtime interfaces, or define layout compatibility.
Lookup API¶
Structural satisfaction has a predicate API and a metadata API:
T.satisfies(Shape, scope: ?Scope = null) Type.Predicate
T.satisfaction(Shape, scope: ?Scope = null) Type.Satisfaction!Type.SatisfactionError
The optional scope argument defaults to null, not Scope.caller(). The called API resolves null to Scope.caller() in its body before delegating. See Predicate Reflection for scope forwarding and predicate facts.
T.satisfies(Shape) returns false when the shape does not match. T.satisfaction(Shape) reports structured errors for failed requirements.
V1 requirements:
Tmust be a concrete type.Shapemust be a structural constraintType.Shapemust expose inspectable structural requirements throughTypereflection.Shapemay be produced bysatisfies(...),mutable_fields(...), or another comptime function that builds an equivalent structural constraintTypethrough compiler-provided primitives.Shapemust not be a semantic contract, contract intersection,dyn C, concrete type, or arbitrary comptimeboolpredicate.
Constraint Metadata Boundary¶
Sema consumes the structural constraint Type and its metadata, not the name of the function that produced it.
The canonical V1 constructors are:
satisfies(...)for read-only field and function shape requirementsmutable_fields(...)for assignable field-slot requirements
Prelude and user code may perform ordinary comptime validation while building a structural constraint. That validation may reject bad input or assemble reusable shape metadata. It does not become a reusable .satisfies fact unless the final value is an inspectable structural constraint Type.
Arbitrary comptime checks in generic factories remain ordinary comptime logic. A check that returns bool can accept or reject code, but it does not create narrowing facts. A custom function can preserve .satisfies facts only by returning or composing compiler-produced Type.Predicate values; facts are not forgeable.
Checking whether one structural constraint implies another is deferred.
Requirement Metadata¶
The declarations in this page describe public metadata members exposed through Type; they use source-shaped const Name = struct { ... } bindings rather than invalid qualified declarations such as struct Type.Name { ... }.
Concrete declaration reflection is separate from constraint requirement reflection:
T.fields()
T.inherent_functions()
Shape.required_fields()
Shape.required_functions()
Field requirements use the common field-access model:
const FieldAccess = enum {
read,
readwrite,
}
const FieldRequirement = struct {
name: []const u8
ty: Type
access: Type.FieldAccess
}
satisfies(...) produces read field requirements. mutable_fields(...) produces readwrite field requirements. A readwrite requirement includes readable access; reflection does not duplicate a separate read requirement for the same field.
Function requirements describe source-visible callable shape:
const FunctionRequirement = struct {
name: []const u8
signature: Type.Function
source: ?SourceLocation
docs: ?[]const u8
}
Function requirement matching uses the same function-shape semantics as function declaration reflection. See Function Reflection.
Satisfaction Metadata¶
Type.Satisfaction should describe the visible structural match as ordinary deterministic comptime data:
const Satisfaction = struct {
ty: Type
shape: Type
scope: Scope
fields: []const Type.SatisfiedField
functions: []const Type.SatisfiedFunction
}
const SatisfiedField = struct {
requirement: Type.FieldRequirement
field: Type.Field
}
const SatisfiedFunction = struct {
requirement: Type.FunctionRequirement
function: Type.FunctionDecl
}
Successful metadata contains one match per active requirement in deterministic requirement order. Extra fields and functions on T are ignored.
Structural satisfaction inspects inherent and source-visible shape, not semantic contract operations available through method lookup. Private members count only in scopes where ordinary code can access them. Source-visible builtin or synthetic members, such as slice .ptr and .len, may satisfy requirements when their reflected metadata matches.
Field requirements are name-based and use ordinary assignability to the required field type. A read requirement is satisfied by a readable const or mutable field. A readwrite requirement requires a field-like member that can be assigned through ordinary field assignment.
Function requirements are name-based and signature-checked. V1 does not define overload sets; if visible lookup for a function requirement is ambiguous, satisfaction fails with an ambiguity error.
Errors¶
Failed metadata lookup returns structured errors:
const SatisfactionErrorKind = enum {
not_concrete_subject,
not_structural_shape,
not_inspectable_shape,
semantic_contract_target,
concrete_type_target,
missing_field,
field_access_mismatch,
field_type_mismatch,
missing_function,
function_signature_mismatch,
ambiguous_function,
}
const SatisfactionError = struct {
kind: Type.SatisfactionErrorKind
subject: Type
shape: Type
scope: Scope
field_requirement: ?Type.FieldRequirement
function_requirement: ?Type.FunctionRequirement
candidates: []const Type.SatisfactionCandidate
}
For field and function failures, the relevant requirement field is present. Candidate lists contain visible candidates only and are deterministic. Missing requirements may include visible near misses when sema can report them deterministically.
const SatisfactionCandidate = struct {
name: []const u8
ty: Type
source: ?SourceLocation
visibility: Visibility
origin: Type.DeclOrigin
}
Predicate Facts¶
When T.satisfies(Shape) succeeds, the returned predicate carries a .satisfies fact for (T, Shape, scope).
In a comptime if condition or declaration guard, that true fact makes the structural requirements from Shape available in the branch or guarded declaration body. Facts are lexical and branch-local, and they are discarded when the predicate is coerced to bool.
Type.Satisfaction metadata is for diagnostics, tooling, and comptime logic. The reusable narrowing fact comes from the predicate API.
Boundaries¶
Deferred:
- constraint-to-constraint implication
- user-defined custom fact producers
- negative structural facts
- structural overload-set matching
- runtime structural interfaces or erased structural objects
- layout compatibility from structural satisfaction
- exposing private or non-visible candidates outside the lookup scope