|
1 | 1 | use rustc::lint::*; |
2 | 2 | use rustc::ty::subst::Subst; |
3 | 3 | use rustc::ty::TypeVariants; |
4 | | -use rustc::ty::fast_reject::simplify_type; |
5 | 4 | use rustc::ty; |
6 | 5 | use rustc::hir::*; |
7 | 6 | use syntax::ast::{Attribute, MetaItemKind}; |
@@ -87,52 +86,44 @@ impl LateLintPass for Derive { |
87 | 86 | } |
88 | 87 |
|
89 | 88 | /// Implementation of the `DERIVE_HASH_XOR_EQ` lint. |
90 | | -fn check_hash_peq(cx: &LateContext, span: Span, trait_ref: &TraitRef, ty: ty::Ty, hash_is_automatically_derived: bool) { |
| 89 | +fn check_hash_peq<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, trait_ref: &TraitRef, ty: ty::Ty<'tcx>, hash_is_automatically_derived: bool) { |
91 | 90 | if_let_chain! {[ |
92 | 91 | match_path(&trait_ref.path, &HASH_PATH), |
93 | 92 | let Some(peq_trait_def_id) = cx.tcx.lang_items.eq_trait() |
94 | 93 | ], { |
95 | 94 | let peq_trait_def = cx.tcx.lookup_trait_def(peq_trait_def_id); |
96 | 95 |
|
97 | | - cx.tcx.populate_implementations_for_trait_if_necessary(peq_trait_def.trait_ref.def_id); |
98 | | - let peq_impls = peq_trait_def.borrow_impl_lists(cx.tcx).1; |
99 | | - |
100 | 96 | // Look for the PartialEq implementations for `ty` |
101 | | - if_let_chain! {[ |
102 | | - let Some(simpl_ty) = simplify_type(cx.tcx, ty, false), |
103 | | - let Some(impl_ids) = peq_impls.get(&simpl_ty) |
104 | | - ], { |
105 | | - for &impl_id in impl_ids { |
106 | | - let peq_is_automatically_derived = cx.tcx.get_attrs(impl_id).iter().any(is_automatically_derived); |
| 97 | + peq_trait_def.for_each_relevant_impl(&cx.tcx, ty, |impl_id| { |
| 98 | + let peq_is_automatically_derived = cx.tcx.get_attrs(impl_id).iter().any(is_automatically_derived); |
107 | 99 |
|
108 | | - if peq_is_automatically_derived == hash_is_automatically_derived { |
109 | | - return; |
110 | | - } |
| 100 | + if peq_is_automatically_derived == hash_is_automatically_derived { |
| 101 | + return; |
| 102 | + } |
111 | 103 |
|
112 | | - let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation"); |
113 | | - |
114 | | - // Only care about `impl PartialEq<Foo> for Foo` |
115 | | - if trait_ref.input_types()[0] == ty { |
116 | | - let mess = if peq_is_automatically_derived { |
117 | | - "you are implementing `Hash` explicitly but have derived `PartialEq`" |
118 | | - } else { |
119 | | - "you are deriving `Hash` but have implemented `PartialEq` explicitly" |
120 | | - }; |
121 | | - |
122 | | - span_lint_and_then( |
123 | | - cx, DERIVE_HASH_XOR_EQ, span, |
124 | | - mess, |
125 | | - |db| { |
126 | | - if let Some(node_id) = cx.tcx.map.as_local_node_id(impl_id) { |
127 | | - db.span_note( |
128 | | - cx.tcx.map.span(node_id), |
129 | | - "`PartialEq` implemented here" |
130 | | - ); |
131 | | - } |
132 | | - }); |
133 | | - } |
| 104 | + let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation"); |
| 105 | + |
| 106 | + // Only care about `impl PartialEq<Foo> for Foo` |
| 107 | + if trait_ref.input_types()[0] == ty { |
| 108 | + let mess = if peq_is_automatically_derived { |
| 109 | + "you are implementing `Hash` explicitly but have derived `PartialEq`" |
| 110 | + } else { |
| 111 | + "you are deriving `Hash` but have implemented `PartialEq` explicitly" |
| 112 | + }; |
| 113 | + |
| 114 | + span_lint_and_then( |
| 115 | + cx, DERIVE_HASH_XOR_EQ, span, |
| 116 | + mess, |
| 117 | + |db| { |
| 118 | + if let Some(node_id) = cx.tcx.map.as_local_node_id(impl_id) { |
| 119 | + db.span_note( |
| 120 | + cx.tcx.map.span(node_id), |
| 121 | + "`PartialEq` implemented here" |
| 122 | + ); |
| 123 | + } |
| 124 | + }); |
134 | 125 | } |
135 | | - }} |
| 126 | + }); |
136 | 127 | }} |
137 | 128 | } |
138 | 129 |
|
|
0 commit comments