Skip to content

Commit b018818

Browse files
committed
Sam's dev merge
12 parents b5f31e2 + 960f702 + ebe14c6 + 77fa12b + 759c2bf + e247fb1 + 26f8fb3 + fea69ec + fcccbf1 + 3ed43d8 + 02af33e + 967c4ac commit b018818

84 files changed

Lines changed: 2613 additions & 402 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ helper.txt
4646
.vscode
4747
.idea
4848

49+
# Emacs
50+
.dir-locals.el
51+
4952
# mdbook generated output
5053
/book/book
5154

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6789,6 +6789,7 @@ Released 2018-09-13
67896789
[`mut_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_mut
67906790
[`mut_mutex_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_mutex_lock
67916791
[`mut_range_bound`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_range_bound
6792+
[`mutable_borrow_of_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutable_borrow_of_copy
67926793
[`mutable_key_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type
67936794
[`mutex_atomic`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_atomic
67946795
[`mutex_integer`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_integer
@@ -6881,6 +6882,7 @@ Released 2018-09-13
68816882
[`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params
68826883
[`panicking_overflow_checks`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_overflow_checks
68836884
[`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_unwrap
6885+
[`parsed_string_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#parsed_string_literals
68846886
[`partial_pub_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#partial_pub_fields
68856887
[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl
68866888
[`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none
@@ -7103,6 +7105,7 @@ Released 2018-09-13
71037105
[`uninit_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_vec
71047106
[`uninlined_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
71057107
[`unit_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_arg
7108+
[`unit_as_impl_trait`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_as_impl_trait
71067109
[`unit_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_cmp
71077110
[`unit_hash`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_hash
71087111
[`unit_return_expecting_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_return_expecting_ord
@@ -7249,6 +7252,7 @@ Released 2018-09-13
72497252
[`cargo-ignore-publish`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cargo-ignore-publish
72507253
[`check-incompatible-msrv-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-incompatible-msrv-in-tests
72517254
[`check-inconsistent-struct-field-initializers`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-inconsistent-struct-field-initializers
7255+
[`check-mutable-borrow-of-copy-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-mutable-borrow-of-copy-in-tests
72527256
[`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
72537257
[`cognitive-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cognitive-complexity-threshold
72547258
[`const-literal-digits-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#const-literal-digits-threshold

book/src/lint_configuration.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,16 @@ fn main() {
472472
* [`inconsistent_struct_constructor`](https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor)
473473

474474

475+
## `check-mutable-borrow-of-copy-in-tests`
476+
Whether to search for mutable borrows of freshly copied data in tests.
477+
478+
**Default Value:** `true`
479+
480+
---
481+
**Affected lints:**
482+
* [`mutable_borrow_of_copy`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_borrow_of_copy)
483+
484+
475485
## `check-private-items`
476486
Whether to also run the listed lints on private items.
477487

clippy_config/src/conf.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,9 @@ define_Conf! {
567567
/// [from rust-clippy#11846]: https://github.com/rust-lang/rust-clippy/issues/11846#issuecomment-1820747924
568568
#[lints(inconsistent_struct_constructor)]
569569
check_inconsistent_struct_field_initializers: bool = false,
570+
/// Whether to search for mutable borrows of freshly copied data in tests.
571+
#[lints(mutable_borrow_of_copy)]
572+
check_mutable_borrow_of_copy_in_tests: bool = true,
570573
/// Whether to also run the listed lints on private items.
571574
#[lints(missing_errors_doc, missing_panics_doc, missing_safety_doc, unnecessary_safety_doc)]
572575
check_private_items: bool = false,

clippy_dev/src/main.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ fn main() {
3939
Err(e) => eprintln!("Unable to create lint: {e}"),
4040
},
4141
DevCommand::Setup(SetupCommand { subcommand }) => match subcommand {
42+
SetupSubcommand::Emacs { remove, force_override } => {
43+
if remove {
44+
setup::emacs::remove_dir_locals();
45+
} else {
46+
setup::emacs::setup_dir_locals(force_override);
47+
}
48+
},
4249
SetupSubcommand::Intellij { remove, repo_path } => {
4350
if remove {
4451
setup::intellij::remove_rustc_src();
@@ -68,6 +75,7 @@ fn main() {
6875
},
6976
},
7077
DevCommand::Remove(RemoveCommand { subcommand }) => match subcommand {
78+
RemoveSubcommand::Emacs => setup::emacs::remove_dir_locals(),
7179
RemoveSubcommand::Intellij => setup::intellij::remove_rustc_src(),
7280
RemoveSubcommand::GitHook => setup::git_hook::remove_hook(),
7381
RemoveSubcommand::VscodeTasks => setup::vscode::remove_tasks(),
@@ -272,6 +280,15 @@ struct SetupCommand {
272280

273281
#[derive(Subcommand)]
274282
enum SetupSubcommand {
283+
/// Add a `.dir-locals.el` so that Emacs can use `rustic-mode` and `eglot`
284+
Emacs {
285+
#[arg(long)]
286+
/// Remove the `.dir-locals.el` file created by `cargo dev setup emacs`
287+
remove: bool,
288+
#[arg(long, short)]
289+
/// Forces the override of an existing git pre-commit hook
290+
force_override: bool,
291+
},
275292
/// Alter dependencies so Intellij Rust can find rustc internals
276293
Intellij {
277294
#[arg(long)]
@@ -332,6 +349,8 @@ struct RemoveCommand {
332349

333350
#[derive(Subcommand)]
334351
enum RemoveSubcommand {
352+
/// Remove the `.dir-locals.el` file created by `cargo dev setup emacs`
353+
Emacs,
335354
/// Remove the dependencies added with 'cargo dev setup intellij'
336355
Intellij,
337356
/// Remove the pre-commit git hook

clippy_dev/src/setup/emacs.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const DIR_LOCALS_EL: &str = ".dir-locals.el";
2+
const DIR_LOCALS: &str = r#";; Emacs configuration
3+
((nil . ((eglot-workspace-configuration .
4+
(:rust-analyzer
5+
(:rustc
6+
(:source "discover" :linkedProjects ["./Cargo.toml" "clippy_dev/Cargo.toml" "lintcheck/Cargo.toml"])
7+
:cargo
8+
(:features ["internal"]))))))
9+
("tests/ui" . ((auto-mode-alist ("\\.fixed\\'" . rustic-mode)))))
10+
"#;
11+
12+
pub fn setup_dir_locals(force_override: bool) {
13+
if !force_override && matches!(std::fs::exists(DIR_LOCALS_EL), Ok(true)) {
14+
eprintln!("error: `{DIR_LOCALS_EL}` already exists");
15+
return;
16+
}
17+
if std::fs::write(DIR_LOCALS_EL, DIR_LOCALS).is_err() {
18+
eprintln!("error: unable to create file `{DIR_LOCALS_EL}`");
19+
return;
20+
}
21+
println!("info: created `{DIR_LOCALS_EL}`");
22+
}
23+
24+
pub fn remove_dir_locals() {
25+
if std::fs::remove_file(DIR_LOCALS_EL).is_err() {
26+
eprintln!("error: unable to remove `{DIR_LOCALS_EL}`");
27+
return;
28+
}
29+
println!("info: removed `{DIR_LOCALS_EL}`");
30+
}

clippy_dev/src/setup/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod emacs;
12
pub mod git_hook;
23
pub mod intellij;
34
pub mod toolchain;

clippy_lints/src/casts/cast_nan_to_int.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
2121

2222
fn is_known_nan(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
2323
match ConstEvalCtxt::new(cx).eval(e) {
24-
// FIXME(f16_f128): add these types when nan checks are available on all platforms
24+
Some(Constant::F128(n)) => n.is_nan(),
2525
Some(Constant::F64(n)) => n.is_nan(),
2626
Some(Constant::F32(n)) => n.is_nan(),
27+
Some(Constant::F16(n)) => n.is_nan(),
2728
_ => false,
2829
}
2930
}

clippy_lints/src/casts/unnecessary_cast.rs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::numeric_literal::NumericLiteral;
3-
use clippy_utils::res::MaybeResPath;
3+
use clippy_utils::res::MaybeResPath as _;
44
use clippy_utils::source::{SpanRangeExt, snippet_opt};
55
use clippy_utils::visitors::{Visitable, for_each_expr_without_closures};
66
use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias};
77
use rustc_ast::{LitFloatType, LitIntType, LitKind};
88
use rustc_errors::Applicability;
99
use rustc_hir::def::{DefKind, Res};
10-
use rustc_hir::{Expr, ExprKind, Lit, Node, Path, QPath, TyKind, UnOp};
10+
use rustc_hir::{Expr, ExprKind, FnRetTy, Lit, Node, Path, QPath, TyKind, UnOp};
1111
use rustc_lint::{LateContext, LintContext};
1212
use rustc_middle::ty::adjustment::Adjust;
1313
use rustc_middle::ty::{self, FloatTy, InferTy, Ty};
@@ -97,7 +97,7 @@ pub(super) fn check<'tcx>(
9797

9898
// skip cast of fn call that returns type alias
9999
if let ExprKind::Cast(inner, ..) = expr.kind
100-
&& is_cast_from_ty_alias(cx, inner, cast_from)
100+
&& is_cast_from_ty_alias(cx, inner)
101101
{
102102
return false;
103103
}
@@ -270,42 +270,33 @@ fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 {
270270

271271
/// Finds whether an `Expr` returns a type alias.
272272
///
273-
/// TODO: Maybe we should move this to `clippy_utils` so others won't need to go down this dark,
274-
/// dark path reimplementing this (or something similar).
275-
fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx>, cast_from: Ty<'tcx>) -> bool {
273+
/// When in doubt, for example because it calls a non-local function that we don't have the
274+
/// declaration for, assume if might be a type alias.
275+
fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx>) -> bool {
276276
for_each_expr_without_closures(expr, |expr| {
277277
// Calls are a `Path`, and usage of locals are a `Path`. So, this checks
278278
// - call() as i32
279279
// - local as i32
280280
if let ExprKind::Path(qpath) = expr.kind {
281281
let res = cx.qpath_res(&qpath, expr.hir_id);
282-
// Function call
283282
if let Res::Def(DefKind::Fn, def_id) = res {
284-
let Some(snippet) = cx.tcx.def_span(def_id).get_source_text(cx) else {
285-
return ControlFlow::Continue(());
283+
let Some(def_id) = def_id.as_local() else {
284+
// External function, we can't know, better be safe
285+
return ControlFlow::Break(());
286286
};
287-
// This is the worst part of this entire function. This is the only way I know of to
288-
// check whether a function returns a type alias. Sure, you can get the return type
289-
// from a function in the current crate as an hir ty, but how do you get it for
290-
// external functions?? Simple: It's impossible. So, we check whether a part of the
291-
// function's declaration snippet is exactly equal to the `Ty`. That way, we can
292-
// see whether it's a type alias.
293-
//
294-
// FIXME: This won't work if the type is given an alias through `use`, should we
295-
// consider this a type alias as well?
296-
if !snippet
297-
.split("->")
298-
.skip(1)
299-
.any(|s| snippet_eq_ty(s, cast_from) || s.split("where").any(|ty| snippet_eq_ty(ty, cast_from)))
287+
if let Some(FnRetTy::Return(ty)) = cx.tcx.hir_get_fn_output(def_id)
288+
&& let TyKind::Path(qpath) = ty.kind
289+
&& is_ty_alias(&qpath)
300290
{
291+
// Function call to a local function returning a type alias
301292
return ControlFlow::Break(());
302293
}
303294
// Local usage
304295
} else if let Res::Local(hir_id) = res
305296
&& let Node::LetStmt(l) = cx.tcx.parent_hir_node(hir_id)
306297
{
307298
if let Some(e) = l.init
308-
&& is_cast_from_ty_alias(cx, e, cast_from)
299+
&& is_cast_from_ty_alias(cx, e)
309300
{
310301
return ControlFlow::Break::<()>(());
311302
}
@@ -323,7 +314,3 @@ fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx
323314
})
324315
.is_some()
325316
}
326-
327-
fn snippet_eq_ty(snippet: &str, ty: Ty<'_>) -> bool {
328-
snippet.trim() == ty.to_string() || snippet.trim().contains(&format!("::{ty}"))
329-
}

clippy_lints/src/collapsible_if.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_hir_and_then;
33
use clippy_utils::msrvs::Msrv;
4-
use clippy_utils::source::{IntoSpan as _, SpanRangeExt, snippet, snippet_block_with_applicability};
4+
use clippy_utils::source::{IntoSpan as _, SpanRangeExt as _, snippet, snippet_block_with_applicability};
55
use clippy_utils::{can_use_if_let_chains, span_contains_non_whitespace, sym, tokenize_with_text};
66
use rustc_ast::{BinOpKind, MetaItemInner};
77
use rustc_errors::Applicability;

0 commit comments

Comments
 (0)