charon_lib/transform/
resolve_sized_ptr_metadata_inherit.rs

1use crate::{ast::*, formatter::IntoFormatter, pretty::FmtWithCtx};
2
3use super::{TransformCtx, ctx::TransformPass};
4
5pub struct Transform;
6
7impl TransformPass for Transform {
8    fn transform_ctx(&self, ctx: &mut TransformCtx) {
9        // If we're hiding `Sized`, let's consider everything to be sized.
10        let everything_is_sized = ctx.options.hide_marker_traits;
11        let trait_decls = &ctx.translated.trait_decls;
12        let mut metadata = vec![];
13        for type_decl in &ctx.translated.type_decls {
14            let fmt = &ctx.into_fmt();
15            let meta = match &type_decl.ptr_metadata {
16                PtrMetadata::InheritFrom(ty) => {
17                    match ty.kind() {
18                        TyKind::TypeVar(..) => {
19                            let is_sized = everything_is_sized
20                                || type_decl.generics.trait_clauses.iter().any(|clause| {
21                                    let impl_trait = clause.trait_.clone().erase();
22                                    impl_trait.generics.types[0] == *ty && {
23                                        let trait_decl = trait_decls.get(impl_trait.id).unwrap();
24                                        matches!(trait_decl.item_meta.lang_item, Some("sized"))
25                                    }
26                                });
27                            if is_sized {
28                                trace!(
29                                    "Resolved ptr-metadata for type {}",
30                                    type_decl.def_id.with_ctx(fmt)
31                                );
32                                PtrMetadata::None
33                            } else {
34                                trace!(
35                                    "Ptr-metadata for type {} inheriting from {} is not Sized, keep inheritance.",
36                                    type_decl.def_id.with_ctx(fmt),
37                                    ty.with_ctx(fmt)
38                                );
39                                // Otherwise, it cannot be resolved
40                                PtrMetadata::InheritFrom(ty.clone())
41                            }
42                        }
43                        // Will there be other cases?
44                        _ => {
45                            trace!(
46                                "Non-type-var inheritance found for type: {}, inheriting from: {}",
47                                type_decl.def_id.with_ctx(fmt),
48                                ty.with_ctx(fmt)
49                            );
50                            PtrMetadata::InheritFrom(ty.clone())
51                        }
52                    }
53                }
54                x => x.clone(),
55            };
56            metadata.push(meta);
57        }
58        let mut iter = metadata.into_iter();
59        for type_decl in &mut ctx.translated.type_decls {
60            type_decl.ptr_metadata = iter.next().unwrap();
61        }
62    }
63}