Skip to content

Commit cc57d9a

Browse files
committed
Auto merge of #148957 - flip1995:clippy-subtree-update, r=Manishearth
Clippy subtree update r? `@Manishearth`
2 parents e92ffc3 + b006b3d commit cc57d9a

File tree

138 files changed

+4877
-3495
lines changed

Some content is hidden

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

138 files changed

+4877
-3495
lines changed

src/tools/clippy/.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ body:
2020
label: Reproducer
2121
description: Please provide the code and steps to reproduce the bug
2222
value: |
23-
I tried this code:
23+
Code:
2424
2525
```rust
2626
<code>
2727
```
2828
29-
I expected to see this happen:
29+
Current output:
3030
31-
Instead, this happened:
31+
Desired output:
3232
- type: textarea
3333
id: version
3434
attributes:

src/tools/clippy/.github/workflows/clippy_mq.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ jobs:
2525
host: i686-unknown-linux-gnu
2626
- os: windows-latest
2727
host: x86_64-pc-windows-msvc
28-
- os: macos-13
29-
host: x86_64-apple-darwin
3028
- os: macos-latest
3129
host: aarch64-apple-darwin
3230

src/tools/clippy/clippy_dev/src/new_lint.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,19 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
157157
let path = "clippy_lints/src/lib.rs";
158158
let mut lib_rs = fs::read_to_string(path).context("reading")?;
159159

160-
let comment_start = lib_rs.find("// add lints here,").expect("Couldn't find comment");
161-
let ctor_arg = if lint.pass == Pass::Late { "_" } else { "" };
162-
let lint_pass = lint.pass;
160+
let (comment, ctor_arg) = if lint.pass == Pass::Late {
161+
("// add late passes here", "_")
162+
} else {
163+
("// add early passes here", "")
164+
};
165+
let comment_start = lib_rs.find(comment).expect("Couldn't find comment");
163166
let module_name = lint.name;
164167
let camel_name = to_camel_case(lint.name);
165168

166169
let new_lint = if enable_msrv {
167-
format!(
168-
"store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(conf)));\n ",
169-
)
170+
format!("Box::new(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(conf))),\n ",)
170171
} else {
171-
format!("store.register_{lint_pass}_pass(|{ctor_arg}| Box::new({module_name}::{camel_name}));\n ",)
172+
format!("Box::new(|{ctor_arg}| Box::new({module_name}::{camel_name})),\n ",)
172173
};
173174

174175
lib_rs.insert_str(comment_start, &new_lint);

src/tools/clippy/clippy_lints/src/booleans.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
33
use clippy_utils::higher::has_let_expr;
44
use clippy_utils::msrvs::{self, Msrv};
55
use clippy_utils::res::MaybeDef;
6-
use clippy_utils::source::SpanRangeExt;
6+
use clippy_utils::source::{SpanRangeExt, snippet_with_context};
77
use clippy_utils::sugg::Sugg;
88
use clippy_utils::ty::implements_trait;
99
use clippy_utils::{eq_expr_value, sym};
@@ -415,19 +415,20 @@ fn simplify_not(cx: &LateContext<'_>, curr_msrv: Msrv, expr: &Expr<'_>) -> Optio
415415
BinOpKind::Ge => Some(" < "),
416416
_ => None,
417417
}
418-
.and_then(|op| {
419-
let lhs_snippet = lhs.span.get_source_text(cx)?;
420-
let rhs_snippet = rhs.span.get_source_text(cx)?;
418+
.map(|op| {
419+
let mut app = Applicability::MachineApplicable;
420+
let (lhs_snippet, _) = snippet_with_context(cx, lhs.span, SyntaxContext::root(), "", &mut app);
421+
let (rhs_snippet, _) = snippet_with_context(cx, rhs.span, SyntaxContext::root(), "", &mut app);
421422

422423
if !(lhs_snippet.starts_with('(') && lhs_snippet.ends_with(')'))
423424
&& let (ExprKind::Cast(..), BinOpKind::Ge) = (&lhs.kind, binop.node)
424425
{
425426
// e.g. `(a as u64) < b`. Without the parens the `<` is
426427
// interpreted as a start of generic arguments for `u64`
427-
return Some(format!("({lhs_snippet}){op}{rhs_snippet}"));
428+
return format!("({lhs_snippet}){op}{rhs_snippet}");
428429
}
429430

430-
Some(format!("{lhs_snippet}{op}{rhs_snippet}"))
431+
format!("{lhs_snippet}{op}{rhs_snippet}")
431432
})
432433
},
433434
ExprKind::MethodCall(path, receiver, args, _) => {

src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
44
use clippy_utils::msrvs::{self, Msrv};
5-
use clippy_utils::res::{MaybeDef, MaybeQPath};
65
use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context};
76
use clippy_utils::sugg::Sugg;
87
use clippy_utils::{
9-
contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, peel_blocks, sym,
8+
as_some_expr, contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context,
9+
is_none_expr, peel_blocks, sym,
1010
};
1111
use rustc_errors::Applicability;
12-
use rustc_hir::LangItem::{OptionNone, OptionSome};
1312
use rustc_hir::{Expr, ExprKind};
1413
use rustc_lint::{LateContext, LateLintPass};
1514
use rustc_session::impl_lint_pass;
@@ -70,11 +69,10 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
7069
}) = higher::If::hir(expr)
7170
&& let ExprKind::Block(then_block, _) = then.kind
7271
&& let Some(then_expr) = then_block.expr
73-
&& let ExprKind::Call(then_call, [then_arg]) = then_expr.kind
72+
&& let Some(then_arg) = as_some_expr(cx, then_expr)
7473
&& !expr.span.from_expansion()
7574
&& !then_expr.span.from_expansion()
76-
&& then_call.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)
77-
&& peel_blocks(els).res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)
75+
&& is_none_expr(cx, peel_blocks(els))
7876
&& !is_else_clause(cx.tcx, expr)
7977
&& !is_in_const_context(cx)
8078
&& self.msrv.meets(cx, msrvs::BOOL_THEN)

src/tools/clippy/clippy_lints/src/incompatible_msrv.rs

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::msrvs::Msrv;
4-
use clippy_utils::{is_in_const_context, is_in_test};
4+
use clippy_utils::{is_in_const_context, is_in_test, sym};
55
use rustc_data_structures::fx::FxHashMap;
66
use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, HirId, RustcVersion, StabilityLevel, StableSince};
77
use rustc_lint::{LateContext, LateLintPass};
88
use rustc_middle::ty::{self, TyCtxt};
99
use rustc_session::impl_lint_pass;
1010
use rustc_span::def_id::{CrateNum, DefId};
11-
use rustc_span::{ExpnKind, Span, sym};
11+
use rustc_span::{ExpnKind, Span};
1212

1313
declare_clippy_lint! {
1414
/// ### What it does
@@ -77,11 +77,36 @@ enum Availability {
7777
Since(RustcVersion),
7878
}
7979

80+
/// All known std crates containing a stability attribute.
81+
struct StdCrates([Option<CrateNum>; 6]);
82+
impl StdCrates {
83+
fn new(tcx: TyCtxt<'_>) -> Self {
84+
let mut res = Self([None; _]);
85+
for &krate in tcx.crates(()) {
86+
// FIXME(@Jarcho): We should have an internal lint to detect when this list is out of date.
87+
match tcx.crate_name(krate) {
88+
sym::alloc => res.0[0] = Some(krate),
89+
sym::core => res.0[1] = Some(krate),
90+
sym::core_arch => res.0[2] = Some(krate),
91+
sym::proc_macro => res.0[3] = Some(krate),
92+
sym::std => res.0[4] = Some(krate),
93+
sym::std_detect => res.0[5] = Some(krate),
94+
_ => {},
95+
}
96+
}
97+
res
98+
}
99+
100+
fn contains(&self, krate: CrateNum) -> bool {
101+
self.0.contains(&Some(krate))
102+
}
103+
}
104+
80105
pub struct IncompatibleMsrv {
81106
msrv: Msrv,
82107
availability_cache: FxHashMap<(DefId, bool), Availability>,
83108
check_in_tests: bool,
84-
core_crate: Option<CrateNum>,
109+
std_crates: StdCrates,
85110

86111
// The most recently called path. Used to skip checking the path after it's
87112
// been checked when visiting the call expression.
@@ -96,11 +121,7 @@ impl IncompatibleMsrv {
96121
msrv: conf.msrv,
97122
availability_cache: FxHashMap::default(),
98123
check_in_tests: conf.check_incompatible_msrv_in_tests,
99-
core_crate: tcx
100-
.crates(())
101-
.iter()
102-
.find(|krate| tcx.crate_name(**krate) == sym::core)
103-
.copied(),
124+
std_crates: StdCrates::new(tcx),
104125
called_path: None,
105126
}
106127
}
@@ -152,21 +173,24 @@ impl IncompatibleMsrv {
152173
node: HirId,
153174
span: Span,
154175
) {
155-
if def_id.is_local() {
156-
// We don't check local items since their MSRV is supposed to always be valid.
176+
if !self.std_crates.contains(def_id.krate) {
177+
// No stability attributes to lookup for these items.
157178
return;
158179
}
159-
let expn_data = span.ctxt().outer_expn_data();
160-
if let ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) = expn_data.kind {
161-
// Desugared expressions get to cheat and stability is ignored.
162-
// Intentionally not using `.from_expansion()`, since we do still care about macro expansions
163-
return;
164-
}
165-
// Functions coming from `core` while expanding a macro such as `assert*!()` get to cheat too: the
166-
// macros may have existed prior to the checked MSRV, but their expansion with a recent compiler
167-
// might use recent functions or methods. Compiling with an older compiler would not use those.
168-
if Some(def_id.krate) == self.core_crate && expn_data.macro_def_id.map(|did| did.krate) == self.core_crate {
169-
return;
180+
// Use `from_expansion` to fast-path the common case.
181+
if span.from_expansion() {
182+
let expn = span.ctxt().outer_expn_data();
183+
match expn.kind {
184+
// FIXME(@Jarcho): Check that the actual desugaring or std macro is supported by the
185+
// current MSRV. Note that nested expansions need to be handled as well.
186+
ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => return,
187+
ExpnKind::Macro(..) if expn.macro_def_id.is_some_and(|did| self.std_crates.contains(did.krate)) => {
188+
return;
189+
},
190+
// All other expansions share the target's MSRV.
191+
// FIXME(@Jarcho): What should we do about version dependant macros from external crates?
192+
_ => {},
193+
}
170194
}
171195

172196
if (self.check_in_tests || !is_in_test(cx.tcx, node))

src/tools/clippy/clippy_lints/src/inherent_impl.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_config::Conf;
22
use clippy_config::types::InherentImplLintScope;
33
use clippy_utils::diagnostics::span_lint_and_then;
4-
use clippy_utils::fulfill_or_allowed;
4+
use clippy_utils::{fulfill_or_allowed, is_cfg_test, is_in_cfg_test};
55
use rustc_data_structures::fx::FxHashMap;
66
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
77
use rustc_hir::{Item, ItemKind, Node};
@@ -100,7 +100,8 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
100100
},
101101
InherentImplLintScope::Crate => Criterion::Crate,
102102
};
103-
match type_map.entry((impl_ty, criterion)) {
103+
let is_test = is_cfg_test(cx.tcx, hir_id) || is_in_cfg_test(cx.tcx, hir_id);
104+
match type_map.entry((impl_ty, criterion, is_test)) {
104105
Entry::Vacant(e) => {
105106
// Store the id for the first impl block of this type. The span is retrieved lazily.
106107
e.insert(IdOrSpan::Id(impl_id));

0 commit comments

Comments
 (0)