Rollup merge of #3851 - phansch:refactor_trait_stuff, r=flip1995
Refactor: Extract `trait_ref_of_method` function This pattern was used in three places after #3844, so I think it's worth moving it into `utils/mod.rs` and documenting it.
This commit is contained in:
commit
1902384d15
@ -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; }
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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{
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user