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
//! One WARN per foreign cfg-gated enum variant, for the whole generation run.
//!
//! A variant merged in from a foreign `[[crates.source_crates]]` crate carries that crate's own
//! `#[cfg(...)]`. No generated binding crate declares a Cargo feature for it, so re-emitting the
//! gate verbatim is an `unexpected cfg condition value` error and every Rust-emitting backend
//! drops the variant instead. Each of those drops used to be its own `tracing::warn!`: fifteen
//! call sites -- eight backends (dart, extendr, ffi, napi, php, rustler, swift, wasm) plus the
//! three shared codegen modules (`conversions::enums`, `generators::enums`, `visitor_result`),
//! several of them once per conversion direction. A single variant therefore produced a wall of
//! WARN on every clean regen: the same fact re-reported once per (backend, direction, generator),
//! scaling with the backend count rather than with the number of variants a consumer can act on.
//!
//! The fan-out was the defect, not the level: `tracing-product-surface` lists skipped/unsupported
//! input under WARN, so demoting the fact would hide a real, actionable signal. Instead the fact
//! is reported once from here and the per-site detail stays at DEBUG, where it is still available
//! under `RUST_LOG=alef=debug` for anyone debugging codegen.
//!
//! Deduplication is by construction, not by a ledger: `ApiSurface` holds each enum once and each
//! variant once within it, so walking the surface a single time per run emits each
//! (enum, variant) fact exactly once with no mutable state to scope, share, or reset. The
//! fifteen emitting sites are pure `fn(&EnumDef, &EnumVariant, ..) -> String` helpers with no
//! reachable generation context, so threading a ledger to them would mean changing every
//! transitive caller up to `Backend::generate_bindings` in eight backends; a process-global
//! ledger is worse still, since it is settable once per process and would let one test's run
//! suppress another's. ~keep
use BTreeSet;
use crateis_host_owned_rust_path;
use crate;
use crateApiSurface;
/// Every spelling of "the host crate" that a requested language's generator will classify enum
/// ownership against.
///
/// This is not one value: most backends ask `is_host_owned_rust_path` with
/// [`ResolvedCrateConfig::core_import_for_language`], but the Dart and Swift Rust-bridge
/// generators ask it with the plain crate name -- Dart's `source_crate_name` from
/// `config.name`, Swift's `source_crate` from `api.crate_name` -- ignoring both
/// `[crate] core_import` and their own `core_crate_override`. Both of those spellings are
/// contributed, since the two fields are separately sourced even though they normally agree.
/// That divergence predates this module and is deliberately not unified here: reproducing it is
/// what keeps this pre-pass from becoming a *second* answer to a question the backends already
/// answer for themselves. ~keep
/// Report every foreign-crate enum variant this run's generators will drop for carrying a
/// `#[cfg(...)]` no generated binding crate can declare.
///
/// Call once per generation run, before the per-language loop. The warning claims something
/// universal -- *every* generated binding crate drops this variant -- so it fires only when the
/// enum is foreign under every host-crate spelling the requested languages use. When the
/// spellings disagree (a `[crate] core_import` facade with Dart or Swift also requested) the
/// claim is not universal, so the fact stays at DEBUG on the backends that actually drop it
/// rather than being over-reported here as if it applied to all of them. ~keep