summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates/ide-db
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@dend.ro>2024-03-10 08:47:38 +0200
committerLaurențiu Nicola <lnicola@dend.ro>2024-03-10 08:47:38 +0200
commit56493e4cbd6262adae03e73aefb8a9e618a9fc2d (patch)
tree404d4a38aff53e1c880c2708478fdcaf0b2f6e61 /src/tools/rust-analyzer/crates/ide-db
parent5bc7b9ac8ace5312e1d2cdc2722715cf58d4f926 (diff)
parent574e23ec508064613783cba3d1833a95fd9a5080 (diff)
downloadrust-56493e4cbd6262adae03e73aefb8a9e618a9fc2d.tar.gz
rust-56493e4cbd6262adae03e73aefb8a9e618a9fc2d.zip
Merge commit '574e23ec508064613783cba3d1833a95fd9a5080' into sync-from-ra
Diffstat (limited to 'src/tools/rust-analyzer/crates/ide-db')
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/Cargo.toml3
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs419
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/helpers.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/lib.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs58
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/tests/line_index.rs49
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/tests/sourcegen_lints.rs342
10 files changed, 361 insertions, 542 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
index b487b138fc0..071e1b47179 100644
--- a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
+++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs
index 2b2df144d6d..017635d88e7 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs
@@ -11,7 +11,7 @@ use profile::{memory_usage, Bytes};
 use rustc_hash::FxHashSet;
 use triomphe::Arc;
 
-use crate::{symbol_index::SymbolsDatabase, Change, RootDatabase};
+use crate::{symbol_index::SymbolsDatabase, ChangeWithProcMacros, RootDatabase};
 
 impl RootDatabase {
     pub fn request_cancellation(&mut self) {
@@ -20,7 +20,7 @@ impl RootDatabase {
         self.synthetic_write(Durability::LOW);
     }
 
-    pub fn apply_change(&mut self, change: Change) {
+    pub fn apply_change(&mut self, change: ChangeWithProcMacros) {
         let _p = tracing::span!(tracing::Level::INFO, "RootDatabase::apply_change").entered();
         self.request_cancellation();
         tracing::trace!("apply_change {:?}", change);
@@ -91,7 +91,6 @@ impl RootDatabase {
             crate::symbol_index::LocalRootsQuery
             crate::symbol_index::LibraryRootsQuery
             // HirDatabase
-            hir::db::InferQueryQuery
             hir::db::MirBodyQuery
             hir::db::BorrowckQuery
             hir::db::TyQuery
@@ -130,12 +129,10 @@ impl RootDatabase {
             hir::db::FnDefVarianceQuery
             hir::db::AdtVarianceQuery
             hir::db::AssociatedTyValueQuery
-            hir::db::TraitSolveQueryQuery
             hir::db::ProgramClausesForChalkEnvQuery
 
             // DefDatabase
             hir::db::FileItemTreeQuery
-            hir::db::CrateDefMapQueryQuery
             hir::db::BlockDefMapQuery
             hir::db::StructDataWithDiagnosticsQuery
             hir::db::UnionDataWithDiagnosticsQuery
@@ -165,7 +162,6 @@ impl RootDatabase {
             hir::db::FunctionVisibilityQuery
             hir::db::ConstVisibilityQuery
             hir::db::CrateSupportsNoStdQuery
-            hir::db::BlockItemTreeQueryQuery
             hir::db::ExternCrateDeclDataQuery
             hir::db::InternAnonymousConstQuery
             hir::db::InternExternCrateQuery
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
index 3329909e9da..d50088e6cf1 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
+++ b/src/tools/rust-analyzer/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 {
@@ -67,10 +71,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[
         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",
@@ -191,14 +187,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[
         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"##,
@@ -389,10 +378,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[
         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"##,
     },
@@ -483,6 +468,10 @@ pub const DEFAULT_LINTS: &[Lint] = &[
         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,6 +492,10 @@ pub const DEFAULT_LINTS: &[Lint] = &[
         description: r##"stable features found in `#[feature]` directive"##,
     },
     Lint {
+        label: "static_mut_refs",
+        description: r##"shared references or mutable references of mutable static is discouraged"##,
+    },
+    Lint {
         label: "suspicious_double_ref_op",
         description: r##"suspicious call of trait method on `&&T`"##,
     },
@@ -576,6 +569,10 @@ pub const DEFAULT_LINTS: &[Lint] = &[
     },
     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"##,
     },
@@ -606,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"##,
@@ -695,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",
@@ -732,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",
@@ -747,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",
@@ -764,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",
@@ -779,6 +768,7 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
             "unstable_syntax_pre_expansion",
             "unsupported_calling_conventions",
             "where_clauses_object_safety",
+            "writes_through_immutable_pointer",
         ],
     },
     LintGroup {
@@ -838,6 +828,13 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
     },
     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",
             description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##,
         },
@@ -1730,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 {
@@ -2376,17 +2381,6 @@ The tracking issue for this feature is: [#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
-
-------------------------
-"##,
-    },
-    Lint {
         label: "cfg_target_compact",
         description: r##"# `cfg_target_compact`
 
@@ -3132,6 +3126,17 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 "##,
     },
     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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "const_intrinsic_forget",
         description: r##"# `const_intrinsic_forget`
 
@@ -3300,6 +3305,17 @@ The tracking issue for this feature is: [#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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "const_option",
         description: r##"# `const_option`
 
@@ -3443,6 +3459,17 @@ The tracking issue for this feature is: [#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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "const_replace",
         description: r##"# `const_replace`
 
@@ -4255,6 +4282,15 @@ The tracking issue for this feature is: [#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.
+
+------------------------
+"##,
+    },
+    Lint {
         label: "deprecated_safe",
         description: r##"# `deprecated_safe`
 
@@ -4635,6 +4671,19 @@ The tracking issue for this feature is: [#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 {
         label: "duration_consts_float",
         description: r##"# `duration_consts_float`
 
@@ -4646,6 +4695,17 @@ The tracking issue for this feature is: [#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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "dyn_star",
         description: r##"# `dyn_star`
 
@@ -5654,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
@@ -5679,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 {
@@ -5758,6 +5868,17 @@ The tracking issue for this feature is: [#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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "is_sorted",
         description: r##"# `is_sorted`
 
@@ -5936,6 +6057,17 @@ The tracking issue for this feature is: [#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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "lang_items",
         description: r##"# `lang_items`
 
@@ -6259,6 +6391,17 @@ The tracking issue for this feature is: [#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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "log_syntax",
         description: r##"# `log_syntax`
 
@@ -6325,6 +6468,17 @@ The tracking issue for this feature is: [#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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "marker_trait_attr",
         description: r##"# `marker_trait_attr`
 
@@ -6538,17 +6692,6 @@ The tracking issue for this feature is: [#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
-
-------------------------
-"##,
-    },
-    Lint {
         label: "naked_functions",
         description: r##"# `naked_functions`
 
@@ -6976,6 +7119,17 @@ The tracking issue for this feature is: [#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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "os_str_slice",
         description: r##"# `os_str_slice`
 
@@ -7106,6 +7260,15 @@ The tracking issue for this feature is: [#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.
+
+------------------------
+"##,
+    },
+    Lint {
         label: "peer_credentials_unix_socket",
         description: r##"# `peer_credentials_unix_socket`
 
@@ -7128,17 +7291,6 @@ The tracking issue for this feature is: [#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
-
-------------------------
-"##,
-    },
-    Lint {
         label: "pointer_is_aligned",
         description: r##"# `pointer_is_aligned`
 
@@ -7184,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
 
 ------------------------
 "##,
@@ -7199,6 +7353,17 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 "##,
     },
     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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "print_internals",
         description: r##"# `print_internals`
 
@@ -7511,6 +7676,17 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 "##,
     },
     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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "register_tool",
         description: r##"# `register_tool`
 
@@ -8181,23 +8357,45 @@ This feature has no tracking issue, and is therefore likely internal to the comp
 "##,
     },
     Lint {
-        label: "stdio_makes_pipe",
-        description: r##"# `stdio_makes_pipe`
+        label: "stdarch_arm_feature_detection",
+        description: r##"# `stdarch_arm_feature_detection`
 
-The tracking issue for this feature is: [#98288]
+The tracking issue for this feature is: [#111190]
 
-[#98288]: https://github.com/rust-lang/rust/issues/98288
+[#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
 
 ------------------------
 "##,
     },
     Lint {
-        label: "stdsimd",
-        description: r##"# `stdsimd`
+        label: "stdio_makes_pipe",
+        description: r##"# `stdio_makes_pipe`
 
-The tracking issue for this feature is: [#48556]
+The tracking issue for this feature is: [#98288]
 
-[#48556]: https://github.com/rust-lang/rust/issues/48556
+[#98288]: https://github.com/rust-lang/rust/issues/98288
 
 ------------------------
 "##,
@@ -8463,6 +8661,17 @@ The tracking issue for this feature is: [#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
+
+------------------------
+"##,
+    },
+    Lint {
         label: "tcp_linger",
         description: r##"# `tcp_linger`
 
@@ -10151,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 {
@@ -10455,6 +10664,12 @@ See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-in
 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",
         description: r##"Checks for `#[deprecated]` annotations with a `since`
 field that is not a valid semantic version. Also allows TBD to signal
@@ -10596,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."##,
@@ -11352,6 +11568,7 @@ cannot be represented as the underlying type without loss."##,
         description: r##"Checks for usage of `std::mem::size_of::<T>() * 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."##,
@@ -11727,6 +11944,10 @@ rather than globally."##,
         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
 digits."##,
@@ -11759,6 +11980,10 @@ 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
 used."##,
@@ -12331,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",
@@ -12440,6 +12665,11 @@ do not change the type."##,
         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."##,
     },
@@ -13092,6 +13322,11 @@ as returning a large `T` directly may be detrimental to performance."##,
 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",
         description: r##"Checks for calls to `TryInto::try_into` and `TryFrom::try_from` when their infallible counterparts
 could be used."##,
@@ -13115,6 +13350,10 @@ 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::<Vec<String>>().join()` on iterators."##,
     },
@@ -13825,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",
@@ -13876,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",
@@ -13913,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",
@@ -14257,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",
@@ -14272,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",
@@ -14288,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",
@@ -14316,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/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
index 0b5ad7060e0..4ac8a7c4c4a 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
@@ -64,7 +64,7 @@ pub fn visit_file_defs(
     cb: &mut dyn FnMut(Definition),
 ) {
     let db = sema.db;
-    let module = match sema.to_module_def(file_id) {
+    let module = match sema.file_to_module_def(file_id) {
         Some(it) => it,
         None => return,
     };
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
index 3e6cb7476bb..be08b37bac3 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
@@ -44,7 +44,7 @@ pub mod syntax_helpers {
     pub use parser::LexedStr;
 }
 
-pub use hir::Change;
+pub use hir::ChangeWithProcMacros;
 
 use std::{fmt, mem::ManuallyDrop};
 
@@ -216,7 +216,6 @@ impl RootDatabase {
 
             // DefDatabase
             hir_db::FileItemTreeQuery
-            hir_db::CrateDefMapQueryQuery
             hir_db::BlockDefMapQuery
             hir_db::StructDataWithDiagnosticsQuery
             hir_db::UnionDataWithDiagnosticsQuery
@@ -248,7 +247,6 @@ impl RootDatabase {
             hir_db::CrateSupportsNoStdQuery
 
             // HirDatabase
-            hir_db::InferQueryQuery
             hir_db::MirBodyQuery
             hir_db::BorrowckQuery
             hir_db::TyQuery
@@ -287,7 +285,6 @@ impl RootDatabase {
             hir_db::FnDefVarianceQuery
             hir_db::AdtVarianceQuery
             hir_db::AssociatedTyValueQuery
-            hir_db::TraitSolveQueryQuery
             hir_db::ProgramClausesForChalkEnvQuery
 
             // SymbolsDatabase
@@ -412,9 +409,3 @@ impl SnippetCap {
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    mod line_index;
-    mod sourcegen_lints;
-}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
index ef15f585fa2..024e8f6ae39 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
@@ -129,7 +129,7 @@ pub fn parallel_prime_caches(
                 crates_currently_indexing.insert(crate_id, crate_name);
             }
             ParallelPrimeCacheWorkerProgress::EndCrate { crate_id } => {
-                crates_currently_indexing.remove(&crate_id);
+                crates_currently_indexing.swap_remove(&crate_id);
                 crates_to_prime.mark_done(crate_id);
                 crates_done += 1;
             }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs
index 49594aee9f3..8ab5a6ede3b 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs
@@ -11,15 +11,12 @@ pub enum Arg {
     Expr(String),
 }
 
-/**
- Add placeholders like `$1` and `$2` in place of [`Arg::Placeholder`],
- and unwraps the [`Arg::Ident`] and [`Arg::Expr`] enums.
- ```rust
- # use ide_db::syntax_helpers::format_string_exprs::*;
- assert_eq!(with_placeholders(vec![Arg::Ident("ident".to_owned()), Arg::Placeholder, Arg::Expr("expr + 2".to_owned())]), vec!["ident".to_owned(), "$1".to_owned(), "expr + 2".to_owned()])
- ```
-*/
-
+/// Add placeholders like `$1` and `$2` in place of [`Arg::Placeholder`],
+/// and unwraps the [`Arg::Ident`] and [`Arg::Expr`] enums.
+/// ```rust
+/// # use ide_db::syntax_helpers::format_string_exprs::*;
+/// assert_eq!(with_placeholders(vec![Arg::Ident("ident".to_owned()), Arg::Placeholder, Arg::Expr("expr + 2".to_owned())]), vec!["ident".to_owned(), "$1".to_owned(), "expr + 2".to_owned()])
+/// ```
 pub fn with_placeholders(args: Vec<Arg>) -> Vec<String> {
     let mut placeholder_id = 1;
     args.into_iter()
@@ -34,18 +31,15 @@ pub fn with_placeholders(args: Vec<Arg>) -> Vec<String> {
         .collect()
 }
 
-/**
- Parser for a format-like string. It is more allowing in terms of string contents,
- as we expect variable placeholders to be filled with expressions.
-
- Built for completions and assists, and escapes `\` and `$` in output.
- (See the comments on `get_receiver_text()` for detail.)
- Splits a format string that may contain expressions
- like
- ```rust
- assert_eq!(parse("{ident} {} {expr + 42} ").unwrap(), ("{} {} {}", vec![Arg::Ident("ident"), Arg::Placeholder, Arg::Expr("expr + 42")]));
- ```
-*/
+/// Parser for a format-like string. It is more allowing in terms of string contents,
+/// as we expect variable placeholders to be filled with expressions.
+///
+/// Splits a format string that may contain expressions
+/// like
+/// ```rust
+/// # use ide_db::syntax_helpers::format_string_exprs::*;
+/// assert_eq!(parse_format_exprs("{ident} {} {expr + 42} ").unwrap(), ("{ident} {} {} ".to_owned(), vec![Arg::Placeholder, Arg::Expr("expr + 42".to_owned())]));
+/// ```
 pub fn parse_format_exprs(input: &str) -> Result<(String, Vec<Arg>), ()> {
     #[derive(Debug, Clone, Copy, PartialEq)]
     enum State {
@@ -79,9 +73,6 @@ pub fn parse_format_exprs(input: &str) -> Result<(String, Vec<Arg>), ()> {
                 state = State::MaybeIncorrect;
             }
             (State::NotArg, _) => {
-                if matches!(chr, '\\' | '$') {
-                    output.push('\\');
-                }
                 output.push(chr);
             }
             (State::MaybeIncorrect, '}') => {
@@ -110,9 +101,6 @@ pub fn parse_format_exprs(input: &str) -> Result<(String, Vec<Arg>), ()> {
                 state = State::FormatOpts;
             }
             (State::MaybeArg, _) => {
-                if matches!(chr, '\\' | '$') {
-                    current_expr.push('\\');
-                }
                 current_expr.push(chr);
 
                 // While Rust uses the unicode sets of XID_start and XID_continue for Identifiers
@@ -172,9 +160,6 @@ pub fn parse_format_exprs(input: &str) -> Result<(String, Vec<Arg>), ()> {
                     state = State::Expr;
                 }
 
-                if matches!(chr, '\\' | '$') {
-                    current_expr.push('\\');
-                }
                 current_expr.push(chr);
             }
             (State::FormatOpts, '}') => {
@@ -182,9 +167,6 @@ pub fn parse_format_exprs(input: &str) -> Result<(String, Vec<Arg>), ()> {
                 state = State::NotArg;
             }
             (State::FormatOpts, _) => {
-                if matches!(chr, '\\' | '$') {
-                    output.push('\\');
-                }
                 output.push(chr);
             }
         }
@@ -217,15 +199,15 @@ mod tests {
     fn format_str_parser() {
         let test_vector = &[
             ("no expressions", expect![["no expressions"]]),
-            (r"no expressions with \$0$1", expect![r"no expressions with \\\$0\$1"]),
+            (r"no expressions with \$0$1", expect![r"no expressions with \$0$1"]),
             ("{expr} is {2 + 2}", expect![["{expr} is {}; 2 + 2"]]),
             ("{expr:?}", expect![["{expr:?}"]]),
-            ("{expr:1$}", expect![[r"{expr:1\$}"]]),
-            ("{:1$}", expect![[r"{:1\$}; $1"]]),
-            ("{:>padding$}", expect![[r"{:>padding\$}; $1"]]),
+            ("{expr:1$}", expect![[r"{expr:1$}"]]),
+            ("{:1$}", expect![[r"{:1$}; $1"]]),
+            ("{:>padding$}", expect![[r"{:>padding$}; $1"]]),
             ("{}, {}, {0}", expect![[r"{}, {}, {0}; $1, $2"]]),
             ("{}, {}, {0:b}", expect![[r"{}, {}, {0:b}; $1, $2"]]),
-            ("{$0}", expect![[r"{}; \$0"]]),
+            ("{$0}", expect![[r"{}; $0"]]),
             ("{malformed", expect![["-"]]),
             ("malformed}", expect![["-"]]),
             ("{{correct", expect![["{{correct"]]),
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs
index 0b0fc669352..97b6d4a572a 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs
@@ -20,7 +20,7 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode {
     let after = Position::after;
 
     let do_indent = |pos: fn(_) -> Position, token: &SyntaxToken, indent| {
-        (pos(token.clone()), make::tokens::whitespace(&" ".repeat(2 * indent)))
+        (pos(token.clone()), make::tokens::whitespace(&" ".repeat(4 * indent)))
     };
     let do_ws = |pos: fn(_) -> Position, token: &SyntaxToken| {
         (pos(token.clone()), make::tokens::single_space())
@@ -41,7 +41,7 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode {
                 if indent > 0 {
                     mods.push((
                         Position::after(node.clone()),
-                        make::tokens::whitespace(&" ".repeat(2 * indent)),
+                        make::tokens::whitespace(&" ".repeat(4 * indent)),
                     ));
                 }
                 if node.parent().is_some() {
@@ -91,10 +91,7 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode {
             LIFETIME_IDENT if is_next(is_text, true) => {
                 mods.push(do_ws(after, tok));
             }
-            MUT_KW if is_next(|it| it == SELF_KW, false) => {
-                mods.push(do_ws(after, tok));
-            }
-            AS_KW | DYN_KW | IMPL_KW | CONST_KW => {
+            AS_KW | DYN_KW | IMPL_KW | CONST_KW | MUT_KW => {
                 mods.push(do_ws(after, tok));
             }
             T![;] if is_next(|it| it != R_CURLY, true) => {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/tests/line_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/tests/line_index.rs
deleted file mode 100644
index 6b49bb2631c..00000000000
--- a/src/tools/rust-analyzer/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<char> = ((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/src/tools/rust-analyzer/crates/ide-db/src/tests/sourcegen_lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/tests/sourcegen_lints.rs
deleted file mode 100644
index 86ed01c8e74..00000000000
--- a/src/tools/rust-analyzer/crates/ide-db/src/tests/sourcegen_lints.rs
+++ /dev/null
@@ -1,342 +0,0 @@
-//! Generates descriptor structures for unstable features from the unstable book
-//! 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};
-
-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() {
-    let sh = &Shell::new().unwrap();
-
-    let rust_repo = project_root().join("./target/rust");
-    if rust_repo.exists() {
-        cmd!(sh, "git -C {rust_repo} pull --rebase").run().unwrap();
-    } else {
-        cmd!(sh, "git clone --depth=1 https://github.com/rust-lang/rust {rust_repo}")
-            .run()
-            .unwrap();
-    }
-    // need submodules for Cargo to parse the workspace correctly
-    cmd!(
-        sh,
-        "git -C {rust_repo} submodule update --init --recursive --depth=1 --
-         compiler library src/tools"
-    )
-    .run()
-    .unwrap();
-
-    let mut contents = String::from(
-        r"
-#[derive(Clone)]
-pub struct Lint {
-    pub label: &'static str,
-    pub description: &'static str,
-}
-
-pub struct LintGroup {
-    pub lint: Lint,
-    pub children: &'static [&'static str],
-}
-
-",
-    );
-
-    generate_lint_descriptor(sh, &mut contents);
-    contents.push('\n');
-
-    let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned());
-    let unstable_book = project_root().join("./target/unstable-book-gen");
-    cmd!(
-        sh,
-        "{cargo} run --manifest-path {rust_repo}/src/tools/unstable-book-gen/Cargo.toml --
-         {rust_repo}/library {rust_repo}/compiler {rust_repo}/src {unstable_book}"
-    )
-    .run()
-    .unwrap();
-    generate_feature_descriptor(&mut contents, &unstable_book.join("src"));
-    contents.push('\n');
-
-    let lints_json = project_root().join("./target/clippy_lints.json");
-    cmd!(
-        sh,
-        "curl https://rust-lang.github.io/rust-clippy/master/lints.json --output {lints_json}"
-    )
-    .run()
-    .unwrap();
-    generate_descriptor_clippy(&mut contents, &lints_json);
-
-    let contents = sourcegen::add_preamble("sourcegen_lints", sourcegen::reformat(contents));
-
-    let destination = project_root().join(DESTINATION);
-    sourcegen::ensure_file_contents(destination.as_path(), &contents);
-}
-
-/// Parses the output of `rustdoc -Whelp` and prints `Lint` and `LintGroup` constants into `buf`.
-///
-/// As of writing, the output of `rustc -Whelp` (not rustdoc) has the following format:
-///
-/// ```text
-/// Lint checks provided by rustc:
-///
-/// name  default  meaning
-/// ----  -------  -------
-///
-/// ...
-///
-/// Lint groups provided by rustc:
-///
-/// name  sub-lints
-/// ----  ---------
-///
-/// ...
-/// ```
-///
-/// `rustdoc -Whelp` (and any other custom `rustc` driver) adds another two
-/// tables after the `rustc` ones, with a different title but the same format.
-fn generate_lint_descriptor(sh: &Shell, buf: &mut String) {
-    let stdout = cmd!(sh, "rustdoc -Whelp").read().unwrap();
-    let lints_pat = "----  -------  -------\n";
-    let lint_groups_pat = "----  ---------\n";
-    let lints = find_and_slice(&stdout, lints_pat);
-    let lint_groups = find_and_slice(lints, lint_groups_pat);
-    let lints_rustdoc = find_and_slice(lint_groups, lints_pat);
-    let lint_groups_rustdoc = find_and_slice(lints_rustdoc, lint_groups_pat);
-
-    buf.push_str(r#"pub const DEFAULT_LINTS: &[Lint] = &["#);
-    buf.push('\n');
-
-    let lints = lints.lines().take_while(|l| !l.is_empty()).map(|line| {
-        let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap();
-        let (_default_level, description) = rest.trim().split_once(char::is_whitespace).unwrap();
-        (name.trim(), Cow::Borrowed(description.trim()), vec![])
-    });
-    let lint_groups = lint_groups.lines().take_while(|l| !l.is_empty()).map(|line| {
-        let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap();
-        (
-            name.trim(),
-            format!("lint group for: {}", lints.trim()).into(),
-            lints
-                .split_ascii_whitespace()
-                .map(|s| s.trim().trim_matches(',').replace('-', "_"))
-                .collect(),
-        )
-    });
-
-    let lints = lints
-        .chain(lint_groups)
-        .sorted_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2))
-        .collect::<Vec<_>>();
-    for (name, description, ..) in &lints {
-        push_lint_completion(buf, &name.replace('-', "_"), description);
-    }
-    buf.push_str("];\n\n");
-
-    buf.push_str(r#"pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &["#);
-    for (name, description, children) in &lints {
-        if !children.is_empty() {
-            // HACK: warnings is emitted with a general description, not with its members
-            if name == &"warnings" {
-                push_lint_group(buf, name, description, &Vec::new());
-                continue;
-            }
-            push_lint_group(buf, &name.replace('-', "_"), description, children);
-        }
-    }
-    buf.push('\n');
-    buf.push_str("];\n");
-
-    // rustdoc
-
-    buf.push('\n');
-    buf.push_str(r#"pub const RUSTDOC_LINTS: &[Lint] = &["#);
-    buf.push('\n');
-
-    let lints_rustdoc = lints_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| {
-        let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap();
-        let (_default_level, description) = rest.trim().split_once(char::is_whitespace).unwrap();
-        (name.trim(), Cow::Borrowed(description.trim()), vec![])
-    });
-    let lint_groups_rustdoc =
-        lint_groups_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| {
-            let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap();
-            (
-                name.trim(),
-                format!("lint group for: {}", lints.trim()).into(),
-                lints
-                    .split_ascii_whitespace()
-                    .map(|s| s.trim().trim_matches(',').replace('-', "_"))
-                    .collect(),
-            )
-        });
-
-    let lints_rustdoc = lints_rustdoc
-        .chain(lint_groups_rustdoc)
-        .sorted_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2))
-        .collect::<Vec<_>>();
-
-    for (name, description, ..) in &lints_rustdoc {
-        push_lint_completion(buf, &name.replace('-', "_"), description)
-    }
-    buf.push_str("];\n\n");
-
-    buf.push_str(r#"pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &["#);
-    for (name, description, children) in &lints_rustdoc {
-        if !children.is_empty() {
-            push_lint_group(buf, &name.replace('-', "_"), description, children);
-        }
-    }
-    buf.push('\n');
-    buf.push_str("];\n");
-}
-
-#[track_caller]
-fn find_and_slice<'a>(i: &'a str, p: &str) -> &'a str {
-    let idx = i.find(p).unwrap();
-    &i[idx + p.len()..]
-}
-
-/// Parses the unstable book `src_dir` and prints a constant with the list of
-/// unstable features into `buf`.
-///
-/// It does this by looking for all `.md` files in the `language-features` and
-/// `library-features` directories, and using the file name as the feature
-/// name, and the file contents as the feature description.
-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)))
-        // Get all `.md` files
-        .filter(|path| path.extension() == Some("md".as_ref()))
-        .map(|path| {
-            let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace('-', "_");
-            let doc = fs::read_to_string(path).unwrap();
-            (feature_ident, doc)
-        })
-        .collect::<Vec<_>>();
-    features.sort_by(|(feature_ident, _), (feature_ident2, _)| feature_ident.cmp(feature_ident2));
-
-    buf.push_str(r#"pub const FEATURES: &[Lint] = &["#);
-    for (feature_ident, doc) in features.into_iter() {
-        push_lint_completion(buf, &feature_ident, &doc)
-    }
-    buf.push('\n');
-    buf.push_str("];\n");
-}
-
-#[derive(Default)]
-struct ClippyLint {
-    help: String,
-    id: String,
-}
-
-fn unescape(s: &str) -> String {
-    s.replace(r#"\""#, "").replace(r#"\n"#, "\n").replace(r#"\r"#, "")
-}
-
-#[allow(clippy::print_stderr)]
-fn generate_descriptor_clippy(buf: &mut String, path: &Path) {
-    let file_content = std::fs::read_to_string(path).unwrap();
-    let mut clippy_lints: Vec<ClippyLint> = Vec::new();
-    let mut clippy_groups: std::collections::BTreeMap<String, Vec<String>> = Default::default();
-
-    for line in file_content.lines().map(str::trim) {
-        if let Some(line) = line.strip_prefix(r#""id": ""#) {
-            let clippy_lint = ClippyLint {
-                id: line.strip_suffix(r#"","#).expect("should be suffixed by comma").into(),
-                help: String::new(),
-            };
-            clippy_lints.push(clippy_lint)
-        } else if let Some(line) = line.strip_prefix(r#""group": ""#) {
-            if let Some(group) = line.strip_suffix("\",") {
-                clippy_groups
-                    .entry(group.to_owned())
-                    .or_default()
-                    .push(clippy_lints.last().unwrap().id.clone());
-            }
-        } else if let Some(line) = line.strip_prefix(r#""docs": ""#) {
-            let header = "### What it does";
-            let line = match line.find(header) {
-                Some(idx) => &line[idx + header.len()..],
-                None => {
-                    let id = &clippy_lints.last().unwrap().id;
-                    // these just don't have the common header
-                    let allowed = ["allow_attributes", "read_line_without_trim"];
-                    if allowed.contains(&id.as_str()) {
-                        line
-                    } else {
-                        eprintln!("\nunexpected clippy prefix for {id}, line={line:?}\n",);
-                        continue;
-                    }
-                }
-            };
-            // Only take the description, any more than this is a lot of additional data we would embed into the exe
-            // which seems unnecessary
-            let up_to = line.find(r#"###"#).expect("no second section found?");
-            let line = &line[..up_to];
-
-            let clippy_lint = clippy_lints.last_mut().expect("clippy lint must already exist");
-            clippy_lint.help = unescape(line).trim().to_owned();
-        }
-    }
-    clippy_lints.sort_by(|lint, lint2| lint.id.cmp(&lint2.id));
-
-    buf.push_str(r#"pub const CLIPPY_LINTS: &[Lint] = &["#);
-    buf.push('\n');
-    for clippy_lint in clippy_lints.into_iter() {
-        let lint_ident = format!("clippy::{}", clippy_lint.id);
-        let doc = clippy_lint.help;
-        push_lint_completion(buf, &lint_ident, &doc);
-    }
-    buf.push_str("];\n");
-
-    buf.push_str(r#"pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &["#);
-    for (id, children) in clippy_groups {
-        let children = children.iter().map(|id| format!("clippy::{id}")).collect::<Vec<_>>();
-        if !children.is_empty() {
-            let lint_ident = format!("clippy::{id}");
-            let description = format!("lint group for: {}", children.iter().join(", "));
-            push_lint_group(buf, &lint_ident, &description, &children);
-        }
-    }
-    buf.push('\n');
-    buf.push_str("];\n");
-}
-
-fn push_lint_completion(buf: &mut String, label: &str, description: &str) {
-    format_to!(
-        buf,
-        r###"    Lint {{
-        label: "{}",
-        description: r##"{}"##,
-    }},"###,
-        label,
-        description,
-    );
-}
-
-fn push_lint_group(buf: &mut String, label: &str, description: &str, children: &[String]) {
-    buf.push_str(
-        r###"    LintGroup {
-        lint:
-        "###,
-    );
-
-    push_lint_completion(buf, label, description);
-
-    let children = format!("&[{}]", children.iter().map(|it| format!("\"{it}\"")).join(", "));
-    format_to!(
-        buf,
-        r###"
-        children: {},
-        }},"###,
-        children,
-    );
-}