Build an IH value for a recursive field in a rule RHS. Direct case (field type = `I_bi params idx_args`): IH = `rec[target] params motives minors idx_args field` Forall-wrapped case (field type = `∀ (xs...), I_bi params idx_args(xs)`): IH = `λ (xs...), rec[target] params motives minors idx_args(xs) (field xs...)`
(
&mut self,
field_idx: u64,
n_fields: u64,
total_lams: u64,
target_bi: usize,
flat: &[FlatBlockMember<M>],
peer_recs: &[KId<M>],
n_rec_params: usize,
n_motives: us
| 3837 | } |
| 3838 | |
| 3839 | if rec_ids.len() != flat.len() { |
| 3840 | return Ok(None); |
| 3841 | } |
| 3842 | |
| 3843 | let mut result: Vec<KId<M>> = Vec::with_capacity(flat.len()); |
| 3844 | for (fi, member) in flat.iter().enumerate() { |
| 3845 | let rec_id = &rec_ids[fi]; |
| 3846 | let (params, motives, minors, indices, ty) = |
| 3847 | match self.try_get_const(rec_id)? { |
| 3848 | Some(KConst::Recr { |
| 3849 | params, motives, minors, indices, ty, .. |
| 3850 | }) => (params, motives, minors, indices, ty.clone()), |
| 3851 | _ => return Ok(None), |
| 3852 | }; |
| 3853 | let skip = checked_metadata_sum::<M>( |
| 3854 | "recursor major index", |
| 3855 | &[params, motives, minors, indices], |
| 3856 | )?; |
| 3857 | let major_id = match self.get_major_inductive_id(&ty, skip) { |
| 3858 | Ok(id) => id, |
| 3859 | Err(TcError::UnknownConst(addr)) => { |
| 3860 | return Err(TcError::UnknownConst(addr)); |
| 3861 | }, |
| 3862 | Err(_) => return Ok(None), |
| 3863 | }; |
| 3864 | if major_id.addr != member.id.addr { |
| 3865 | return Ok(None); |
| 3866 | } |
| 3867 | if !member.is_aux { |
| 3868 | result.push(rec_id.clone()); |
| 3869 | continue; |
| 3870 | } |
| 3871 | // Auxiliary: verify spec_params match the stored major's param args. |
| 3872 | let saved = self.lctx.len(); |
| 3873 | let mut cur = ty; |
| 3874 | for _ in 0..skip { |
| 3875 | match self.whnf(&cur) { |
| 3876 | Ok(w) => match w.data() { |
| 3877 | ExprData::All(_, _, dom, b, _) => { |
| 3878 | let _ = self.push_fvar_decl_anon(dom.clone()); |
| 3879 | cur = b.clone(); |
| 3880 | }, |
| 3881 | _ => break, |
| 3882 | }, |
| 3883 | _ => break, |
| 3884 | } |
| 3885 | } |
| 3886 | let mut matched = false; |
| 3887 | if let Ok(w) = self.whnf(&cur) |
| 3888 | && let ExprData::All(_, _, dom, _, _) = w.data() |
| 3889 | { |
| 3890 | let (_, major_args) = collect_app_spine(dom); |
| 3891 | let n_par = match u64_to_usize::<M>(member.own_params) { |
| 3892 | Ok(n) => n, |
| 3893 | Err(_) => return Ok(None), |
| 3894 | }; |
| 3895 | if major_args.len() >= n_par && member.spec_params.len() == n_par { |
| 3896 | let n_rec_params = flat.first().map_or(0, |m| m.own_params); |
no test coverage detected