charon_lib/transform/simplify_output/
hide_marker_traits.rs1use derive_generic_visitor::*;
2use itertools::Itertools;
3use std::collections::HashSet;
4
5use crate::{ast::*, name_matcher::NamePattern};
6
7use crate::transform::{TransformCtx, ctx::TransformPass};
8
9#[derive(Visitor)]
10struct RemoveMarkersVisitor {
11 exclude: HashSet<TraitDeclId>,
12}
13
14impl RemoveMarkersVisitor {
15 fn filter_trait_refs(&mut self, trait_refs: &mut Vector<TraitClauseId, TraitRef>) {
16 for i in trait_refs.all_indices() {
17 let tref = &trait_refs[i];
18 if self.exclude.contains(&tref.trait_decl_ref.skip_binder.id) {
19 trait_refs.remove(i);
20 }
21 }
22 }
23
24 fn filter_trait_clauses(&mut self, trait_clauses: &mut Vector<TraitClauseId, TraitParam>) {
25 for i in trait_clauses.all_indices() {
26 let clause = &trait_clauses[i];
27 if self.exclude.contains(&clause.trait_.skip_binder.id) {
28 trait_clauses.remove(i);
29 }
30 }
31 }
32}
33
34impl VisitAstMut for RemoveMarkersVisitor {
38 fn enter_generic_params(&mut self, args: &mut GenericParams) {
39 self.filter_trait_clauses(&mut args.trait_clauses);
40 }
41 fn enter_generic_args(&mut self, args: &mut GenericArgs) {
42 self.filter_trait_refs(&mut args.trait_refs);
43 }
44 fn enter_trait_decl(&mut self, tdecl: &mut TraitDecl) {
45 self.filter_trait_clauses(&mut tdecl.implied_clauses);
46 }
47 fn enter_trait_impl(&mut self, timpl: &mut TraitImpl) {
48 self.filter_trait_refs(&mut timpl.implied_trait_refs);
49 }
50 fn enter_trait_ref_kind(&mut self, x: &mut TraitRefKind) {
51 if let TraitRefKind::BuiltinOrAuto {
52 parent_trait_refs,
53 types,
54 ..
55 } = x
56 {
57 self.filter_trait_refs(parent_trait_refs);
58 for (_, assoc_ty) in types {
59 self.filter_trait_refs(&mut assoc_ty.implied_trait_refs);
60 }
61 }
62 }
63}
64
65pub struct Transform;
66impl TransformPass for Transform {
67 fn transform_ctx(&self, ctx: &mut TransformCtx) {
68 let mut exclude = if ctx.options.hide_marker_traits {
70 vec![
71 "core::marker::Destruct",
72 "core::marker::PointeeSized",
73 "core::marker::MetaSized",
74 "core::marker::Sized",
75 "core::marker::Tuple",
76 "core::marker::Send",
77 "core::marker::Sync",
78 "core::marker::Unpin",
79 "core::clone::TrivialClone",
80 ]
81 } else {
82 vec![]
83 };
84 if ctx.options.hide_allocator {
85 exclude.push("core::alloc::Allocator");
86 }
87 if exclude.is_empty() {
88 return;
89 }
90
91 let exclude: Vec<NamePattern> = exclude
92 .into_iter()
93 .map(|s| NamePattern::parse(s).unwrap())
94 .collect_vec();
95 let exclude: HashSet<TraitDeclId> = ctx
96 .translated
97 .item_names
98 .iter()
99 .filter(|(_, name)| exclude.iter().any(|p| p.matches(&ctx.translated, name)))
100 .filter_map(|(id, _)| id.as_trait_decl())
101 .copied()
102 .collect();
103
104 for &trait_id in &exclude {
106 if let Some(tdecl) = &ctx.translated.trait_decls.get(trait_id) {
107 for method in &tdecl.methods {
108 ctx.translated.fun_decls.remove(method.skip_binder.item.id);
109 }
110 }
111 ctx.translated.trait_decls.remove(trait_id);
112 }
113 for impl_id in ctx.translated.trait_impls.all_indices() {
115 if let Some(timpl) = &ctx.translated.trait_impls.get(impl_id)
116 && exclude.contains(&timpl.impl_trait.id)
117 {
118 for (_, method) in &timpl.methods {
119 ctx.translated.fun_decls.remove(method.skip_binder.id);
120 }
121 ctx.translated.trait_impls.remove(impl_id);
122 }
123 }
124
125 let _ = ctx
126 .translated
127 .drive_mut(&mut RemoveMarkersVisitor { exclude });
128 }
129}