Skip to content

V1 Prelude Attributes

Accepted

Accepted for the V1 prelude attribute set.

V1 prelude attributes are:

@attribute
@callconv(.c)
@export(.c)
@extern(.c)
@link_name("...")
@resource
@repr(...)
@align(...)
@deprecated(...)

The V1 prelude defines no optimization-hint or aliasing-promise attributes.

Future inlining controls are tracked by CEP-0058: Source-Level Optimization Hints. Future aliasing and exclusivity annotations are tracked by CEP-0010: Aliasing and Exclusivity Annotations.

C ABI Attributes

@callconv(.c) targets function and function_type. It is non-repeatable and sets call ABI metadata only. It does not export a symbol, import a symbol, or set a link name.

@callconv(.c)
fn local_c_abi_helper(x: i32) i32 {
  return x
}

@export(.c) targets free function definitions with bodies in V1. It is non-repeatable, implies @callconv(.c), sets the default exported symbol name to the function name, and validates that the signature is C-ABI-safe for the V1 scalar C export model.

@export(.c)
fn scale(x: f32) f32 {
  return x
}

@extern(.c) targets const_decl in V1. For C function imports, the const type must be an explicit function pointer whose pointee type has @callconv(.c).

@extern(.c)
@link_name("fabsf")
const fabs: *const @callconv(.c) fn(x: f32) f32

@link_name("...") targets function and const_decl. It is non-repeatable and sets the exact external symbol name. It is valid only when the same finalized declaration has @export(.c) or @extern(.c) linkage. It is invalid with @callconv alone.

Matching explicit @callconv(.c) on an @export(.c) function is allowed but lintable as interop/redundant-export-callconv. Conflicting calling conventions are hard errors.

Stacked C ABI attributes evaluate in source order, but the valid @export/@extern plus @link_name combinations are order-stable.

Sema finalization validates the completed declaration after all direct attributes have run, so @link_name may appear before or after the linkage attribute. @link_name without final export or extern linkage is a hard error.

Bodyless C imports are deferred. See C ABI Interop.

@resource

@resource targets struct_type, is non-repeatable, requires explicit visible Disposable, and sets copyability to .forbidden.

const File = @resource struct(Disposable) {
  fn dispose(self: *Self) void {
  }
}

Public resource types must publicly implement or require Disposable. The provider checks this through reflection.

@resource does not inject cleanup, and the compiler does not infer cleanup behavior from a method merely named dispose. Separately, compiler-generated temporaries and hidden owners that end a value's lifetime use Disposable conformance for generated cleanup.

@repr

@repr(...) targets struct_type only in V1 and is non-repeatable.

const Header = @repr(.catalyst) struct {
}

V1 accepts only .catalyst, which is also the default when @repr is omitted. Explicit @repr(.catalyst) is valid but redundant.

@repr(.c), @repr(.packed), .transparent, enum repr, union repr, and other representation modes are deferred to CEP-0063: Representation Modes and C Layout. V1 compilers should reject @repr(.c) and @repr(.packed) with diagnostics that point to the deferred representation-mode proposal rather than treating them as provenance-only metadata.

@align

@align(bytes) targets struct_type and field, and is non-repeatable.

const Header = struct {
  magic: u32

  @align(16)
  data: [128]f32
}

The value is bytes, must be nonzero, must be a power of two, and must not exceed the selected target's maximum object alignment. @align may raise a struct or field's effective alignment, but V1 rejects attempts to lower natural alignment. Field alignment affects layout, so it runs before layout finalization. Layout Reflection owns the exact .catalyst layout algorithm.

@deprecated

@deprecated is non-repeatable provenance metadata for documentation and linting. It does not create compiler-owned deprecation metadata, and the compiler does not hard-code deprecation warnings as a semantic rule in V1.

@deprecated
fn old() void {
}

@deprecated("use NewBuffer")
const OldBuffer = Buffer

The message is optional provenance. V1 has no version, date, or removal model. Targets are const_decl, function, field, and contract_operation. It is not allowed on struct_type or contract_type in V1; deprecate the binding or alias instead. Documentation tools and lints that care about deprecation inspect accepted attribute provenance.