1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//! Zig's consumer side of the FFI presence channel.
//!
//! A Rust `Option<i64>` return crosses the C ABI as a bare `i64`, so `None` and a legitimate
//! `Some(0)` arrive at the Zig wrapper as the same bits. `unwrap_return_expr` passes that raw
//! value straight through and lets Zig coerce `i64` into the declared `?i64` — a coercion that is
//! *never* null, so before this gate every `None` reached the caller as `0`.
//!
//! Zig needs no declaration for the companion: the backend pulls the entire C surface in through
//! one build-system-translated C header import (see `c_import.jinja`), so
//! `c.{sym}_has_result` is already in scope wherever the primary is. What it does need is to call
//! the companion only when the FFI
//! crate actually exported one, which is asked of
//! [`crate::backends::ffi::type_map::result_presence_companion_exists`] — the same predicate
//! `gen_method_result_presence_wrapper` uses to decide whether to emit the symbol. Re-deriving
//! "is this an ambiguous `Option` leaf" here would let the two sides drift, and C translation
//! resolves externs at comptime: a name the header never declared is a build error in the
//! consumer's package, not a wrong value. See `two-generators-disagree` in the repo's skill set.
//! ~keep
use crateresult_presence_companion_exists;
use craterender;
use cratec_consumerresult_presence_symbol;
use crate;
/// The companion's "result is present" return value. `0` means absent and `-1` means the
/// companion itself failed (bad handle, param conversion, caught panic), so the gate tests for
/// `!= 1` rather than `== 0` — treating a failed companion as "present" would hand the caller the
/// primary getter's sentinel as if it were real data. ~keep
const PRESENT: &str = "1";
/// The indent a free-function wrapper body sits at.
const FUNCTION_INDENT: &str = " ";
/// The indent an opaque-handle method body sits at — one level deeper, inside the struct.
pub const METHOD_INDENT: &str = " ";
/// Re-indent a fragment that was emitted at the wrapper's own indent so it can sit one block
/// deeper, inside the gate.
///
/// The parameter-teardown emitters write at a fixed indent because every other caller emits them
/// at statement level; the gate is the one place they land inside a block. ~keep
/// The presence guard for a free-function wrapper, or `None` when the FFI crate exports no
/// companion for this return type.
///
/// Emitted before the primary call, never after: every FFI wrapper clears the crate's last-error
/// slot on entry, so a companion invoked second would erase an error the primary had just
/// recorded. Because the gate returns early it has to run the parameter teardown the wrapper
/// would otherwise run after the call, so that teardown is rebuilt here at the gate's indent. ~keep
pub
/// The return shape and (optional) receiver identifying which companion presence check applies.
/// Kept together because both feed [`result_presence_companion_exists`] as a single eligibility
/// query, and grouping them keeps `result_presence_gate` at 6 parameters. ~keep
pub
/// Render the presence guard a Zig wrapper emits immediately before its primary C call, or `None`
/// when the FFI crate exports no companion for this return type and receiver.
///
/// `primary_c_call` is the wrapper's own already-built call expression
/// (`c.{sym}({args})`); the companion's call is derived from it rather than rebuilt, so the two
/// cannot disagree about arity, and the `_has_result` spelling still comes from
/// [`result_presence_symbol`] so the suffix has exactly one definition.
///
/// `target.receiver` is passed straight through to the eligibility authority: the companion
/// re-invokes the underlying method to observe presence, which an owned receiver cannot survive
/// because its first call already removed the handle from the registry.
///
/// `cleanup` is the parameter teardown the wrapper would otherwise run after the call — the gate
/// returns early, so it has to run it too. `error_type` is the wrapper's resolved Zig error set
/// when it is fallible; the gate then reports the companion's own `-1` failure as that error
/// instead of silently claiming absence. Emitting it here is safe for
/// `assert_error_set_covers_body` because the surrounding body already returns the same error.
pub