charon_lib/transform/
skip_trait_refs_when_known.rs1use crate::{register_error, transform::TransformCtx, ullbc_ast::*};
2
3use super::ctx::UllbcPass;
4
5fn transform_call(ctx: &mut TransformCtx, span: Span, call: &mut Call) {
6 let FnOperand::Regular(fn_ptr) = &mut call.func else {
8 return;
9 };
10 let FunIdOrTraitMethodRef::Trait(trait_ref, name, _) = &fn_ptr.func else {
11 return;
12 };
13 let TraitRefKind::TraitImpl(impl_id, impl_generics) = &trait_ref.kind else {
14 return;
15 };
16 let Some(trait_impl) = &ctx.translated.trait_impls.get(*impl_id) else {
17 return;
18 };
19 let Some((_, bound_fn)) = trait_impl.methods().find(|(n, _)| n == name) else {
21 return;
22 };
23 let method_generics = &fn_ptr.generics;
24
25 if !method_generics.matches(&bound_fn.params) {
26 register_error!(
27 ctx,
28 span,
29 "Mismatched method generics:\nparams: {:?}\nsupplied: {:?}",
30 bound_fn.params,
31 method_generics
32 );
33 }
34
35 let fn_ref: Binder<Binder<FunDeclRef>> = Binder::new(
38 BinderKind::Other,
39 trait_impl.generics.clone(),
40 bound_fn.clone(),
41 );
42 let fn_ref = fn_ref.apply(impl_generics).apply(method_generics);
44 fn_ptr.generics = fn_ref.generics;
45 fn_ptr.func = FunIdOrTraitMethodRef::Fun(FunId::Regular(fn_ref.id));
46}
47
48pub struct Transform;
49impl UllbcPass for Transform {
50 fn transform_body(&self, ctx: &mut TransformCtx, b: &mut ExprBody) {
51 for block in b.body.iter_mut() {
52 for st in block.statements.iter_mut() {
53 if let RawStatement::Call(call) = &mut st.content {
54 transform_call(ctx, st.span, call)
55 };
56 }
57 }
58 }
59}