Merge commit '3e7c6dec24' into clippyup

This commit is contained in:
flip1995 2020-11-23 13:51:04 +01:00
parent 113c1476c9
commit d3d2018ead
141 changed files with 3104 additions and 876 deletions

View file

@ -110,8 +110,7 @@ pub fn eq_expr_opt(l: &Option<P<Expr>>, r: &Option<P<Expr>>) -> bool {
pub fn eq_struct_rest(l: &StructRest, r: &StructRest) -> bool {
match (l, r) {
(StructRest::Base(lb), StructRest::Base(rb)) => eq_expr(lb, rb),
(StructRest::Rest(_), StructRest::Rest(_)) => true,
(StructRest::None, StructRest::None) => true,
(StructRest::Rest(_), StructRest::Rest(_)) | (StructRest::None, StructRest::None) => true,
_ => false,
}
}

View file

@ -9,7 +9,7 @@
//! - or-fun-call
//! - option-if-let-else
use crate::utils::is_ctor_or_promotable_const_function;
use crate::utils::{is_ctor_or_promotable_const_function, is_type_diagnostic_item, match_type, paths};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit;
@ -96,6 +96,11 @@ fn identify_some_potentially_expensive_patterns<'tcx>(cx: &LateContext<'tcx>, ex
let call_found = match &expr.kind {
// ignore enum and struct constructors
ExprKind::Call(..) => !is_ctor_or_promotable_const_function(self.cx, expr),
ExprKind::Index(obj, _) => {
let ty = self.cx.typeck_results().expr_ty(obj);
is_type_diagnostic_item(self.cx, ty, sym!(hashmap_type))
|| match_type(self.cx, ty, &paths::BTREEMAP)
},
ExprKind::MethodCall(..) => true,
_ => false,
};

View file

@ -21,6 +21,7 @@ pub mod ptr;
pub mod qualify_min_const_fn;
pub mod sugg;
pub mod usage;
pub mod visitors;
pub use self::attrs::*;
pub use self::diagnostics::*;
@ -468,6 +469,13 @@ pub fn is_entrypoint_fn(cx: &LateContext<'_>, def_id: DefId) -> bool {
.map_or(false, |(entry_fn_def_id, _)| def_id == entry_fn_def_id.to_def_id())
}
/// Returns `true` if the expression is in the program's `#[panic_handler]`.
pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
let parent = cx.tcx.hir().get_parent_item(e.hir_id);
let def_id = cx.tcx.hir().local_def_id(parent).to_def_id();
Some(def_id) == cx.tcx.lang_items().panic_impl()
}
/// Gets the name of the item the expression is in, if available.
pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id);
@ -659,6 +667,35 @@ pub fn indent_of<T: LintContext>(cx: &T, span: Span) -> Option<usize> {
snippet_opt(cx, line_span(cx, span)).and_then(|snip| snip.find(|c: char| !c.is_whitespace()))
}
/// Returns the positon just before rarrow
///
/// ```rust,ignore
/// fn into(self) -> () {}
/// ^
/// // in case of unformatted code
/// fn into2(self)-> () {}
/// ^
/// fn into3(self) -> () {}
/// ^
/// ```
#[allow(clippy::needless_pass_by_value)]
pub fn position_before_rarrow(s: String) -> Option<usize> {
s.rfind("->").map(|rpos| {
let mut rpos = rpos;
let chars: Vec<char> = s.chars().collect();
while rpos > 1 {
if let Some(c) = chars.get(rpos - 1) {
if c.is_whitespace() {
rpos -= 1;
continue;
}
}
break;
}
rpos
})
}
/// Extends the span to the beginning of the spans line, incl. whitespaces.
///
/// ```rust,ignore

View file

@ -126,6 +126,7 @@ pub const STRING: [&str; 3] = ["alloc", "string", "String"];
pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "<impl str>", "ends_with"];
pub const STR_FROM_UTF8: [&str; 4] = ["core", "str", "converts", "from_utf8"];
pub const STR_LEN: [&str; 4] = ["core", "str", "<impl str>", "len"];
pub const STR_STARTS_WITH: [&str; 4] = ["core", "str", "<impl str>", "starts_with"];
pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];

View file

@ -0,0 +1,125 @@
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_lint::LateContext;
use rustc_middle::hir::map::Map;
/// returns `true` if expr contains match expr desugared from try
fn contains_try(expr: &hir::Expr<'_>) -> bool {
struct TryFinder {
found: bool,
}
impl<'hir> intravisit::Visitor<'hir> for TryFinder {
type Map = Map<'hir>;
fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
intravisit::NestedVisitorMap::None
}
fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
if self.found {
return;
}
match expr.kind {
hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar) => self.found = true,
_ => intravisit::walk_expr(self, expr),
}
}
}
let mut visitor = TryFinder { found: false };
visitor.visit_expr(expr);
visitor.found
}
pub fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir hir::Expr<'hir>, callback: F) -> bool
where
F: FnMut(&'hir hir::Expr<'hir>) -> bool,
{
struct RetFinder<F> {
in_stmt: bool,
failed: bool,
cb: F,
}
struct WithStmtGuarg<'a, F> {
val: &'a mut RetFinder<F>,
prev_in_stmt: bool,
}
impl<F> RetFinder<F> {
fn inside_stmt(&mut self, in_stmt: bool) -> WithStmtGuarg<'_, F> {
let prev_in_stmt = std::mem::replace(&mut self.in_stmt, in_stmt);
WithStmtGuarg {
val: self,
prev_in_stmt,
}
}
}
impl<F> std::ops::Deref for WithStmtGuarg<'_, F> {
type Target = RetFinder<F>;
fn deref(&self) -> &Self::Target {
self.val
}
}
impl<F> std::ops::DerefMut for WithStmtGuarg<'_, F> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.val
}
}
impl<F> Drop for WithStmtGuarg<'_, F> {
fn drop(&mut self) {
self.val.in_stmt = self.prev_in_stmt;
}
}
impl<'hir, F: FnMut(&'hir hir::Expr<'hir>) -> bool> intravisit::Visitor<'hir> for RetFinder<F> {
type Map = Map<'hir>;
fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
intravisit::NestedVisitorMap::None
}
fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'_>) {
intravisit::walk_stmt(&mut *self.inside_stmt(true), stmt)
}
fn visit_expr(&mut self, expr: &'hir hir::Expr<'_>) {
if self.failed {
return;
}
if self.in_stmt {
match expr.kind {
hir::ExprKind::Ret(Some(expr)) => self.inside_stmt(false).visit_expr(expr),
_ => intravisit::walk_expr(self, expr),
}
} else {
match expr.kind {
hir::ExprKind::Match(cond, arms, _) => {
self.inside_stmt(true).visit_expr(cond);
for arm in arms {
self.visit_expr(arm.body);
}
},
hir::ExprKind::Block(..) => intravisit::walk_expr(self, expr),
hir::ExprKind::Ret(Some(expr)) => self.visit_expr(expr),
_ => self.failed |= !(self.cb)(expr),
}
}
}
}
!contains_try(expr) && {
let mut ret_finder = RetFinder {
in_stmt: false,
failed: false,
cb: callback,
};
ret_finder.visit_expr(expr);
!ret_finder.failed
}
}