• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

facet-rs / facet / 15200164445

23 May 2025 01:21AM UTC coverage: 57.288% (+0.1%) from 57.185%
15200164445

Pull #666

github

web-flow
Merge 4232978c5 into 4b41e5c8a
Pull Request #666: Add indirection to vtable fns to fix cyclic types

715 of 1482 new or added lines in 34 files covered. (48.25%)

14 existing lines in 5 files now uncovered.

9747 of 17014 relevant lines covered (57.29%)

132.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.48
/facet-core/src/impls_std/hashmap.rs
1
use core::hash::{BuildHasher, Hash};
2
use std::collections::HashMap;
3
use std::hash::RandomState;
4

5
use crate::ptr::{PtrConst, PtrMut};
6

7
use crate::{
8
    Def, Facet, IterVTable, MapDef, MapVTable, MarkerTraits, ScalarAffinity, ScalarDef, Shape,
9
    Type, TypeParam, UserType, VTableView, ValueVTable, value_vtable,
10
};
11

12
type HashMapIterator<'mem, K, V> = std::collections::hash_map::Iter<'mem, K, V>;
13

14
unsafe impl<'a, K, V, S> Facet<'a> for HashMap<K, V, S>
15
where
16
    K: Facet<'a> + core::cmp::Eq + core::hash::Hash,
17
    V: Facet<'a>,
18
    S: Facet<'a> + Default + BuildHasher,
19
{
20
    const VTABLE: &'static ValueVTable = &const {
21
        ValueVTable::builder::<Self>()
22
            .marker_traits(|| {
2✔
23
                let arg_dependent_traits = MarkerTraits::SEND
2✔
24
                    .union(MarkerTraits::SYNC)
2✔
25
                    .union(MarkerTraits::EQ)
2✔
26
                    .union(MarkerTraits::UNPIN);
2✔
27
                arg_dependent_traits
2✔
28
                    .intersection(V::SHAPE.vtable.marker_traits())
2✔
29
                    .intersection(K::SHAPE.vtable.marker_traits())
2✔
30
            })
2✔
31
            .type_name(|f, opts| {
35✔
32
                if let Some(opts) = opts.for_children() {
35✔
33
                    write!(f, "HashMap<")?;
35✔
34
                    (K::SHAPE.vtable.type_name)(f, opts)?;
35✔
35
                    write!(f, ", ")?;
35✔
36
                    (V::SHAPE.vtable.type_name)(f, opts)?;
35✔
37
                    write!(f, ">")
35✔
38
                } else {
39
                    write!(f, "HashMap<⋯>")
×
40
                }
41
            })
35✔
42
            .debug(|| {
14✔
43
                if (K::SHAPE.vtable.debug)().is_some() && (V::SHAPE.vtable.debug)().is_some() {
14✔
44
                    Some(|value, f| {
10✔
45
                        let k_debug = <VTableView<K>>::of().debug().unwrap();
10✔
46
                        let v_debug = <VTableView<V>>::of().debug().unwrap();
10✔
47
                        write!(f, "{{")?;
10✔
48
                        for (i, (key, val)) in value.iter().enumerate() {
16✔
49
                            if i > 0 {
16✔
50
                                write!(f, ", ")?;
8✔
51
                            }
8✔
52
                            (k_debug)(key, f)?;
16✔
53
                            write!(f, ": ")?;
16✔
54
                            (v_debug)(val, f)?;
16✔
55
                        }
56
                        write!(f, "}}")
10✔
57
                    })
10✔
58
                } else {
NEW
59
                    None
×
60
                }
61
            })
14✔
62
            .default_in_place(|| Some(|target| unsafe { target.put(Self::default()) }))
49✔
63
            .clone_into(|| {
5✔
64
                if (K::SHAPE.vtable.clone_into)().is_some()
5✔
65
                    && (V::SHAPE.vtable.clone_into)().is_some()
5✔
66
                {
67
                    Some(|src, dst| unsafe {
68
                        let map = src;
1✔
69
                        let mut new_map =
1✔
70
                            HashMap::with_capacity_and_hasher(map.len(), S::default());
1✔
71

72
                        let k_clone_into = <VTableView<K>>::of().clone_into().unwrap();
1✔
73
                        let v_clone_into = <VTableView<V>>::of().clone_into().unwrap();
1✔
74

75
                        for (k, v) in map {
2✔
76
                            use crate::TypedPtrUninit;
77
                            use core::mem::MaybeUninit;
78

79
                            let mut new_k = MaybeUninit::<K>::uninit();
1✔
80
                            let mut new_v = MaybeUninit::<V>::uninit();
1✔
81

82
                            let uninit_k = TypedPtrUninit::new(new_k.as_mut_ptr());
1✔
83
                            let uninit_v = TypedPtrUninit::new(new_v.as_mut_ptr());
1✔
84

85
                            (k_clone_into)(k, uninit_k);
1✔
86
                            (v_clone_into)(v, uninit_v);
1✔
87

88
                            new_map.insert(new_k.assume_init(), new_v.assume_init());
1✔
89
                        }
90

91
                        dst.put(new_map)
1✔
92
                    })
1✔
93
                } else {
NEW
94
                    None
×
95
                }
96
            })
5✔
97
            .eq(|| {
4✔
98
                if (V::SHAPE.vtable.eq)().is_some() {
4✔
99
                    Some(|a, b| {
2✔
100
                        let v_eq = <VTableView<V>>::of().eq().unwrap();
2✔
101
                        a.len() == b.len()
2✔
102
                            && a.iter().all(|(key_a, val_a)| {
3✔
103
                                b.get(key_a).is_some_and(|val_b| (v_eq)(val_a, val_b))
3✔
104
                            })
3✔
105
                    })
2✔
106
                } else {
NEW
107
                    None
×
108
                }
109
            })
4✔
NEW
110
            .hash(|| {
×
NEW
111
                if (V::SHAPE.vtable.hash)().is_some() {
×
112
                    Some(|map, hasher_this, hasher_write_fn| unsafe {
113
                        use crate::HasherProxy;
NEW
114
                        let v_hash = <VTableView<V>>::of().hash().unwrap();
×
NEW
115
                        let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
×
NEW
116
                        map.len().hash(&mut hasher);
×
NEW
117
                        for (k, v) in map {
×
NEW
118
                            k.hash(&mut hasher);
×
NEW
119
                            (v_hash)(v, hasher_this, hasher_write_fn);
×
NEW
120
                        }
×
NEW
121
                    })
×
122
                } else {
NEW
123
                    None
×
124
                }
NEW
125
            })
×
126
            .build()
127
    };
128

129
    const SHAPE: &'static Shape<'static> = &const {
130
        Shape::builder_for_sized::<Self>()
131
            .type_params(&[
132
                TypeParam {
133
                    name: "K",
134
                    shape: || K::SHAPE,
135
                },
136
                TypeParam {
137
                    name: "V",
138
                    shape: || V::SHAPE,
139
                },
140
                TypeParam {
141
                    name: "S",
142
                    shape: || S::SHAPE,
143
                },
144
            ])
145
            .ty(Type::User(UserType::Opaque))
146
            .def(Def::Map(
147
                MapDef::builder()
148
                    .k(|| K::SHAPE)
149
                    .v(|| V::SHAPE)
150
                    .vtable(
151
                        &const {
152
                            MapVTable::builder()
153
                                .init_in_place_with_capacity(|uninit, capacity| unsafe {
154
                                    uninit
×
155
                                        .put(Self::with_capacity_and_hasher(capacity, S::default()))
×
156
                                })
×
157
                                .insert(|ptr, key, value| unsafe {
158
                                    let map = ptr.as_mut::<HashMap<K, V>>();
50✔
159
                                    let key = key.read::<K>();
50✔
160
                                    let value = value.read::<V>();
50✔
161
                                    map.insert(key, value);
50✔
162
                                })
50✔
163
                                .len(|ptr| unsafe {
164
                                    let map = ptr.get::<HashMap<K, V>>();
22✔
165
                                    map.len()
22✔
166
                                })
22✔
167
                                .contains_key(|ptr, key| unsafe {
168
                                    let map = ptr.get::<HashMap<K, V>>();
8✔
169
                                    map.contains_key(key.get())
8✔
170
                                })
8✔
171
                                .get_value_ptr(|ptr, key| unsafe {
172
                                    let map = ptr.get::<HashMap<K, V>>();
8✔
173
                                    map.get(key.get()).map(|v| PtrConst::new(v))
8✔
174
                                })
8✔
175
                                .iter_vtable(
176
                                    IterVTable::builder()
177
                                        .init_with_value(|ptr| unsafe {
178
                                            let map = ptr.get::<HashMap<K, V>>();
24✔
179
                                            let iter: HashMapIterator<'_, K, V> = map.iter();
24✔
180
                                            let iter_state = Box::new(iter);
24✔
181
                                            PtrMut::new(Box::into_raw(iter_state) as *mut u8)
24✔
182
                                        })
24✔
183
                                        .next(|iter_ptr| unsafe {
184
                                            let state =
56✔
185
                                                iter_ptr.as_mut::<HashMapIterator<'_, K, V>>();
56✔
186
                                            state.next().map(|(key, value)| {
56✔
187
                                                (
34✔
188
                                                    PtrConst::new(key as *const K),
34✔
189
                                                    PtrConst::new(value as *const V),
34✔
190
                                                )
34✔
191
                                            })
34✔
192
                                        })
56✔
193
                                        .dealloc(|iter_ptr| unsafe {
194
                                            drop(Box::from_raw(
24✔
195
                                                iter_ptr.as_ptr::<HashMapIterator<'_, K, V>>()
24✔
196
                                                    as *mut HashMapIterator<'_, K, V>,
24✔
197
                                            ));
198
                                        })
24✔
199
                                        .build(),
200
                                )
201
                                .build()
202
                        },
203
                    )
204
                    .build(),
205
            ))
206
            .build()
207
    };
208
}
209

210
unsafe impl Facet<'_> for RandomState {
211
    const VTABLE: &'static ValueVTable =
212
        &const { value_vtable!((), |f, _opts| write!(f, "RandomState")) };
1✔
213

214
    const SHAPE: &'static Shape<'static> = &const {
215
        Shape::builder_for_sized::<Self>()
216
            .ty(Type::User(UserType::Opaque))
217
            .def(Def::Scalar(
218
                ScalarDef::builder()
219
                    .affinity(&const { ScalarAffinity::opaque().build() })
220
                    .build(),
221
            ))
222
            .build()
223
    };
224
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc