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
//! Retry-routing error classifiers: pure substring predicates over SPIRV-Tools / native-emitter
//! message text that decide which failure-recovery retry a translate error routes to, plus the
//! aggregate [`ValidationClass`]/[`EmitErrorClass`] enums `lib.rs`'s cascade matches on. Keeping the
//! validator-text matching in this one adapter means a SPIRV-Tools message change touches one place.
//! Unit coverage lives in `error_classifier_tests`.
/// Whether a spirv-val error message is one of the buffer pointer-typing failures the raw byte-offset
/// path repairs (the pointer-merge frontier class). Anything else — a CFG/back-edge error, a missing
/// capability, or a spirv-val spawn failure — returns false so the ground-truth retry is skipped.
/// Whether a native-emitter ERROR (the default typed emission returned `Err` *before* any spirv-val
/// runs) is a buffer/pointer-typing gap the raw byte-offset model can express: a reinterpret-load
/// width mismatch (a buffer's declared pointee width differs from the load's result width, so the
/// typed access chain cannot be formed) or a missing pointer storage class. The ground-truth raw retry
/// uses this to also recover from an outright emit failure — not only a spirv-val rejection of a
/// produced module — by re-emitting with buffers modeled raw and adopting that only if it independently
/// validates. Floor-safe: a banked case emits and validates on the default path, so it never reaches
/// the retry; an emit failure was already a hard FALLBACK, so the raw attempt can only add a win.
/// Whether a spirv-val rejection of a produced module (`branches to the selection construct`,
/// `back-edge`, `header block`, `does not dominate`, …) is a control-flow structurization failure the
/// relooper retry tiers can restructure. Used by [`classify_validation_error`] to route a rejected
/// module to the `CfgStructurization` cascade; a false positive only wastes a retry that is discarded
/// unless it independently validates. Anything pointer/parser/intrinsic-shaped returns false so the
/// cfg retry stays off that path. The needle set is spirv-val phrasings only: the legacy emit-error
/// `cost budget` / `clone budget` needles were deleted at cleanup-plan S2 (the repair roster that
/// produced them died at W4, and [`classify_emit_error`] no longer consults this predicate).
/// Whether a spirv-val error is the illegal-logical-pointer-`OpPhi` rejection the M4 phi-the-index
/// rewrite ([`rewrite_logical_pointer_phis_retry_module`]) targets: a pointer `OpPhi`/`OpSelect` in
/// a storage class `VariablePointers` cannot cover (Private/UniformConstant/Function). Used by
/// `lib.rs`'s retry to route a rejected module to the rewrite; a false positive only wastes a retry
/// that is discarded unless the rewrite independently validates.
/// Whether a spirv-val error is the cross-binding pointer-merge rejection the W1 PhysicalStorageBuffer64
/// rewrite ([`rewrite_cross_binding_pointer_merges_bytes`]) targets: an `OpSelect`/`OpPhi` over pointers
/// from DISTINCT descriptor bindings, illegal under Logical addressing ("Variable pointers must point
/// into the same structure"). Used by `lib.rs`'s retry to route a rejected module to the PSB rewrite; a
/// false positive only wastes a retry that is discarded unless the rewrite independently validates.
/// Whether a spirv-val rejection is the dynamic-structure-index rule ("Index into a structure must be
/// an OpConstant"): an access chain indexed a struct member with a runtime value, illegal in
/// structured SPIR-V. Classifies as [`ValidationClass::Other`] (no dedicated tier), but `lib.rs`'s
/// `primary_dynamic_struct_index_inline_sroa_relooper` rewrite refines within `Other` on exactly this
/// message. Kept here so validator-text matching lives only in this adapter (cleanup-plan S1).
/// Whether a spirv-val rejection is the illegal-logical-pointer-operand rule ("Instruction may not
/// have a logical pointer operand"): an instruction other than an allowed pointer op took a logical
/// pointer where the storage class forbids it. Classifies as [`ValidationClass::Other`], but `lib.rs`'s
/// `primary_logical_pointer_inline_sroa_raw` rewrite refines within `Other` on exactly this message.
/// Distinct from [`is_logical_pointer_phi_error`] (the `OpPhi`-specific rule). Kept here so
/// validator-text matching lives only in this adapter (cleanup-plan S1).
/// Structural class of a spirv-val rejection of an *emitted* module, used to route the
/// failure-triggered retry cascade in `lib.rs`. This is the single classifier over the substring
/// matchers above (§2.2 fact 5 in the refactor plan): a SPIRV-Tools message change now touches one
/// place. The precedence here is load-bearing — it MUST equal the order of `lib.rs`'s
/// `Err(e) if is_*(e)` guard chain (pointer-typing, then cfg, then logical-pointer-phi, then
/// cross-binding), so that `match classify_validation_error(e)` fires exactly the arm the guard chain
/// did for an error that matches more than one family (spirv-val reports one error per module, but the
/// families are not provably disjoint).
/// Classify a spirv-val rejection into its [`ValidationClass`]. Equivalent, arm-for-arm, to the
/// ordered `Err(e) if is_*(e)` guard chain it replaces.
/// Structural class of a native-emitter `Err` returned *before* any spirv-val runs, used to route the
/// emit-failure retry cascade in `lib.rs`. Only the pointer-typing gap has a dedicated raw-byte
/// recovery arm; everything else (including any residual CFG-shaped emit gap) routes to the BDA/raw
/// last-resort cascade. (The dedicated cfg-emit-error arm was removed with the W4 repair-roster
/// deletion: the roster's repair fixpoint was the sole producer of a cfg-class emit *error*, so no
/// emit path returns one anymore — a reject function now emits complete unrepaired bytes that fail
/// *validation*, routing through the validation-side cfg cascade instead.)
/// Classify a native-emitter emit `Err` into its [`EmitErrorClass`]. Equivalent, arm-for-arm, to the
/// ordered `Err(emit_err) if is_*(emit_err)` guard chain it replaces.