Ruta graveolens  ·  notes from a language experiment  ·  cultivated since 2025

Items

Items

This chapter describes items in Rue.

Grammar note. The EBNF fragments in this chapter are illustrative excerpts scoped to the construct under discussion, and are deliberately narrower than the full syntax (they may omit pub, directives, receiver modes, method bodies, or variant payloads). Appendix A is the normative grammar; where a fragment here differs from it, Appendix A governs.

Items are top-level definitions in a program. Unlike statements, items are visible throughout the module.

The item kinds are:

  • Functions (fn, 6.1), including the program entry point main.
  • Structs (struct, 6.2), which may declare methods and associated functions in the struct body (6.4).
  • Enums (enum, 6.3).
  • Constants (const, 6.5).
  • Top-level destructors (drop fn, 3.9), which are declared at the top level rather than inside any enclosing block.
  • Interfaces (interface, 6.8) and conformance assertions (is), a preview feature.
  • Structured concurrency (std.parallel.join_inout, 6.9), a preview feature.
  • Tests (test "name" { … }, 6.7), which are roots for a test request and are never part of an executable program.

Rue has no separate impl block: methods and associated functions are written inside the struct body (6.4), and a user-defined destructor for a named struct is a top-level drop fn item (3.9). There is no item form that groups implementations under a type the way an impl block does in other languages.

Module-level Value Bindings

Specification note. Module-level value bindings are const only (6.5:1–2) and therefore immutable compile-time values. Rue has no module-level let, let mut, or mutable static item. ADR-0089 records this policy and the direction for future shared runtime state: immutable bindings with an explicitly designed interior-mutability abstraction. Such an abstraction remains undesigned.

Type Name Uniqueness

User-defined type names (structs and enums) MUST be unique within their defining module (source file). Defining multiple types with the same name in one file produces a compile-time error (E0405; this is the per-file check of 10.5:1). Distinct modules MAY each define a type with the same name (10.5:2); declarations in other modules do not participate in this check and do not constrain the names a module may define.

User-defined type names are resolved by ordinary lexical and module lookup. The language reserves exactly one type-name spelling: str, the built-in view over borrowed UTF-8 bytes (3.7), which the implementation provides in every module's scope rather than declaring in source. A struct or enum declaration named str produces a compile-time error. No other spelling is reserved; in particular, StrBuf is an ordinary standard-library declaration and may also name an unrelated user type.

// OK: this is an ordinary user nominal, unrelated to std.strbuf.StrBuf.
struct StrBuf { data: i32 }

// Error: `str` names the built-in text view and may not be redefined.
struct str { data: i32 }  // compile error: reserved type name

User-defined functions MUST NOT use names reserved for runtime and code-generation helpers. The reserved function names are exactly: any name beginning with __rue_; the program entry points _start and _main; and the compiler-builtin memory routines memcpy, memmove, memset, memcmp, and bcmp (the runtime exports these under their fixed platform names, so a user definition would collide at link time). Compiler- and runtime-emitted helpers such as __rue_alloc and __rue_str_eq live under the __rue_ prefix, so the reserved set does not grow as helpers are added. Defining a function with a reserved name produces a compile-time error.

// Error: cannot define function with reserved name
fn __rue_alloc() -> i32 { 0 }  // compile error: `__rue_` prefix is reserved

// OK: `String__len` is an ordinary identifier, distinct from the
// source-defined `std.strbuf.StrBuf.len` method.
fn String__len() -> i32 { 0 }  // allowed

In this section