Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions clippy_lints/src/assign_ops.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
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;
@@ -140,13 +142,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; }
}
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};
@@ -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;
}
},
@@ -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
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};
@@ -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{
27 changes: 27 additions & 0 deletions clippy_lints/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -301,6 +301,33 @@ 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 `Add` trait in this example:
///
/// ```rust
/// struct Point(isize, isize);
///
/// impl std::ops::Add for Point {
/// type Output = Self;
///
/// fn add(self, other: Self) -> Self {
/// Point(0, 0)
/// }
/// }
/// ```
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() {