Skip to main content

gruel_air/sema/
info.rs

1//! Information types for functions, methods, and constants.
2//!
3//! These types store metadata about declarations gathered during the first
4//! phase of semantic analysis. They are used to resolve function calls,
5//! method calls, and constant references during function body analysis.
6
7use gruel_util::{FileId, Span};
8use lasso::Spur;
9
10use crate::param_arena::ParamRange;
11use crate::types::Type;
12
13/// Information about a function.
14#[derive(Debug, Clone, Copy)]
15pub struct FunctionInfo {
16    /// Parameter data (names, types, modes, comptime flags) stored in arena.
17    /// Access via `arena.names(params)`, `arena.types(params)`, etc.
18    pub params: ParamRange,
19    /// Return type
20    pub return_type: Type,
21    /// The return type symbol (before resolution) - needed for generic function specialization
22    pub return_type_sym: Spur,
23    /// The RIR instruction ref for the function body - needed for generic function specialization
24    pub body: gruel_rir::InstRef,
25    /// Span of the function declaration
26    pub span: Span,
27    /// Whether this function has any comptime type parameters
28    pub is_generic: bool,
29    /// Whether this function is public (visible outside its directory)
30    pub is_pub: bool,
31    /// Whether this function is marked `unchecked` (can only be called from checked blocks)
32    pub is_unchecked: bool,
33    /// File ID this function was declared in (for visibility checking)
34    pub file_id: FileId,
35    /// ADR-0078: when this entry is an item-level re-export alias
36    /// (`pub const X = mod.Y`), this is the canonical name `Y` of the
37    /// re-exported function. Call-site codegen uses this name so the
38    /// emitted `Call` instruction targets the original function symbol
39    /// (which is what's actually defined in the binary). For
40    /// non-aliased entries this is `None`.
41    pub canonical_name: Option<Spur>,
42    /// ADR-0085: when this entry is a C extern (declared inside a
43    /// `link_extern("…") { … }` block), this is the library name. None
44    /// for regular Gruel fns and C exports.
45    pub link_library: Option<Spur>,
46    /// ADR-0085: when this entry is a C extern or `@mark(c) fn` export
47    /// and an explicit `@link_name("…")` directive overrides the
48    /// emitted symbol, this is the override. None means the symbol
49    /// equals the Gruel identifier.
50    pub link_name: Option<Spur>,
51    /// ADR-0085: true iff this entry came from inside a `link_extern`
52    /// block — the body field is meaningless and codegen must emit a
53    /// declaration only.
54    pub is_extern: bool,
55    /// ADR-0085: true iff the host is a top-level `@mark(c) fn …{ … }`
56    /// or an extern fn — both use the platform C calling convention
57    /// and suppress Gruel name mangling at the emitted symbol.
58    pub is_c_abi: bool,
59}
60
61/// Information about a method in an impl block.
62///
63/// Note: Captured comptime values for anonymous struct methods are stored at the
64/// struct level in `Sema::anon_struct_captured_values`, not per-method. This ensures
65/// that different instantiations with different captured values create different types.
66#[derive(Debug, Clone, Copy)]
67pub struct MethodInfo {
68    /// The struct type this method belongs to
69    pub struct_type: Type,
70    /// Whether this is a method (has self) or associated function (no self)
71    pub has_self: bool,
72    /// Receiver mode (`self`, `inout self`, `borrow self`). Meaningful only
73    /// when `has_self` is true; `ByValue` is used as a placeholder for
74    /// associated functions (ADR-0060).
75    pub receiver: crate::types::ReceiverMode,
76    /// Parameter data (names, types, modes, comptime flags) stored in arena.
77    /// Access via `arena.names(params)`, `arena.types(params)`, etc.
78    /// Note: This excludes `self` if present - only explicit parameters.
79    pub params: ParamRange,
80    /// Return type
81    pub return_type: Type,
82    /// The RIR instruction ref for the method body
83    pub body: gruel_rir::InstRef,
84    /// Span of the method declaration
85    pub span: Span,
86    /// Whether this method is marked `unchecked` (can only be called from checked blocks)
87    pub is_unchecked: bool,
88    /// True if this method has its own comptime type parameters (e.g.,
89    /// `fn apply(self, comptime F: type, f: F) -> T`). Such methods are
90    /// generic at the method level (independent of the enclosing function's
91    /// comptime params) and their bodies are only analyzed at specialization.
92    pub is_generic: bool,
93    /// Return-type symbol as written in source. Preserved (as well as the
94    /// resolved `return_type` above) so that generic-method specialization
95    /// can substitute method-level comptime type params in the return type.
96    pub return_type_sym: lasso::Spur,
97    /// ADR-0073: whether this method is `pub`. Cross-module callers need
98    /// `is_pub` to be true; intra-module callers always succeed.
99    pub is_pub: bool,
100    /// ADR-0073: file the method was declared in (for visibility checks).
101    pub file_id: FileId,
102}
103
104/// Method signature for anonymous struct structural equality comparison.
105///
106/// This captures only the parts of a method that affect structural equality:
107/// method name, whether it has self, parameter types (as symbols), and return type.
108/// Method bodies do NOT affect structural equality - only signatures matter.
109///
110/// Type symbols are stored as Spur (interned strings) rather than resolved Types
111/// because at comparison time, `Self` hasn't been resolved to a concrete StructId yet.
112/// Two methods using `Self` in the same positions are considered structurally equal.
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct AnonMethodSig {
115    /// Method name
116    pub name: Spur,
117    /// Whether this is a method (has self) or associated function (no self)
118    pub has_self: bool,
119    /// Parameter type symbols (excluding self parameter)
120    pub param_types: Vec<Spur>,
121    /// Return type symbol
122    pub return_type: Spur,
123}
124
125/// A single method declaration inside a `derive` body (ADR-0058).
126///
127/// Captures the structural info needed to splice the method into a host
128/// type's method list at derive expansion: the original RIR refs are
129/// preserved verbatim — the existing generic-method machinery substitutes
130/// `Self` at first call.
131#[derive(Debug, Clone, Copy)]
132#[allow(dead_code)]
133pub struct DeriveMethod {
134    /// Method name.
135    pub name: Spur,
136    /// Whether this method takes a `self` receiver.
137    pub has_self: bool,
138    /// RIR instruction ref for the method's `FnDecl` (the same instruction
139    /// `gen_method` emits for an inline method).
140    pub method_ref: gruel_rir::InstRef,
141    /// Span of the method declaration (used for diagnostics).
142    pub span: Span,
143}
144
145/// A pending `@derive(D)` attachment from a struct or enum declaration.
146///
147/// Recorded during Phase 3 (directive resolution); consumed by Phase 4
148/// to splice the derive's methods into the host type's method list.
149#[derive(Debug, Clone, Copy)]
150#[allow(dead_code)]
151pub struct DeriveBinding {
152    /// Host type — the struct or enum whose declaration carries the
153    /// `@derive(...)` directive.
154    pub host_name: Spur,
155    /// Whether the host is an enum (`true`) or a struct (`false`).
156    pub host_is_enum: bool,
157    /// Name of the derive being attached (must resolve to a `derive` item
158    /// in `Sema::derives`).
159    pub derive_name: Spur,
160    /// Span of the host type's declaration.
161    pub host_span: Span,
162    /// Span of the `@derive(...)` directive itself, for diagnostics.
163    pub directive_span: Span,
164}
165
166/// Information about a `derive` item (ADR-0058).
167#[derive(Debug, Clone)]
168#[allow(dead_code)]
169pub struct DeriveInfo {
170    /// Derive name (e.g., `Drop`).
171    pub name: Spur,
172    /// RIR ref to the `DeriveDecl` instruction itself.
173    pub decl_ref: gruel_rir::InstRef,
174    /// Span covering the derive item.
175    pub span: Span,
176    /// One entry per method declaration in the derive body, in source order.
177    pub methods: Vec<DeriveMethod>,
178}
179
180/// Information about a constant declaration.
181///
182/// Constants are compile-time values. In the module system, they're primarily
183/// used for re-exports:
184/// ```gruel
185/// pub const strings = @import("utils/strings.gruel");
186/// pub const helper = @import("utils/internal.gruel").helper;
187/// ```
188#[derive(Debug, Clone)]
189pub struct ConstInfo {
190    /// Whether this constant is public
191    pub is_pub: bool,
192    /// The type of the constant value (e.g., Type::Module for imports)
193    pub ty: Type,
194    /// The RIR instruction ref for the initializer
195    pub init: gruel_rir::InstRef,
196    /// Span of the const declaration
197    pub span: Span,
198}