Repository: rust-analyzer/rust-analyzer
Pull request #8884 (2021-05-19 18:24:20)

fix: add_explicit_type produces invalid code on `@` patterns
In
```rust
let name @ () = ();
```
 an explicit type should be inserted after the pattern, not just after the name.
`let` statement defined as `LetStmt = Attr* 'let' Pat (':' Type)? '=' initializer:Expr ';'`


Patch:
diff --git a/crates/hir_def/src/intern.rs b/crates/hir_def/src/intern.rs
index 5cc7f2df65..abc304ef0d 100644
--- a/crates/hir_def/src/intern.rs
+++ b/crates/hir_def/src/intern.rs
@@ -4,7 +4,7 @@
 
 use std::{
     collections::HashMap,
-    fmt::{self, Debug, Display},
+    fmt::{self, Debug},
     hash::{BuildHasherDefault, Hash, Hasher},
     ops::Deref,
     sync::Arc,
@@ -171,12 +171,6 @@ impl<T: Debug + Internable + ?Sized> Debug for Interned<T> {
     }
 }
 
-impl<T: Display + Internable + ?Sized> Display for Interned<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        (*self.arc).fmt(f)
-    }
-}
-
 pub struct InternStorage<T: ?Sized> {
     map: OnceCell<InternMap<T>>,
 }
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 221a5a5567..d4840be2fb 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -21,7 +21,6 @@ use syntax::ast;
 
 use crate::{
     attr::{AttrId, Attrs},
-    builtin_attr,
     db::DefDatabase,
     derive_macro_as_call_id,
     intern::Interned,
@@ -100,7 +99,6 @@ pub(super) fn collect_defs(
         proc_macros,
         exports_proc_macros: false,
         from_glob_import: Default::default(),
-        ignore_attrs_on: FxHashSet::default(),
     };
     match block {
         Some(block) => {
@@ -219,7 +217,6 @@ struct MacroDirective {
 enum MacroDirectiveKind {
     FnLike { ast_id: AstIdWithPath<ast::MacroCall>, fragment: FragmentKind },
     Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId },
-    Attr { ast_id: AstIdWithPath<ast::Item>, attr: AttrId, mod_item: ModItem },
 }
 
 struct DefData<'a> {
@@ -246,7 +243,6 @@ struct DefCollector<'a> {
     proc_macros: Vec<(Name, ProcMacroExpander)>,
     exports_proc_macros: bool,
     from_glob_import: PerNsGlobImports,
-    ignore_attrs_on: FxHashSet<ModItem>,
 }
 
 impl DefCollector<'_> {
@@ -296,26 +292,16 @@ impl DefCollector<'_> {
     fn collect(&mut self) {
         // main name resolution fixed-point loop.
         let mut i = 0;
-        'outer: loop {
-            loop {
-                self.db.check_canceled();
-                loop {
-                    if self.resolve_imports() == ReachedFixedPoint::Yes {
-                        break;
-                    }
-                }
-                if self.resolve_macros() == ReachedFixedPoint::Yes {
-                    break;
-                }
+        loop {
+            self.db.check_canceled();
+            self.resolve_imports();
 
-                i += 1;
-                if i == FIXED_POINT_LIMIT {
-                    log::error!("name resolution is stuck");
-                    break 'outer;
-                }
+            match self.resolve_macros() {
+                ReachedFixedPoint::Yes => break,
+                ReachedFixedPoint::No => i += 1,
             }
-
-            if self.reseed_with_unresolved_attributes() == ReachedFixedPoint::Yes {
+            if i == FIXED_POINT_LIMIT {
+                log::error!("name resolution is stuck");
                 break;
             }
         }
@@ -357,50 +343,6 @@ impl DefCollector<'_> {
         }
     }
 
-    /// When the fixed-point loop reaches a stable state, we might still have some unresolved
-    /// attributes (or unexpanded attribute proc macros) left over. This takes them, and feeds the
-    /// item they're applied to back into name resolution.
-    ///
-    /// This effectively ignores the fact that the macro is there and just treats the items as
-    /// normal code.
-    ///
-    /// This improves UX when proc macros are turned off or don't work, and replicates the behavior
-    /// before we supported proc. attribute macros.
-    fn reseed_with_unresolved_attributes(&mut self) -> ReachedFixedPoint {
-        let mut added_items = false;
-        let unexpanded_macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new());
-        for directive in &unexpanded_macros {
-            if let MacroDirectiveKind::Attr { mod_item, .. } = &directive.kind {
-                // Make sure to only add such items once.
-                if !self.ignore_attrs_on.insert(*mod_item) {
-                    continue;
-                }
-
-                let file_id = self.def_map[directive.module_id].definition_source(self.db).file_id;
-                let item_tree = self.db.file_item_tree(file_id);
-                let mod_dir = self.mod_dirs[&directive.module_id].clone();
-                ModCollector {
-                    def_collector: &mut *self,
-                    macro_depth: directive.depth,
-                    module_id: directive.module_id,
-                    file_id,
-                    item_tree: &item_tree,
-                    mod_dir,
-                }
-                .collect(&[*mod_item]);
-                added_items = true;
-            }
-        }
-        self.unexpanded_macros = unexpanded_macros;
-
-        if added_items {
-            // Continue name resolution with the new data.
-            ReachedFixedPoint::No
-        } else {
-            ReachedFixedPoint::Yes
-        }
-    }
-
     /// Adds a definition of procedural macro `name` to the root module.
     ///
     /// # Notes on procedural macro resolution
@@ -562,35 +504,35 @@ impl DefCollector<'_> {
         }
     }
 
-    /// Tries to resolve every currently unresolved import.
-    fn resolve_imports(&mut self) -> ReachedFixedPoint {
-        let mut res = ReachedFixedPoint::Yes;
-        let imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
-        let imports = imports
-            .into_iter()
-            .filter_map(|mut directive| {
+    /// Import resolution
+    ///
+    /// This is a fix point algorithm. We resolve imports until no forward
+    /// progress in resolving imports is made
+    fn resolve_imports(&mut self) {
+        let mut n_previous_unresolved = self.unresolved_imports.len() + 1;
+
+        while self.unresolved_imports.len() < n_previous_unresolved {
+            n_previous_unresolved = self.unresolved_imports.len();
+            let imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
+            for mut directive in imports {
                 directive.status = self.resolve_import(directive.module_id, &directive.import);
                 match directive.status {
                     PartialResolvedImport::Indeterminate(_) => {
                         self.record_resolved_import(&directive);
                         // FIXME: For avoid performance regression,
                         // we consider an imported resolved if it is indeterminate (i.e not all namespace resolved)
-                        self.resolved_imports.push(directive);
-                        res = ReachedFixedPoint::No;
-                        None
+                        self.resolved_imports.push(directive)
                     }
                     PartialResolvedImport::Resolved(_) => {
                         self.record_resolved_import(&directive);
-                        self.resolved_imports.push(directive);
-                        res = ReachedFixedPoint::No;
-                        None
+                        self.resolved_imports.push(directive)
+                    }
+                    PartialResolvedImport::Unresolved => {
+                        self.unresolved_imports.push(directive);
                     }
-                    PartialResolvedImport::Unresolved => Some(directive),
                 }
-            })
-            .collect();
-        self.unresolved_imports = imports;
-        res
+            }
+        }
     }
 
     fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport {
@@ -914,9 +856,6 @@ impl DefCollector<'_> {
                         Err(UnresolvedMacro { .. }) => (),
                     }
                 }
-                MacroDirectiveKind::Attr { .. } => {
-                    // not yet :)
-                }
             }
 
             true
@@ -1009,7 +948,7 @@ impl DefCollector<'_> {
                         ));
                     }
                 },
-                MacroDirectiveKind::Derive { .. } | MacroDirectiveKind::Attr { .. } => {
+                MacroDirectiveKind::Derive { .. } => {
                     // FIXME: we might want to diagnose this too
                 }
             }
@@ -1117,14 +1056,6 @@ impl ModCollector<'_, '_> {
                     continue;
                 }
             }
-
-            if let Err(()) = self.resolve_attributes(&attrs, item) {
-                // Do not process the item. It has at least one non-builtin attribute, which *must*
-                // resolve to a proc macro (or fail to resolve), so we'll never see this item during
-                // normal name resolution.
-                continue;
-            }
-
             let module = self.def_collector.def_map.module_id(self.module_id);
 
             let mut def = None;
@@ -1431,62 +1362,6 @@ impl ModCollector<'_, '_> {
         res
     }
 
-    /// Resolves attributes on an item.
-    ///
-    /// Returns `Err` when some attributes could not be resolved to builtins and have been
-    /// registered as unresolved.
-    fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> {
-        fn is_builtin_attr(path: &ModPath) -> bool {
-            if path.kind == PathKind::Plain {
-                if let Some(tool_module) = path.segments().first() {
-                    let tool_module = tool_module.to_string();
-                    if builtin_attr::TOOL_MODULES.iter().any(|m| tool_module == *m) {
-                        return true;
-                    }
-                }
-
-                if let Some(name) = path.as_ident() {
-                    let name = name.to_string();
-                    if builtin_attr::INERT_ATTRIBUTES
-                        .iter()
-                        .chain(builtin_attr::EXTRA_ATTRIBUTES)
-                        .any(|attr| name == *attr)
-                    {
-                        return true;
-                    }
-                }
-            }
-
-            false
-        }
-
-        // We failed to resolve an attribute on this item earlier, and are falling back to treating
-        // the item as-is.
-        if self.def_collector.ignore_attrs_on.contains(&mod_item) {
-            return Ok(());
-        }
-
-        match attrs.iter().find(|attr| !is_builtin_attr(&attr.path)) {
-            Some(non_builtin_attr) => {
-                log::debug!("non-builtin attribute {}", non_builtin_attr.path);
-
-                let ast_id = AstIdWithPath::new(
-                    self.file_id,
-                    mod_item.ast_id(self.item_tree),
-                    non_builtin_attr.path.as_ref().clone(),
-                );
-                self.def_collector.unexpanded_macros.push(MacroDirective {
-                    module_id: self.module_id,
-                    depth: self.macro_depth + 1,
-                    kind: MacroDirectiveKind::Attr { ast_id, attr: non_builtin_attr.id, mod_item },
-                });
-
-                Err(())
-            }
-            None => Ok(()),
-        }
-    }
-
     fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId<ast::Item>) {
         for derive in attrs.by_key("derive").attrs() {
             match derive.parse_derive() {
@@ -1719,7 +1594,6 @@ mod tests {
             proc_macros: Default::default(),
             exports_proc_macros: false,
             from_glob_import: Default::default(),
-            ignore_attrs_on: FxHashSet::default(),
         };
         collector.seed_with_top_level();
         collector.collect();
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index b9a69b79c8..47709c1e8f 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -211,7 +211,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
 
         // FIXME: Due to shortcomings in the current type system implementation, only emit this
         // diagnostic if there are no type mismatches in the containing function.
-        if self.infer.expr_type_mismatches().next().is_some() {
+        if self.infer.type_mismatches.iter().next().is_some() {
             return;
         }
 
@@ -311,12 +311,11 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
                 // necessary.
                 //
                 // FIXME we should use the type checker for this.
-                if (pat_ty == match_expr_ty
+                if pat_ty == match_expr_ty
                     || match_expr_ty
                         .as_reference()
                         .map(|(match_expr_ty, ..)| match_expr_ty == pat_ty)
-                        .unwrap_or(false))
-                    && types_of_subpatterns_do_match(pat, &cx.body, &infer)
+                        .unwrap_or(false)
                 {
                     // If we had a NotUsefulMatchArm diagnostic, we could
                     // check the usefulness of each pattern as we added it
@@ -497,21 +496,6 @@ pub fn record_pattern_missing_fields(
     Some((variant_def, missed_fields, exhaustive))
 }
 
-fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResult) -> bool {
-    fn walk(pat: PatId, body: &Body, infer: &InferenceResult, has_type_mismatches: &mut bool) {
-        match infer.type_mismatch_for_pat(pat) {
-            Some(_) => *has_type_mismatches = true,
-            None => {
-                body[pat].walk_child_pats(|subpat| walk(subpat, body, infer, has_type_mismatches))
-            }
-        }
-    }
-
-    let mut has_type_mismatches = false;
-    walk(pat, body, infer, &mut has_type_mismatches);
-    !has_type_mismatches
-}
-
 #[cfg(test)]
 mod tests {
     use crate::diagnostics::tests::check_diagnostics;
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index e8dd669bf6..6ee0529c62 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -1127,18 +1127,6 @@ fn main() {
         );
     }
 
-    #[test]
-    fn mismatched_types_in_or_patterns() {
-        check_diagnostics(
-            r#"
-fn main() {
-    match false { true | () => {} }
-    match (false,) { (true | (),) => {} }
-}
-"#,
-        );
-    }
-
     #[test]
     fn malformed_match_arm_tuple_enum_missing_pattern() {
         // We are testing to be sure we don't panic here when the match
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 0ee851a74c..bf2da2d4ae 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -137,12 +137,8 @@ pub struct InferenceResult {
     assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>,
     diagnostics: Vec<InferenceDiagnostic>,
     pub type_of_expr: ArenaMap<ExprId, Ty>,
-    /// For each pattern record the type it resolves to.
-    ///
-    /// **Note**: When a pattern type is resolved it may still contain
-    /// unresolved or missing subpatterns or subpatterns of mismatched types.
     pub type_of_pat: ArenaMap<PatId, Ty>,
-    type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
+    pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>,
     /// Interned Unknown to return references to.
     standard_types: InternedStandardTypes,
 }
@@ -167,22 +163,7 @@ impl InferenceResult {
         self.assoc_resolutions.get(&id.into()).copied()
     }
     pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
-        self.type_mismatches.get(&expr.into())
-    }
-    pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch> {
-        self.type_mismatches.get(&pat.into())
-    }
-    pub fn expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch)> {
-        self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
-            ExprOrPatId::ExprId(expr) => Some((expr, mismatch)),
-            _ => None,
-        })
-    }
-    pub fn pat_type_mismatches(&self) -> impl Iterator<Item = (PatId, &TypeMismatch)> {
-        self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
-            ExprOrPatId::PatId(pat) => Some((pat, mismatch)),
-            _ => None,
-        })
+        self.type_mismatches.get(expr)
     }
     pub fn add_diagnostics(
         &self,
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 7278faeec0..b6b5a1b750 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -42,7 +42,7 @@ impl<'a> InferenceContext<'a> {
         let could_unify = self.unify(&ty, &expected.ty);
         if !could_unify {
             self.result.type_mismatches.insert(
-                tgt_expr.into(),
+                tgt_expr,
                 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
             );
         }
@@ -54,10 +54,9 @@ impl<'a> InferenceContext<'a> {
     pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
         let ty = self.infer_expr_inner(expr, &expected);
         let ty = if !self.coerce(&ty, &expected.coercion_target()) {
-            self.result.type_mismatches.insert(
-                expr.into(),
-                TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
-            );
+            self.result
+                .type_mismatches
+                .insert(expr, TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() });
             // Return actual type when type mismatch.
             // This is needed for diagnostic when return type mismatch.
             ty
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index b15f4977dd..60b94a6422 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -10,7 +10,7 @@ use hir_def::{
 };
 use hir_expand::name::Name;
 
-use super::{BindingMode, Expectation, InferenceContext, TypeMismatch};
+use super::{BindingMode, Expectation, InferenceContext};
 use crate::{
     lower::lower_to_chalk_mutability, static_lifetime, Interner, Substitution, Ty, TyBuilder,
     TyExt, TyKind,
@@ -266,10 +266,7 @@ impl<'a> InferenceContext<'a> {
         // use a new type variable if we got error type here
         let ty = self.insert_type_vars_shallow(ty);
         if !self.unify(&ty, expected) {
-            self.result.type_mismatches.insert(
-                pat.into(),
-                TypeMismatch { expected: expected.clone(), actual: ty.clone() },
-            );
+            // FIXME record mismatch, we need to change the type of self.type_mismatches for that
         }
         let ty = self.resolve_ty_as_possible(ty);
         self.write_pat_ty(pat, ty.clone());
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index 01fe3a1a16..2bf9533052 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -55,14 +55,12 @@ pub(crate) fn prepare_rename(
     match def {
         Definition::SelfType(_) => bail!("Cannot rename `Self`"),
         Definition::ModuleDef(ModuleDef::BuiltinType(_)) => bail!("Cannot rename builtin type"),
-        Definition::ModuleDef(ModuleDef::Module(_)) => (),
-        _ => {
-            let nav = def
-                .try_to_nav(sema.db)
-                .ok_or_else(|| format_err!("No references found at position"))?;
-            nav.focus_range.ok_or_else(|| format_err!("No identifier available to rename"))?;
-        }
+        _ => {}
     };
+    let nav =
+        def.try_to_nav(sema.db).ok_or_else(|| format_err!("No references found at position"))?;
+    nav.focus_range.ok_or_else(|| format_err!("No identifier available to rename"))?;
+
     let name_like = sema
         .find_node_at_offset_with_descend(&syntax, position.offset)
         .ok_or_else(|| format_err!("No references found at position"))?;
diff --git a/crates/ide_assists/src/handlers/add_explicit_type.rs b/crates/ide_assists/src/handlers/add_explicit_type.rs
index 36589203d5..b7617ca3da 100644
--- a/crates/ide_assists/src/handlers/add_explicit_type.rs
+++ b/crates/ide_assists/src/handlers/add_explicit_type.rs
@@ -1,6 +1,6 @@
 use hir::HirDisplay;
 use syntax::{
-    ast::{self, AstNode, LetStmt, NameOwner},
+    ast::{self, AstNode, LetStmt},
     TextRange,
 };
 
@@ -31,9 +31,6 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
         _ => return None,
     };
     let pat_range = pat.syntax().text_range();
-    // The binding must have a name
-    let name = pat.name()?;
-    let name_range = name.syntax().text_range();
 
     // Assist should only be applicable if cursor is between 'let' and '='
     let cursor_in_range = {
@@ -74,7 +71,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
                 builder.replace(ascribed_ty.syntax().text_range(), inferred_type);
             }
             None => {
-                builder.insert(name_range.end(), format!(": {}", inferred_type));
+                builder.insert(pat_range.end(), format!(": {}", inferred_type));
             }
         },
     )
@@ -243,6 +240,24 @@ struct Test<K, T = u8> { k: K, t: T }
 fn main() {
     let test: Test<i32> = Test { t: 23u8, k: 33 };
 }
+"#,
+        );
+    }
+
+    #[test]
+    fn type_should_be_added_after_pattern() {
+        // LetStmt = Attr* 'let' Pat (':' Type)? '=' initializer:Expr ';'
+        check_assist(
+            add_explicit_type,
+            r#"
+fn main() {
+    let $0test @ () = ();
+}
+"#,
+            r#"
+fn main() {
+    let test @ (): () = ();
+}
 "#,
         );
     }
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index b2317618a8..3c87782f28 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -122,7 +122,6 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
             "runnables": {
                 "kinds": [ "cargo" ],
             },
-            "workspaceSymbolScopeKindFiltering": true,
         })),
     }
 }
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 3c4eacfeb5..2d3787d0fe 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -651,36 +651,32 @@ export const enum Direction {
 }
 ```
 
-## Workspace Symbols Filtering
+## Lookup workspace symbol search scope and kind
 
 **Issue:** https://github.com/rust-analyzer/rust-analyzer/pull/7698
 
-**Experimental Server Capability:** `{ "workspaceSymbolScopeKindFiltering": boolean }`
+This request is sent from client to server to search for workspace symbols filtered by an
+optional search scope and / or an optional symbol kind.
 
-Extends the existing `workspace/symbol` request with ability to filter symbols by broad scope and kind of symbol.
-If this capability is set, `workspace/symbol` parameter gains two new optional fields:
+**Method:** `workspace/symbol`
 
+**Request:** `WorkspaceSymbolParams`
+
+**Response:** `SymbolInformation[] | null`
 
 ```typescript
-interface WorkspaceSymbolParams {
-    /**
-     * Return only the symbols defined in the specified scope.
-     */
+interface lsp_ext.WorkspaceSymbolParams extends WorkspaceSymbolParams {
     searchScope?: WorkspaceSymbolSearchScope;
-    /**
-     * Return only the symbols of specified kinds.
-     */
     searchKind?: WorkspaceSymbolSearchKind;
-    ...
 }
 
 const enum WorkspaceSymbolSearchScope {
-    Workspace = "workspace",
-    WorkspaceAndDependencies = "workspaceAndDependencies"
+    Workspace = "Workspace",
+    WorkspaceAndDependencies = "WorkspaceAndDependencies"
 }
 
 const enum WorkspaceSymbolSearchKind {
-    OnlyTypes = "onlyTypes",
-    AllSymbols = "allSymbols"
+    OnlyTypes = "OnlyTypes",
+    AllSymbols = "AllSymbols"
 }
 ```


Test patch:
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index cc819373c6..ccfb88c52d 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -130,10 +130,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
                 }
                 Err(SyntheticSyntax) => continue,
             };
-            types.push((syntax_ptr.clone(), ty));
-            if let Some(mismatch) = inference_result.type_mismatch_for_pat(pat) {
-                mismatches.push((syntax_ptr, mismatch));
-            }
+            types.push((syntax_ptr, ty));
         }
 
         for (expr, ty) in inference_result.type_of_expr.iter() {
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index ddbadbe400..787647e9f3 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -546,9 +546,7 @@ fn infer_const_pattern() {
             273..276 'Bar': usize
             280..283 'Bar': usize
             200..223: expected (), got Foo
-            211..214: expected (), got Foo
             262..285: expected (), got usize
-            273..276: expected (), got usize
         "#]],
     );
 }
@@ -705,7 +703,7 @@ fn box_pattern() {
 
 #[test]
 fn tuple_ellipsis_pattern() {
-    check_infer_with_mismatches(
+    check_infer(
         r#"
 fn foo(tuple: (u8, i16, f32)) {
     match tuple {
@@ -746,8 +744,6 @@ fn foo(tuple: (u8, i16, f32)) {
             186..200 '{/*too long*/}': ()
             209..210 '_': (u8, i16, f32)
             214..216 '{}': ()
-            136..142: expected (u8, i16, f32), got (u8, i16)
-            170..182: expected (u8, i16, f32), got (u8, i16, f32, _)
         "#]],
     );
 }
@@ -855,55 +851,3 @@ fn f(e: Enum) {
     "#,
     )
 }
-
-#[test]
-fn type_mismatch_in_or_pattern() {
-    check_infer_with_mismatches(
-        r#"
-fn main() {
-    match (false,) {
-        (true | (),) => {}
-        (() | true,) => {}
-        (_ | (),) => {}
-        (() | _,) => {}
-    }
-}
-"#,
-        expect![[r#"
-            10..142 '{     ...   } }': ()
-            16..140 'match ...     }': ()
-            22..30 '(false,)': (bool,)
-            23..28 'false': bool
-            41..53 '(true | (),)': (bool,)
-            42..46 'true': bool
-            42..46 'true': bool
-            42..51 'true | ()': bool
-            49..51 '()': ()
-            57..59 '{}': ()
-            68..80 '(() | true,)': ((),)
-            69..71 '()': ()
-            69..78 '() | true': ()
-            74..78 'true': bool
-            74..78 'true': bool
-            84..86 '{}': ()
-            95..104 '(_ | (),)': (bool,)
-            96..97 '_': bool
-            96..102 '_ | ()': bool
-            100..102 '()': ()
-            108..110 '{}': ()
-            119..128 '(() | _,)': ((),)
-            120..122 '()': ()
-            120..126 '() | _': ()
-            125..126 '_': bool
-            132..134 '{}': ()
-            49..51: expected bool, got ()
-            68..80: expected (bool,), got ((),)
-            69..71: expected bool, got ()
-            69..78: expected bool, got ()
-            100..102: expected bool, got ()
-            119..128: expected (bool,), got ((),)
-            120..122: expected bool, got ()
-            120..126: expected bool, got ()
-        "#]],
-    );
-}