Skip to content

Commit 57f63a3

Browse files
authored
Rollup merge of #120345 - flip1995:clippy-subtree-update, r=Manishearth
Clippy subtree update r? `@Manishearth` Closes rust-lang#12148
2 parents f096e91 + 9ce0b83 commit 57f63a3

File tree

158 files changed

+2840
-1000
lines changed

Some content is hidden

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

158 files changed

+2840
-1000
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -5606,6 +5606,7 @@ Released 2018-09-13
56065606
[`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting
56075607
[`suspicious_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_map
56085608
[`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_op_assign_impl
5609+
[`suspicious_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_open_options
56095610
[`suspicious_operation_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_operation_groupings
56105611
[`suspicious_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_splitn
56115612
[`suspicious_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_to_owned
@@ -5814,6 +5815,7 @@ Released 2018-09-13
58145815
[`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
58155816
[`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
58165817
[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
5818+
[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
58175819
[`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
58185820
[`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
58195821
[`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior

book/src/lint_configuration.md

+17-4
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ default configuration of Clippy. By default, any configuration will replace the
212212
* `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
213213
* `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
214214

215-
**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
215+
**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
216216

217217
---
218218
**Affected lints:**
@@ -768,7 +768,19 @@ Additional dotfiles (files or directories starting with a dot) to allow
768768
* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
769769

770770

771+
## `allowed-duplicate-crates`
772+
A list of crate names to allow duplicates of
773+
774+
**Default Value:** `[]`
775+
776+
---
777+
**Affected lints:**
778+
* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions)
779+
780+
771781
## `enforce-iter-loop-reborrow`
782+
Whether to recommend using implicit into iter for reborrowed values.
783+
772784
#### Example
773785
```no_run
774786
let mut vec = vec![1, 2, 3];
@@ -793,7 +805,7 @@ for _ in &mut *rmvec {}
793805

794806

795807
## `check-private-items`
796-
808+
Whether to also run the listed lints on private items.
797809

798810
**Default Value:** `false`
799811

@@ -806,9 +818,10 @@ for _ in &mut *rmvec {}
806818

807819

808820
## `pub-underscore-fields-behavior`
821+
Lint "public" fields in a struct that are prefixed with an underscore based on their
822+
exported visibility, or whether they are marked as "pub".
809823

810-
811-
**Default Value:** `"PublicallyExported"`
824+
**Default Value:** `"PubliclyExported"`
812825

813826
---
814827
**Affected lints:**

clippy_config/src/conf.rs

+63-17
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ use crate::msrvs::Msrv;
22
use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename};
33
use crate::ClippyConfiguration;
44
use rustc_data_structures::fx::FxHashSet;
5+
use rustc_errors::Applicability;
56
use rustc_session::Session;
7+
use rustc_span::edit_distance::edit_distance;
68
use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
79
use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor};
810
use serde::{Deserialize, Deserializer, Serialize};
@@ -26,7 +28,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
2628
"NaN", "NaNs",
2729
"OAuth", "GraphQL",
2830
"OCaml",
29-
"OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS",
31+
"OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry",
3032
"WebGL", "WebGL2", "WebGPU",
3133
"TensorFlow",
3234
"TrueType",
@@ -59,18 +61,25 @@ impl TryConf {
5961
#[derive(Debug)]
6062
struct ConfError {
6163
message: String,
64+
suggestion: Option<Suggestion>,
6265
span: Span,
6366
}
6467

6568
impl ConfError {
6669
fn from_toml(file: &SourceFile, error: &toml::de::Error) -> Self {
6770
let span = error.span().unwrap_or(0..file.source_len.0 as usize);
68-
Self::spanned(file, error.message(), span)
71+
Self::spanned(file, error.message(), None, span)
6972
}
7073

71-
fn spanned(file: &SourceFile, message: impl Into<String>, span: Range<usize>) -> Self {
74+
fn spanned(
75+
file: &SourceFile,
76+
message: impl Into<String>,
77+
suggestion: Option<Suggestion>,
78+
span: Range<usize>,
79+
) -> Self {
7280
Self {
7381
message: message.into(),
82+
suggestion,
7483
span: Span::new(
7584
file.start_pos + BytePos::from_usize(span.start),
7685
file.start_pos + BytePos::from_usize(span.end),
@@ -147,16 +156,18 @@ macro_rules! define_Conf {
147156
match Field::deserialize(name.get_ref().as_str().into_deserializer()) {
148157
Err(e) => {
149158
let e: FieldError = e;
150-
errors.push(ConfError::spanned(self.0, e.0, name.span()));
159+
errors.push(ConfError::spanned(self.0, e.error, e.suggestion, name.span()));
151160
}
152161
$(Ok(Field::$name) => {
153-
$(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), name.span()));)?
162+
$(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), None, name.span()));)?
154163
let raw_value = map.next_value::<toml::Spanned<toml::Value>>()?;
155164
let value_span = raw_value.span();
156165
match <$ty>::deserialize(raw_value.into_inner()) {
157-
Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), value_span)),
166+
Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), None, value_span)),
158167
Ok(value) => match $name {
159-
Some(_) => errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), name.span())),
168+
Some(_) => {
169+
errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), None, name.span()));
170+
}
160171
None => {
161172
$name = Some(value);
162173
// $new_conf is the same as one of the defined `$name`s, so
@@ -165,7 +176,7 @@ macro_rules! define_Conf {
165176
Some(_) => errors.push(ConfError::spanned(self.0, concat!(
166177
"duplicate field `", stringify!($new_conf),
167178
"` (provided as `", stringify!($name), "`)"
168-
), name.span())),
179+
), None, name.span())),
169180
None => $new_conf = $name.clone(),
170181
})?
171182
},
@@ -523,7 +534,11 @@ define_Conf! {
523534
///
524535
/// Additional dotfiles (files or directories starting with a dot) to allow
525536
(allowed_dotfiles: FxHashSet<String> = FxHashSet::default()),
526-
/// Lint: EXPLICIT_ITER_LOOP
537+
/// Lint: MULTIPLE_CRATE_VERSIONS.
538+
///
539+
/// A list of crate names to allow duplicates of
540+
(allowed_duplicate_crates: FxHashSet<String> = FxHashSet::default()),
541+
/// Lint: EXPLICIT_ITER_LOOP.
527542
///
528543
/// Whether to recommend using implicit into iter for reborrowed values.
529544
///
@@ -543,15 +558,15 @@ define_Conf! {
543558
/// for _ in &mut *rmvec {}
544559
/// ```
545560
(enforce_iter_loop_reborrow: bool = false),
546-
/// Lint: MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC, MISSING_PANICS_DOC, MISSING_ERRORS_DOC
561+
/// Lint: MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC, MISSING_PANICS_DOC, MISSING_ERRORS_DOC.
547562
///
548563
/// Whether to also run the listed lints on private items.
549564
(check_private_items: bool = false),
550-
/// Lint: PUB_UNDERSCORE_FIELDS
565+
/// Lint: PUB_UNDERSCORE_FIELDS.
551566
///
552567
/// Lint "public" fields in a struct that are prefixed with an underscore based on their
553568
/// exported visibility, or whether they are marked as "pub".
554-
(pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PublicallyExported),
569+
(pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PubliclyExported),
555570
}
556571

557572
/// Search for the configuration file.
@@ -669,10 +684,16 @@ impl Conf {
669684

670685
// all conf errors are non-fatal, we just use the default conf in case of error
671686
for error in errors {
672-
sess.dcx().span_err(
687+
let mut diag = sess.dcx().struct_span_err(
673688
error.span,
674689
format!("error reading Clippy's configuration file: {}", error.message),
675690
);
691+
692+
if let Some(sugg) = error.suggestion {
693+
diag.span_suggestion(error.span, sugg.message, sugg.suggestion, Applicability::MaybeIncorrect);
694+
}
695+
696+
diag.emit();
676697
}
677698

678699
for warning in warnings {
@@ -689,19 +710,31 @@ impl Conf {
689710
const SEPARATOR_WIDTH: usize = 4;
690711

691712
#[derive(Debug)]
692-
struct FieldError(String);
713+
struct FieldError {
714+
error: String,
715+
suggestion: Option<Suggestion>,
716+
}
717+
718+
#[derive(Debug)]
719+
struct Suggestion {
720+
message: &'static str,
721+
suggestion: &'static str,
722+
}
693723

694724
impl std::error::Error for FieldError {}
695725

696726
impl Display for FieldError {
697727
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
698-
f.pad(&self.0)
728+
f.pad(&self.error)
699729
}
700730
}
701731

702732
impl serde::de::Error for FieldError {
703733
fn custom<T: Display>(msg: T) -> Self {
704-
Self(msg.to_string())
734+
Self {
735+
error: msg.to_string(),
736+
suggestion: None,
737+
}
705738
}
706739

707740
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
@@ -723,7 +756,20 @@ impl serde::de::Error for FieldError {
723756
write!(msg, "{:SEPARATOR_WIDTH$}{field:column_width$}", " ").unwrap();
724757
}
725758
}
726-
Self(msg)
759+
760+
let suggestion = expected
761+
.iter()
762+
.filter_map(|expected| {
763+
let dist = edit_distance(field, expected, 4)?;
764+
Some((dist, expected))
765+
})
766+
.min_by_key(|&(dist, _)| dist)
767+
.map(|(_, suggestion)| Suggestion {
768+
message: "perhaps you meant",
769+
suggestion,
770+
});
771+
772+
Self { error: msg, suggestion }
727773
}
728774
}
729775

clippy_config/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern crate rustc_ast;
1111
extern crate rustc_data_structures;
1212
#[allow(unused_extern_crates)]
1313
extern crate rustc_driver;
14+
extern crate rustc_errors;
1415
extern crate rustc_session;
1516
extern crate rustc_span;
1617

clippy_config/src/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,6 @@ unimplemented_serialize! {
129129

130130
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
131131
pub enum PubUnderscoreFieldsBehaviour {
132-
PublicallyExported,
132+
PubliclyExported,
133133
AllPubFields,
134134
}

clippy_dev/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ version = "0.0.1"
44
edition = "2021"
55

66
[dependencies]
7-
aho-corasick = "0.7"
7+
aho-corasick = "1.0"
88
clap = "4.1.4"
99
indoc = "1.0"
1010
itertools = "0.11"
11-
opener = "0.5"
11+
opener = "0.6"
1212
shell-escape = "0.1"
1313
walkdir = "2.3"
1414

clippy_dev/src/update_lints.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,8 @@ fn replace_ident_like(contents: &str, replacements: &[(&str, &str)]) -> Option<S
504504
}
505505

506506
let searcher = AhoCorasickBuilder::new()
507-
.dfa(true)
508507
.match_kind(aho_corasick::MatchKind::LeftmostLongest)
509-
.build_with_size::<u16, _, _>(replacements.iter().map(|&(x, _)| x.as_bytes()))
508+
.build(replacements.iter().map(|&(x, _)| x.as_bytes()))
510509
.unwrap();
511510

512511
let mut result = String::with_capacity(contents.len() + 1024);

clippy_lints/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ edition = "2021"
1010

1111
[dependencies]
1212
arrayvec = { version = "0.7", default-features = false }
13-
cargo_metadata = "0.15.3"
13+
cargo_metadata = "0.18"
1414
clippy_config = { path = "../clippy_config" }
1515
clippy_utils = { path = "../clippy_utils" }
1616
declare_clippy_lint = { path = "../declare_clippy_lint" }

clippy_lints/src/arc_with_non_send_sync.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ declare_clippy_lint! {
1414
/// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`.
1515
///
1616
/// ### Why is this bad?
17-
/// `Arc<T>` is an Atomic `RC<T>` and guarantees that updates to the reference counter are
18-
/// Atomic. This is useful in multiprocessing scenarios. To send an `Arc<T>` across processes
19-
/// and make use of the atomic ref counter, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-Send-for-Arc%3CT%3E),
20-
/// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
17+
/// `Arc<T>` is a thread-safe `Rc<T>` and guarantees that updates to the reference counter
18+
/// use atomic operations. To send an `Arc<T>` across thread boundaries and
19+
/// share ownership between multiple threads, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#thread-safety),
20+
/// so either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
2121
///
2222
/// ### Example
2323
/// ```no_run

clippy_lints/src/blocks_in_conditions.rs

+5
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
6767
);
6868

6969
if let ExprKind::Block(block, _) = &cond.kind {
70+
if !block.span.eq_ctxt(expr.span) {
71+
// If the block comes from a macro, or as an argument to a macro,
72+
// do not lint.
73+
return;
74+
}
7075
if block.rules == BlockCheckMode::DefaultBlock {
7176
if block.stmts.is_empty() {
7277
if let Some(ex) = &block.expr {

clippy_lints/src/cargo/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod wildcard_dependencies;
66
use cargo_metadata::MetadataCommand;
77
use clippy_utils::diagnostics::span_lint;
88
use clippy_utils::is_lint_allowed;
9+
use rustc_data_structures::fx::FxHashSet;
910
use rustc_hir::hir_id::CRATE_HIR_ID;
1011
use rustc_lint::{LateContext, LateLintPass, Lint};
1112
use rustc_session::impl_lint_pass;
@@ -128,6 +129,8 @@ declare_clippy_lint! {
128129
/// ### Known problems
129130
/// Because this can be caused purely by the dependencies
130131
/// themselves, it's not always possible to fix this issue.
132+
/// In those cases, you can allow that specific crate using
133+
/// the `allowed_duplicate_crates` configuration option.
131134
///
132135
/// ### Example
133136
/// ```toml
@@ -163,6 +166,7 @@ declare_clippy_lint! {
163166
}
164167

165168
pub struct Cargo {
169+
pub allowed_duplicate_crates: FxHashSet<String>,
166170
pub ignore_publish: bool,
167171
}
168172

@@ -208,7 +212,7 @@ impl LateLintPass<'_> for Cargo {
208212
{
209213
match MetadataCommand::new().exec() {
210214
Ok(metadata) => {
211-
multiple_crate_versions::check(cx, &metadata);
215+
multiple_crate_versions::check(cx, &metadata, &self.allowed_duplicate_crates);
212216
},
213217
Err(e) => {
214218
for lint in WITH_DEPS_LINTS {

0 commit comments

Comments
 (0)