|
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