about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock18
-rw-r--r--compiler/rustc_parse/src/parser/item.rs18
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs38
-rw-r--r--compiler/rustc_resolve/src/imports.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs67
-rw-r--r--src/bootstrap/Cargo.lock8
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css4
-rw-r--r--src/test/rustdoc-gui/search-result-color.goml943
-rw-r--r--src/test/ui/closures/multiple-fn-bounds.rs15
-rw-r--r--src/test/ui/closures/multiple-fn-bounds.stderr24
-rw-r--r--src/test/ui/extenv/issue-55897.stderr5
-rw-r--r--src/test/ui/imports/issue-56125.stderr12
-rw-r--r--src/test/ui/imports/issue-57015.stderr5
-rw-r--r--src/test/ui/parser/removed-syntax-field-let.stderr10
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/not-allowed.stderr7
-rw-r--r--src/test/ui/simd/portable-intrinsics-arent-exposed.stderr5
-rw-r--r--src/test/ui/test-attrs/inaccessible-test-modules.stderr14
-rw-r--r--src/test/ui/unresolved/unresolved-candidates.rs13
-rw-r--r--src/test/ui/unresolved/unresolved-candidates.stderr26
-rw-r--r--src/tools/rust-analyzer/Cargo.lock8
-rw-r--r--src/tools/tidy/src/deps.rs10
23 files changed, 538 insertions, 743 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3b8d0d87f2a..db166cf0c51 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2721,11 +2721,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.37"
+version = "1.0.46"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
+checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
 dependencies = [
- "unicode-xid",
+ "unicode-ident",
 ]
 
 [[package]]
@@ -4719,13 +4719,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
 [[package]]
 name = "syn"
-version = "1.0.91"
+version = "1.0.102"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
+checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
 dependencies = [
  "proc-macro2",
  "quote",
- "unicode-xid",
+ "unicode-ident",
 ]
 
 [[package]]
@@ -5216,6 +5216,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
 name = "unicode-normalization"
 version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 25425fbb2c6..e82044a89c4 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1788,7 +1788,23 @@ impl<'a> Parser<'a> {
                     }
                 }
             } else {
-                self.expected_ident_found()
+                let mut err = self.expected_ident_found();
+                if let Some((ident, _)) = self.token.ident() && ident.as_str() == "let" {
+                    self.bump(); // `let`
+                    let span = self.prev_token.span.until(self.token.span);
+                    err.span_suggestion(
+                        span,
+                        "remove the let, the `let` keyword is not allowed in struct field definitions",
+                        String::new(),
+                        Applicability::MachineApplicable,
+                    );
+                    err.note("the `let` keyword is not allowed in `struct` fields");
+                    err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
+                    err.emit();
+                    self.bump();
+                    return Ok(ident);
+                }
+                err
             };
             return Err(err);
         }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 98982240af2..9a3eac2f866 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -70,6 +70,7 @@ impl TypoSuggestion {
 }
 
 /// A free importable items suggested in case of resolution failure.
+#[derive(Debug, Clone)]
 pub(crate) struct ImportSuggestion {
     pub did: Option<DefId>,
     pub descr: &'static str,
@@ -139,6 +140,7 @@ impl<'a> Resolver<'a> {
                     if instead { Instead::Yes } else { Instead::No },
                     found_use,
                     IsPattern::No,
+                    IsImport::No,
                     path,
                 );
                 err.emit();
@@ -698,6 +700,7 @@ impl<'a> Resolver<'a> {
                         Instead::No,
                         FoundUse::Yes,
                         IsPattern::Yes,
+                        IsImport::No,
                         vec![],
                     );
                 }
@@ -1481,6 +1484,7 @@ impl<'a> Resolver<'a> {
             Instead::No,
             FoundUse::Yes,
             IsPattern::No,
+            IsImport::No,
             vec![],
         );
 
@@ -2449,6 +2453,34 @@ enum IsPattern {
     No,
 }
 
+/// Whether a binding is part of a use statement. Used for diagnostics.
+enum IsImport {
+    Yes,
+    No,
+}
+
+pub(crate) fn import_candidates(
+    session: &Session,
+    source_span: &IndexVec<LocalDefId, Span>,
+    err: &mut Diagnostic,
+    // This is `None` if all placement locations are inside expansions
+    use_placement_span: Option<Span>,
+    candidates: &[ImportSuggestion],
+) {
+    show_candidates(
+        session,
+        source_span,
+        err,
+        use_placement_span,
+        candidates,
+        Instead::Yes,
+        FoundUse::Yes,
+        IsPattern::No,
+        IsImport::Yes,
+        vec![],
+    );
+}
+
 /// When an entity with a given name is not available in scope, we search for
 /// entities with that name in all crates. This method allows outputting the
 /// results of this search in a programmer-friendly way
@@ -2462,6 +2494,7 @@ fn show_candidates(
     instead: Instead,
     found_use: FoundUse,
     is_pattern: IsPattern,
+    is_import: IsImport,
     path: Vec<Segment>,
 ) {
     if candidates.is_empty() {
@@ -2521,7 +2554,8 @@ fn show_candidates(
                 // produce an additional newline to separate the new use statement
                 // from the directly following item.
                 let additional_newline = if let FoundUse::Yes = found_use { "" } else { "\n" };
-                candidate.0 = format!("use {};\n{}", &candidate.0, additional_newline);
+                let add_use = if let IsImport::Yes = is_import { "" } else { "use " };
+                candidate.0 = format!("{}{};\n{}", add_use, &candidate.0, additional_newline);
             }
 
             err.span_suggestions(
@@ -2551,7 +2585,7 @@ fn show_candidates(
 
             err.note(&msg);
         }
-    } else {
+    } else if matches!(is_import, IsImport::No) {
         assert!(!inaccessible_path_strings.is_empty());
 
         let prefix =
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 5bdb4274781..9e2234ae4a5 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -1,9 +1,9 @@
 //! A bunch of methods and structures more or less related to resolving imports.
 
-use crate::diagnostics::Suggestion;
+use crate::diagnostics::{import_candidates, Suggestion};
 use crate::Determinacy::{self, *};
 use crate::Namespace::{self, *};
-use crate::{module_to_string, names_to_string};
+use crate::{module_to_string, names_to_string, ImportSuggestion};
 use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
 use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
 use crate::{NameBinding, NameBindingKind, PathResult};
@@ -406,6 +406,7 @@ struct UnresolvedImportError {
     label: Option<String>,
     note: Option<String>,
     suggestion: Option<Suggestion>,
+    candidate: Option<Vec<ImportSuggestion>>,
 }
 
 pub struct ImportResolver<'a, 'b> {
@@ -497,6 +498,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     label: None,
                     note: None,
                     suggestion: None,
+                    candidate: None,
                 };
                 if path.contains("::") {
                     errors.push((path, err))
@@ -547,6 +549,16 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 }
                 diag.multipart_suggestion(&msg, suggestions, applicability);
             }
+
+            if let Some(candidate) = &err.candidate {
+                import_candidates(
+                    self.r.session,
+                    &self.r.source_span,
+                    &mut diag,
+                    Some(err.span),
+                    &candidate,
+                )
+            }
         }
 
         diag.emit();
@@ -664,6 +676,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             Some(finalize),
             ignore_binding,
         );
+
         let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
         import.vis.set(orig_vis);
         let module = match path_res {
@@ -706,12 +719,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                                 String::from("a similar path exists"),
                                 Applicability::MaybeIncorrect,
                             )),
+                            candidate: None,
                         },
                         None => UnresolvedImportError {
                             span,
                             label: Some(label),
                             note: None,
                             suggestion,
+                            candidate: None,
                         },
                     };
                     return Some(err);
@@ -754,6 +769,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                             label: Some(String::from("cannot glob-import a module into itself")),
                             note: None,
                             suggestion: None,
+                            candidate: None,
                         });
                     }
                 }
@@ -919,11 +935,19 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     }
                 };
 
+                let parent_suggestion =
+                    self.r.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true);
+
                 Some(UnresolvedImportError {
                     span: import.span,
                     label: Some(label),
                     note,
                     suggestion,
+                    candidate: if !parent_suggestion.is_empty() {
+                        Some(parent_suggestion)
+                    } else {
+                        None
+                    },
                 })
             } else {
                 // `resolve_ident_in_module` reported a privacy error.
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 490b0e86322..4e8baa2dfab 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1255,6 +1255,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         found_span,
                         found_trait_ref,
                         expected_trait_ref,
+                        obligation.cause.code(),
                     )
                 } else {
                     let (closure_span, found) = found_did
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 980e85b4526..fda6a2236b1 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -254,8 +254,15 @@ pub trait TypeErrCtxtExt<'tcx> {
         found_span: Option<Span>,
         found: ty::PolyTraitRef<'tcx>,
         expected: ty::PolyTraitRef<'tcx>,
+        cause: &ObligationCauseCode<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
 
+    fn note_conflicting_closure_bounds(
+        &self,
+        cause: &ObligationCauseCode<'tcx>,
+        err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+    );
+
     fn suggest_fully_qualified_path(
         &self,
         err: &mut Diagnostic,
@@ -1584,6 +1591,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         found_span: Option<Span>,
         found: ty::PolyTraitRef<'tcx>,
         expected: ty::PolyTraitRef<'tcx>,
+        cause: &ObligationCauseCode<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         pub(crate) fn build_fn_sig_ty<'tcx>(
             infcx: &InferCtxt<'tcx>,
@@ -1645,9 +1653,68 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let signature_kind = format!("{argument_kind} signature");
         err.note_expected_found(&signature_kind, expected_str, &signature_kind, found_str);
 
+        self.note_conflicting_closure_bounds(cause, &mut err);
+
         err
     }
 
+    // Add a note if there are two `Fn`-family bounds that have conflicting argument
+    // requirements, which will always cause a closure to have a type error.
+    fn note_conflicting_closure_bounds(
+        &self,
+        cause: &ObligationCauseCode<'tcx>,
+        err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+    ) {
+        // First, look for an `ExprBindingObligation`, which means we can get
+        // the unsubstituted predicate list of the called function. And check
+        // that the predicate that we failed to satisfy is a `Fn`-like trait.
+        if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = cause
+            && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
+            && let Some(pred) = predicates.predicates.get(*idx)
+            && let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder()
+            && ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id()).is_some()
+        {
+            let expected_self =
+                self.tcx.anonymize_late_bound_regions(pred.kind().rebind(trait_pred.self_ty()));
+            let expected_substs = self
+                .tcx
+                .anonymize_late_bound_regions(pred.kind().rebind(trait_pred.trait_ref.substs));
+
+            // Find another predicate whose self-type is equal to the expected self type,
+            // but whose substs don't match.
+            let other_pred = std::iter::zip(&predicates.predicates, &predicates.spans)
+                .enumerate()
+                .find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
+                    ty::PredicateKind::Trait(trait_pred)
+                        if ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id())
+                            .is_some()
+                            && other_idx != idx
+                            // Make sure that the self type matches
+                            // (i.e. constraining this closure)
+                            && expected_self
+                                == self.tcx.anonymize_late_bound_regions(
+                                    pred.kind().rebind(trait_pred.self_ty()),
+                                )
+                            // But the substs don't match (i.e. incompatible args)
+                            && expected_substs
+                                != self.tcx.anonymize_late_bound_regions(
+                                    pred.kind().rebind(trait_pred.trait_ref.substs),
+                                ) =>
+                    {
+                        true
+                    }
+                    _ => false,
+                });
+            // If we found one, then it's very likely the cause of the error.
+            if let Some((_, (_, other_pred_span))) = other_pred {
+                err.span_note(
+                    *other_pred_span,
+                    "closure inferred to have a different signature due to this bound",
+                );
+            }
+        }
+    }
+
     fn suggest_fully_qualified_path(
         &self,
         err: &mut Diagnostic,
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 84c06fdce70..baecca44cd9 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -445,9 +445,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.39"
+version = "1.0.46"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
+checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
 dependencies = [
  "unicode-ident",
 ]
@@ -596,9 +596,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "1.0.95"
+version = "1.0.102"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
+checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index d33c3a2128b..e96a87111cb 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.12.0
\ No newline at end of file
+0.12.2
\ No newline at end of file
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index eb64147d906..d4228a2ebc6 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -734,9 +734,7 @@ a {
 	display: initial;
 }
 
-.impl:hover > .anchor, .method.trait-impl:hover > .anchor,
-.type.trait-impl:hover > .anchor, .associatedconstant.trait-impl:hover > .anchor,
-.associatedtype.trait-impl:hover > .anchor {
+.impl:hover > .anchor, .trait-impl:hover > .anchor {
 	display: inline-block;
 	position: absolute;
 }
diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml
index bb781837783..69bb30df954 100644
--- a/src/test/rustdoc-gui/search-result-color.goml
+++ b/src/test/rustdoc-gui/search-result-color.goml
@@ -1,4 +1,57 @@
 // The goal of this test is to ensure the color of the text is the one expected.
+
+define-function: (
+    "check-result-color",
+    (result_kind, color, hover_color),
+    [
+        (
+            "assert-css",
+            (".result-" + |result_kind| + " ." + |result_kind|, {"color": |color|}, ALL),
+        ),
+        (
+            "assert-css",
+            (
+                ".result-" + |result_kind|,
+                {"color": |entry_color|, "background-color": |background_color|},
+            ),
+        ),
+        (
+            "move-cursor-to",
+            ".result-" + |result_kind|,
+        ),
+        (
+            "assert-css",
+            (
+                ".result-" + |result_kind| + ":hover",
+                {"color": |hover_entry_color|, "background-color": |hover_background_color|},
+            ),
+        ),
+        (
+            "assert-css",
+            (".result-" + |result_kind| + ":hover ." + |result_kind|, {"color": |hover_color|}),
+        ),
+        (
+            "move-cursor-to",
+            ".search-input",
+        ),
+        (
+            "focus",
+            ".result-" + |result_kind|,
+        ),
+        (
+            "assert-css",
+            (
+                ".result-" + |result_kind| + ":focus",
+                {"color": |hover_entry_color|, "background-color": |hover_background_color|},
+            ),
+        ),
+        (
+            "assert-css",
+            (".result-" + |result_kind| + ":focus ." + |result_kind|, {"color": |hover_color|}),
+        ),
+    ],
+)
+
 goto: "file://" + |DOC_PATH| + "/test_docs/index.html?search=coo"
 
 // This is needed so that the text color is computed.
@@ -28,240 +81,66 @@ assert-css: (
     {"color": "rgb(120, 135, 151)"},
 )
 
-// Checking the color of "keyword".
-assert-css: (
-    ".result-keyword .keyword",
-    {"color": "rgb(57, 175, 215)"},
-    ALL,
-)
-assert-css: (
-    ".result-keyword",
-    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-keyword"
-assert-css: (
-    ".result-keyword:hover",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-keyword:hover .keyword",
-    {"color": "rgb(57, 175, 215)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-keyword"
-assert-css: (
-    ".result-keyword:focus",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-keyword:focus .keyword",
-    {"color": "rgb(57, 175, 215)"},
-)
-
-// Check the color of "struct".
-assert-css: (
-    ".result-struct .struct",
-    {"color": "rgb(255, 160, 165)"},
-    ALL,
-)
-assert-css: (
-    ".result-struct",
-    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-struct"
-assert-css: (
-    ".result-struct:hover",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-struct:hover .struct",
-    {"color": "rgb(255, 160, 165)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-struct"
-assert-css: (
-    ".result-struct:focus",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-struct:focus .struct",
-    {"color": "rgb(255, 160, 165)"},
-)
-
-// Check the color of "associated type".
-assert-css: (
-    ".result-associatedtype .associatedtype",
-    {"color": "rgb(57, 175, 215)"},
-    ALL,
-)
-assert-css: (
-    ".result-associatedtype",
-    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-associatedtype"
-assert-css: (
-    ".result-associatedtype:hover",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-associatedtype:hover .associatedtype",
-    {"color": "rgb(57, 175, 215)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-associatedtype"
-assert-css: (
-    ".result-associatedtype:focus",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-associatedtype:focus .associatedtype",
-    {"color": "rgb(57, 175, 215)"},
-)
-
-// Check the color of "type method".
-assert-css: (
-    ".result-tymethod .tymethod",
-    {"color": "rgb(253, 214, 135)"},
-    ALL,
-)
-assert-css: (
-    ".result-tymethod",
-    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-assert-css: (
-    ".result-tymethod .tymethod",
-    {"color": "rgb(253, 214, 135)"},
-)
-move-cursor-to: ".result-tymethod"
-assert-css: (
-    ".result-tymethod:hover",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-tymethod"
-assert-css: (
-    ".result-tymethod:focus",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-
-// Check the color of "method".
-assert-css: (
-    ".result-method .method",
-    {"color": "rgb(253, 214, 135)"},
-    ALL,
-)
-assert-css: (
-    ".result-method",
-    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-method"
-assert-css: (
-    ".result-method:hover",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-method:hover .method",
-    {"color": "rgb(253, 214, 135)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-method"
-assert-css: (
-    ".result-method:focus",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-method:focus .method",
-    {"color": "rgb(253, 214, 135)"},
-)
-
-// Check the color of "struct field".
-assert-css: (
-    ".result-structfield .structfield",
-    {"color": "rgb(0, 150, 207)"},
-    ALL,
-)
-assert-css: (
-    ".result-structfield",
-    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-structfield"
-assert-css: (
-    ".result-structfield:hover",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-structfield:hover .structfield",
-    {"color": "rgb(255, 255, 255)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-structfield"
-assert-css: (
-    ".result-structfield:focus",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-structfield:focus .structfield",
-    {"color": "rgb(255, 255, 255)"},
-)
-
-// Check the color of "macro".
-assert-css: (
-    ".result-macro .macro",
-    {"color": "rgb(163, 122, 204)"},
-    ALL,
-)
-assert-css: (
-    ".result-macro",
-    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-macro"
-assert-css: (
-    ".result-macro:hover",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-macro:hover .macro",
-    {"color": "rgb(163, 122, 204)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-macro"
-assert-css: (
-    ".result-macro:focus",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-macro:focus .macro",
-    {"color": "rgb(163, 122, 204)"},
-)
-
-// Check the color of "fn".
-assert-css: (
-    ".result-fn .fn",
-    {"color": "rgb(253, 214, 135)"},
-    ALL,
-)
-assert-css: (
-    ".result-fn",
-    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-fn"
-assert-css: (
-    ".result-fn:hover",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-fn:hover .fn",
-    {"color": "rgb(253, 214, 135)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-fn"
-assert-css: (
-    ".result-fn:focus",
-    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
-)
-assert-css: (
-    ".result-fn:focus .fn",
-    {"color": "rgb(253, 214, 135)"},
+store-value: (entry_color, "rgb(0, 150, 207)") // color of the search entry
+store-value: (hover_entry_color, "rgb(255, 255, 255)") // color of the hovered/focused search entry
+store-value: (background_color, "rgba(0, 0, 0, 0)") // background color
+store-value: (hover_background_color, "rgb(60, 60, 60)") // hover background color
+
+call-function: (
+    "check-result-color", (
+        "keyword", // item kind
+        "rgb(57, 175, 215)", // color of item kind
+        "rgb(57, 175, 215)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "struct", // item kind
+        "rgb(255, 160, 165)", // color of item kind
+        "rgb(255, 160, 165)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "associatedtype", // item kind
+        "rgb(57, 175, 215)", // color of item kind
+        "rgb(57, 175, 215)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "tymethod", // item kind
+        "rgb(253, 214, 135)", // color of item kind
+        "rgb(253, 214, 135)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "method", // item kind
+        "rgb(253, 214, 135)", // color of item kind
+        "rgb(253, 214, 135)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "structfield", // item kind
+        "rgb(0, 150, 207)", // color of item kind
+        "rgb(255, 255, 255)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "macro", // item kind
+        "rgb(163, 122, 204)", // color of item kind
+        "rgb(163, 122, 204)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "fn", // item kind
+        "rgb(253, 214, 135)", // color of item kind
+        "rgb(253, 214, 135)", // color of hovered/focused item kind
+    ),
 )
 
 // Checking the `<a>` container.
@@ -308,244 +187,66 @@ assert-css: (
     {"color": "rgb(221, 221, 221)"},
 )
 
-// Checking the color of "keyword".
-assert-css: (
-    ".result-keyword .keyword",
-    {"color": "rgb(210, 153, 29)"},
-    ALL,
-)
-assert-css: (
-    ".result-keyword",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-keyword"
-assert-css: (
-    ".result-keyword:hover",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-keyword:hover .keyword",
-    {"color": "rgb(210, 153, 29)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-keyword"
-assert-css: (
-    ".result-keyword:focus",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-keyword:focus .keyword",
-    {"color": "rgb(210, 153, 29)"},
-)
-
-// Check the color of "struct".
-assert-css: (
-    ".result-struct .struct",
-    {"color": "rgb(45, 191, 184)"},
-    ALL,
-)
-assert-css: (
-    ".result-struct",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-struct"
-assert-css: (
-    ".result-struct:hover",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-struct:hover .struct",
-    {"color": "rgb(45, 191, 184)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-struct"
-assert-css: (
-    ".result-struct:focus",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-struct:focus .struct",
-    {"color": "rgb(45, 191, 184)"},
-)
-
-// Check the color of "associated type".
-assert-css: (
-    ".result-associatedtype .associatedtype",
-    {"color": "rgb(210, 153, 29)"},
-    ALL,
-)
-assert-css: (
-    ".result-associatedtype",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-associatedtype"
-assert-css: (
-    ".result-associatedtype:hover",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-associatedtype:hover .associatedtype",
-    {"color": "rgb(210, 153, 29)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-associatedtype"
-assert-css: (
-    ".result-associatedtype:focus",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-associatedtype:focus .associatedtype",
-    {"color": "rgb(210, 153, 29)"},
-)
-
-// Check the color of "type method".
-assert-css: (
-    ".result-tymethod .tymethod",
-    {"color": "rgb(43, 171, 99)"},
-    ALL,
-)
-assert-css: (
-    ".result-tymethod",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-tymethod"
-assert-css: (
-    ".result-tymethod:hover",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-tymethod:hover .tymethod",
-    {"color": "rgb(43, 171, 99)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-tymethod"
-assert-css: (
-    ".result-tymethod:focus",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-tymethod:focus .tymethod",
-    {"color": "rgb(43, 171, 99)"},
-)
-
-// Check the color of "method".
-assert-css: (
-    ".result-method .method",
-    {"color": "rgb(43, 171, 99)"},
-    ALL,
-)
-assert-css: (
-    ".result-method",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-method"
-assert-css: (
-    ".result-method:hover",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-method:hover .method",
-    {"color": "rgb(43, 171, 99)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-method"
-assert-css: (
-    ".result-method:focus",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-method:focus .method",
-    {"color": "rgb(43, 171, 99)"},
-)
-
-// Check the color of "struct field".
-assert-css: (
-    ".result-structfield .structfield",
-    {"color": "rgb(221, 221, 221)"},
-    ALL,
-)
-assert-css: (
-    ".result-structfield",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-structfield"
-assert-css: (
-    ".result-structfield:hover",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-structfield:hover .structfield",
-    {"color": "rgb(221, 221, 221)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-structfield"
-assert-css: (
-    ".result-structfield:focus",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-structfield:focus .structfield",
-    {"color": "rgb(221, 221, 221)"},
-)
-
-// Check the color of "macro".
-assert-css: (
-    ".result-macro .macro",
-    {"color": "rgb(9, 189, 0)"},
-    ALL,
-)
-assert-css: (
-    ".result-macro",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-macro"
-assert-css: (
-    ".result-macro:hover",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-macro:hover .macro",
-    {"color": "rgb(9, 189, 0)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-macro"
-assert-css: (
-    ".result-macro:focus",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-macro:focus .macro",
-    {"color": "rgb(9, 189, 0)"},
-)
-
-// Check the color of "fn".
-assert-css: (
-    ".result-fn .fn",
-    {"color": "rgb(43, 171, 99)"},
-    ALL,
-)
-assert-css: (
-    ".result-fn",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-fn"
-assert-css: (
-    ".result-fn:hover",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-fn:hover .fn",
-    {"color": "rgb(43, 171, 99)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-fn"
-assert-css: (
-    ".result-fn:focus",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
-)
-assert-css: (
-    ".result-fn:focus .fn",
-    {"color": "rgb(43, 171, 99)"},
+store-value: (entry_color, "rgb(221, 221, 221)") // color of the search entry
+store-value: (hover_entry_color, "rgb(221, 221, 221)") // color of the hovered/focused search entry
+store-value: (background_color, "rgba(0, 0, 0, 0)") // background color
+store-value: (hover_background_color, "rgb(97, 97, 97)") // hover background color
+
+call-function: (
+    "check-result-color", (
+        "keyword", // item kind
+        "rgb(210, 153, 29)", // color of item kind
+        "rgb(210, 153, 29)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "struct", // item kind
+        "rgb(45, 191, 184)", // color of item kind
+        "rgb(45, 191, 184)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "associatedtype", // item kind
+        "rgb(210, 153, 29)", // color of item kind
+        "rgb(210, 153, 29)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "tymethod", // item kind
+        "rgb(43, 171, 99)", // color of item kind
+        "rgb(43, 171, 99)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "method", // item kind
+        "rgb(43, 171, 99)", // color of item kind
+        "rgb(43, 171, 99)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "structfield", // item kind
+        "rgb(221, 221, 221)", // color of item kind
+        "rgb(221, 221, 221)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "macro", // item kind
+        "rgb(9, 189, 0)", // color of item kind
+        "rgb(9, 189, 0)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "fn", // item kind
+        "rgb(43, 171, 99)", // color of item kind
+        "rgb(43, 171, 99)", // color of hovered/focused item kind
+    ),
 )
 
 // Checking the `<a>` container.
@@ -577,244 +278,66 @@ assert-css: (
     {"color": "rgb(0, 0, 0)"},
 )
 
-// Checking the color of "keyword".
-assert-css: (
-    ".result-keyword .keyword",
-    {"color": "rgb(56, 115, 173)"},
-    ALL,
-)
-assert-css: (
-    ".result-keyword",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-keyword"
-assert-css: (
-    ".result-keyword:hover",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-keyword:hover .keyword",
-    {"color": "rgb(56, 115, 173)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-keyword"
-assert-css: (
-    ".result-keyword:focus",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-keyword:focus .keyword",
-    {"color": "rgb(56, 115, 173)"},
-)
-
-// Check the color of "struct".
-assert-css: (
-    ".result-struct .struct",
-    {"color": "rgb(173, 55, 138)"},
-    ALL,
-)
-assert-css: (
-    ".result-struct",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-struct"
-assert-css: (
-    ".result-struct:hover",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-struct:hover .struct",
-    {"color": "rgb(173, 55, 138)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-struct"
-assert-css: (
-    ".result-struct:focus",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-struct:focus .struct",
-    {"color": "rgb(173, 55, 138)"},
-)
-
-// Check the color of "associated type".
-assert-css: (
-    ".result-associatedtype .associatedtype",
-    {"color": "rgb(56, 115, 173)"},
-    ALL,
-)
-assert-css: (
-    ".result-associatedtype",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-associatedtype"
-assert-css: (
-    ".result-associatedtype:hover",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-associatedtype:hover .associatedtype",
-    {"color": "rgb(56, 115, 173)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-associatedtype"
-assert-css: (
-    ".result-associatedtype:focus",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-associatedtype:focus .associatedtype",
-    {"color": "rgb(56, 115, 173)"},
-)
-
-// Check the color of "type method".
-assert-css: (
-    ".result-tymethod .tymethod",
-    {"color": "rgb(173, 124, 55)"},
-    ALL,
-)
-assert-css: (
-    ".result-tymethod",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-tymethod"
-assert-css: (
-    ".result-tymethod:hover",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-tymethod:hover .tymethod",
-    {"color": "rgb(173, 124, 55)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-tymethod"
-assert-css: (
-    ".result-tymethod:focus",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-tymethod:focus .tymethod",
-    {"color": "rgb(173, 124, 55)"},
-)
-
-// Check the color of "method".
-assert-css: (
-    ".result-method .method",
-    {"color": "rgb(173, 124, 55)"},
-    ALL,
-)
-assert-css: (
-    ".result-method",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-method"
-assert-css: (
-    ".result-method:hover",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-method:hover .method",
-    {"color": "rgb(173, 124, 55)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-method"
-assert-css: (
-    ".result-method:focus",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-method:focus .method",
-    {"color": "rgb(173, 124, 55)"},
-)
-
-// Check the color of "struct field".
-assert-css: (
-    ".result-structfield .structfield",
-    {"color": "rgb(0, 0, 0)"},
-    ALL,
-)
-assert-css: (
-    ".result-structfield",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-structfield"
-assert-css: (
-    ".result-structfield:hover",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-structfield:hover .structfield",
-    {"color": "rgb(0, 0, 0)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-structfield"
-assert-css: (
-    ".result-structfield:focus",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-structfield:focus .structfield",
-    {"color": "rgb(0, 0, 0)"},
-)
-
-// Check the color of "macro".
-assert-css: (
-    ".result-macro .macro",
-    {"color": "rgb(6, 128, 0)"},
-    ALL,
-)
-assert-css: (
-    ".result-macro",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-macro"
-assert-css: (
-    ".result-macro:hover",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-macro:hover .macro",
-    {"color": "rgb(6, 128, 0)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-macro"
-assert-css: (
-    ".result-macro:focus",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-macro:focus .macro",
-    {"color": "rgb(6, 128, 0)"},
-)
-
-// Check the color of "fn".
-assert-css: (
-    ".result-fn .fn",
-    {"color": "rgb(173, 124, 55)"},
-    ALL,
-)
-assert-css: (
-    ".result-fn",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".result-fn"
-assert-css: (
-    ".result-fn:hover",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-fn:hover .fn",
-    {"color": "rgb(173, 124, 55)"},
-)
-move-cursor-to: ".search-input"
-focus: ".result-fn"
-assert-css: (
-    ".result-fn:focus",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
-)
-assert-css: (
-    ".result-fn:focus .fn",
-    {"color": "rgb(173, 124, 55)"},
+store-value: (entry_color, "rgb(0, 0, 0)") // color of the search entry
+store-value: (hover_entry_color, "rgb(0, 0, 0)") // color of the hovered/focused search entry
+store-value: (background_color, "rgba(0, 0, 0, 0)") // background color
+store-value: (hover_background_color, "rgb(204, 204, 204)") // hover background color
+
+call-function: (
+    "check-result-color", (
+        "keyword", // item kind
+        "rgb(56, 115, 173)", // color of item kind
+        "rgb(56, 115, 173)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "struct", // item kind
+        "rgb(173, 55, 138)", // color of item kind
+        "rgb(173, 55, 138)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "associatedtype", // item kind
+        "rgb(56, 115, 173)", // color of item kind
+        "rgb(56, 115, 173)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "tymethod", // item kind
+        "rgb(173, 124, 55)", // color of item kind
+        "rgb(173, 124, 55)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "method", // item kind
+        "rgb(173, 124, 55)", // color of item kind
+        "rgb(173, 124, 55)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "structfield", // item kind
+        "rgb(0, 0, 0)", // color of item kind
+        "rgb(0, 0, 0)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "macro", // item kind
+        "rgb(6, 128, 0)", // color of item kind
+        "rgb(6, 128, 0)", // color of hovered/focused item kind
+    ),
+)
+call-function: (
+    "check-result-color", (
+        "fn", // item kind
+        "rgb(173, 124, 55)", // color of item kind
+        "rgb(173, 124, 55)", // color of hovered/focused item kind
+    ),
 )
 
 // Checking the `<a>` container.
diff --git a/src/test/ui/closures/multiple-fn-bounds.rs b/src/test/ui/closures/multiple-fn-bounds.rs
new file mode 100644
index 00000000000..6bb4098e2bb
--- /dev/null
+++ b/src/test/ui/closures/multiple-fn-bounds.rs
@@ -0,0 +1,15 @@
+fn foo<F: Fn(&char) -> bool + Fn(char) -> bool>(f: F) {
+    //~^ NOTE required by a bound in `foo`
+    //~| NOTE required by this bound in `foo`
+    //~| NOTE closure inferred to have a different signature due to this bound
+    todo!();
+}
+
+fn main() {
+    let v = true;
+    foo(move |x| v);
+    //~^ ERROR type mismatch in closure arguments
+    //~| NOTE expected closure signature
+    //~| NOTE expected due to this
+    //~| NOTE found signature defined here
+}
diff --git a/src/test/ui/closures/multiple-fn-bounds.stderr b/src/test/ui/closures/multiple-fn-bounds.stderr
new file mode 100644
index 00000000000..eefc123fed7
--- /dev/null
+++ b/src/test/ui/closures/multiple-fn-bounds.stderr
@@ -0,0 +1,24 @@
+error[E0631]: type mismatch in closure arguments
+  --> $DIR/multiple-fn-bounds.rs:10:5
+   |
+LL |     foo(move |x| v);
+   |     ^^^ -------- found signature defined here
+   |     |
+   |     expected due to this
+   |
+   = note: expected closure signature `fn(char) -> _`
+              found closure signature `for<'a> fn(&'a char) -> _`
+note: closure inferred to have a different signature due to this bound
+  --> $DIR/multiple-fn-bounds.rs:1:11
+   |
+LL | fn foo<F: Fn(&char) -> bool + Fn(char) -> bool>(f: F) {
+   |           ^^^^^^^^^^^^^^^^^
+note: required by a bound in `foo`
+  --> $DIR/multiple-fn-bounds.rs:1:31
+   |
+LL | fn foo<F: Fn(&char) -> bool + Fn(char) -> bool>(f: F) {
+   |                               ^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0631`.
diff --git a/src/test/ui/extenv/issue-55897.stderr b/src/test/ui/extenv/issue-55897.stderr
index e2afe6f34c1..63797d4a71b 100644
--- a/src/test/ui/extenv/issue-55897.stderr
+++ b/src/test/ui/extenv/issue-55897.stderr
@@ -26,6 +26,11 @@ error[E0432]: unresolved import `env`
    |
 LL |     use env;
    |         ^^^ no `env` in the root
+   |
+help: consider importing this module instead
+   |
+LL |     use std::env;
+   |         ~~~~~~~~~
 
 error: cannot determine resolution for the macro `env`
   --> $DIR/issue-55897.rs:6:22
diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr
index 2e4ba862376..059ca96808d 100644
--- a/src/test/ui/imports/issue-56125.stderr
+++ b/src/test/ui/imports/issue-56125.stderr
@@ -3,6 +3,18 @@ error[E0432]: unresolved import `empty::issue_56125`
    |
 LL |     use empty::issue_56125;
    |         ^^^^^^^^^^^^^^^^^^ no `issue_56125` in `m3::empty`
+   |
+help: consider importing one of these items instead
+   |
+LL |     use crate::m3::last_segment::issue_56125;
+   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     use crate::m3::non_last_segment::non_last_segment::issue_56125;
+   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     use issue_56125::issue_56125;
+   |         ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     use issue_56125::last_segment::issue_56125;
+   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+     and 1 other candidate
 
 error[E0659]: `issue_56125` is ambiguous
   --> $DIR/issue-56125.rs:6:9
diff --git a/src/test/ui/imports/issue-57015.stderr b/src/test/ui/imports/issue-57015.stderr
index d200d23ab28..3b72d57fee4 100644
--- a/src/test/ui/imports/issue-57015.stderr
+++ b/src/test/ui/imports/issue-57015.stderr
@@ -3,6 +3,11 @@ error[E0432]: unresolved import `single_err::something`
    |
 LL | use single_err::something;
    |     ^^^^^^^^^^^^^^^^^^^^^ no `something` in `single_err`
+   |
+help: consider importing this module instead
+   |
+LL | use glob_ok::something;
+   |     ~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-field-let.stderr b/src/test/ui/parser/removed-syntax-field-let.stderr
index ab3d2056581..bd1b23f7e3b 100644
--- a/src/test/ui/parser/removed-syntax-field-let.stderr
+++ b/src/test/ui/parser/removed-syntax-field-let.stderr
@@ -1,10 +1,16 @@
 error: expected identifier, found keyword `let`
   --> $DIR/removed-syntax-field-let.rs:2:5
    |
-LL | struct S {
-   |        - while parsing this struct
 LL |     let foo: (),
    |     ^^^ expected identifier, found keyword
+   |
+   = note: the `let` keyword is not allowed in `struct` fields
+   = note: see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information
+help: remove the let, the `let` keyword is not allowed in struct field definitions
+   |
+LL -     let foo: (),
+LL +     foo: (),
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/not-allowed.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/not-allowed.stderr
index a66330ccc46..761089cd387 100644
--- a/src/test/ui/rfc-2126-extern-absolute-paths/not-allowed.stderr
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/not-allowed.stderr
@@ -3,6 +3,13 @@ error[E0432]: unresolved import `alloc`
    |
 LL | use alloc;
    |     ^^^^^ no external crate `alloc`
+   |
+help: consider importing one of these items instead
+   |
+LL | use core::alloc;
+   |     ~~~~~~~~~~~~
+LL | use std::alloc;
+   |     ~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/simd/portable-intrinsics-arent-exposed.stderr b/src/test/ui/simd/portable-intrinsics-arent-exposed.stderr
index 870f4064de4..8881ede0dbc 100644
--- a/src/test/ui/simd/portable-intrinsics-arent-exposed.stderr
+++ b/src/test/ui/simd/portable-intrinsics-arent-exposed.stderr
@@ -11,6 +11,11 @@ error[E0432]: unresolved import `std::simd::intrinsics`
    |
 LL | use std::simd::intrinsics;
    |     ^^^^^^^^^^^^^^^^^^^^^ no `intrinsics` in `simd`
+   |
+help: consider importing this module instead
+   |
+LL | use std::intrinsics;
+   |     ~~~~~~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/test-attrs/inaccessible-test-modules.stderr b/src/test/ui/test-attrs/inaccessible-test-modules.stderr
index a94ea1e79bc..0c16ecd4c86 100644
--- a/src/test/ui/test-attrs/inaccessible-test-modules.stderr
+++ b/src/test/ui/test-attrs/inaccessible-test-modules.stderr
@@ -11,10 +11,16 @@ error[E0432]: unresolved import `test`
   --> $DIR/inaccessible-test-modules.rs:6:5
    |
 LL | use test as y;
-   |     ----^^^^^
-   |     |
-   |     no `test` in the root
-   |     help: a similar name exists in the module: `test`
+   |     ^^^^^^^^^ no `test` in the root
+   |
+help: a similar name exists in the module
+   |
+LL | use test as y;
+   |     ~~~~
+help: consider importing this module instead
+   |
+LL | use test::test;
+   |     ~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unresolved/unresolved-candidates.rs b/src/test/ui/unresolved/unresolved-candidates.rs
new file mode 100644
index 00000000000..38b227f609b
--- /dev/null
+++ b/src/test/ui/unresolved/unresolved-candidates.rs
@@ -0,0 +1,13 @@
+mod a {
+    pub trait Trait {}
+}
+
+mod b {
+    use Trait; //~ ERROR unresolved import `Trait`
+}
+
+mod c {
+    impl Trait for () {} //~ ERROR cannot find trait `Trait` in this scope
+}
+
+fn main() {}
diff --git a/src/test/ui/unresolved/unresolved-candidates.stderr b/src/test/ui/unresolved/unresolved-candidates.stderr
new file mode 100644
index 00000000000..bbd3eec2a54
--- /dev/null
+++ b/src/test/ui/unresolved/unresolved-candidates.stderr
@@ -0,0 +1,26 @@
+error[E0432]: unresolved import `Trait`
+  --> $DIR/unresolved-candidates.rs:6:9
+   |
+LL |     use Trait;
+   |         ^^^^^ no `Trait` in the root
+   |
+help: consider importing this trait instead
+   |
+LL |     use a::Trait;
+   |         ~~~~~~~~~
+
+error[E0405]: cannot find trait `Trait` in this scope
+  --> $DIR/unresolved-candidates.rs:10:10
+   |
+LL |     impl Trait for () {}
+   |          ^^^^^ not found in this scope
+   |
+help: consider importing this trait
+   |
+LL |     use a::Trait;
+   |
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0405, E0432.
+For more information about an error, try `rustc --explain E0405`.
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 216cf51447f..6173f9a78c5 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -1190,9 +1190,9 @@ version = "0.0.0"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.43"
+version = "1.0.46"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
+checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
 dependencies = [
  "unicode-ident",
 ]
@@ -1593,9 +1593,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "1.0.99"
+version = "1.0.102"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
+checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index d4733107e79..b9e0d48c9bc 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -18,10 +18,11 @@ const LICENSES: &[&str] = &[
     "ISC",
     "Unlicense/MIT",
     "Unlicense OR MIT",
-    "0BSD OR MIT OR Apache-2.0", // adler license
-    "Zlib OR Apache-2.0 OR MIT", // tinyvec
-    "MIT OR Apache-2.0 OR Zlib", // tinyvec_macros
-    "MIT OR Zlib OR Apache-2.0", // miniz_oxide
+    "0BSD OR MIT OR Apache-2.0",                // adler license
+    "Zlib OR Apache-2.0 OR MIT",                // tinyvec
+    "MIT OR Apache-2.0 OR Zlib",                // tinyvec_macros
+    "MIT OR Zlib OR Apache-2.0",                // miniz_oxide
+    "(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident
 ];
 
 /// These are exceptions to Rust's permissive licensing policy, and
@@ -235,6 +236,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "unic-langid-macros",
     "unic-langid-macros-impl",
     "unic-ucd-version",
+    "unicode-ident",
     "unicode-normalization",
     "unicode-script",
     "unicode-security",