Skip to content

Commit

Permalink
Merge branch 'rust-lang:master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
Rudxain committed Jun 24, 2024
2 parents a73bc9d + 32374a1 commit c81afb5
Show file tree
Hide file tree
Showing 34 changed files with 1,088 additions and 263 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5917,6 +5917,7 @@ Released 2018-09-13
[`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations
[`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap
[`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_on_constructor
[`unnecessary_min_or_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_min_or_max
[`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
[`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation
[`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings
Expand Down
22 changes: 8 additions & 14 deletions clippy_lints/src/cognitive_complexity.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! calculate cognitive complexity and warn about overly complex functions

use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::snippet_opt;
use clippy_utils::source::{IntoSpan, SpanRangeExt};
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::visitors::for_each_expr_without_closures;
use clippy_utils::{get_async_fn_body, is_async_fn, LimitStack};
Expand All @@ -12,7 +12,7 @@ use rustc_hir::{Body, Expr, ExprKind, FnDecl};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::impl_lint_pass;
use rustc_span::def_id::LocalDefId;
use rustc_span::{sym, BytePos, Span};
use rustc_span::{sym, Span};

declare_clippy_lint! {
/// ### What it does
Expand Down Expand Up @@ -50,7 +50,6 @@ impl CognitiveComplexity {
impl_lint_pass!(CognitiveComplexity => [COGNITIVE_COMPLEXITY]);

impl CognitiveComplexity {
#[expect(clippy::cast_possible_truncation)]
fn check<'tcx>(
&mut self,
cx: &LateContext<'tcx>,
Expand Down Expand Up @@ -100,17 +99,12 @@ impl CognitiveComplexity {
FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span,
FnKind::Closure => {
let header_span = body_span.with_hi(decl.output.span().lo());
let pos = snippet_opt(cx, header_span).and_then(|snip| {
let low_offset = snip.find('|')?;
let high_offset = 1 + snip.get(low_offset + 1..)?.find('|')?;
let low = header_span.lo() + BytePos(low_offset as u32);
let high = low + BytePos(high_offset as u32 + 1);

Some((low, high))
});

if let Some((low, high)) = pos {
Span::new(low, high, header_span.ctxt(), header_span.parent())
#[expect(clippy::range_plus_one)]
if let Some(range) = header_span.map_range(cx, |src, range| {
let mut idxs = src.get(range.clone())?.match_indices('|');
Some(range.start + idxs.next()?.0..range.start + idxs.next()?.0 + 1)
}) {
range.with_ctxt(header_span.ctxt())
} else {
return;
}
Expand Down
16 changes: 8 additions & 8 deletions clippy_lints/src/copies.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then};
use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt};
use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, IntoSpan, SpanRangeExt};
use clippy_utils::ty::{needs_ordered_drop, InteriorMut};
use clippy_utils::visitors::for_each_expr_without_closures;
use clippy_utils::{
Expand All @@ -14,7 +14,7 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
use rustc_span::hygiene::walk_chain;
use rustc_span::source_map::SourceMap;
use rustc_span::{BytePos, Span, Symbol};
use rustc_span::{Span, Symbol};
use std::borrow::Cow;

declare_clippy_lint! {
Expand Down Expand Up @@ -266,12 +266,12 @@ fn lint_branches_sharing_code<'tcx>(

let span = span.with_hi(last_block.span.hi());
// Improve formatting if the inner block has indention (i.e. normal Rust formatting)
let test_span = Span::new(span.lo() - BytePos(4), span.lo(), span.ctxt(), span.parent());
let span = if snippet_opt(cx, test_span).map_or(false, |snip| snip == " ") {
span.with_lo(test_span.lo())
} else {
span
};
let span = span
.map_range(cx, |src, range| {
(range.start > 4 && src.get(range.start - 4..range.start)? == " ")
.then_some(range.start - 4..range.end)
})
.map_or(span, |range| range.with_ctxt(span.ctxt()));
(span, suggestion.to_string())
});

Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/declared_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::methods::UNNECESSARY_JOIN_INFO,
crate::methods::UNNECESSARY_LAZY_EVALUATIONS_INFO,
crate::methods::UNNECESSARY_LITERAL_UNWRAP_INFO,
crate::methods::UNNECESSARY_MIN_OR_MAX_INFO,
crate::methods::UNNECESSARY_RESULT_MAP_OR_ELSE_INFO,
crate::methods::UNNECESSARY_SORT_BY_INFO,
crate::methods::UNNECESSARY_TO_OWNED_INFO,
Expand Down
40 changes: 17 additions & 23 deletions clippy_lints/src/implicit_hasher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_span::symbol::sym;
use rustc_span::Span;

use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
use clippy_utils::source::{snippet, snippet_opt};
use clippy_utils::source::{snippet, IntoSpan, SpanRangeExt};
use clippy_utils::ty::is_type_diagnostic_item;

declare_clippy_lint! {
Expand Down Expand Up @@ -59,10 +59,8 @@ declare_clippy_lint! {
declare_lint_pass!(ImplicitHasher => [IMPLICIT_HASHER]);

impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
#[expect(clippy::cast_possible_truncation, clippy::too_many_lines)]
#[expect(clippy::too_many_lines)]
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
use rustc_span::BytePos;

fn suggestion(
cx: &LateContext<'_>,
diag: &mut Diag<'_, ()>,
Expand Down Expand Up @@ -123,10 +121,11 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
}

let generics_suggestion_span = impl_.generics.span.substitute_dummy({
let pos = snippet_opt(cx, item.span.until(target.span()))
.and_then(|snip| Some(item.span.lo() + BytePos(snip.find("impl")? as u32 + 4)));
if let Some(pos) = pos {
Span::new(pos, pos, item.span.ctxt(), item.span.parent())
let range = (item.span.lo()..target.span().lo()).map_range(cx, |src, range| {
Some(src.get(range.clone())?.find("impl")? + 4..range.end)
});
if let Some(range) = range {
range.with_ctxt(item.span.ctxt())
} else {
return;
}
Expand Down Expand Up @@ -163,21 +162,16 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
continue;
}
let generics_suggestion_span = generics.span.substitute_dummy({
let pos = snippet_opt(
cx,
Span::new(
item.span.lo(),
body.params[0].pat.span.lo(),
item.span.ctxt(),
item.span.parent(),
),
)
.and_then(|snip| {
let i = snip.find("fn")?;
Some(item.span.lo() + BytePos((i + snip[i..].find('(')?) as u32))
})
.expect("failed to create span for type parameters");
Span::new(pos, pos, item.span.ctxt(), item.span.parent())
let range = (item.span.lo()..body.params[0].pat.span.lo()).map_range(cx, |src, range| {
let (pre, post) = src.get(range.clone())?.split_once("fn")?;
let pos = post.find('(')? + pre.len() + 2;
Some(pos..pos)
});
if let Some(range) = range {
range.with_ctxt(item.span.ctxt())
} else {
return;
}
});

let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target);
Expand Down
9 changes: 2 additions & 7 deletions clippy_lints/src/manual_unwrap_or_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,15 @@ declare_lint_pass!(ManualUnwrapOrDefault => [MANUAL_UNWRAP_OR_DEFAULT]);

fn get_some<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option<HirId> {
if let PatKind::TupleStruct(QPath::Resolved(_, path), &[pat], _) = pat.kind
&& let PatKind::Binding(_, pat_id, _, _) = pat.kind
&& let Some(def_id) = path.res.opt_def_id()
// Since it comes from a pattern binding, we need to get the parent to actually match
// against it.
&& let Some(def_id) = cx.tcx.opt_parent(def_id)
&& (cx.tcx.lang_items().get(LangItem::OptionSome) == Some(def_id)
|| cx.tcx.lang_items().get(LangItem::ResultOk) == Some(def_id))
{
let mut bindings = Vec::new();
pat.each_binding(|_, id, _, _| bindings.push(id));
if let &[id] = bindings.as_slice() {
Some(id)
} else {
None
}
Some(pat_id)
} else {
None
}
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/matches/single_match.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::{expr_block, get_source_text, snippet};
use clippy_utils::source::{expr_block, snippet, SpanRangeExt};
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item, peel_mid_ty_refs};
use clippy_utils::{is_lint_allowed, is_unit_expr, is_wild, peel_blocks, peel_hir_pat_refs, peel_n_hir_expr_refs};
use core::cmp::max;
Expand All @@ -17,7 +17,7 @@ use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE};
/// span, e.g. a string literal `"//"`, but we know that this isn't the case for empty
/// match arms.
fn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool {
if let Some(ff) = get_source_text(cx, span)
if let Some(ff) = span.get_source_text(cx)
&& let Some(text) = ff.as_str()
{
text.as_bytes().windows(2).any(|w| w == b"//" || w == b"/*")
Expand Down
31 changes: 18 additions & 13 deletions clippy_lints/src/methods/manual_inspect.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::{get_source_text, with_leading_whitespace, SpanRange};
use clippy_utils::source::{IntoSpan, SpanRangeExt};
use clippy_utils::ty::get_field_by_name;
use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures};
use clippy_utils::{expr_use_ctxt, is_diag_item_method, is_diag_trait_item, path_to_local_id, ExprUseNode};
Expand All @@ -9,7 +9,7 @@ use rustc_errors::Applicability;
use rustc_hir::{BindingMode, BorrowKind, ByRef, ClosureKind, Expr, ExprKind, Mutability, Node, PatKind};
use rustc_lint::LateContext;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
use rustc_span::{sym, BytePos, Span, Symbol, DUMMY_SP};
use rustc_span::{sym, Span, Symbol, DUMMY_SP};

use super::MANUAL_INSPECT;

Expand Down Expand Up @@ -98,17 +98,19 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
let mut addr_of_edits = Vec::with_capacity(delayed.len());
for x in delayed {
match x {
UseKind::Return(s) => edits.push((with_leading_whitespace(cx, s).set_span_pos(s), String::new())),
UseKind::Return(s) => edits.push((s.with_leading_whitespace(cx).with_ctxt(s.ctxt()), String::new())),
UseKind::Borrowed(s) => {
if let Some(src) = get_source_text(cx, s)
&& let Some(src) = src.as_str()
&& let trim_src = src.trim_start_matches([' ', '\t', '\n', '\r', '('])
&& trim_src.starts_with('&')
{
let range = s.into_range();
#[expect(clippy::cast_possible_truncation)]
let start = BytePos(range.start.0 + (src.len() - trim_src.len()) as u32);
addr_of_edits.push(((start..BytePos(start.0 + 1)).set_span_pos(s), String::new()));
#[expect(clippy::range_plus_one)]
let range = s.map_range(cx, |src, range| {
let src = src.get(range.clone())?;
let trimmed = src.trim_start_matches([' ', '\t', '\n', '\r', '(']);
trimmed.starts_with('&').then(|| {
let pos = range.start + src.len() - trimmed.len();
pos..pos + 1
})
});
if let Some(range) = range {
addr_of_edits.push((range.with_ctxt(s.ctxt()), String::new()));
} else {
requires_copy = true;
requires_deref = true;
Expand Down Expand Up @@ -174,7 +176,10 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
}),
));
edits.push((
with_leading_whitespace(cx, final_expr.span).set_span_pos(final_expr.span),
final_expr
.span
.with_leading_whitespace(cx)
.with_ctxt(final_expr.span.ctxt()),
String::new(),
));
let app = if edits.iter().any(|(s, _)| s.from_expansion()) {
Expand Down
30 changes: 30 additions & 0 deletions clippy_lints/src/methods/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ mod unnecessary_iter_cloned;
mod unnecessary_join;
mod unnecessary_lazy_eval;
mod unnecessary_literal_unwrap;
mod unnecessary_min_or_max;
mod unnecessary_result_map_or_else;
mod unnecessary_sort_by;
mod unnecessary_to_owned;
Expand Down Expand Up @@ -3945,6 +3946,31 @@ declare_clippy_lint! {
"cloning an `Option` via `as_ref().cloned()`"
}

declare_clippy_lint! {
/// ### What it does
/// Checks for unnecessary calls to `min()` or `max()` in the following cases
/// - Either both side is constant
/// - One side is clearly larger than the other, like i32::MIN and an i32 variable
///
/// ### Why is this bad?
///
/// In the aformentioned cases it is not necessary to call `min()` or `max()`
/// to compare values, it may even cause confusion.
///
/// ### Example
/// ```no_run
/// let _ = 0.min(7_u32);
/// ```
/// Use instead:
/// ```no_run
/// let _ = 0;
/// ```
#[clippy::version = "1.78.0"]
pub UNNECESSARY_MIN_OR_MAX,
complexity,
"using 'min()/max()' when there is no need for it"
}

declare_clippy_lint! {
/// ### What it does
/// Checks for usage of `.map_or_else()` "map closure" for `Result` type.
Expand Down Expand Up @@ -4267,6 +4293,7 @@ impl_lint_pass!(Methods => [
UNNECESSARY_GET_THEN_CHECK,
NEEDLESS_CHARACTER_ITERATION,
MANUAL_INSPECT,
UNNECESSARY_MIN_OR_MAX,
]);

/// Extracts a method call name, args, and `Span` of the method name.
Expand Down Expand Up @@ -4566,6 +4593,9 @@ impl Methods {
Some(("bytes", recv2, [], _, _)) => bytes_count_to_len::check(cx, expr, recv, recv2),
_ => {},
},
("min" | "max", [arg]) => {
unnecessary_min_or_max::check(cx, expr, name, recv, arg);
},
("drain", ..) => {
if let Node::Stmt(Stmt { hir_id: _, kind, .. }) = cx.tcx.parent_hir_node(expr.hir_id)
&& matches!(kind, StmtKind::Semi(_))
Expand Down
Loading

0 comments on commit c81afb5

Please sign in to comment.