Skip to content

Attribute Diagnostics

Accepted

Accepted for V1 attribute diagnostics and the comptime diagnostics boundary.

Attributes use the same comptime diagnostics API as other comptime code.

Diagnostics owns Compiler.note, Compiler.warn, Compiler.err, and structured diagnostic payloads.

Compiler.note(.{ .message = "message" })
Compiler.warn(.{ .message = "message" })
Compiler.err(.{ .message = "message" })

Locations

  • Attribute provider errors should use the attribute use site as the primary location.
  • Notes may point into the provider implementation when helpful.
  • Errors from registering an attribute provider with @attribute point at the provider declaration.

Hard Errors and Lints

Sema rejects invalid attribute structure before provider execution when:

  • the attribute name cannot be resolved;
  • the resolved declaration is not a registered attribute provider;
  • the provider target list does not include the actual target kind;
  • a non-repeatable provider is applied more than once to the same target;
  • attribute argument arity, type, or comptime checks fail;
  • the target site is not a V1 attribute target.

Provider execution rejects the program when the provider calls Compiler.err, returns an unhandled error, or trips a target setter validation error.

Lints own redundant but valid combinations, suspicious order dependence, and policy diagnostics that must be stable independent of comptime caching. Provider warnings and notes are execution-time comptime effects and are not required to replay when a successful cached provider result is reused.

Deferred

Open or deferred

Tracked by CEP-0030: Attribute Target Expansion, CEP-0031: Attribute Semantic Effects, and CEP-0009: Generated Declarations and Impls.

  • interaction with future declaration/type construction APIs
  • attribute effects that require generated declarations or impls
  • expression, statement, local variable, call argument, and arbitrary type-use attributes

For provider-specific source locations, pass an explicit structured payload:

Compiler.err(.{
  .message = "@resource requires Disposable",
  .primary = context.source(),
  .notes = .{
    .{
      .message = "add struct(Disposable)",
      .source = context.source(),
    },
  },
})