charon_lib/transform/
duplicate_defaulted_methods.rs1use std::{collections::HashMap, mem};
3
4use crate::ast::*;
5
6use super::{TransformCtx, ctx::TransformPass};
7
8pub struct Transform;
9impl TransformPass for Transform {
10 fn transform_ctx(&self, ctx: &mut TransformCtx) {
11 for impl_id in ctx.translated.trait_impls.all_indices() {
12 let Some(timpl) = ctx.translated.trait_impls.get_mut(impl_id) else {
13 continue;
14 };
15 let Some(tdecl) = ctx.translated.trait_decls.get(timpl.impl_trait.id) else {
16 continue;
17 };
18 if tdecl.methods.len() == timpl.methods.len() {
19 continue;
20 }
21
22 let self_impl_ref = TraitImplRef {
24 id: timpl.def_id,
25 generics: Box::new(timpl.generics.identity_args()),
26 };
27 let self_predicate = TraitRef {
28 kind: TraitRefKind::TraitImpl(self_impl_ref.clone()),
29 trait_decl_ref: RegionBinder::empty(timpl.impl_trait.clone()),
30 };
31 let mut methods_map: HashMap<TraitItemName, _> =
33 mem::take(&mut timpl.methods).into_iter().collect();
34 let timpl = ctx.translated.trait_impls.get(impl_id).unwrap();
36 let mut methods = vec![];
37 for bound_method in &tdecl.methods {
38 if let Some(kv) = methods_map.remove_entry(bound_method.name()) {
39 methods.push(kv);
40 continue;
41 }
42 let declared_fun_id = bound_method.skip_binder.item.id;
43 let declared_fun_name = ctx.translated.item_name(declared_fun_id).unwrap();
44 let new_fun_name = {
45 let mut item_name = timpl.item_meta.name.clone();
46 item_name
47 .name
48 .push(declared_fun_name.name.last().unwrap().clone());
49 item_name
50 };
51 let opacity = ctx.opacity_for_name(&new_fun_name);
52 let new_fun_id = ctx.translated.fun_decls.reserve_slot();
53 ctx.translated
54 .item_names
55 .insert(new_fun_id.into(), new_fun_name.clone());
56
57 let bound_method = bound_method
59 .clone()
60 .substitute_with_self(&timpl.impl_trait.generics, &self_predicate.kind);
61 let new_fn_ref = Binder {
65 skip_binder: FunDeclRef {
66 id: new_fun_id,
67 generics: Box::new(
68 timpl
69 .generics
70 .identity_args_at_depth(DeBruijnId::one())
71 .concat(
72 &bound_method
73 .params
74 .identity_args_at_depth(DeBruijnId::zero()),
75 ),
76 ),
77 },
78 params: bound_method.params.clone(),
79 kind: bound_method.kind.clone(),
80 };
81 methods.push((bound_method.name().clone(), new_fn_ref));
82
83 if let Some(fun_decl) = ctx.translated.fun_decls.get(declared_fun_id)
84 && !opacity.is_invisible()
85 {
86 let bound_method = Binder {
87 params: timpl.generics.clone(),
88 skip_binder: bound_method,
89 kind: BinderKind::Other,
90 };
91 let bound_method = bound_method.flatten();
95 let FunDecl {
97 def_id: _,
98 item_meta,
99 signature,
100 kind,
101 is_global_initializer,
102 body,
103 } = fun_decl.clone();
104 let span = timpl.item_meta.span;
107 let item_meta = ItemMeta {
108 name: new_fun_name,
109 is_local: timpl.item_meta.is_local,
110 opacity,
111 span,
112 ..item_meta
113 };
114 let signature = FunSig {
115 generics: bound_method.params,
116 inputs: signature.inputs.substitute_with_self(
117 &bound_method.skip_binder.item.generics,
118 &self_predicate.kind,
119 ),
120 output: signature.output.substitute_with_self(
121 &bound_method.skip_binder.item.generics,
122 &self_predicate.kind,
123 ),
124 ..signature
125 };
126 let kind = if let ItemKind::TraitDecl {
127 trait_ref,
128 item_name,
129 ..
130 } = kind
131 {
132 ItemKind::TraitImpl {
133 impl_ref: self_impl_ref.clone(),
134 trait_ref: trait_ref.substitute_with_self(
135 &bound_method.skip_binder.item.generics,
136 &self_predicate.kind,
137 ),
138 item_name,
139 reuses_default: true,
140 }
141 } else {
142 unreachable!()
143 };
144 let body = if opacity.is_transparent() {
145 body.substitute_with_self(
146 &bound_method.skip_binder.item.generics,
147 &self_predicate.kind,
148 )
149 } else {
150 Err(Opaque)
151 };
152 ctx.translated.fun_decls.set_slot(
153 new_fun_id,
154 FunDecl {
155 def_id: new_fun_id,
156 item_meta,
157 signature,
158 kind,
159 is_global_initializer,
160 body,
161 },
162 );
163 }
164 }
165 let timpl = ctx.translated.trait_impls.get_mut(impl_id).unwrap();
166 timpl.methods = methods;
167 }
168 }
169}