Skip to content

Commit

Permalink
Merge commit '7248d06384c6a90de58c04c1f46be88821278d8b' into sync-fro…
Browse files Browse the repository at this point in the history
…m-clippy
  • Loading branch information
David Koloski committed Sep 21, 2022
1 parent 0dc24ca commit 4d01529
Show file tree
Hide file tree
Showing 111 changed files with 1,997 additions and 1,631 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3800,6 +3800,7 @@ Released 2018-09-13
[`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements
[`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect
[`iter_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_count
[`iter_kv_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map
[`iter_next_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_loop
[`iter_next_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_slice
[`iter_not_returning_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_not_returning_iterator
Expand Down
25 changes: 15 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,23 +110,28 @@ Just make sure to remove the dependencies again before finally making a pull req
[IntelliJ_rust_homepage]: https://intellij-rust.github.io/

### Rust Analyzer
As of [#6869][6869], [`rust-analyzer`][ra_homepage] can understand that Clippy uses compiler-internals
using `extern crate` when `package.metadata.rust-analyzer.rustc_private` is set to `true` in Clippy's `Cargo.toml.`
You will require a `nightly` toolchain with the `rustc-dev` component installed.
Make sure that in the `rust-analyzer` configuration, you set
For [`rust-analyzer`][ra_homepage] to work correctly make sure that in the `rust-analyzer` configuration you set

```json
{ "rust-analyzer.rustc.source": "discover" }
```
and
```json
{ "rust-analyzer.updates.channel": "nightly" }
```

You should be able to see information on things like `Expr` or `EarlyContext` now if you hover them, also
a lot more type hints.
This will work with `rust-analyzer 2021-03-15` shipped in nightly `1.52.0-nightly (107896c32 2021-03-15)` or later.

To have `rust-analyzer` also work in the `clippy_dev` and `lintcheck` crates, add the following configuration

```json
{
"rust-analyzer.linkedProjects": [
"./Cargo.toml",
"clippy_dev/Cargo.toml",
"lintcheck/Cargo.toml",
]
}
```

[ra_homepage]: https://rust-analyzer.github.io/
[6869]: https://github.com/rust-lang/rust-clippy/pull/6869

## How Clippy works

Expand Down
1 change: 1 addition & 0 deletions book/src/development/adding_lints.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ We start by opening the test file created at `tests/ui/foo_functions.rs`.
Update the file with some examples to get started:

```rust
#![allow(unused)]
#![warn(clippy::foo_functions)]

// Impl methods
Expand Down
15 changes: 5 additions & 10 deletions book/src/development/common_tools_writing_lints.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ There are three ways to do this, depending on if the target trait has a
diagnostic item, lang item or neither.

```rust
use clippy_utils::{implements_trait, is_trait_method, match_trait_method, paths};
use clippy_utils::ty::implements_trait;
use clippy_utils::is_trait_method;
use rustc_span::symbol::sym;

impl LateLintPass<'_> for MyStructLint {
Expand All @@ -143,13 +144,6 @@ impl LateLintPass<'_> for MyStructLint {
.map_or(false, |id| implements_trait(cx, ty, id, &[])) {
// `expr` implements `Drop` trait
}

// 3. Using the type path with the expression
// we use `match_trait_method` function from Clippy's utils
// (This method should be avoided if possible)
if match_trait_method(cx, expr, &paths::INTO) {
// `expr` implements `Into` trait
}
}
}
```
Expand Down Expand Up @@ -233,8 +227,9 @@ functions to deal with macros:
crates

```rust
#[macro_use]
extern crate a_crate_with_macros;
use rustc_middle::lint::in_external_macro;

use a_crate_with_macros::foo;

// `foo` is defined in `a_crate_with_macros`
foo!("bar");
Expand Down
1 change: 1 addition & 0 deletions clippy_dev/src/new_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ pub(crate) fn get_stabilization_version() -> String {
fn get_test_file_contents(lint_name: &str, header_commands: Option<&str>) -> String {
let mut contents = format!(
indoc! {"
#![allow(unused)]
#![warn(clippy::{})]
fn main() {{
Expand Down
2 changes: 2 additions & 0 deletions clippy_lints/src/almost_complete_letter_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use clippy_utils::{meets_msrv, msrvs};
use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
Expand Down Expand Up @@ -79,6 +80,7 @@ fn check_range(cx: &EarlyContext<'_>, span: Span, start: &Expr, end: &Expr, sugg
(LitKind::Byte(b'a') | LitKind::Char('a'), LitKind::Byte(b'z') | LitKind::Char('z'))
| (LitKind::Byte(b'A') | LitKind::Char('A'), LitKind::Byte(b'Z') | LitKind::Char('Z'))
)
&& !in_external_macro(cx.sess(), span)
{
span_lint_and_then(
cx,
Expand Down
22 changes: 9 additions & 13 deletions clippy_lints/src/assertions_on_result_states.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::{find_assert_args, root_macro_call_first_node, PanicExpn};
use clippy_utils::path_res;
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item};
use clippy_utils::ty::{has_debug_impl, is_copy, is_type_diagnostic_item};
use clippy_utils::usage::local_used_after_expr;
use clippy_utils::{is_expr_final_block_expr, path_res};
use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::{Expr, ExprKind};
Expand Down Expand Up @@ -58,6 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
return;
}
}
let semicolon = if is_expr_final_block_expr(cx.tcx, e) {";"} else {""};
let mut app = Applicability::MachineApplicable;
match method_segment.ident.as_str() {
"is_ok" if type_suitable_to_unwrap(cx, substs.type_at(1)) => {
Expand All @@ -68,8 +69,9 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
"called `assert!` with `Result::is_ok`",
"replace with",
format!(
"{}.unwrap()",
snippet_with_context(cx, recv.span, condition.span.ctxt(), "..", &mut app).0
"{}.unwrap(){}",
snippet_with_context(cx, recv.span, condition.span.ctxt(), "..", &mut app).0,
semicolon
),
app,
);
Expand All @@ -82,8 +84,9 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
"called `assert!` with `Result::is_err`",
"replace with",
format!(
"{}.unwrap_err()",
snippet_with_context(cx, recv.span, condition.span.ctxt(), "..", &mut app).0
"{}.unwrap_err(){}",
snippet_with_context(cx, recv.span, condition.span.ctxt(), "..", &mut app).0,
semicolon
),
app,
);
Expand All @@ -94,13 +97,6 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
}
}

/// This checks whether a given type is known to implement Debug.
fn has_debug_impl<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
cx.tcx
.get_diagnostic_item(sym::Debug)
.map_or(false, |debug| implements_trait(cx, ty, debug, &[]))
}

fn type_suitable_to_unwrap<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
has_debug_impl(cx, ty) && !ty.is_unit() && !ty.is_never()
}
47 changes: 29 additions & 18 deletions clippy_lints/src/bool_to_int_with_if.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use rustc_ast::{ExprPrecedence, LitKind};
use rustc_ast::LitKind;
use rustc_hir::{Block, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

use clippy_utils::{diagnostics::span_lint_and_then, is_else_clause, source::snippet_block_with_applicability};
use clippy_utils::{diagnostics::span_lint_and_then, is_else_clause, sugg::Sugg};
use rustc_errors::Applicability;

declare_clippy_lint! {
Expand Down Expand Up @@ -55,27 +55,42 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
if let ExprKind::If(check, then, Some(else_)) = expr.kind
&& let Some(then_lit) = int_literal(then)
&& let Some(else_lit) = int_literal(else_)
&& check_int_literal_equals_val(then_lit, 1)
&& check_int_literal_equals_val(else_lit, 0)
{
let inverted = if
check_int_literal_equals_val(then_lit, 1)
&& check_int_literal_equals_val(else_lit, 0) {
false
} else if
check_int_literal_equals_val(then_lit, 0)
&& check_int_literal_equals_val(else_lit, 1) {
true
} else {
// Expression isn't boolean, exit
return;
};
let mut applicability = Applicability::MachineApplicable;
let snippet = snippet_block_with_applicability(ctx, check.span, "..", None, &mut applicability);
let snippet_with_braces = {
let need_parens = should_have_parentheses(check);
let (left_paren, right_paren) = if need_parens {("(", ")")} else {("", "")};
format!("{left_paren}{snippet}{right_paren}")
let snippet = {
let mut sugg = Sugg::hir_with_applicability(ctx, check, "..", &mut applicability);
if inverted {
sugg = !sugg;
}
sugg
};

let ty = ctx.typeck_results().expr_ty(then_lit); // then and else must be of same type

let suggestion = {
let wrap_in_curly = is_else_clause(ctx.tcx, expr);
let (left_curly, right_curly) = if wrap_in_curly {("{", "}")} else {("", "")};
format!(
"{left_curly}{ty}::from({snippet}){right_curly}"
)
let mut s = Sugg::NonParen(format!("{ty}::from({snippet})").into());
if wrap_in_curly {
s = s.blockify();
}
s
}; // when used in else clause if statement should be wrapped in curly braces

let into_snippet = snippet.clone().maybe_par();
let as_snippet = snippet.as_ty(ty);

span_lint_and_then(ctx,
BOOL_TO_INT_WITH_IF,
expr.span,
Expand All @@ -87,7 +102,7 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
suggestion,
applicability,
);
diag.note(format!("`{snippet_with_braces} as {ty}` or `{snippet_with_braces}.into()` can also be valid options"));
diag.note(format!("`{as_snippet}` or `{into_snippet}.into()` can also be valid options"));
});
};
}
Expand Down Expand Up @@ -119,7 +134,3 @@ fn check_int_literal_equals_val<'tcx>(expr: &'tcx rustc_hir::Expr<'tcx>, expecte
false
}
}

fn should_have_parentheses<'tcx>(check: &'tcx rustc_hir::Expr<'tcx>) -> bool {
check.precedence().order() < ExprPrecedence::Cast.order()
}
2 changes: 1 addition & 1 deletion clippy_lints/src/booleans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
}
},
&Term(n) => {
let snip = snippet_opt(self.cx, self.terminals[n as usize].span)?;
let snip = snippet_opt(self.cx, self.terminals[n as usize].span.source_callsite())?;
self.output.push_str(&snip);
},
}
Expand Down
7 changes: 2 additions & 5 deletions clippy_lints/src/dereference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,13 +297,10 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
if !is_lint_allowed(cx, EXPLICIT_DEREF_METHODS, expr.hir_id)
&& position.lint_explicit_deref() =>
{
let ty_changed_count = usize::from(!deref_method_same_type(expr_ty, typeck.expr_ty(sub_expr)));
self.state = Some((
State::DerefMethod {
ty_changed_count: if deref_method_same_type(expr_ty, typeck.expr_ty(sub_expr)) {
0
} else {
1
},
ty_changed_count,
is_final_ufcs: matches!(expr.kind, ExprKind::Call(..)),
target_mut,
},
Expand Down
24 changes: 19 additions & 5 deletions clippy_lints/src/derivable_impls.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{is_default_equivalent, peel_blocks};
use rustc_errors::Applicability;
use rustc_hir::{
def::{DefKind, Res},
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
Expand Down Expand Up @@ -100,15 +101,28 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
ExprKind::Struct(_, fields, _) => fields.iter().all(|ef| is_default_equivalent(cx, ef.expr)),
_ => false,
};

if should_emit {
let path_string = cx.tcx.def_path_str(adt_def.did());
span_lint_and_help(
let struct_span = cx.tcx.def_span(adt_def.did());
span_lint_and_then(
cx,
DERIVABLE_IMPLS,
item.span,
"this `impl` can be derived",
None,
&format!("try annotating `{}` with `#[derive(Default)]`", path_string),
|diag| {
diag.span_suggestion_hidden(
item.span,
"remove the manual implementation...",
String::new(),
Applicability::MachineApplicable
);
diag.span_suggestion(
struct_span.shrink_to_lo(),
"...and instead derive it",
"#[derive(Default)]\n".to_string(),
Applicability::MachineApplicable
);
}
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
let value = arg.param.value;
if_chain! {
if format_args.format_string.parts == [kw::Empty];
if arg.format.is_default();
if match cx.typeck_results().expr_ty(value).peel_refs().kind() {
ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did()),
ty::Str => true,
_ => false,
};
if !arg.format.has_string_formatting();
then {
let is_new_string = match value.kind {
ExprKind::Binary(..) => true,
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/format_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
if let ExpnKind::Macro(_, name) = outermost_expn_data.kind;
then {
for arg in &format_args.args {
if arg.format.has_string_formatting() {
if !arg.format.is_default() {
continue;
}
if is_aliased(&format_args, arg.param.value.hir_id) {
Expand Down
Loading

0 comments on commit 4d01529

Please sign in to comment.