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] [dev-dependencies]
clippy_dev = { version = "0.0.1", path = "clippy_dev" } clippy_dev = { version = "0.0.1", path = "clippy_dev" }
cargo_metadata = "0.7.1" cargo_metadata = "0.7.1"
compiletest_rs = "0.3.18" compiletest_rs = "=0.3.18"
lazy_static = "1.0" lazy_static = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
clippy-mini-macro-test = { version = "0.2", path = "mini-macro" } 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; 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 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 if match_borrow_depth(expected_type_of_self, actual_type_of_self) {
return match (expected_type_of_self, actual_type_of_self) { return Some(cx.tcx.item_path_str(trait_id));
(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)),
},
};
} }
cx.tcx.impl_of_method(method_def_id).and_then(|_| { 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) { if match_types(expected_type_of_self, actual_type_of_self) {
return Some(get_type_name(cx, &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 { fn match_types(lhs: &ty::TyKind<'_>, rhs: &ty::TyKind<'_>) -> bool {
match (lhs, rhs) { match (lhs, rhs) {
(ty::Bool, ty::Bool) (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); let nodeid = cx.tcx.hir().hir_to_node_id(hir_id);
self.check_raw_ptr(cx, unsafety, decl, body, nodeid); 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) { 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) { if in_external_macro(cx.sess(), span) {
return; return;
} }
let code_snippet = snippet(cx, span, ".."); let code_snippet = snippet(cx, body.value.span, "..");
let mut line_count: u64 = 0; let mut line_count: u64 = 0;
let mut in_comment = false; let mut in_comment = false;
let mut code_in_line; let mut code_in_line;

View file

@ -1,8 +1,9 @@
use crate::utils::{is_entrypoint_fn, span_lint}; use crate::utils::{is_entrypoint_fn, span_lint};
use if_chain::if_chain;
use rustc::hir; use rustc::hir;
use rustc::hir::intravisit::FnKind; use rustc::hir::intravisit::FnKind;
use rustc::hir::{Body, Constness, FnDecl, HirId}; 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::{declare_tool_lint, lint_array};
use rustc_mir::transform::qualify_min_const_fn::is_min_const_fn; use rustc_mir::transform::qualify_min_const_fn::is_min_const_fn;
use syntax_pos::Span; 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); 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; return;
} }
@ -95,7 +96,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
} }
}, },
FnKind::Method(_, sig, ..) => { FnKind::Method(_, sig, ..) => {
if already_const(sig.header) { if is_trait_method(cx, hir_id) || already_const(sig.header) {
return; 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` // We don't have to lint on something that's already `const`
fn already_const(header: hir::FnHeader) -> bool { fn already_const(header: hir::FnHeader) -> bool {
header.constness == Constness::Const 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 }) let c = Some(TestStruct { some_ref: &i })
.as_ref() .as_ref()
.map(|c| c.to_ascii_uppercase()); .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) fn meta<F>(f: F)

View file

@ -55,3 +55,16 @@ trait Foo {
33 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)
}
}