@@ -18,7 +18,9 @@ use tracing::{debug, debug_span, trace, warn};
18
18
use rustc_data_structures:: fingerprint:: Fingerprint ;
19
19
use rustc_data_structures:: fx:: FxHashSet ;
20
20
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
21
+ use rustc_hir:: def:: DefKind ;
21
22
use rustc_hir:: def_id:: DefId ;
23
+ use rustc_hir:: ItemId ;
22
24
use rustc_middle:: mir:: interpret:: { AllocId , ConstValue , ErrorHandled , GlobalAlloc , Scalar } ;
23
25
use rustc_middle:: mir:: mono:: MonoItem ;
24
26
use rustc_middle:: mir:: visit:: Visitor as MirVisitor ;
@@ -57,18 +59,35 @@ pub fn collect_reachable_items<'tcx>(
57
59
}
58
60
59
61
/// Collect all (top-level) items in the crate that matches the given predicate.
62
+ /// An item can only be a root if they are: non-generic Fn / Static / GlobalASM
60
63
pub fn filter_crate_items < F > ( tcx : TyCtxt , predicate : F ) -> Vec < MonoItem >
61
64
where
62
- F : FnMut ( TyCtxt , DefId ) -> bool ,
65
+ F : Fn ( TyCtxt , DefId ) -> bool ,
63
66
{
64
- let mut filter = predicate;
65
- tcx. hir_crate_items ( ( ) )
66
- . items ( )
67
- . filter_map ( |hir_id| {
68
- let def_id = hir_id. owner_id . def_id . to_def_id ( ) ;
69
- filter ( tcx, def_id) . then ( || MonoItem :: Fn ( Instance :: mono ( tcx, def_id) ) )
70
- } )
71
- . collect ( )
67
+ let crate_items = tcx. hir_crate_items ( ( ) ) ;
68
+ // Filter regular items.
69
+ let root_items = crate_items. items ( ) . filter_map ( |item| {
70
+ let def_id = item. owner_id . def_id . to_def_id ( ) ;
71
+ if !is_generic ( tcx, def_id) && predicate ( tcx, def_id) {
72
+ to_mono_root ( tcx, item, def_id)
73
+ } else {
74
+ None
75
+ }
76
+ } ) ;
77
+
78
+ // Filter items from implementation blocks.
79
+ let impl_items = crate_items. impl_items ( ) . filter_map ( |impl_item| {
80
+ let def_id = impl_item. owner_id . def_id . to_def_id ( ) ;
81
+ if matches ! ( tcx. def_kind( def_id) , DefKind :: AssocFn )
82
+ && !is_generic ( tcx, def_id)
83
+ && predicate ( tcx, def_id)
84
+ {
85
+ Some ( MonoItem :: Fn ( Instance :: mono ( tcx, def_id) ) )
86
+ } else {
87
+ None
88
+ }
89
+ } ) ;
90
+ root_items. chain ( impl_items) . collect ( )
72
91
}
73
92
74
93
/// Use a predicate to find `const` declarations, then extract all closures from those declarations
@@ -96,6 +115,24 @@ where
96
115
roots
97
116
}
98
117
118
+ fn is_generic ( tcx : TyCtxt , def_id : DefId ) -> bool {
119
+ let generics = tcx. generics_of ( def_id) ;
120
+ generics. requires_monomorphization ( tcx)
121
+ }
122
+
123
+ fn to_mono_root ( tcx : TyCtxt , item_id : ItemId , def_id : DefId ) -> Option < MonoItem > {
124
+ let kind = tcx. def_kind ( def_id) ;
125
+ match kind {
126
+ DefKind :: Static ( ..) => Some ( MonoItem :: Static ( def_id) ) ,
127
+ DefKind :: Fn => Some ( MonoItem :: Fn ( Instance :: mono ( tcx, def_id) ) ) ,
128
+ DefKind :: GlobalAsm => Some ( MonoItem :: GlobalAsm ( item_id) ) ,
129
+ _ => {
130
+ debug ! ( ?def_id, ?kind, "Ignored item. Not a root type." ) ;
131
+ None
132
+ }
133
+ }
134
+ }
135
+
99
136
struct MonoItemsCollector < ' tcx > {
100
137
/// The compiler context.
101
138
tcx : TyCtxt < ' tcx > ,
0 commit comments