Merge pull request #4003 from rust-lang/stable-backports

Backport some things to stable
This commit is contained in:
Manish Goregaokar 2019-04-18 22:14:09 -07:00 committed by GitHub
commit 726176e322
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 72 additions and 16 deletions

View file

@ -47,7 +47,7 @@ rustc_tools_util = { version = "0.1.1", path = "rustc_tools_util"}
[dev-dependencies]
clippy_dev = { version = "0.0.1", path = "clippy_dev" }
cargo_metadata = "0.7.1"
compiletest_rs = "0.3.18"
compiletest_rs = "=0.3.18"
lazy_static = "1.0"
serde_derive = "1.0"
clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }

View file

@ -129,18 +129,13 @@ fn get_ufcs_type_name(
let actual_type_of_self = &cx.tables.node_type(self_arg.hir_id).sty;
if let Some(trait_id) = cx.tcx.trait_of_item(method_def_id) {
//if the method expectes &self, ufcs requires explicit borrowing so closure can't be removed
return match (expected_type_of_self, actual_type_of_self) {
(ty::Ref(_, _, _), ty::Ref(_, _, _)) => Some(cx.tcx.item_path_str(trait_id)),
(l, r) => match (l, r) {
(ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _)) => None,
(_, _) => Some(cx.tcx.item_path_str(trait_id)),
},
};
if match_borrow_depth(expected_type_of_self, actual_type_of_self) {
return Some(cx.tcx.item_path_str(trait_id));
}
}
cx.tcx.impl_of_method(method_def_id).and_then(|_| {
//a type may implicitly implement other types methods (e.g. Deref)
//a type may implicitly implement other type's methods (e.g. Deref)
if match_types(expected_type_of_self, actual_type_of_self) {
return Some(get_type_name(cx, &actual_type_of_self));
}
@ -148,6 +143,16 @@ fn get_ufcs_type_name(
})
}
fn match_borrow_depth(lhs: &ty::TyKind<'_>, rhs: &ty::TyKind<'_>) -> bool {
match (lhs, rhs) {
(ty::Ref(_, t1, _), ty::Ref(_, t2, _)) => match_borrow_depth(&t1.sty, &t2.sty),
(l, r) => match (l, r) {
(ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _)) => false,
(_, _) => true,
},
}
}
fn match_types(lhs: &ty::TyKind<'_>, rhs: &ty::TyKind<'_>) -> bool {
match (lhs, rhs) {
(ty::Bool, ty::Bool)

View file

@ -150,7 +150,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
let nodeid = cx.tcx.hir().hir_to_node_id(hir_id);
self.check_raw_ptr(cx, unsafety, decl, body, nodeid);
self.check_line_number(cx, span);
self.check_line_number(cx, span, body);
}
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) {
@ -181,12 +181,12 @@ impl<'a, 'tcx> Functions {
}
}
fn check_line_number(self, cx: &LateContext<'_, '_>, span: Span) {
fn check_line_number(self, cx: &LateContext<'_, '_>, span: Span, body: &'tcx hir::Body) {
if in_external_macro(cx.sess(), span) {
return;
}
let code_snippet = snippet(cx, span, "..");
let code_snippet = snippet(cx, body.value.span, "..");
let mut line_count: u64 = 0;
let mut in_comment = false;
let mut code_in_line;

View file

@ -1,8 +1,9 @@
use crate::utils::{is_entrypoint_fn, span_lint};
use if_chain::if_chain;
use rustc::hir;
use rustc::hir::intravisit::FnKind;
use rustc::hir::{Body, Constness, FnDecl, HirId};
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_tool_lint, lint_array};
use rustc_mir::transform::qualify_min_const_fn::is_min_const_fn;
use syntax_pos::Span;
@ -82,7 +83,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
) {
let def_id = cx.tcx.hir().local_def_id_from_hir_id(hir_id);
if is_entrypoint_fn(cx, def_id) {
if in_external_macro(cx.tcx.sess, span) || is_entrypoint_fn(cx, def_id) {
return;
}
@ -95,7 +96,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
}
},
FnKind::Method(_, sig, ..) => {
if already_const(sig.header) {
if is_trait_method(cx, hir_id) || already_const(sig.header) {
return;
}
},
@ -114,6 +115,18 @@ 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

View file

@ -0,0 +1,17 @@
/// Test for https://github.com/rust-lang/rust-clippy/issues/3747
macro_rules! a {
( $pub:tt $($attr:tt)* ) => {
$($attr)* $pub fn say_hello() {}
};
}
macro_rules! b {
() => {
a! { pub }
};
}
b! {}
fn main() {}

View file

@ -88,6 +88,14 @@ fn test_redundant_closures_containing_method_calls() {
let c = Some(TestStruct { some_ref: &i })
.as_ref()
.map(|c| c.to_ascii_uppercase());
fn test_different_borrow_levels<T>(t: &[&T])
where
T: TestTrait,
{
t.iter().filter(|x| x.trait_foo_ref());
t.iter().map(|x| x.trait_foo_ref());
}
}
fn meta<F>(f: F)

View file

@ -55,3 +55,16 @@ trait Foo {
33
}
}
// Don't lint in external macros (derive)
#[derive(PartialEq, Eq)]
struct Point(isize, isize);
impl std::ops::Add for Point {
type Output = Self;
// Don't lint in trait impls of derived methods
fn add(self, other: Self) -> Self {
Point(self.0 + other.0, self.1 + other.1)
}
}