Skip to content

Commit 1902384

Browse files
authored
Rollup merge of rust-lang#3851 - phansch:refactor_trait_stuff, r=flip1995
Refactor: Extract `trait_ref_of_method` function This pattern was used in three places after rust-lang#3844, so I think it's worth moving it into `utils/mod.rs` and documenting it.
2 parents bd6b5a1 + 131b89b commit 1902384

File tree

4 files changed

+35
-27
lines changed

4 files changed

+35
-27
lines changed

clippy_lints/src/assign_ops.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::utils::{get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, SpanlessEq};
1+
use crate::utils::{
2+
get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, trait_ref_of_method, SpanlessEq,
3+
};
24
use crate::utils::{higher, sugg};
35
use if_chain::if_chain;
46
use rustc::hir;
@@ -140,13 +142,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
140142
};
141143
// check that we are not inside an `impl AssignOp` of this exact operation
142144
let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id);
143-
let parent_impl = cx.tcx.hir().get_parent_item(parent_fn);
144-
// the crate node is the only one that is not in the map
145145
if_chain! {
146-
if parent_impl != hir::CRATE_HIR_ID;
147-
if let hir::Node::Item(item) = cx.tcx.hir().get_by_hir_id(parent_impl);
148-
if let hir::ItemKind::Impl(_, _, _, _, Some(trait_ref), _, _) =
149-
&item.node;
146+
if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
150147
if trait_ref.path.def.def_id() == trait_id;
151148
then { return; }
152149
}

clippy_lints/src/missing_const_for_fn.rs

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use crate::utils::{is_entrypoint_fn, span_lint};
2-
use if_chain::if_chain;
1+
use crate::utils::{is_entrypoint_fn, span_lint, trait_ref_of_method};
32
use rustc::hir;
43
use rustc::hir::intravisit::FnKind;
54
use rustc::hir::{Body, Constness, FnDecl, HirId};
@@ -96,7 +95,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
9695
}
9796
},
9897
FnKind::Method(_, sig, ..) => {
99-
if is_trait_method(cx, hir_id) || already_const(sig.header) {
98+
if trait_ref_of_method(cx, hir_id).is_some() || already_const(sig.header) {
10099
return;
101100
}
102101
},
@@ -115,18 +114,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
115114
}
116115
}
117116

118-
fn is_trait_method(cx: &LateContext<'_, '_>, hir_id: HirId) -> bool {
119-
// Get the implemented trait for the current function
120-
let parent_impl = cx.tcx.hir().get_parent_item(hir_id);
121-
if_chain! {
122-
if parent_impl != hir::CRATE_HIR_ID;
123-
if let hir::Node::Item(item) = cx.tcx.hir().get_by_hir_id(parent_impl);
124-
if let hir::ItemKind::Impl(_, _, _, _, Some(_trait_ref), _, _) = &item.node;
125-
then { return true; }
126-
}
127-
false
128-
}
129-
130117
// We don't have to lint on something that's already `const`
131118
fn already_const(header: hir::FnHeader) -> bool {
132119
header.constness == Constness::Const

clippy_lints/src/suspicious_trait_impl.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::utils::{get_trait_def_id, span_lint};
1+
use crate::utils::{get_trait_def_id, span_lint, trait_ref_of_method};
22
use if_chain::if_chain;
33
use rustc::hir;
44
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
@@ -177,12 +177,9 @@ fn check_binop<'a>(
177177

178178
// Get the actually implemented trait
179179
let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id);
180-
let parent_impl = cx.tcx.hir().get_parent_item(parent_fn);
181180

182181
if_chain! {
183-
if parent_impl != hir::CRATE_HIR_ID;
184-
if let hir::Node::Item(item) = cx.tcx.hir().get_by_hir_id(parent_impl);
185-
if let hir::ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, _) = item.node;
182+
if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
186183
if let Some(idx) = trait_ids.iter().position(|&tid| tid == trait_ref.path.def.def_id());
187184
if binop != expected_ops[idx];
188185
then{

clippy_lints/src/utils/mod.rs

+27
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,33 @@ pub fn implements_trait<'a, 'tcx>(
301301
.enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
302302
}
303303

304+
/// Get the `hir::TraitRef` of the trait the given method is implemented for
305+
///
306+
/// Use this if you want to find the `TraitRef` of the `Add` trait in this example:
307+
///
308+
/// ```rust
309+
/// struct Point(isize, isize);
310+
///
311+
/// impl std::ops::Add for Point {
312+
/// type Output = Self;
313+
///
314+
/// fn add(self, other: Self) -> Self {
315+
/// Point(0, 0)
316+
/// }
317+
/// }
318+
/// ```
319+
pub fn trait_ref_of_method(cx: &LateContext<'_, '_>, hir_id: HirId) -> Option<TraitRef> {
320+
// Get the implemented trait for the current function
321+
let parent_impl = cx.tcx.hir().get_parent_item(hir_id);
322+
if_chain! {
323+
if parent_impl != hir::CRATE_HIR_ID;
324+
if let hir::Node::Item(item) = cx.tcx.hir().get_by_hir_id(parent_impl);
325+
if let hir::ItemKind::Impl(_, _, _, _, trait_ref, _, _) = &item.node;
326+
then { return trait_ref.clone(); }
327+
}
328+
None
329+
}
330+
304331
/// Check whether this type implements Drop.
305332
pub fn has_drop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
306333
match ty.ty_adt_def() {

0 commit comments

Comments
 (0)