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}