5656
5757use crate :: { declare_bevy_lint, declare_bevy_lint_pass} ;
5858use clippy_utils:: {
59- def_path_res,
6059 diagnostics:: span_lint_hir_and_then,
61- get_trait_def_id ,
60+ paths :: PathLookup ,
6261 sugg:: DiagExt ,
6362 ty:: { implements_trait, ty_from_hir_ty} ,
6463} ;
6564use rustc_errors:: Applicability ;
66- use rustc_hir:: {
67- HirId , Item , ItemKind , Node , OwnerId , QPath , TyKind ,
68- def:: { DefKind , Res } ,
69- } ;
65+ use rustc_hir:: { HirId , Item , ItemKind , Node , OwnerId , QPath , TyKind , def:: DefKind } ;
7066use rustc_lint:: { LateContext , LateLintPass } ;
71- use rustc_middle:: { span_bug, ty :: TyCtxt } ;
67+ use rustc_middle:: span_bug;
7268use rustc_span:: Span ;
7369
7470declare_bevy_lint ! {
@@ -87,36 +83,27 @@ impl<'tcx> LateLintPass<'tcx> for MissingReflect {
8783 fn check_crate ( & mut self , cx : & LateContext < ' tcx > ) {
8884 // Finds all types that implement `Reflect` in this crate.
8985 let reflected: Vec < TraitType > =
90- TraitType :: from_local_crate ( cx. tcx , & crate :: paths:: REFLECT ) . collect ( ) ;
86+ TraitType :: from_local_crate ( cx, & crate :: paths:: REFLECT ) . collect ( ) ;
9187
9288 // Finds all non-`Reflect` types that implement `Event` in this crate.
93- let events: Vec < TraitType > = TraitType :: from_local_crate ( cx. tcx , & crate :: paths:: EVENT )
89+ let events: Vec < TraitType > = TraitType :: from_local_crate ( cx, & crate :: paths:: EVENT )
9490 . filter ( |trait_type| !reflected. contains ( trait_type) )
9591 . collect ( ) ;
9692
9793 // Finds all non-`Reflect` types that implement `Component` and *not* `Event` in this
9894 // crate. Because events are also components, we need to deduplicate the two to avoid
9995 // emitting multiple diagnostics for the same type.
100- let components: Vec < TraitType > =
101- TraitType :: from_local_crate ( cx. tcx , & crate :: paths:: COMPONENT )
102- . filter ( |trait_type| {
103- !( reflected. contains ( trait_type) || events. contains ( trait_type) )
104- } )
105- . collect ( ) ;
96+ let components: Vec < TraitType > = TraitType :: from_local_crate ( cx, & crate :: paths:: COMPONENT )
97+ . filter ( |trait_type| !( reflected. contains ( trait_type) || events. contains ( trait_type) ) )
98+ . collect ( ) ;
10699
107100 // Finds all non-`Reflect` types that implement `Resource` in this crate.
108- let resources: Vec < TraitType > =
109- TraitType :: from_local_crate ( cx. tcx , & crate :: paths:: RESOURCE )
110- . filter ( |trait_type| !reflected. contains ( trait_type) )
111- . collect ( ) ;
101+ let resources: Vec < TraitType > = TraitType :: from_local_crate ( cx, & crate :: paths:: RESOURCE )
102+ . filter ( |trait_type| !reflected. contains ( trait_type) )
103+ . collect ( ) ;
104+
105+ let reflect_trait_def_ids = crate :: paths:: PARTIAL_REFLECT . get ( cx) ;
112106
113- // This is an expensive function that is purposefully called outside of the `for` loop. Note
114- // that this will only return `None` if `PartialReflect` does not exist (e.g. `bevy_reflect`
115- // is not available.)
116- let Some ( reflect_trait_def_id) = get_trait_def_id ( cx. tcx , & crate :: paths:: PARTIAL_REFLECT )
117- else {
118- return ;
119- } ;
120107 // Emit diagnostics for each of these types.
121108 for ( checked_trait, trait_name, message_phrase) in [
122109 ( events, "Event" , "an event" ) ,
@@ -173,7 +160,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingReflect {
173160 // Check if the field's type implements the `PartialReflect` trait. If it does
174161 // not, change the `Applicability` level to `MaybeIncorrect` because `Reflect`
175162 // cannot be automatically derived.
176- if !implements_trait ( cx, ty, reflect_trait_def_id, & [ ] ) {
163+ if !reflect_trait_def_ids
164+ . iter ( )
165+ . any ( |& trait_id| implements_trait ( cx, ty, trait_id, & [ ] ) )
166+ {
177167 applicability = Applicability :: MaybeIncorrect ;
178168 break ;
179169 }
@@ -220,34 +210,32 @@ struct TraitType {
220210}
221211
222212impl TraitType {
223- fn from_local_crate < ' tcx > (
224- tcx : TyCtxt < ' tcx > ,
225- trait_path : & [ & str ] ,
226- ) -> impl Iterator < Item = Self > + use < ' tcx > {
213+ fn from_local_crate < ' tcx , ' a > (
214+ cx : & ' a LateContext < ' tcx > ,
215+ trait_path : & ' a PathLookup ,
216+ ) -> impl Iterator < Item = Self > + use < ' tcx , ' a > {
227217 // Find the `DefId` of the trait. There may be multiple if there are multiple versions of
228218 // the same crate.
229- let trait_def_ids = def_path_res ( tcx, trait_path)
219+ let trait_def_ids = trait_path
220+ . get ( cx)
230221 . into_iter ( )
231- . filter_map ( |res| match res {
232- Res :: Def ( DefKind :: Trait , def_id) => Some ( def_id) ,
233- _ => None ,
234- } ) ;
222+ . filter ( |& def_id| cx. tcx . def_kind ( def_id) == DefKind :: Trait ) ;
235223
236224 // Find a map of all trait `impl` items within the current crate. The key is the `DefId` of
237225 // the trait, and the value is a `Vec<LocalDefId>` for all `impl` items.
238- let all_trait_impls = tcx. all_local_trait_impls ( ( ) ) ;
226+ let all_trait_impls = cx . tcx . all_local_trait_impls ( ( ) ) ;
239227
240228 // Find all `impl` items for the specific trait.
241229 let trait_impls = trait_def_ids
242- . filter_map ( |def_id| all_trait_impls. get ( & def_id) )
230+ . filter_map ( |def_id| all_trait_impls. get ( def_id) )
243231 . flatten ( )
244232 . copied ( ) ;
245233
246234 // Map the `DefId`s of `impl` items to `TraitType`s. Sometimes this conversion can fail, so
247235 // we use `filter_map()` to skip errors.
248236 trait_impls. filter_map ( move |local_def_id| {
249237 // Retrieve the node of the `impl` item from its `DefId`.
250- let node = tcx. hir_node_by_def_id ( local_def_id) ;
238+ let node = cx . tcx . hir_node_by_def_id ( local_def_id) ;
251239
252240 // Verify that it's an `impl` item and not something else.
253241 let Node :: Item ( Item {
@@ -284,7 +272,7 @@ impl TraitType {
284272
285273 // Find the span where the type was declared. This is guaranteed to be an item, so we
286274 // can safely call `expect_item()` without it panicking.
287- let item_span = tcx. hir_node ( hir_id) . expect_item ( ) . span ;
275+ let item_span = cx . tcx . hir_node ( hir_id) . expect_item ( ) . span ;
288276
289277 Some ( TraitType {
290278 hir_id,
0 commit comments