@@ -28,7 +28,7 @@ use cexpr;
28
28
use clang_sys;
29
29
use proc_macro2:: { Ident , Span } ;
30
30
use std:: borrow:: Cow ;
31
- use std:: cell:: Cell ;
31
+ use std:: cell:: { Cell , RefCell } ;
32
32
use std:: collections:: HashMap as StdHashMap ;
33
33
use std:: iter:: IntoIterator ;
34
34
use std:: mem;
@@ -380,6 +380,10 @@ pub struct BindgenContext {
380
380
/// computed after parsing our IR, and before running any of our analyses.
381
381
allowlisted : Option < ItemSet > ,
382
382
383
+ /// Cache for calls to `ParseCallbacks::blocklisted_type_implements_trait`
384
+ blocklisted_types_implement_traits :
385
+ RefCell < HashMap < DeriveTrait , HashMap < ItemId , CanDerive > > > ,
386
+
383
387
/// The set of `ItemId`s that are allowlisted for code generation _and_ that
384
388
/// we should generate accounting for the codegen options.
385
389
///
@@ -560,6 +564,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
560
564
options,
561
565
generated_bindgen_complex : Cell :: new ( false ) ,
562
566
allowlisted : None ,
567
+ blocklisted_types_implement_traits : Default :: default ( ) ,
563
568
codegen_items : None ,
564
569
used_template_parameters : None ,
565
570
need_bitfield_allocation : Default :: default ( ) ,
@@ -2205,6 +2210,37 @@ If you encounter an error missing from this list, please file an issue or a PR!"
2205
2210
self . allowlisted . as_ref ( ) . unwrap ( )
2206
2211
}
2207
2212
2213
+ /// Check whether a particular blocklisted type implements a trait or not.
2214
+ /// Results may be cached.
2215
+ pub fn blocklisted_type_implements_trait (
2216
+ & self ,
2217
+ item : & Item ,
2218
+ derive_trait : DeriveTrait ,
2219
+ ) -> CanDerive {
2220
+ assert ! ( self . in_codegen_phase( ) ) ;
2221
+ assert ! ( self . current_module == self . root_module) ;
2222
+
2223
+ let cb = match self . options . parse_callbacks {
2224
+ Some ( ref cb) => cb,
2225
+ None => return CanDerive :: No ,
2226
+ } ;
2227
+
2228
+ * self
2229
+ . blocklisted_types_implement_traits
2230
+ . borrow_mut ( )
2231
+ . entry ( derive_trait)
2232
+ . or_default ( )
2233
+ . entry ( item. id ( ) )
2234
+ . or_insert_with ( || {
2235
+ item. expect_type ( )
2236
+ . name ( )
2237
+ . and_then ( |name| {
2238
+ cb. blocklisted_type_implements_trait ( name, derive_trait)
2239
+ } )
2240
+ . unwrap_or ( CanDerive :: No )
2241
+ } )
2242
+ }
2243
+
2208
2244
/// Get a reference to the set of items we should generate.
2209
2245
pub fn codegen_items ( & self ) -> & ItemSet {
2210
2246
assert ! ( self . in_codegen_phase( ) ) ;
0 commit comments