Validate a recursor by comparing with generated canonical form.
(
&mut self,
id: &KId<M>,
)
| 4067 | _ => { |
| 4068 | return Err(TcError::Other(format!( |
| 4069 | "populate_recursor_rules_from_block: rec_ids[{gi}]={rid} is not a recursor" |
| 4070 | ))); |
| 4071 | }, |
| 4072 | }; |
| 4073 | let gen_skip = checked_metadata_sum::<M>( |
| 4074 | "generated recursor major index", |
| 4075 | &[prefix_base, flat[gi].n_indices], |
| 4076 | )?; |
| 4077 | let gen_major = self.recursor_major_domain_for_addr( |
| 4078 | &gen_rec.ty, |
| 4079 | gen_skip, |
| 4080 | target_addr, |
| 4081 | )?; |
| 4082 | let stored_skip = checked_metadata_sum::<M>( |
| 4083 | "recursor major index", |
| 4084 | &[params, motives, minors, indices], |
| 4085 | )?; |
| 4086 | let stored_major = |
| 4087 | self.recursor_major_domain_for_addr(&ty, stored_skip, target_addr)?; |
| 4088 | let signatures_match = match (&gen_major, &stored_major) { |
| 4089 | (Some(g), Some(s)) => self.major_domain_signature_eq(g, s)?, |
| 4090 | _ => false, |
| 4091 | }; |
| 4092 | if !signatures_match { |
| 4093 | self.dump_recursor_alignment_failure( |
| 4094 | ind_block_id, |
| 4095 | rec_block_id, |
| 4096 | &generated_snapshot, |
| 4097 | &flat, |
| 4098 | &rec_ids, |
| 4099 | prefix_base, |
| 4100 | gi, |
| 4101 | gen_major.as_ref(), |
| 4102 | stored_major.as_ref(), |
| 4103 | ); |
| 4104 | return Err(TcError::Other(format!( |
| 4105 | "populate_recursor_rules_from_block: canonical-order mismatch at peer {gi}: \ |
| 4106 | flat[{gi}].id={} (target_addr={}…), rec_ids[{gi}]={}; gen and stored major-domain signatures differ. \ |
| 4107 | This indicates the kernel's `canonical_aux_order` and the stored recursor block diverge — \ |
| 4108 | re-run with `IX_RECURSOR_DUMP={}` for the full breakdown.", |
| 4109 | flat[gi].id, |
| 4110 | &target_addr.hex()[..8], |
| 4111 | rid, |
| 4112 | ind_block_id |
| 4113 | ))); |
| 4114 | } |
| 4115 | peers.push(rid.clone()); |
| 4116 | } |
| 4117 | |
| 4118 | let peer_recs: Vec<KId<M>> = peers; |
| 4119 | let is_large = univ_offset > 0; |
| 4120 | let n_params = u64_to_usize::<M>(n_params_u64)?; |
| 4121 | let mut generated_with_rules = generated_snapshot; |
| 4122 | |
| 4123 | for gi in 0..flat.len() { |
| 4124 | let member = &flat[gi]; |
| 4125 | let rec_ty_for_member = generated_with_rules[gi].ty.clone(); |
| 4126 | let mut rules = Vec::with_capacity(member.ctors.len()); |
no test coverage detected