Skip to content

Commit

Permalink
Refactor: Extract trait_ref_of_method function
Browse files Browse the repository at this point in the history
  • Loading branch information
phansch committed Mar 7, 2019
1 parent 00baf7a commit a6b082c
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 27 deletions.
9 changes: 2 additions & 7 deletions clippy_lints/src/assign_ops.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utils::{get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, SpanlessEq};
use crate::utils::{get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, trait_ref_of_method, SpanlessEq};
use crate::utils::{higher, sugg};
use if_chain::if_chain;
use rustc::hir;
Expand Down Expand Up @@ -140,13 +140,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
};
// check that we are not inside an `impl AssignOp` of this exact operation
let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id);
let parent_impl = cx.tcx.hir().get_parent_item(parent_fn);
// the crate node is the only one that is not in the map
if_chain! {
if parent_impl != hir::CRATE_HIR_ID;
if let hir::Node::Item(item) = cx.tcx.hir().get_by_hir_id(parent_impl);
if let hir::ItemKind::Impl(_, _, _, _, Some(trait_ref), _, _) =
&item.node;
if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
if trait_ref.path.def.def_id() == trait_id;
then { return; }
}
Expand Down
17 changes: 2 additions & 15 deletions clippy_lints/src/missing_const_for_fn.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::utils::{is_entrypoint_fn, span_lint};
use if_chain::if_chain;
use crate::utils::{is_entrypoint_fn, span_lint, trait_ref_of_method};
use rustc::hir;
use rustc::hir::intravisit::FnKind;
use rustc::hir::{Body, Constness, FnDecl, HirId};
Expand Down Expand Up @@ -96,7 +95,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
}
},
FnKind::Method(_, sig, ..) => {
if is_trait_method(cx, hir_id) || already_const(sig.header) {
if trait_ref_of_method(cx, hir_id).is_some() || already_const(sig.header) {
return;
}
},
Expand All @@ -115,18 +114,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
}
}

fn is_trait_method(cx: &LateContext<'_, '_>, hir_id: HirId) -> bool {
// Get the implemented trait for the current function
let parent_impl = cx.tcx.hir().get_parent_item(hir_id);
if_chain! {
if parent_impl != hir::CRATE_HIR_ID;
if let hir::Node::Item(item) = cx.tcx.hir().get_by_hir_id(parent_impl);
if let hir::ItemKind::Impl(_, _, _, _, Some(_trait_ref), _, _) = &item.node;
then { return true; }
}
false
}

// We don't have to lint on something that's already `const`
fn already_const(header: hir::FnHeader) -> bool {
header.constness == Constness::Const
Expand Down
7 changes: 2 additions & 5 deletions clippy_lints/src/suspicious_trait_impl.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utils::{get_trait_def_id, span_lint};
use crate::utils::{get_trait_def_id, span_lint, trait_ref_of_method};
use if_chain::if_chain;
use rustc::hir;
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
Expand Down Expand Up @@ -177,12 +177,9 @@ fn check_binop<'a>(

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

if_chain! {
if parent_impl != hir::CRATE_HIR_ID;
if let hir::Node::Item(item) = cx.tcx.hir().get_by_hir_id(parent_impl);
if let hir::ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, _) = item.node;
if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
if let Some(idx) = trait_ids.iter().position(|&tid| tid == trait_ref.path.def.def_id());
if binop != expected_ops[idx];
then{
Expand Down
22 changes: 22 additions & 0 deletions clippy_lints/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,28 @@ pub fn implements_trait<'a, 'tcx>(
.enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
}

/// Get the `hir::TraitRef` of the trait the given method is implemented for
///
/// Use this if you want to find the `TraitRef` of the `Point` trait in this example:
///
/// ```rust
/// trait Point;
///
/// impl std::ops::Add for Point {}
/// ```
/// See https://doc.rust-lang.org/nightly/nightly-rustc/rustc/hir/struct.TraitRef.html
pub fn trait_ref_of_method(cx: &LateContext<'_, '_>, hir_id: HirId) -> Option<TraitRef> {
// Get the implemented trait for the current function
let parent_impl = cx.tcx.hir().get_parent_item(hir_id);
if_chain! {
if parent_impl != hir::CRATE_HIR_ID;
if let hir::Node::Item(item) = cx.tcx.hir().get_by_hir_id(parent_impl);
if let hir::ItemKind::Impl(_, _, _, _, trait_ref, _, _) = &item.node;
then { return trait_ref.clone(); }
}
None
}

/// Check whether this type implements Drop.
pub fn has_drop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
match ty.ty_adt_def() {
Expand Down

0 comments on commit a6b082c

Please sign in to comment.