From 0964374274a64ad15c640d57982d74ce66c58b84 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 4 Mar 2024 16:49:03 +0100 Subject: [PATCH 1/3] Move diagnostics docs generation into xtask/codegen --- Cargo.lock | 1 - crates/ide-assists/Cargo.toml | 3 -- crates/ide-diagnostics/Cargo.toml | 4 --- crates/ide/Cargo.toml | 3 -- crates/rust-analyzer/Cargo.toml | 1 - xtask/src/codegen.rs | 1 + .../src/codegen/diagnostics_docs.rs | 28 +++++++++++-------- 7 files changed, 17 insertions(+), 24 deletions(-) rename crates/ide-diagnostics/src/tests/sourcegen.rs => xtask/src/codegen/diagnostics_docs.rs (71%) diff --git a/Cargo.lock b/Cargo.lock index 9b431d85a6..45f4aa8911 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -747,7 +747,6 @@ dependencies = [ "itertools", "once_cell", "serde_json", - "sourcegen", "stdx", "syntax", "test-fixture", diff --git a/crates/ide-assists/Cargo.toml b/crates/ide-assists/Cargo.toml index a78129fc47..b1e7609afe 100644 --- a/crates/ide-assists/Cargo.toml +++ b/crates/ide-assists/Cargo.toml @@ -33,8 +33,5 @@ expect-test = "1.4.0" test-utils.workspace = true test-fixture.workspace = true -[features] -in-rust-tree = [] - [lints] workspace = true diff --git a/crates/ide-diagnostics/Cargo.toml b/crates/ide-diagnostics/Cargo.toml index 509c5a152f..8ccea99e9e 100644 --- a/crates/ide-diagnostics/Cargo.toml +++ b/crates/ide-diagnostics/Cargo.toml @@ -33,10 +33,6 @@ expect-test = "1.4.0" # local deps test-utils.workspace = true test-fixture.workspace = true -sourcegen.workspace = true - -[features] -in-rust-tree = [] [lints] workspace = true diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml index bb06d61445..eab3925aab 100644 --- a/crates/ide/Cargo.toml +++ b/crates/ide/Cargo.toml @@ -51,8 +51,5 @@ expect-test = "1.4.0" test-utils.workspace = true test-fixture.workspace = true -[features] -in-rust-tree = ["ide-assists/in-rust-tree", "ide-diagnostics/in-rust-tree"] - [lints] workspace = true diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index a212041e66..766606be7b 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -85,7 +85,6 @@ force-always-assert = ["always-assert/force"] sysroot-abi = [] in-rust-tree = [ "sysroot-abi", - "ide/in-rust-tree", "syntax/in-rust-tree", "parser/in-rust-tree", "hir/in-rust-tree", diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index e579660ac9..d51daa3395 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs @@ -8,6 +8,7 @@ use xshell::{cmd, Shell}; use crate::{flags, project_root}; pub(crate) mod assists_doc_tests; +pub(crate) mod diagnostics_docs; impl flags::Codegen { pub(crate) fn run(self, _sh: &Shell) -> anyhow::Result<()> { diff --git a/crates/ide-diagnostics/src/tests/sourcegen.rs b/xtask/src/codegen/diagnostics_docs.rs similarity index 71% rename from crates/ide-diagnostics/src/tests/sourcegen.rs rename to xtask/src/codegen/diagnostics_docs.rs index 9e7fcfc590..a45b412fda 100644 --- a/crates/ide-diagnostics/src/tests/sourcegen.rs +++ b/xtask/src/codegen/diagnostics_docs.rs @@ -2,22 +2,26 @@ use std::{fmt, fs, io, path::PathBuf}; -use sourcegen::project_root; +use crate::{ + codegen::{add_preamble, list_rust_files, CommentBlock, Location}, + project_root, +}; -#[test] -fn sourcegen_diagnostic_docs() { +fn generate(check: bool) { let diagnostics = Diagnostic::collect().unwrap(); - let contents = - diagnostics.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"); - let contents = sourcegen::add_preamble("sourcegen_diagnostic_docs", contents); - let dst = project_root().join("docs/user/generated_diagnostic.adoc"); - fs::write(dst, contents).unwrap(); + if !check { + let contents = + diagnostics.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"); + let contents = add_preamble("sourcegen_diagnostic_docs", contents); + let dst = project_root().join("docs/user/generated_diagnostic.adoc"); + fs::write(dst, contents).unwrap(); + } } #[derive(Debug)] struct Diagnostic { id: String, - location: sourcegen::Location, + location: Location, doc: String, } @@ -26,7 +30,7 @@ impl Diagnostic { let handlers_dir = project_root().join("crates/ide-diagnostics/src/handlers"); let mut res = Vec::new(); - for path in sourcegen::list_rust_files(&handlers_dir) { + for path in list_rust_files(&handlers_dir) { collect_file(&mut res, path)?; } res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id)); @@ -34,7 +38,7 @@ impl Diagnostic { fn collect_file(acc: &mut Vec, path: PathBuf) -> io::Result<()> { let text = fs::read_to_string(&path)?; - let comment_blocks = sourcegen::CommentBlock::extract("Diagnostic", &text); + let comment_blocks = CommentBlock::extract("Diagnostic", &text); for block in comment_blocks { let id = block.id; @@ -42,7 +46,7 @@ impl Diagnostic { panic!("invalid diagnostic name: {id:?}:\n {msg}") } let doc = block.contents.join("\n"); - let location = sourcegen::Location { file: path.clone(), line: block.line }; + let location = Location { file: path.clone(), line: block.line }; acc.push(Diagnostic { id, location, doc }) } From 76463eee48a0b6dcaac5cd95aff91251a1abf475 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 4 Mar 2024 17:02:28 +0100 Subject: [PATCH 2/3] Move lint definition generation into xtask/codegen --- Cargo.lock | 4 +- crates/ide-db/Cargo.toml | 3 -- crates/ide-db/src/lib.rs | 6 --- crates/ide-db/src/tests/line_index.rs | 49 ----------------- crates/ide-diagnostics/src/tests.rs | 2 - lib/line-index/Cargo.toml | 5 +- lib/line-index/src/tests.rs | 53 +++++++++++++++++++ xtask/src/codegen.rs | 6 +++ xtask/src/codegen/diagnostics_docs.rs | 2 +- .../src/codegen/lints.rs | 40 +++++++------- xtask/src/flags.rs | 4 ++ xtask/src/release.rs | 2 +- 12 files changed, 90 insertions(+), 86 deletions(-) delete mode 100644 crates/ide-db/src/tests/line_index.rs rename crates/ide-db/src/tests/sourcegen_lints.rs => xtask/src/codegen/lints.rs (93%) diff --git a/Cargo.lock b/Cargo.lock index 45f4aa8911..89a1f68cce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -717,12 +717,10 @@ dependencies = [ "memchr", "nohash-hasher", "once_cell", - "oorandom", "parser", "profile", "rayon", "rustc-hash", - "sourcegen", "span", "stdx", "syntax", @@ -731,7 +729,6 @@ dependencies = [ "text-edit", "tracing", "triomphe", - "xshell", ] [[package]] @@ -916,6 +913,7 @@ name = "line-index" version = "0.1.1" dependencies = [ "nohash-hasher", + "oorandom", "text-size", ] diff --git a/crates/ide-db/Cargo.toml b/crates/ide-db/Cargo.toml index b487b138fc..071e1b4717 100644 --- a/crates/ide-db/Cargo.toml +++ b/crates/ide-db/Cargo.toml @@ -44,13 +44,10 @@ line-index.workspace = true [dev-dependencies] expect-test = "1.4.0" -oorandom = "11.1.3" -xshell.workspace = true # local deps test-utils.workspace = true test-fixture.workspace = true -sourcegen.workspace = true [lints] workspace = true diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs index a9f7e58de9..0d11858ed7 100644 --- a/crates/ide-db/src/lib.rs +++ b/crates/ide-db/src/lib.rs @@ -412,9 +412,3 @@ impl SnippetCap { } } } - -#[cfg(test)] -mod tests { - mod line_index; - mod sourcegen_lints; -} diff --git a/crates/ide-db/src/tests/line_index.rs b/crates/ide-db/src/tests/line_index.rs deleted file mode 100644 index 6b49bb2631..0000000000 --- a/crates/ide-db/src/tests/line_index.rs +++ /dev/null @@ -1,49 +0,0 @@ -use line_index::{LineCol, LineIndex, WideEncoding}; -use test_utils::skip_slow_tests; - -#[test] -fn test_every_chars() { - if skip_slow_tests() { - return; - } - - let text: String = { - let mut chars: Vec = ((0 as char)..char::MAX).collect(); // Neat! - chars.extend("\n".repeat(chars.len() / 16).chars()); - let mut rng = oorandom::Rand32::new(stdx::rand::seed()); - stdx::rand::shuffle(&mut chars, |i| rng.rand_range(0..i as u32) as usize); - chars.into_iter().collect() - }; - assert!(text.contains('💩')); // Sanity check. - - let line_index = LineIndex::new(&text); - - let mut lin_col = LineCol { line: 0, col: 0 }; - let mut col_utf16 = 0; - let mut col_utf32 = 0; - for (offset, c) in text.char_indices() { - let got_offset = line_index.offset(lin_col).unwrap(); - assert_eq!(usize::from(got_offset), offset); - - let got_lin_col = line_index.line_col(got_offset); - assert_eq!(got_lin_col, lin_col); - - for (enc, col) in [(WideEncoding::Utf16, col_utf16), (WideEncoding::Utf32, col_utf32)] { - let wide_lin_col = line_index.to_wide(enc, lin_col).unwrap(); - let got_lin_col = line_index.to_utf8(enc, wide_lin_col).unwrap(); - assert_eq!(got_lin_col, lin_col); - assert_eq!(wide_lin_col.col, col) - } - - if c == '\n' { - lin_col.line += 1; - lin_col.col = 0; - col_utf16 = 0; - col_utf32 = 0; - } else { - lin_col.col += c.len_utf8() as u32; - col_utf16 += c.len_utf16() as u32; - col_utf32 += 1; - } - } -} diff --git a/crates/ide-diagnostics/src/tests.rs b/crates/ide-diagnostics/src/tests.rs index 901ceffbb2..dcaa212089 100644 --- a/crates/ide-diagnostics/src/tests.rs +++ b/crates/ide-diagnostics/src/tests.rs @@ -1,6 +1,4 @@ #![allow(clippy::print_stderr)] -#[cfg(not(feature = "in-rust-tree"))] -mod sourcegen; use ide_db::{ assists::AssistResolveStrategy, base_db::SourceDatabaseExt, LineIndexDatabase, RootDatabase, diff --git a/lib/line-index/Cargo.toml b/lib/line-index/Cargo.toml index 77e187de1e..8ae4954dd0 100644 --- a/lib/line-index/Cargo.toml +++ b/lib/line-index/Cargo.toml @@ -10,5 +10,8 @@ edition = "2021" text-size = "1.1.1" nohash-hasher = "0.2.0" +[dev-dependencies] +oorandom = "11.1.3" + [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/lib/line-index/src/tests.rs b/lib/line-index/src/tests.rs index 981008e346..57fad1dfc0 100644 --- a/lib/line-index/src/tests.rs +++ b/lib/line-index/src/tests.rs @@ -142,3 +142,56 @@ fn test_to_wide() { let wide_line_col = line_index.to_wide(WideEncoding::Utf16, line_col.unwrap()); assert_eq!(wide_line_col, Some(WideLineCol { line: 5, col: 4 })); } + +#[test] +fn test_every_chars() { + let text: String = { + let mut chars: Vec = ((0 as char)..char::MAX).collect(); // Neat! + chars.extend("\n".repeat(chars.len() / 16).chars()); + let seed = std::hash::Hasher::finish(&std::hash::BuildHasher::build_hasher( + #[allow(clippy::disallowed_types)] + &std::collections::hash_map::RandomState::new(), + )); + let mut rng = oorandom::Rand32::new(seed); + let mut rand_index = |i| rng.rand_range(0..i as u32) as usize; + let mut remaining = chars.len() - 1; + while remaining > 0 { + let index = rand_index(remaining); + chars.swap(remaining, index); + remaining -= 1; + } + chars.into_iter().collect() + }; + assert!(text.contains('💩')); // Sanity check. + + let line_index = LineIndex::new(&text); + + let mut lin_col = LineCol { line: 0, col: 0 }; + let mut col_utf16 = 0; + let mut col_utf32 = 0; + for (offset, c) in text.char_indices() { + let got_offset = line_index.offset(lin_col).unwrap(); + assert_eq!(usize::from(got_offset), offset); + + let got_lin_col = line_index.line_col(got_offset); + assert_eq!(got_lin_col, lin_col); + + for (enc, col) in [(WideEncoding::Utf16, col_utf16), (WideEncoding::Utf32, col_utf32)] { + let wide_lin_col = line_index.to_wide(enc, lin_col).unwrap(); + let got_lin_col = line_index.to_utf8(enc, wide_lin_col).unwrap(); + assert_eq!(got_lin_col, lin_col); + assert_eq!(wide_lin_col.col, col) + } + + if c == '\n' { + lin_col.line += 1; + lin_col.col = 0; + col_utf16 = 0; + col_utf32 = 0; + } else { + lin_col.col += c.len_utf8() as u32; + col_utf16 += c.len_utf16() as u32; + col_utf32 += 1; + } + } +} diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index d51daa3395..40f872a24a 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs @@ -9,14 +9,20 @@ use crate::{flags, project_root}; pub(crate) mod assists_doc_tests; pub(crate) mod diagnostics_docs; +mod lints; impl flags::Codegen { pub(crate) fn run(self, _sh: &Shell) -> anyhow::Result<()> { match self.codegen_type.unwrap_or_default() { flags::CodegenType::All => { + diagnostics_docs::generate(self.check); assists_doc_tests::generate(self.check); + // lints::generate(self.check) Updating clones the rust repo, so don't run it unless + // explicitly asked for } flags::CodegenType::AssistsDocTests => assists_doc_tests::generate(self.check), + flags::CodegenType::DiagnosticsDocs => diagnostics_docs::generate(self.check), + flags::CodegenType::LintDefinitions => lints::generate(self.check), } Ok(()) } diff --git a/xtask/src/codegen/diagnostics_docs.rs b/xtask/src/codegen/diagnostics_docs.rs index a45b412fda..cf30531e7f 100644 --- a/xtask/src/codegen/diagnostics_docs.rs +++ b/xtask/src/codegen/diagnostics_docs.rs @@ -7,7 +7,7 @@ use crate::{ project_root, }; -fn generate(check: bool) { +pub(crate) fn generate(check: bool) { let diagnostics = Diagnostic::collect().unwrap(); if !check { let contents = diff --git a/crates/ide-db/src/tests/sourcegen_lints.rs b/xtask/src/codegen/lints.rs similarity index 93% rename from crates/ide-db/src/tests/sourcegen_lints.rs rename to xtask/src/codegen/lints.rs index 86ed01c8e7..63abcfc090 100644 --- a/crates/ide-db/src/tests/sourcegen_lints.rs +++ b/xtask/src/codegen/lints.rs @@ -2,18 +2,18 @@ //! and lints from rustc, rustdoc, and clippy. use std::{borrow::Cow, fs, path::Path}; -use itertools::Itertools; use stdx::format_to; -use test_utils::project_root; use xshell::{cmd, Shell}; +use crate::{ + codegen::{add_preamble, ensure_file_contents, list_files, reformat}, + project_root, +}; + const DESTINATION: &str = "crates/ide-db/src/generated/lints.rs"; -/// This clones rustc repo, and so is not worth to keep up-to-date. We update -/// manually by un-ignoring the test from time to time. -#[test] -#[ignore] -fn sourcegen_lint_completions() { +/// This clones rustc repo, and so is not worth to keep up-to-date on a constant basis. +pub(crate) fn generate(check: bool) { let sh = &Shell::new().unwrap(); let rust_repo = project_root().join("./target/rust"); @@ -73,10 +73,10 @@ pub struct LintGroup { .unwrap(); generate_descriptor_clippy(&mut contents, &lints_json); - let contents = sourcegen::add_preamble("sourcegen_lints", sourcegen::reformat(contents)); + let contents = add_preamble("sourcegen_lints", reformat(contents)); let destination = project_root().join(DESTINATION); - sourcegen::ensure_file_contents(destination.as_path(), &contents); + ensure_file_contents(destination.as_path(), &contents, check); } /// Parses the output of `rustdoc -Whelp` and prints `Lint` and `LintGroup` constants into `buf`. @@ -130,10 +130,9 @@ fn generate_lint_descriptor(sh: &Shell, buf: &mut String) { ) }); - let lints = lints - .chain(lint_groups) - .sorted_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2)) - .collect::>(); + let mut lints = lints.chain(lint_groups).collect::>(); + lints.sort_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2)); + for (name, description, ..) in &lints { push_lint_completion(buf, &name.replace('-', "_"), description); } @@ -177,10 +176,8 @@ fn generate_lint_descriptor(sh: &Shell, buf: &mut String) { ) }); - let lints_rustdoc = lints_rustdoc - .chain(lint_groups_rustdoc) - .sorted_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2)) - .collect::>(); + let mut lints_rustdoc = lints_rustdoc.chain(lint_groups_rustdoc).collect::>(); + lints_rustdoc.sort_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2)); for (name, description, ..) in &lints_rustdoc { push_lint_completion(buf, &name.replace('-', "_"), description) @@ -212,7 +209,7 @@ fn find_and_slice<'a>(i: &'a str, p: &str) -> &'a str { fn generate_feature_descriptor(buf: &mut String, src_dir: &Path) { let mut features = ["language-features", "library-features"] .into_iter() - .flat_map(|it| sourcegen::list_files(&src_dir.join(it))) + .flat_map(|it| list_files(&src_dir.join(it))) // Get all `.md` files .filter(|path| path.extension() == Some("md".as_ref())) .map(|path| { @@ -302,7 +299,7 @@ fn generate_descriptor_clippy(buf: &mut String, path: &Path) { let children = children.iter().map(|id| format!("clippy::{id}")).collect::>(); if !children.is_empty() { let lint_ident = format!("clippy::{id}"); - let description = format!("lint group for: {}", children.iter().join(", ")); + let description = format!("lint group for: {}", children.join(", ")); push_lint_group(buf, &lint_ident, &description, &children); } } @@ -331,7 +328,10 @@ fn push_lint_group(buf: &mut String, label: &str, description: &str, children: & push_lint_completion(buf, label, description); - let children = format!("&[{}]", children.iter().map(|it| format!("\"{it}\"")).join(", ")); + let children = format!( + "&[{}]", + children.iter().map(|it| format!("\"{it}\"")).collect::>().join(", ") + ); format_to!( buf, r###" diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs index f5827170b6..681c588bd0 100644 --- a/xtask/src/flags.rs +++ b/xtask/src/flags.rs @@ -92,6 +92,8 @@ pub enum CodegenType { #[default] All, AssistsDocTests, + DiagnosticsDocs, + LintDefinitions, } impl FromStr for CodegenType { @@ -100,6 +102,8 @@ impl FromStr for CodegenType { match s { "all" => Ok(Self::All), "assists-doc-tests" => Ok(Self::AssistsDocTests), + "diagnostics-docs" => Ok(Self::DiagnosticsDocs), + "lints-definitions" => Ok(Self::LintDefinitions), _ => Err("Invalid option".to_owned()), } } diff --git a/xtask/src/release.rs b/xtask/src/release.rs index f99f9ecbc3..1a5e6dfb4c 100644 --- a/xtask/src/release.rs +++ b/xtask/src/release.rs @@ -23,7 +23,7 @@ impl flags::Release { } // Generates bits of manual.adoc. - cmd!(sh, "cargo test -p ide-diagnostics -p rust-analyzer -- sourcegen_").run()?; + codegen::diagnostics_docs::generate(false); codegen::assists_doc_tests::generate(false); let website_root = project_root().join("../rust-analyzer.github.io"); From b9dbb8afd9903b481f6902a1171d87a104b2e540 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 4 Mar 2024 17:12:08 +0100 Subject: [PATCH 3/3] Regenerate lints table --- crates/ide-db/src/generated/lints.rs | 426 +++++++++++++++++++++------ crates/ide/src/hover/tests.rs | 54 +++- 2 files changed, 386 insertions(+), 94 deletions(-) diff --git a/crates/ide-db/src/generated/lints.rs b/crates/ide-db/src/generated/lints.rs index 2fc0793320..d50088e6cf 100644 --- a/crates/ide-db/src/generated/lints.rs +++ b/crates/ide-db/src/generated/lints.rs @@ -22,6 +22,10 @@ pub const DEFAULT_LINTS: &[Lint] = &[ description: r##"detects certain glob imports that require reporting an ambiguity error"##, }, Lint { label: "ambiguous_glob_reexports", description: r##"ambiguous glob re-exports"## }, + Lint { + label: "ambiguous_wide_pointer_comparisons", + description: r##"detects ambiguous wide pointer comparisons"##, + }, Lint { label: "anonymous_parameters", description: r##"detects anonymous parameters"## }, Lint { label: "arithmetic_overflow", description: r##"arithmetic operation overflows"## }, Lint { @@ -66,10 +70,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "coherence_leak_check", description: r##"distinct impls distinguished only by the leak-check code"##, }, - Lint { - label: "coinductive_overlap_in_coherence", - description: r##"impls that are not considered to overlap may be considered to overlap in the future"##, - }, Lint { label: "conflicting_repr_hints", description: r##"conflicts between `#[repr(..)]` hints that were previously accepted and used in practice"##, @@ -86,10 +86,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "const_item_mutation", description: r##"detects attempts to mutate a `const` item"##, }, - Lint { - label: "const_patterns_without_partial_eq", - description: r##"constant in pattern does not implement `PartialEq`"##, - }, Lint { label: "dead_code", description: r##"detect unused, unexported items"## }, Lint { label: "deprecated", description: r##"detects use of deprecated items"## }, Lint { @@ -176,7 +172,7 @@ pub const DEFAULT_LINTS: &[Lint] = &[ }, Lint { label: "future_incompatible", - description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, coinductive-overlap-in-coherence, conflicting-repr-hints, const-evaluatable-unchecked, const-patterns-without-partial-eq, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, illegal-floating-point-literal-pattern, implied-bounds-entailment, indirect-structural-match, invalid-doc-attributes, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, nontrivial-structural-match, order-dependent-trait-objects, patterns-in-fns-without-body, pointer-structural-match, proc-macro-back-compat, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, semicolon-in-expressions-from-macros, soft-unstable, suspicious-auto-trait-impls, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, where-clauses-object-safety"##, + description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, indirect-structural-match, invalid-doc-attributes, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, patterns-in-fns-without-body, pointer-structural-match, proc-macro-back-compat, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, semicolon-in-expressions-from-macros, soft-unstable, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, where-clauses-object-safety, writes-through-immutable-pointer"##, }, Lint { label: "fuzzy_provenance_casts", @@ -190,14 +186,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "ill_formed_attribute_input", description: r##"ill-formed attribute inputs that were previously accepted and used in practice"##, }, - Lint { - label: "illegal_floating_point_literal_pattern", - description: r##"floating-point literals cannot be used in patterns"##, - }, - Lint { - label: "implied_bounds_entailment", - description: r##"impl method assumes more implied bounds than its corresponding trait method"##, - }, Lint { label: "improper_ctypes", description: r##"proper use of libc types in foreign modules"##, @@ -372,6 +360,7 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "non_fmt_panics", description: r##"detect single-argument panic!() invocations in which the argument is not a format string"##, }, + Lint { label: "non_local_definitions", description: r##"checks for non-local definitions"## }, Lint { label: "non_shorthand_field_patterns", description: r##"using `Struct { x: x }` instead of `Struct { x }` in a pattern"##, @@ -388,10 +377,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "nonstandard_style", description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##, }, - Lint { - label: "nontrivial_structural_match", - description: r##"constant used in pattern of non-structural-match type and the constant's initializer expression contains values of non-structural-match types"##, - }, Lint { label: "noop_method_call", description: r##"detects the use of well-known noop methods"##, @@ -482,6 +467,10 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "rust_2021_prelude_collisions", description: r##"detects the usage of trait methods which are ambiguous with traits added to the prelude in future editions"##, }, + Lint { + label: "rust_2024_compatibility", + description: r##"lint group for: static-mut-refs, unsafe-op-in-unsafe-fn"##, + }, Lint { label: "semicolon_in_expressions_from_macros", description: r##"trailing semicolon in macro body used as expression"##, @@ -503,8 +492,8 @@ pub const DEFAULT_LINTS: &[Lint] = &[ description: r##"stable features found in `#[feature]` directive"##, }, Lint { - label: "suspicious_auto_trait_impls", - description: r##"the rules governing auto traits have recently changed resulting in potential breakage"##, + label: "static_mut_refs", + description: r##"shared references or mutable references of mutable static is discouraged"##, }, Lint { label: "suspicious_double_ref_op", @@ -579,6 +568,10 @@ pub const DEFAULT_LINTS: &[Lint] = &[ description: r##"enabling track_caller on an async fn is a no-op unless the async_fn_track_caller feature is enabled"##, }, Lint { label: "uninhabited_static", description: r##"uninhabited static"## }, + Lint { + label: "unit_bindings", + description: r##"binding is useless because it has the unit `()` type"##, + }, Lint { label: "unknown_crate_types", description: r##"unknown crate type found in `#[crate_type]` directive"##, @@ -610,10 +603,7 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "unsafe_op_in_unsafe_fn", description: r##"unsafe operations in unsafe functions without an explicit unsafe block are deprecated"##, }, - Lint { - label: "unstable_features", - description: r##"enabling unstable features (deprecated. do not use)"##, - }, + Lint { label: "unstable_features", description: r##"enabling unstable features"## }, Lint { label: "unstable_name_collisions", description: r##"detects name collision with an existing but unstable method"##, @@ -699,10 +689,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "unused_results", description: r##"unused result of an expression in a statement"##, }, - Lint { - label: "unused_tuple_struct_fields", - description: r##"detects tuple struct fields that are never read"##, - }, Lint { label: "unused_unsafe", description: r##"unnecessary use of an `unsafe` block"## }, Lint { label: "unused_variables", @@ -736,13 +722,17 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "while_true", description: r##"suggest using `loop { }` instead of `while true { }`"##, }, + Lint { + label: "writes_through_immutable_pointer", + description: r##"shared references are immutable, and pointers derived from them must not be written to"##, + }, ]; pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "future_incompatible", - description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, coinductive-overlap-in-coherence, conflicting-repr-hints, const-evaluatable-unchecked, const-patterns-without-partial-eq, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, illegal-floating-point-literal-pattern, implied-bounds-entailment, indirect-structural-match, invalid-doc-attributes, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, nontrivial-structural-match, order-dependent-trait-objects, patterns-in-fns-without-body, pointer-structural-match, proc-macro-back-compat, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, semicolon-in-expressions-from-macros, soft-unstable, suspicious-auto-trait-impls, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, where-clauses-object-safety"##, + description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, indirect-structural-match, invalid-doc-attributes, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, patterns-in-fns-without-body, pointer-structural-match, proc-macro-back-compat, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, semicolon-in-expressions-from-macros, soft-unstable, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, where-clauses-object-safety, writes-through-immutable-pointer"##, }, children: &[ "deref_into_dyn_supertrait", @@ -751,16 +741,12 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "byte_slice_in_packed_struct_with_derive", "cenum_impl_drop_cast", "coherence_leak_check", - "coinductive_overlap_in_coherence", "conflicting_repr_hints", "const_evaluatable_unchecked", - "const_patterns_without_partial_eq", "deprecated_cfg_attr_crate_type_name", "elided_lifetimes_in_associated_constant", "forbidden_lint_groups", "ill_formed_attribute_input", - "illegal_floating_point_literal_pattern", - "implied_bounds_entailment", "indirect_structural_match", "invalid_doc_attributes", "invalid_type_param_default", @@ -768,7 +754,6 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "legacy_derive_helpers", "macro_expanded_macro_exports_accessed_by_absolute_paths", "missing_fragment_specifier", - "nontrivial_structural_match", "order_dependent_trait_objects", "patterns_in_fns_without_body", "pointer_structural_match", @@ -778,12 +763,12 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "repr_transparent_external_private_fields", "semicolon_in_expressions_from_macros", "soft_unstable", - "suspicious_auto_trait_impls", "uninhabited_static", "unstable_name_collisions", "unstable_syntax_pre_expansion", "unsupported_calling_conventions", "where_clauses_object_safety", + "writes_through_immutable_pointer", ], }, LintGroup { @@ -841,6 +826,13 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "non_fmt_panics", ], }, + LintGroup { + lint: Lint { + label: "rust_2024_compatibility", + description: r##"lint group for: static-mut-refs, unsafe-op-in-unsafe-fn"##, + }, + children: &["static_mut_refs", "unsafe_op_in_unsafe_fn"], + }, LintGroup { lint: Lint { label: "unused", @@ -1735,9 +1727,17 @@ The tracking issue for this feature is: [#110011] label: "async_fn_traits", description: r##"# `async_fn_traits` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +See Also: [`fn_traits`](../library-features/fn-traits.md) ------------------------- +---- + +The `async_fn_traits` feature allows for implementation of the [`AsyncFn*`] traits +for creating custom closure-like types that return futures. + +[`AsyncFn*`]: ../../std/ops/trait.AsyncFn.html + +The main difference to the `Fn*` family of traits is that `AsyncFn` can return a future +that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFn::CallFuture` does). "##, }, Lint { @@ -2377,17 +2377,6 @@ The tracking issue for this feature is: [#89653] [#89653]: https://github.com/rust-lang/rust/issues/89653 ------------------------- -"##, - }, - Lint { - label: "cfg_target_abi", - description: r##"# `cfg_target_abi` - -The tracking issue for this feature is: [#80970] - -[#80970]: https://github.com/rust-lang/rust/issues/80970 - ------------------------ "##, }, @@ -3133,6 +3122,17 @@ The tracking issue for this feature is: [#90603] This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +------------------------ +"##, + }, + Lint { + label: "const_intrinsic_copy", + description: r##"# `const_intrinsic_copy` + +The tracking issue for this feature is: [#80697] + +[#80697]: https://github.com/rust-lang/rust/issues/80697 + ------------------------ "##, }, @@ -3301,6 +3301,17 @@ The tracking issue for this feature is: [#110840] [#110840]: https://github.com/rust-lang/rust/issues/110840 +------------------------ +"##, + }, + Lint { + label: "const_ops", + description: r##"# `const_ops` + +The tracking issue for this feature is: [#90080] + +[#90080]: https://github.com/rust-lang/rust/issues/90080 + ------------------------ "##, }, @@ -3444,6 +3455,17 @@ The tracking issue for this feature is: [#80384] [#80384]: https://github.com/rust-lang/rust/issues/80384 +------------------------ +"##, + }, + Lint { + label: "const_refs_to_static", + description: r##"# `const_refs_to_static` + +The tracking issue for this feature is: [#119618] + +[#119618]: https://github.com/rust-lang/rust/issues/119618 + ------------------------ "##, }, @@ -4256,6 +4278,15 @@ The tracking issue for this feature is: [#27336] [#27336]: https://github.com/rust-lang/rust/issues/27336 +------------------------ +"##, + }, + Lint { + label: "delayed_debug_assertions", + description: r##"# `delayed_debug_assertions` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + ------------------------ "##, }, @@ -4637,6 +4668,19 @@ The tracking issue for this feature is: [#57391] [#57391]: https://github.com/rust-lang/rust/issues/57391 ------------------------ +"##, + }, + Lint { + label: "duration_constructors", + description: r##"# `duration_constructors` + +The tracking issue for this feature is: [#120301] + +[#120301]: https://github.com/rust-lang/rust/issues/120301 + +------------------------ + +Add the methods `from_mins`, `from_hours` and `from_days` to `Duration`. "##, }, Lint { @@ -4647,6 +4691,17 @@ The tracking issue for this feature is: [#72440] [#72440]: https://github.com/rust-lang/rust/issues/72440 +------------------------ +"##, + }, + Lint { + label: "duration_units", + description: r##"# `duration_units` + +The tracking issue for this feature is: [#120301] + +[#120301]: https://github.com/rust-lang/rust/issues/120301 + ------------------------ "##, }, @@ -5659,13 +5714,62 @@ raw pointers in intra-doc links are unstable until it does. The tracking issue for this feature is: None. -Intrinsics are never intended to be stable directly, but intrinsics are often +Intrinsics are rarely intended to be stable directly, but are usually exported in some sort of stable manner. Prefer using the stable interfaces to the intrinsic directly when you can. ------------------------ +## Intrinsics with fallback logic + +Many intrinsics can be written in pure rust, albeit inefficiently or without supporting +some features that only exist on some backends. Backends can simply not implement those +intrinsics without causing any code miscompilations or failures to compile. +All intrinsic fallback bodies are automatically made cross-crate inlineable (like `#[inline]`) +by the codegen backend, but not the MIR inliner. + +```rust +#![feature(rustc_attrs, effects)] +#![allow(internal_features)] + +#[rustc_intrinsic] +const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} +``` + +Since these are just regular functions, it is perfectly ok to create the intrinsic twice: + +```rust +#![feature(rustc_attrs, effects)] +#![allow(internal_features)] + +#[rustc_intrinsic] +const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} + +mod foo { + #[rustc_intrinsic] + const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) { + panic!("noisy const dealloc") + } +} + +``` + +The behaviour on backends that override the intrinsic is exactly the same. On other +backends, the intrinsic behaviour depends on which implementation is called, just like +with any regular function. + +## Intrinsics lowered to MIR instructions + +Various intrinsics have native MIR operations that they correspond to. Instead of requiring +backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass +will convert the calls to the MIR operation. Backends do not need to know about these intrinsics +at all. + +## Intrinsics without fallback logic + +These must be implemented by all backends. + These are imported as if they were FFI functions, with the special `rust-intrinsic` ABI. For example, if one was in a freestanding context, but wished to be able to `transmute` between types, and @@ -5684,7 +5788,8 @@ extern "rust-intrinsic" { } ``` -As with any other FFI functions, these are always `unsafe` to call. +As with any other FFI functions, these are by default always `unsafe` to call. +You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call. "##, }, Lint { @@ -5759,6 +5864,17 @@ The tracking issue for this feature is: [#101288] [#101288]: https://github.com/rust-lang/rust/issues/101288 +------------------------ +"##, + }, + Lint { + label: "is_riscv_feature_detected", + description: r##"# `is_riscv_feature_detected` + +The tracking issue for this feature is: [#111192] + +[#111192]: https://github.com/rust-lang/rust/issues/111192 + ------------------------ "##, }, @@ -5937,6 +6053,17 @@ The tracking issue for this feature is: [#87053] [#87053]: https://github.com/rust-lang/rust/issues/87053 +------------------------ +"##, + }, + Lint { + label: "lahfsahf_target_feature", + description: r##"# `lahfsahf_target_feature` + +The tracking issue for this feature is: [#44839] + +[#44839]: https://github.com/rust-lang/rust/issues/44839 + ------------------------ "##, }, @@ -6260,6 +6387,17 @@ The tracking issue for this feature is: [#82971] [#82971]: https://github.com/rust-lang/rust/issues/82971 +------------------------ +"##, + }, + Lint { + label: "local_waker", + description: r##"# `local_waker` + +The tracking issue for this feature is: [#118959] + +[#118959]: https://github.com/rust-lang/rust/issues/118959 + ------------------------ "##, }, @@ -6326,6 +6464,17 @@ The tracking issue for this feature is: [#82766] [#82766]: https://github.com/rust-lang/rust/issues/82766 +------------------------ +"##, + }, + Lint { + label: "mapped_lock_guards", + description: r##"# `mapped_lock_guards` + +The tracking issue for this feature is: [#117108] + +[#117108]: https://github.com/rust-lang/rust/issues/117108 + ------------------------ "##, }, @@ -6539,17 +6688,6 @@ The tracking issue for this feature is: [#83310] [#83310]: https://github.com/rust-lang/rust/issues/83310 ------------------------- -"##, - }, - Lint { - label: "mutex_unlock", - description: r##"# `mutex_unlock` - -The tracking issue for this feature is: [#81872] - -[#81872]: https://github.com/rust-lang/rust/issues/81872 - ------------------------ "##, }, @@ -6977,6 +7115,17 @@ The tracking issue for this feature is: [#70086] [#70086]: https://github.com/rust-lang/rust/issues/70086 +------------------------ +"##, + }, + Lint { + label: "os_str_display", + description: r##"# `os_str_display` + +The tracking issue for this feature is: [#120048] + +[#120048]: https://github.com/rust-lang/rust/issues/120048 + ------------------------ "##, }, @@ -7107,6 +7256,15 @@ The tracking issue for this feature is: [#27721] [#27721]: https://github.com/rust-lang/rust/issues/27721 +------------------------ +"##, + }, + Lint { + label: "pattern_complexity", + description: r##"# `pattern_complexity` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + ------------------------ "##, }, @@ -7129,17 +7287,6 @@ The tracking issue for this feature is: [#86918] [#86918]: https://github.com/rust-lang/rust/issues/86918 ------------------------- -"##, - }, - Lint { - label: "platform_intrinsics", - description: r##"# `platform_intrinsics` - -The tracking issue for this feature is: [#27731] - -[#27731]: https://github.com/rust-lang/rust/issues/27731 - ------------------------ "##, }, @@ -7189,7 +7336,9 @@ The tracking issue for this feature is: [#44839] label: "prelude_2024", description: r##"# `prelude_2024` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#121042] + +[#121042]: https://github.com/rust-lang/rust/issues/121042 ------------------------ "##, @@ -7200,6 +7349,17 @@ This feature has no tracking issue, and is therefore likely internal to the comp This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +------------------------ +"##, + }, + Lint { + label: "prfchw_target_feature", + description: r##"# `prfchw_target_feature` + +The tracking issue for this feature is: [#44839] + +[#44839]: https://github.com/rust-lang/rust/issues/44839 + ------------------------ "##, }, @@ -7512,6 +7672,17 @@ The tracking issue for this feature is: [#101196] This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +------------------------ +"##, + }, + Lint { + label: "reentrant_lock", + description: r##"# `reentrant_lock` + +The tracking issue for this feature is: [#121440] + +[#121440]: https://github.com/rust-lang/rust/issues/121440 + ------------------------ "##, }, @@ -8182,6 +8353,39 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize { This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +------------------------ +"##, + }, + Lint { + label: "stdarch_arm_feature_detection", + description: r##"# `stdarch_arm_feature_detection` + +The tracking issue for this feature is: [#111190] + +[#111190]: https://github.com/rust-lang/rust/issues/111190 + +------------------------ +"##, + }, + Lint { + label: "stdarch_mips_feature_detection", + description: r##"# `stdarch_mips_feature_detection` + +The tracking issue for this feature is: [#111188] + +[#111188]: https://github.com/rust-lang/rust/issues/111188 + +------------------------ +"##, + }, + Lint { + label: "stdarch_powerpc_feature_detection", + description: r##"# `stdarch_powerpc_feature_detection` + +The tracking issue for this feature is: [#111191] + +[#111191]: https://github.com/rust-lang/rust/issues/111191 + ------------------------ "##, }, @@ -8193,17 +8397,6 @@ The tracking issue for this feature is: [#98288] [#98288]: https://github.com/rust-lang/rust/issues/98288 ------------------------- -"##, - }, - Lint { - label: "stdsimd", - description: r##"# `stdsimd` - -The tracking issue for this feature is: [#48556] - -[#48556]: https://github.com/rust-lang/rust/issues/48556 - ------------------------ "##, }, @@ -8464,6 +8657,17 @@ The tracking issue for this feature is: [#44839] [#44839]: https://github.com/rust-lang/rust/issues/44839 +------------------------ +"##, + }, + Lint { + label: "tcp_deferaccept", + description: r##"# `tcp_deferaccept` + +The tracking issue for this feature is: [#119639] + +[#119639]: https://github.com/rust-lang/rust/issues/119639 + ------------------------ "##, }, @@ -10156,7 +10360,7 @@ table: }, Lint { label: "clippy::blocks_in_conditions", - description: r##"Checks for `if` conditions that use blocks containing an + description: r##"Checks for `if` and `match` conditions that use blocks containing an expression, statements or conditions that use closures with blocks."##, }, Lint { @@ -10458,6 +10662,12 @@ See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-in label: "clippy::deprecated_cfg_attr", description: r##"Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it with `#[rustfmt::skip]`."##, + }, + Lint { + label: "clippy::deprecated_clippy_cfg_attr", + description: r##"Checks for `#[cfg_attr(feature = cargo-clippy, ...)]` and for +`#[cfg(feature = cargo-clippy)]` and suggests to replace it with +`#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`."##, }, Lint { label: "clippy::deprecated_semver", @@ -10601,6 +10811,7 @@ eagerly (e.g. using `bool::then_some`)."##, description: r##"Checks for usage of if expressions with an `else if` branch, but without a final `else` branch."##, }, + Lint { label: "clippy::empty_docs", description: r##"Detects documentation that is empty."## }, Lint { label: "clippy::empty_drop", description: r##"Checks for empty `Drop` implementations."##, @@ -11357,6 +11568,7 @@ cannot be represented as the underlying type without loss."##, description: r##"Checks for usage of `std::mem::size_of::() * 8` when `T::BITS` is available."##, }, + Lint { label: "clippy::manual_c_str_literals", description: r##""## }, Lint { label: "clippy::manual_clamp", description: r##"Identifies good opportunities for a clamp function from std or core, and suggests using it."##, @@ -11731,6 +11943,10 @@ rather than globally."##, label: "clippy::mistyped_literal_suffixes", description: r##"Warns for mistyped suffix in literals"##, }, + Lint { + label: "clippy::mixed_attributes_style", + description: r##"Checks that an item has only one kind of attributes."##, + }, Lint { label: "clippy::mixed_case_hex_literals", description: r##"Warns on hexadecimal literals with mixed-case letter @@ -11763,6 +11979,10 @@ containing module's name."##, one."##, }, Lint { label: "clippy::multi_assignments", description: r##"Checks for nested assignments."## }, + Lint { + label: "clippy::multiple_bound_locations", + description: r##"Check if a generic is defined both in the bound predicate and in the `where` clause."##, + }, Lint { label: "clippy::multiple_crate_versions", description: r##"Checks to see if multiple versions of a crate are being @@ -12336,8 +12556,8 @@ in `vec![elem; len]`"##, Lint { label: "clippy::read_line_without_trim", description: r##"Looks for calls to [`Stdin::read_line`] to read a line from the standard input -into a string, then later attempting to parse this string into a type without first trimming it, which will -always fail because the string has a trailing newline in it."##, +into a string, then later attempting to use that string for an operation that will never +work for strings with a trailing newline character in it (e.g. parsing into a `i32`)."##, }, Lint { label: "clippy::read_zero_byte_vec", @@ -12444,6 +12664,11 @@ do not change the type."##, label: "clippy::redundant_type_annotations", description: r##"Warns about needless / redundant type annotations."##, }, + Lint { + label: "clippy::ref_as_ptr", + description: r##"Checks for casts of references to pointer using `as` +and suggests `std::ptr::from_ref` and `std::ptr::from_mut` instead."##, + }, Lint { label: "clippy::ref_binding_to_reference", description: r##"Checks for `ref` bindings which create a reference to a reference."##, @@ -13095,6 +13320,11 @@ as returning a large `T` directly may be detrimental to performance."##, label: "clippy::unnecessary_cast", description: r##"Checks for casts to the same type, casts of int literals to integer types, casts of float literals to float types and casts between raw pointers without changing type or constness."##, + }, + Lint { + label: "clippy::unnecessary_clippy_cfg", + description: r##"Checks for `#[cfg_attr(clippy, allow(clippy::lint))]` +and suggests to replace it with `#[allow(clippy::lint)]`."##, }, Lint { label: "clippy::unnecessary_fallible_conversions", @@ -13119,6 +13349,10 @@ find or map operations and suggests the appropriate option."##, Specifically, this checks for `fold`s which could be replaced by `any`, `all`, `sum` or `product`."##, }, + Lint { + label: "clippy::unnecessary_get_then_check", + description: r##"Checks the usage of `.get().is_some()` or `.get().is_none()` on std map types."##, + }, Lint { label: "clippy::unnecessary_join", description: r##"Checks for usage of `.collect::>().join()` on iterators."##, @@ -13830,7 +14064,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::pedantic", - description: r##"lint group for: clippy::bool_to_int_with_if, clippy::borrow_as_ptr, clippy::case_sensitive_file_extension_comparisons, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_precision_loss, clippy::cast_ptr_alignment, clippy::cast_sign_loss, clippy::checked_conversions, clippy::cloned_instead_of_copied, clippy::copy_iterator, clippy::default_trait_access, clippy::doc_link_with_quotes, clippy::doc_markdown, clippy::empty_enum, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_deref_methods, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::flat_map_option, clippy::float_cmp, clippy::fn_params_excessive_bools, clippy::from_iter_instead_of_collect, clippy::if_not_else, clippy::ignored_unit_patterns, clippy::implicit_clone, clippy::implicit_hasher, clippy::inconsistent_struct_constructor, clippy::index_refutable_slice, clippy::inefficient_to_string, clippy::inline_always, clippy::into_iter_without_iter, clippy::invalid_upcast_comparisons, clippy::items_after_statements, clippy::iter_filter_is_ok, clippy::iter_filter_is_some, clippy::iter_not_returning_iterator, clippy::iter_without_into_iter, clippy::large_digit_groups, clippy::large_futures, clippy::large_stack_arrays, clippy::large_types_passed_by_value, clippy::linkedlist, clippy::macro_use_imports, clippy::manual_assert, clippy::manual_instant_elapsed, clippy::manual_is_variant_and, clippy::manual_let_else, clippy::manual_ok_or, clippy::manual_string_new, clippy::many_single_char_names, clippy::map_unwrap_or, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wild_err_arm, clippy::match_wildcard_for_single_variants, clippy::maybe_infinite_iter, clippy::mismatching_type_param_order, clippy::missing_errors_doc, clippy::missing_fields_in_debug, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::mut_mut, clippy::naive_bytecount, clippy::needless_bitwise_bool, clippy::needless_continue, clippy::needless_for_each, clippy::needless_pass_by_value, clippy::needless_raw_string_hashes, clippy::no_effect_underscore_binding, clippy::no_mangle_with_rust_abi, clippy::option_as_ref_cloned, clippy::option_option, clippy::ptr_as_ptr, clippy::ptr_cast_constness, clippy::pub_underscore_fields, clippy::range_minus_one, clippy::range_plus_one, clippy::redundant_closure_for_method_calls, clippy::redundant_else, clippy::ref_binding_to_reference, clippy::ref_option_ref, clippy::return_self_not_must_use, clippy::same_functions_in_if_condition, clippy::semicolon_if_nothing_returned, clippy::should_panic_without_expect, clippy::similar_names, clippy::single_match_else, clippy::stable_sort_primitive, clippy::str_split_at_newline, clippy::string_add_assign, clippy::struct_excessive_bools, clippy::struct_field_names, clippy::too_many_lines, clippy::transmute_ptr_to_ptr, clippy::trivially_copy_pass_by_ref, clippy::unchecked_duration_subtraction, clippy::unicode_not_nfc, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_join, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::unreadable_literal, clippy::unsafe_derive_deserialize, clippy::unused_async, clippy::unused_self, clippy::used_underscore_binding, clippy::verbose_bit_mask, clippy::wildcard_imports, clippy::zero_sized_map_values"##, + description: r##"lint group for: clippy::bool_to_int_with_if, clippy::borrow_as_ptr, clippy::case_sensitive_file_extension_comparisons, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_precision_loss, clippy::cast_ptr_alignment, clippy::cast_sign_loss, clippy::checked_conversions, clippy::cloned_instead_of_copied, clippy::copy_iterator, clippy::default_trait_access, clippy::doc_link_with_quotes, clippy::doc_markdown, clippy::empty_enum, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_deref_methods, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::flat_map_option, clippy::float_cmp, clippy::fn_params_excessive_bools, clippy::from_iter_instead_of_collect, clippy::if_not_else, clippy::ignored_unit_patterns, clippy::implicit_clone, clippy::implicit_hasher, clippy::inconsistent_struct_constructor, clippy::index_refutable_slice, clippy::inefficient_to_string, clippy::inline_always, clippy::into_iter_without_iter, clippy::invalid_upcast_comparisons, clippy::items_after_statements, clippy::iter_filter_is_ok, clippy::iter_filter_is_some, clippy::iter_not_returning_iterator, clippy::iter_without_into_iter, clippy::large_digit_groups, clippy::large_futures, clippy::large_stack_arrays, clippy::large_types_passed_by_value, clippy::linkedlist, clippy::macro_use_imports, clippy::manual_assert, clippy::manual_c_str_literals, clippy::manual_instant_elapsed, clippy::manual_is_variant_and, clippy::manual_let_else, clippy::manual_ok_or, clippy::manual_string_new, clippy::many_single_char_names, clippy::map_unwrap_or, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wild_err_arm, clippy::match_wildcard_for_single_variants, clippy::maybe_infinite_iter, clippy::mismatching_type_param_order, clippy::missing_errors_doc, clippy::missing_fields_in_debug, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::mut_mut, clippy::naive_bytecount, clippy::needless_bitwise_bool, clippy::needless_continue, clippy::needless_for_each, clippy::needless_pass_by_value, clippy::needless_raw_string_hashes, clippy::no_effect_underscore_binding, clippy::no_mangle_with_rust_abi, clippy::option_as_ref_cloned, clippy::option_option, clippy::ptr_as_ptr, clippy::ptr_cast_constness, clippy::pub_underscore_fields, clippy::range_minus_one, clippy::range_plus_one, clippy::redundant_closure_for_method_calls, clippy::redundant_else, clippy::ref_as_ptr, clippy::ref_binding_to_reference, clippy::ref_option_ref, clippy::return_self_not_must_use, clippy::same_functions_in_if_condition, clippy::semicolon_if_nothing_returned, clippy::should_panic_without_expect, clippy::similar_names, clippy::single_match_else, clippy::stable_sort_primitive, clippy::str_split_at_newline, clippy::string_add_assign, clippy::struct_excessive_bools, clippy::struct_field_names, clippy::too_many_lines, clippy::transmute_ptr_to_ptr, clippy::trivially_copy_pass_by_ref, clippy::unchecked_duration_subtraction, clippy::unicode_not_nfc, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_join, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::unreadable_literal, clippy::unsafe_derive_deserialize, clippy::unused_async, clippy::unused_self, clippy::used_underscore_binding, clippy::verbose_bit_mask, clippy::wildcard_imports, clippy::zero_sized_map_values"##, }, children: &[ "clippy::bool_to_int_with_if", @@ -13881,6 +14115,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::linkedlist", "clippy::macro_use_imports", "clippy::manual_assert", + "clippy::manual_c_str_literals", "clippy::manual_instant_elapsed", "clippy::manual_is_variant_and", "clippy::manual_let_else", @@ -13918,6 +14153,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::range_plus_one", "clippy::redundant_closure_for_method_calls", "clippy::redundant_else", + "clippy::ref_as_ptr", "clippy::ref_binding_to_reference", "clippy::ref_option_ref", "clippy::return_self_not_must_use", @@ -14262,7 +14498,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::suspicious", - description: r##"lint group for: clippy::almost_complete_range, clippy::arc_with_non_send_sync, clippy::await_holding_invalid_type, clippy::await_holding_lock, clippy::await_holding_refcell_ref, clippy::blanket_clippy_restriction_lints, clippy::cast_abs_to_unsigned, clippy::cast_enum_constructor, clippy::cast_enum_truncation, clippy::cast_nan_to_int, clippy::cast_slice_from_raw_parts, clippy::crate_in_macro_def, clippy::drop_non_drop, clippy::duplicate_mod, clippy::empty_loop, clippy::float_equality_without_abs, clippy::forget_non_drop, clippy::four_forward_slashes, clippy::from_raw_with_void_ptr, clippy::incompatible_msrv, clippy::ineffective_open_options, clippy::iter_out_of_bounds, clippy::join_absolute_paths, clippy::let_underscore_future, clippy::lines_filter_map_ok, clippy::maybe_misused_cfg, clippy::misnamed_getters, clippy::misrefactored_assign_op, clippy::multi_assignments, clippy::mut_range_bound, clippy::mutable_key_type, clippy::no_effect_replace, clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, clippy::octal_escapes, clippy::path_ends_with_ext, clippy::permissions_set_readonly_false, clippy::print_in_format_impl, clippy::rc_clone_in_vec_init, clippy::repeat_vec_with_capacity, clippy::single_range_in_vec_init, clippy::size_of_ref, clippy::suspicious_arithmetic_impl, clippy::suspicious_assignment_formatting, clippy::suspicious_command_arg_space, clippy::suspicious_doc_comments, clippy::suspicious_else_formatting, clippy::suspicious_map, clippy::suspicious_op_assign_impl, clippy::suspicious_open_options, clippy::suspicious_to_owned, clippy::suspicious_unary_op_formatting, clippy::swap_ptr_to_ref, clippy::test_attr_in_doctest, clippy::type_id_on_box, clippy::unconditional_recursion, clippy::unnecessary_result_map_or_else"##, + description: r##"lint group for: clippy::almost_complete_range, clippy::arc_with_non_send_sync, clippy::await_holding_invalid_type, clippy::await_holding_lock, clippy::await_holding_refcell_ref, clippy::blanket_clippy_restriction_lints, clippy::cast_abs_to_unsigned, clippy::cast_enum_constructor, clippy::cast_enum_truncation, clippy::cast_nan_to_int, clippy::cast_slice_from_raw_parts, clippy::crate_in_macro_def, clippy::deprecated_clippy_cfg_attr, clippy::drop_non_drop, clippy::duplicate_mod, clippy::empty_docs, clippy::empty_loop, clippy::float_equality_without_abs, clippy::forget_non_drop, clippy::four_forward_slashes, clippy::from_raw_with_void_ptr, clippy::incompatible_msrv, clippy::ineffective_open_options, clippy::iter_out_of_bounds, clippy::join_absolute_paths, clippy::let_underscore_future, clippy::lines_filter_map_ok, clippy::maybe_misused_cfg, clippy::misnamed_getters, clippy::misrefactored_assign_op, clippy::mixed_attributes_style, clippy::multi_assignments, clippy::multiple_bound_locations, clippy::mut_range_bound, clippy::mutable_key_type, clippy::no_effect_replace, clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, clippy::octal_escapes, clippy::path_ends_with_ext, clippy::permissions_set_readonly_false, clippy::print_in_format_impl, clippy::rc_clone_in_vec_init, clippy::repeat_vec_with_capacity, clippy::single_range_in_vec_init, clippy::size_of_ref, clippy::suspicious_arithmetic_impl, clippy::suspicious_assignment_formatting, clippy::suspicious_command_arg_space, clippy::suspicious_doc_comments, clippy::suspicious_else_formatting, clippy::suspicious_map, clippy::suspicious_op_assign_impl, clippy::suspicious_open_options, clippy::suspicious_to_owned, clippy::suspicious_unary_op_formatting, clippy::swap_ptr_to_ref, clippy::test_attr_in_doctest, clippy::type_id_on_box, clippy::unconditional_recursion, clippy::unnecessary_clippy_cfg, clippy::unnecessary_get_then_check, clippy::unnecessary_result_map_or_else"##, }, children: &[ "clippy::almost_complete_range", @@ -14277,8 +14513,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::cast_nan_to_int", "clippy::cast_slice_from_raw_parts", "clippy::crate_in_macro_def", + "clippy::deprecated_clippy_cfg_attr", "clippy::drop_non_drop", "clippy::duplicate_mod", + "clippy::empty_docs", "clippy::empty_loop", "clippy::float_equality_without_abs", "clippy::forget_non_drop", @@ -14293,7 +14531,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::maybe_misused_cfg", "clippy::misnamed_getters", "clippy::misrefactored_assign_op", + "clippy::mixed_attributes_style", "clippy::multi_assignments", + "clippy::multiple_bound_locations", "clippy::mut_range_bound", "clippy::mutable_key_type", "clippy::no_effect_replace", @@ -14321,6 +14561,8 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::test_attr_in_doctest", "clippy::type_id_on_box", "clippy::unconditional_recursion", + "clippy::unnecessary_clippy_cfg", + "clippy::unnecessary_get_then_check", "clippy::unnecessary_result_map_or_else", ], }, diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 3411133f50..e63717e35a 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -5434,13 +5434,62 @@ fn hover_feature() { The tracking issue for this feature is: None. - Intrinsics are never intended to be stable directly, but intrinsics are often + Intrinsics are rarely intended to be stable directly, but are usually exported in some sort of stable manner. Prefer using the stable interfaces to the intrinsic directly when you can. ------------------------ + ## Intrinsics with fallback logic + + Many intrinsics can be written in pure rust, albeit inefficiently or without supporting + some features that only exist on some backends. Backends can simply not implement those + intrinsics without causing any code miscompilations or failures to compile. + All intrinsic fallback bodies are automatically made cross-crate inlineable (like `#[inline]`) + by the codegen backend, but not the MIR inliner. + + ```rust + #![feature(rustc_attrs, effects)] + #![allow(internal_features)] + + #[rustc_intrinsic] + const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} + ``` + + Since these are just regular functions, it is perfectly ok to create the intrinsic twice: + + ```rust + #![feature(rustc_attrs, effects)] + #![allow(internal_features)] + + #[rustc_intrinsic] + const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} + + mod foo { + #[rustc_intrinsic] + const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) { + panic!("noisy const dealloc") + } + } + + ``` + + The behaviour on backends that override the intrinsic is exactly the same. On other + backends, the intrinsic behaviour depends on which implementation is called, just like + with any regular function. + + ## Intrinsics lowered to MIR instructions + + Various intrinsics have native MIR operations that they correspond to. Instead of requiring + backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass + will convert the calls to the MIR operation. Backends do not need to know about these intrinsics + at all. + + ## Intrinsics without fallback logic + + These must be implemented by all backends. + These are imported as if they were FFI functions, with the special `rust-intrinsic` ABI. For example, if one was in a freestanding context, but wished to be able to `transmute` between types, and @@ -5459,7 +5508,8 @@ fn hover_feature() { } ``` - As with any other FFI functions, these are always `unsafe` to call. + As with any other FFI functions, these are by default always `unsafe` to call. + You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call. "#]], )