1use rustc_middle::ty;
2
3use super::translate_ctx::*;
4use crate::hax;
5use crate::hax::FullDefKind;
6use crate::translate::translate_crate::TransItemSourceKind;
7use charon_lib::ast::*;
8
9impl<'tcx> ItemTransCtx<'tcx, '_> {
10 pub fn translate_drop_glue_method_id(
11 &mut self,
12 destruct_trait_def_id: &hax::DefId,
13 destruct_trait_id: TraitDeclId,
14 ) -> Result<TraitMethodId, Error> {
15 self.register_assoc_items(destruct_trait_def_id, destruct_trait_id)?;
16 let method_id = TraitMethodId::ZERO; Ok(method_id)
18 }
19
20 pub fn translate_drop_glue_method_call(
22 &mut self,
23 span: Span,
24 ty: ty::Ty<'tcx>,
25 ) -> Result<FnPtr, Error> {
26 let trait_proof = hax::solve_destruct(self.hax_state_with_id(), ty);
27 let tref = self
28 .translate_trait_proof(span, &trait_proof)?
29 .no_bound_vars();
30 let method_id = self.translate_drop_glue_method_id(
31 &trait_proof.pred.hax_skip_binder_ref().def_id,
32 tref.trait_id(),
33 )?;
34 let fn_ptr = FnPtr::new(
35 FnPtrKind::Trait(tref, method_id),
36 self.drop_glue_generic_args(),
37 );
38 Ok(fn_ptr)
39 }
40
41 fn translate_drop_glue_method_body(
42 &mut self,
43 span: Span,
44 def: &hax::FullDef<'tcx>,
45 ) -> Result<Body, Error> {
46 let (hax::FullDefKind::Adt(_) | hax::FullDefKind::Closure(_)) = def.kind() else {
47 return Ok(Body::Missing);
48 };
49
50 let body = def.this().drop_glue_shim(self.hax_state());
51 Ok(self.translate_body(span, body, &def.source_text))
52 }
53
54 #[tracing::instrument(skip(self, item_meta, def))]
57 pub fn translate_drop_glue_method(
58 mut self,
59 def_id: FunDeclId,
60 item_meta: ItemMeta,
61 def: &hax::FullDef<'tcx>,
62 impl_kind: TransImplSource,
63 ) -> Result<FunDecl, Error> {
64 let span = item_meta.span;
65 let borrow_region = self.drop_glue_region();
66
67 assert_eq!(impl_kind, TransImplSource::ImplicitDestruct);
69 let trait_pred = match def.kind() {
70 FullDefKind::Adt(adt) => &adt.destruct_impl(self.hax_state()).trait_pred,
71 FullDefKind::Closure(c) => &c.destruct_impl(self.hax_state()).trait_pred,
72 _ => unreachable!(),
73 };
74
75 let implemented_trait = self.translate_trait_predicate(span, trait_pred)?;
76 let item_id =
77 self.translate_drop_glue_method_id(&trait_pred.trait_ref.def_id, implemented_trait.id)?;
78 let self_ty = implemented_trait
79 .self_ty(&self.t_ctx.translated)
80 .unwrap()
81 .clone();
82
83 let signature = self.drop_glue_method_sig(self_ty.clone(), borrow_region);
84 let src = {
85 let mut impl_generics = self.the_only_binder().params.identity_args();
86 impl_generics
87 .regions
88 .pop()
89 .expect("drop glue method should have a borrow lifetime");
90 let destruct_impl_id =
91 self.register_item(span, def.this(), TransItemSourceKind::TraitImpl(impl_kind));
92 let impl_ref = TraitImplRef {
93 id: destruct_impl_id,
94 generics: Box::new(impl_generics),
95 };
96 FunSource::TraitImpl {
97 impl_ref,
98 trait_ref: implemented_trait,
99 item_id,
100 reuses_default: false,
101 }
102 };
103
104 let body = if item_meta.opacity.with_private_contents().is_opaque() {
105 Body::Opaque
106 } else {
107 self.translate_drop_glue_method_body(span, def)?
108 };
109
110 Ok(FunDecl {
111 def_id,
112 item_meta,
113 generics: self.into_generics(),
114 signature: Box::new(signature),
115 src,
116 body,
117 })
118 }
119
120 pub(crate) fn drop_glue_region(&self) -> Region {
121 Region::Var(DeBruijnVar::new_at_zero(
122 self.the_only_binder()
123 .drop_glue_region
124 .expect("drop glue item should have a borrow lifetime"),
125 ))
126 }
127
128 pub(crate) fn drop_glue_generic_args(&mut self) -> GenericArgs {
129 let mut generics = GenericArgs::empty();
130 generics.regions.push(self.translate_erased_region());
131 generics
132 }
133
134 pub(crate) fn drop_glue_params() -> GenericParams {
135 let mut params = GenericParams::empty();
136 params
137 .regions
138 .push_with(|index| RegionParam::new(index, None, Variance::Covariant));
139 params
140 }
141
142 pub fn drop_glue_method_sig(&self, self_ty: Ty, region: Region) -> FunSig {
144 let self_ref = TyKind::Ref(region, self_ty, RefKind::Mut).into_ty();
145 FunSig {
146 is_unsafe: true,
147 abi: Abi::rust(),
148 is_variadic: false,
149 inputs: [self_ref].into(),
150 output: Ty::mk_unit(),
151 }
152 }
153
154 pub fn drop_glue_fn_ptr_sig(&self, self_ty: Ty) -> RegionBinder<FunSig> {
155 let params = Self::drop_glue_params();
156 let region = Region::Var(DeBruijnVar::new_at_zero(RegionId::ZERO));
157 let self_ty = self_ty.move_under_binder();
158 RegionBinder {
159 regions: params.regions,
160 outlives: params.outlives,
161 skip_binder: self.drop_glue_method_sig(self_ty, region),
162 }
163 }
164
165 #[tracing::instrument(skip(self, item_meta, def))]
166 pub fn translate_implicit_destruct_impl(
167 mut self,
168 impl_id: TraitImplId,
169 item_meta: ItemMeta,
170 def: &hax::FullDef<'tcx>,
171 ) -> Result<TraitImpl, Error> {
172 let span = item_meta.span;
173
174 let destruct_impl = match def.kind() {
175 FullDefKind::Adt(adt) => adt.destruct_impl(self.hax_state()),
176 FullDefKind::Closure(c) => c.destruct_impl(self.hax_state()),
177 _ => unreachable!("{:?}", def.def_id()),
178 };
179 let mut timpl = self.translate_virtual_trait_impl(
180 impl_id,
181 item_meta,
182 def.this(),
183 TransImplSource::ImplicitDestruct,
184 destruct_impl,
185 )?;
186
187 let destruct_trait_id = timpl.impl_trait.id;
189 let destruct_trait_def_id: &hax::DefId = &destruct_impl.trait_pred.trait_ref.def_id;
190 let method_id =
191 self.translate_drop_glue_method_id(destruct_trait_def_id, destruct_trait_id)?;
192 let method_binder = {
193 let fun_id = self.register_item(
194 span,
195 def.this(),
196 TransItemSourceKind::DropGlueMethod(TransImplSource::ImplicitDestruct),
197 );
198 let method_params = Self::drop_glue_params();
199 let generics = self
200 .outermost_binder()
201 .params
202 .identity_args_at_depth(DeBruijnId::one())
203 .concat(&method_params.identity_args());
204 Binder::new(
205 BinderKind::TraitMethod(destruct_trait_id, method_id),
206 method_params,
207 FunDeclRef {
208 id: fun_id,
209 generics: Box::new(generics),
210 },
211 )
212 };
213 timpl.methods.set_slot_extend(method_id, method_binder);
214
215 Ok(timpl)
216 }
217}