Attributes¶
Accepted
Accepted for V1 attribute syntax, target placement, and the non-macro attribute model.
Attributes are lightweight hooks for declaration metadata, validation, and controlled semantic metadata changes. An attribute provider receives the decorated target and a context object.
Attributes are not macros in V1. They do not replace declarations or type values. They may validate, emit comptime diagnostics, store normalized attribute metadata, and call explicit target setter APIs.
Attribute Syntax¶
Attributes use @ followed by a resolvable name path:
@resource
@prelude.resource
@deprecated("use new_name")
@range(f32, 0.0, 1.0)
Examples using names outside the V1 prelude, such as @range, @trusted, or @contract_note, assume user-defined providers in scope.
No-argument attributes may omit parentheses:
@resource
@deprecated
Attribute arguments use normal function-call syntax. All attribute arguments are comptime-known.
Attribute provider signatures supply expected types for their arguments, so attribute calls may use expected-type shorthand:
@export(.c)
Here .c resolves through the expected type of the first @export argument. It is not a string and not a local name.
Attributes come before the syntactic construct they decorate:
@export(.c)
pub fn foo() void {
}
fn parse({ @trusted alloc, diag }: *const CompilerContext, source: Source) Ast!ParseError {
}
const Header = struct {
@align(16)
data: [128]f32
}
const File = @resource struct(pub Disposable) {
}
fn Sequence(comptime T: Type) => @contract_note contract(Indexable(T)) {
}
Stacked attributes are allowed and evaluate in source order:
@export(.c)
@link_name("foo")
pub fn foo() void {
}
const File = @resource @repr(.catalyst) struct(Disposable) {
}
Later attributes can inspect metadata set by earlier attributes on the same target. Unnecessary order dependence is lintable as attributes/order-dependence.
Attribute Targets¶
V1 attributes may target:
- top-level declarations
- member declarations
- fields
- function parameters
- comptime/generic parameters
- implementation declarations
- implementation operation declarations
structtype constructorscontracttype constructors- function type expressions that explicitly allow function-signature attributes, such as
@callconv
Deferred target sites:
- local variable declarations
- arbitrary expressions
- statements
- call arguments
- arbitrary type-use sites
Unsupported target sites are hard compile errors.
Post-V1 attribute expansion, named attribute arguments, and attribute-generated declarations are tracked with CEP-0030: Attribute Target Expansion, CEP-0015: Named Arguments, and CEP-0009: Generated Declarations and Impls.
Type-constructor attributes apply to the type constructor, not to a general expression:
const File = @resource struct(pub Disposable) {
}
fn Buffer(comptime T: Type) => @resource struct(Disposable) {
}
This is allowed anywhere the corresponding type constructor is allowed, including generic type factory returns. The resulting Type carries the metadata set by the attribute.
Declaration and type-constructor attributes can coexist:
@deprecated("use NewFile")
pub const File = @resource struct(pub Disposable) {
}
Here @resource targets the struct_type; @deprecated targets the const_decl.
Parameter attributes target the parameter declaration or parameter binding pattern, not the parameter type:
@attribute(.{ .targets = .{ .param } })
fn trusted(comptime target: Attribute.Target, comptime context: Attribute.Context) void {
}
fn parse(@trusted input: []const u8) Ast!ParseError {
}
Attributes may also decorate destructured parameter bindings when that binding is the attribute target:
fn parse({ @trusted alloc, diag }: *const CompilerContext, source: Source) Ast!ParseError {
}
Related Details¶
- Provider Model: provider resolution, target metadata, evaluation order, and conflict handling.
- Prelude Attributes: V1 prelude attributes.
- Diagnostics: comptime diagnostics from attribute providers.