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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//! Folding a `#[serde(default = "path")]` field's [`DefaultValue::FunctionCall`] down to the
//! concrete value its named function's body computes, when that body is a single
//! constant-foldable expression.
//!
//! `helpers::fields::extract_field` records every `#[serde(default = "path")]` field as
//! `FunctionCall(path)` unconditionally — it never reads what `path` points to. That is correct
//! as a starting point: `path` may be a private function, may be feature-gated, or may compute
//! something no generated binding crate could reproduce. But the common real-world shape is
//! `fn default_page_number() -> u32 { 1 }` — a private, unconditional, literal-returning helper
//! next to the struct it defaults for — and refusing to read a value this plain forces every
//! `#[serde(default = "path")]` field in a struct with such a sibling to fail generation, even
//! though the value is right there in the same module.
//!
//! This pass runs the same constant-fold [`expr_to_default_value`] applies to `impl Default`
//! bodies over the *tail expression* of the named function's body, when that body is exactly one
//! statement. A body of more than one statement is refused outright, for the same reason
//! `mutation::read_struct_body` refuses anything but the narrow shapes it can prove: a second
//! statement could branch, early-return, or depend on something this pass has no way to see, and
//! guessing past that is the exact fabrication this module exists to avoid.
//!
//! Deliberately applied to a function regardless of its own visibility or whether it resolves to
//! a [`DefaultValue::PublicFunctionCall`] elsewhere (`postprocess::resolve_public_default_functions`,
//! which only recognizes public *associated methods*, never free functions). A folded literal
//! renders correctly in every target language via `codegen::config_gen::default_value_for_field`;
//! `PublicFunctionCall` only ever produces a real value for the "rust"-emitting backends (Magnus,
//! NAPI, PHP, Rustler, PyO3) that generate a Rust bridge and call the function directly — every
//! other language still renders `None`/`nil`/`null` for it. So when a function's value can be
//! proven at all, folding it is strictly more useful than leaving it a function call, public or
//! not: a literal is portable, a call is Rust-only. A function whose body cannot be proven keeps
//! today's behavior unchanged, `FunctionCall`/`PublicFunctionCall` and all. ~keep
use ;
use AHashMap;
/// Every free (module-level) function declared directly in one module, keyed by name.
///
/// Scoped to a single module for the same reason [`super::collect_literal_consts`] and
/// [`super::collect_constructors`] are: `#[serde(default = "path")]` overwhelmingly names a
/// helper declared next to the struct it defaults for, and resolving a `use`-imported function
/// from another module would need a crate-wide index this pass does not build. `#[cfg(test)]`
/// functions are excluded — they do not exist in a normal build, so treating a test helper's
/// value as a normal build's default would be the same class of fabrication `mutation`'s
/// attributed-statement refusal exists to avoid. ~keep
pub type FreeFunctionIndex<'a> = ;
pub
/// Attempt to fold every [`DefaultValue::FunctionCall`] among `fields` down to the concrete
/// value its named function computes. A field whose function cannot be resolved or whose body
/// is not constant-foldable is left exactly as `extract_field` recorded it. ~keep
pub
/// Resolve `path` — a bare free-function name (`default_page_number`) or a path ending in
/// `Owner::method` (`Settings::default_retry_limit`, `crate::settings::Settings::default_retry_limit`)
/// — to the function it names, and fold that function's body.
///
/// An associated-function match is tried first: `[.., owner, method]` mirrors
/// `postprocess::resolve_public_default_functions`'s own path resolution, taking the last two
/// segments regardless of how many precede them. It is also final — see the check's own comment.
/// The free-function lookup is reached only when no associated function matched, and covers both
/// a truly bare path and a fully qualified free-function path whose leading segments this pass
/// cannot otherwise resolve. ~keep
/// Fold a zero-argument function's body to a [`DefaultValue`], or `None` when the function takes
/// arguments, is `async` (serde's `default = "path"` requires a plain `fn() -> T`, so this shape
/// cannot be the real target and reading it would be a coincidence, not a resolution), or its
/// body is not a single constant-foldable statement.
/// The lone statement of a single-statement function body, unwrapped to the expression it
/// evaluates to: a bare tail expression (no semicolon) or `return expr;`.
///
/// Refuses any body with more than one statement outright, with no attempt to look past a
/// leading statement the way `mutation::read_mutated_body` does for `impl Default` — that reader
/// earns the extra reach by proving every leading statement is an unescaped, unattributed
/// mutation of one binding. A generic `#[serde(default = "path")]` helper carries no such
/// promise, so a second statement could be an early return, a `cfg`-gated branch, or a
/// side-effecting call this pass cannot see through; refusing the whole body is the safe
/// direction. ~keep
/// True for every [`DefaultValue`] that represents a value alef actually knows, as opposed to
/// one that records the absence of a reading ([`DefaultValue::Unresolved`]) or an uncalled
/// function ([`DefaultValue::FunctionCall`] / [`DefaultValue::PublicFunctionCall`]).
///
/// Deliberately broader than `carries_value`, which gates a narrower question — "may this be
/// bound to a constructor parameter" — and excludes [`DefaultValue::Empty`] and
/// [`DefaultValue::None`] for that question's own reasons (see its doc comment). Both of those
/// variants *are* a fully known value here: `Empty` asserts the value is the field's own type
/// zero and `None` asserts it is literally `Option::None`, and every backend already renders
/// both correctly with no further context. Only the three variants excluded below assert
/// "unknown" rather than carrying one. ~keep