Repository: rust-analyzer/rust-analyzer
Pull request #11925 (2022-04-07 13:43:59)

internal: Add and use `HirFormatter::write_{str,char}`
Saves slightly over 3 KB of `text`, but comparing the total with that from two weeks ago in #11776, this is a losing battle (we're 951 KB larger).

```
   text	   data	    bss	    dec	    hex	filename
24693512	1542704	   4424	26240640	1906680	rust-analyzer-baseline
24690216	1542112	   4424	26236752	1905750	rust-analyzer-pr
```



Patch:
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 9edb6de9df..c1efab0918 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -27,16 +27,16 @@ impl HirDisplay for Function {
         let data = f.db.function_data(self.id);
         write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
         if data.is_default() {
-            write!(f, "default ")?;
+            f.write_str("default ")?;
         }
         if data.is_const() {
-            write!(f, "const ")?;
+            f.write_str("const ")?;
         }
         if data.is_async() {
-            write!(f, "async ")?;
+            f.write_str("async ")?;
         }
         if data.is_unsafe() {
-            write!(f, "unsafe ")?;
+            f.write_str("unsafe ")?;
         }
         if let Some(abi) = &data.abi {
             // FIXME: String escape?
@@ -46,23 +46,23 @@ impl HirDisplay for Function {
 
         write_generic_params(GenericDefId::FunctionId(self.id), f)?;
 
-        write!(f, "(")?;
+        f.write_char('(')?;
 
         let write_self_param = |ty: &TypeRef, f: &mut HirFormatter| match ty {
-            TypeRef::Path(p) if p.is_self_type() => write!(f, "self"),
+            TypeRef::Path(p) if p.is_self_type() => f.write_str("self"),
             TypeRef::Reference(inner, lifetime, mut_) if matches!(&**inner,TypeRef::Path(p) if p.is_self_type()) =>
             {
-                write!(f, "&")?;
+                f.write_char('&')?;
                 if let Some(lifetime) = lifetime {
                     write!(f, "{} ", lifetime.name)?;
                 }
                 if let hir_def::type_ref::Mutability::Mut = mut_ {
-                    write!(f, "mut ")?;
+                    f.write_str("mut ")?;
                 }
-                write!(f, "self")
+                f.write_str("self")
             }
             _ => {
-                write!(f, "self: ")?;
+                f.write_str("self: ")?;
                 ty.hir_fmt(f)
             }
         };
@@ -70,7 +70,7 @@ impl HirDisplay for Function {
         let mut first = true;
         for (name, type_ref) in &data.params {
             if !first {
-                write!(f, ", ")?;
+                f.write_str(", ")?;
             } else {
                 first = false;
                 if data.has_self_param() {
@@ -80,7 +80,7 @@ impl HirDisplay for Function {
             }
             match name {
                 Some(name) => write!(f, "{}: ", name)?,
-                None => write!(f, "_: ")?,
+                None => f.write_str("_: ")?,
             }
             // FIXME: Use resolved `param.ty` or raw `type_ref`?
             // The former will ignore lifetime arguments currently.
@@ -88,10 +88,10 @@ impl HirDisplay for Function {
         }
 
         if data.is_varargs() {
-            write!(f, ", ...")?;
+            f.write_str(", ...")?;
         }
 
-        write!(f, ")")?;
+        f.write_char(')')?;
 
         // `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns.
         // Use ugly pattern match to strip the Future trait.
@@ -117,7 +117,7 @@ impl HirDisplay for Function {
         match ret_type {
             TypeRef::Tuple(tup) if tup.is_empty() => {}
             ty => {
-                write!(f, " -> ")?;
+                f.write_str(" -> ")?;
                 ty.hir_fmt(f)?;
             }
         }
@@ -141,7 +141,7 @@ impl HirDisplay for Adt {
 impl HirDisplay for Struct {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
-        write!(f, "struct ")?;
+        f.write_str("struct ")?;
         write!(f, "{}", self.name(f.db))?;
         let def_id = GenericDefId::AdtId(AdtId::StructId(self.id));
         write_generic_params(def_id, f)?;
@@ -153,7 +153,7 @@ impl HirDisplay for Struct {
 impl HirDisplay for Enum {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
-        write!(f, "enum ")?;
+        f.write_str("enum ")?;
         write!(f, "{}", self.name(f.db))?;
         let def_id = GenericDefId::AdtId(AdtId::EnumId(self.id));
         write_generic_params(def_id, f)?;
@@ -165,7 +165,7 @@ impl HirDisplay for Enum {
 impl HirDisplay for Union {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
-        write!(f, "union ")?;
+        f.write_str("union ")?;
         write!(f, "{}", self.name(f.db))?;
         let def_id = GenericDefId::AdtId(AdtId::UnionId(self.id));
         write_generic_params(def_id, f)?;
@@ -189,34 +189,34 @@ impl HirDisplay for Variant {
         match &*data {
             VariantData::Unit => {}
             VariantData::Tuple(fields) => {
-                write!(f, "(")?;
+                f.write_char('(')?;
                 let mut first = true;
                 for (_, field) in fields.iter() {
                     if first {
                         first = false;
                     } else {
-                        write!(f, ", ")?;
+                        f.write_str(", ")?;
                     }
                     // Enum variant fields must be pub.
                     field.type_ref.hir_fmt(f)?;
                 }
-                write!(f, ")")?;
+                f.write_char(')')?;
             }
             VariantData::Record(fields) => {
-                write!(f, " {{")?;
+                f.write_str(" {{")?;
                 let mut first = true;
                 for (_, field) in fields.iter() {
                     if first {
                         first = false;
-                        write!(f, " ")?;
+                        f.write_char(' ')?;
                     } else {
-                        write!(f, ", ")?;
+                        f.write_str(", ")?;
                     }
                     // Enum variant fields must be pub.
                     write!(f, "{}: ", field.name)?;
                     field.type_ref.hir_fmt(f)?;
                 }
-                write!(f, " }}")?;
+                f.write_str(" }}")?;
             }
         }
         Ok(())
@@ -301,7 +301,7 @@ fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), H
     {
         return Ok(());
     }
-    write!(f, "<")?;
+    f.write_char('<')?;
 
     let mut first = true;
     let mut delim = |f: &mut HirFormatter| {
@@ -309,7 +309,7 @@ fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), H
             first = false;
             Ok(())
         } else {
-            write!(f, ", ")
+            f.write_str(", ")
         }
     };
     for (_, lifetime) in params.lifetimes.iter() {
@@ -326,7 +326,7 @@ fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), H
                     delim(f)?;
                     write!(f, "{}", name)?;
                     if let Some(default) = &ty.default {
-                        write!(f, " = ")?;
+                        f.write_str(" = ")?;
                         default.hir_fmt(f)?;
                     }
                 }
@@ -339,7 +339,7 @@ fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), H
         }
     }
 
-    write!(f, ">")?;
+    f.write_char('>')?;
     Ok(())
 }
 
@@ -370,31 +370,30 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), Hir
         WherePredicateTypeTarget::TypeOrConstParam(id) => {
             match &params.type_or_consts[*id].name() {
                 Some(name) => write!(f, "{}", name),
-                None => write!(f, "{{unnamed}}"),
+                None => f.write_str("{{unnamed}}"),
             }
         }
     };
 
-    write!(f, "\nwhere")?;
+    f.write_str("\nwhere")?;
 
     for (pred_idx, pred) in params.where_predicates.iter().enumerate() {
         let prev_pred =
             if pred_idx == 0 { None } else { Some(&params.where_predicates[pred_idx - 1]) };
 
-        let new_predicate = |f: &mut HirFormatter| {
-            write!(f, "{}", if pred_idx == 0 { "\n    " } else { ",\n    " })
-        };
+        let new_predicate =
+            |f: &mut HirFormatter| f.write_str(if pred_idx == 0 { "\n    " } else { ",\n    " });
 
         match pred {
             WherePredicate::TypeBound { target, .. } if is_unnamed_type_target(target) => {}
             WherePredicate::TypeBound { target, bound } => {
                 if matches!(prev_pred, Some(WherePredicate::TypeBound { target: target_, .. }) if target_ == target)
                 {
-                    write!(f, " + ")?;
+                    f.write_str(" + ")?;
                 } else {
                     new_predicate(f)?;
                     write_target(target, f)?;
-                    write!(f, ": ")?;
+                    f.write_str(": ")?;
                 }
                 bound.hir_fmt(f)?;
             }
@@ -413,19 +412,19 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), Hir
                     Some(WherePredicate::ForLifetime { lifetimes: lifetimes_, target: target_, .. })
                     if lifetimes_ == lifetimes && target_ == target,
                 ) {
-                    write!(f, " + ")?;
+                    f.write_str(" + ")?;
                 } else {
                     new_predicate(f)?;
-                    write!(f, "for<")?;
+                    f.write_str("for<")?;
                     for (idx, lifetime) in lifetimes.iter().enumerate() {
                         if idx != 0 {
-                            write!(f, ", ")?;
+                            f.write_str(", ")?;
                         }
                         write!(f, "{}", lifetime)?;
                     }
-                    write!(f, "> ")?;
+                    f.write_str("> ")?;
                     write_target(target, f)?;
-                    write!(f, ": ")?;
+                    f.write_str(": ")?;
                 }
                 bound.hir_fmt(f)?;
             }
@@ -433,7 +432,7 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), Hir
     }
 
     // End of final predicate. There must be at least one predicate here.
-    write!(f, ",")?;
+    f.write_char(',')?;
 
     Ok(())
 }
@@ -442,10 +441,10 @@ impl HirDisplay for Const {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
         let data = f.db.const_data(self.id);
-        write!(f, "const ")?;
+        f.write_str("const ")?;
         match &data.name {
             Some(name) => write!(f, "{}: ", name)?,
-            None => write!(f, "_: ")?,
+            None => f.write_str("_: ")?,
         }
         data.type_ref.hir_fmt(f)?;
         Ok(())
@@ -456,9 +455,9 @@ impl HirDisplay for Static {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
         let data = f.db.static_data(self.id);
-        write!(f, "static ")?;
+        f.write_str("static ")?;
         if data.mutable {
-            write!(f, "mut ")?;
+            f.write_str("mut ")?;
         }
         write!(f, "{}: ", &data.name)?;
         data.type_ref.hir_fmt(f)?;
@@ -471,10 +470,10 @@ impl HirDisplay for Trait {
         write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
         let data = f.db.trait_data(self.id);
         if data.is_unsafe {
-            write!(f, "unsafe ")?;
+            f.write_str("unsafe ")?;
         }
         if data.is_auto {
-            write!(f, "auto ")?;
+            f.write_str("auto ")?;
         }
         write!(f, "trait {}", data.name)?;
         let def_id = GenericDefId::TraitId(self.id);
@@ -490,11 +489,11 @@ impl HirDisplay for TypeAlias {
         let data = f.db.type_alias_data(self.id);
         write!(f, "type {}", data.name)?;
         if !data.bounds.is_empty() {
-            write!(f, ": ")?;
+            f.write_str(": ")?;
             f.write_joined(&data.bounds, " + ")?;
         }
         if let Some(ty) = &data.type_ref {
-            write!(f, " = ")?;
+            f.write_str(" = ")?;
             ty.hir_fmt(f)?;
         }
         Ok(())
@@ -508,9 +507,9 @@ impl HirDisplay for Module {
             Some(name) => write!(f, "mod {}", name),
             None if self.is_crate_root(f.db) => match self.krate().display_name(f.db) {
                 Some(name) => write!(f, "extern crate {}", name),
-                None => write!(f, "extern crate {{unknown}}"),
+                None => f.write_str("extern crate {{unknown}}"),
             },
-            None => write!(f, "mod {{unnamed}}"),
+            None => f.write_str("mod {{unnamed}}"),
         }
     }
 }
@@ -518,9 +517,9 @@ impl HirDisplay for Module {
 impl HirDisplay for Macro {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         match self.id {
-            hir_def::MacroId::Macro2Id(_) => write!(f, "macro"),
-            hir_def::MacroId::MacroRulesId(_) => write!(f, "macro_rules!"),
-            hir_def::MacroId::ProcMacroId(_) => write!(f, "proc_macro"),
+            hir_def::MacroId::Macro2Id(_) => f.write_str("macro"),
+            hir_def::MacroId::MacroRulesId(_) => f.write_str("macro_rules!"),
+            hir_def::MacroId::ProcMacroId(_) => f.write_str("proc_macro"),
         }?;
         write!(f, " {}", self.name(f.db))
     }
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 89ba16d087..e96c400740 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -299,53 +299,45 @@ impl SourceAnalyzer {
         let parent = || parent.clone();
 
         let mut prefer_value_ns = false;
-        let resolved = (|| {
-            if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
-                let expr_id = self.expr_id(db, &path_expr.into())?;
-                let infer = self.infer.as_ref()?;
-                if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
-                    return Some(PathResolution::Def(AssocItem::from(assoc).into()));
-                }
-                if let Some(VariantId::EnumVariantId(variant)) =
-                    infer.variant_resolution_for_expr(expr_id)
-                {
-                    return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
-                }
-                prefer_value_ns = true;
-            } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
-                let pat_id = self.pat_id(&path_pat.into())?;
-                if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
-                    return Some(PathResolution::Def(AssocItem::from(assoc).into()));
-                }
-                if let Some(VariantId::EnumVariantId(variant)) =
-                    self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
-                {
-                    return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
-                }
-            } else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
-                let expr_id = self.expr_id(db, &rec_lit.into())?;
-                if let Some(VariantId::EnumVariantId(variant)) =
-                    self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
-                {
-                    return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
-                }
-            } else {
-                let record_pat = parent().and_then(ast::RecordPat::cast).map(ast::Pat::from);
-                let tuple_struct_pat =
-                    || parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from);
-                if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
-                    let pat_id = self.pat_id(&pat)?;
-                    let variant_res_for_pat =
-                        self.infer.as_ref()?.variant_resolution_for_pat(pat_id);
-                    if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat {
-                        return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
-                    }
-                }
+        if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
+            let expr_id = self.expr_id(db, &path_expr.into())?;
+            let infer = self.infer.as_ref()?;
+            if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
+                return Some(PathResolution::Def(AssocItem::from(assoc).into()));
+            }
+            if let Some(VariantId::EnumVariantId(variant)) =
+                infer.variant_resolution_for_expr(expr_id)
+            {
+                return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
+            }
+            prefer_value_ns = true;
+        } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
+            let pat_id = self.pat_id(&path_pat.into())?;
+            if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
+                return Some(PathResolution::Def(AssocItem::from(assoc).into()));
+            }
+            if let Some(VariantId::EnumVariantId(variant)) =
+                self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
+            {
+                return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
+            }
+        } else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
+            let expr_id = self.expr_id(db, &rec_lit.into())?;
+            if let Some(VariantId::EnumVariantId(variant)) =
+                self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
+            {
+                return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
+            }
+        }
+
+        let record_pat = parent().and_then(ast::RecordPat::cast).map(ast::Pat::from);
+        let tuple_struct_pat = || parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from);
+        if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
+            let pat_id = self.pat_id(&pat)?;
+            let variant_res_for_pat = self.infer.as_ref()?.variant_resolution_for_pat(pat_id);
+            if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat {
+                return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
             }
-            None
-        })();
-        if let Some(_) = resolved {
-            return resolved;
         }
 
         // This must be a normal source file rather than macro file.
@@ -389,7 +381,7 @@ impl SourceAnalyzer {
             let builtin = name_ref.as_ref().and_then(|name_ref| {
                 BuiltinAttr::by_name(db, self.resolver.krate().into(), &name_ref.text())
             });
-            if let Some(_) = builtin {
+            if let builtin @ Some(_) = builtin {
                 return builtin.map(PathResolution::BuiltinAttr);
             }
             return match resolve_hir_path_as_macro(db, &self.resolver, &hir_path) {
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index 8e0bb0c34d..ffb733c2b9 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -57,6 +57,10 @@ impl FunctionData {
             flags.bits |= FnFlags::IS_VARARGS;
         }
 
+        if matches!(loc.container, ItemContainerId::ExternBlockId(_)) {
+            flags.bits |= FnFlags::IS_IN_EXTERN_BLOCK;
+        }
+
         let legacy_const_generics_indices = item_tree
             .attrs(db, krate, ModItem::from(loc.id.value).into())
             .by_key("rustc_legacy_const_generics")
@@ -110,6 +114,10 @@ impl FunctionData {
         self.flags.bits & FnFlags::IS_UNSAFE != 0
     }
 
+    pub fn is_in_extern_block(&self) -> bool {
+        self.flags.bits & FnFlags::IS_IN_EXTERN_BLOCK != 0
+    }
+
     pub fn is_varargs(&self) -> bool {
         self.flags.bits & FnFlags::IS_VARARGS != 0
     }
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index bf60c6bc6a..4bde87b8d4 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -612,6 +612,9 @@ impl FnFlags {
     pub(crate) const IS_CONST: u8 = 1 << 3;
     pub(crate) const IS_ASYNC: u8 = 1 << 4;
     pub(crate) const IS_UNSAFE: u8 = 1 << 5;
+    /// Whether the function is located in an `extern` block (*not* whether it is an
+    /// `extern "abi" fn`).
+    pub(crate) const IS_IN_EXTERN_BLOCK: u8 = 1 << 6;
     pub(crate) const IS_VARARGS: u8 = 1 << 7;
 }
 
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index d6c5feefa3..3fa2d9d32c 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -295,13 +295,13 @@ impl<'a> Ctx<'a> {
                         let mut pat = param.pat();
                         // FIXME: This really shouldn't be here, in fact FunctionData/ItemTree's function shouldn't know about
                         // pattern names at all
-                        let name = 'name: loop {
+                        let name = loop {
                             match pat {
                                 Some(ast::Pat::RefPat(ref_pat)) => pat = ref_pat.pat(),
                                 Some(ast::Pat::IdentPat(ident)) => {
-                                    break 'name ident.name().map(|it| it.as_name())
+                                    break ident.name().map(|it| it.as_name())
                                 }
-                                _ => break 'name None,
+                                _ => break None,
                             }
                         };
                         self.data().params.alloc(Param::Normal(name, ty))
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index f7031a8546..9e1f934034 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -19,8 +19,7 @@ use hir_def::{
     adt::VariantData,
     expr::{Pat, PatId},
     src::HasSource,
-    AdtId, AttrDefId, ConstId, EnumId, FunctionId, ItemContainerId, Lookup, ModuleDefId, StaticId,
-    StructId,
+    AdtId, AttrDefId, ConstId, EnumId, FunctionId, Lookup, ModuleDefId, StaticId, StructId,
 };
 use hir_expand::{
     name::{AsName, Name},
@@ -199,7 +198,7 @@ impl<'a> DeclValidator<'a> {
 
     fn validate_func(&mut self, func: FunctionId) {
         let data = self.db.function_data(func);
-        if matches!(func.lookup(self.db.upcast()).container, ItemContainerId::ExternBlockId(_)) {
+        if data.is_in_extern_block() {
             cov_mark::hit!(extern_func_incorrect_case_ignored);
             return;
         }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index eb74809bfe..2609a60794 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -172,6 +172,16 @@ impl<'a> HirFormatter<'a> {
         self.fmt.write_str(&self.buf).map_err(HirDisplayError::from)
     }
 
+    pub fn write_str(&mut self, s: &str) -> Result<(), HirDisplayError> {
+        self.fmt.write_str(s)?;
+        Ok(())
+    }
+
+    pub fn write_char(&mut self, c: char) -> Result<(), HirDisplayError> {
+        self.fmt.write_char(c)?;
+        Ok(())
+    }
+
     pub fn should_truncate(&self) -> bool {
         match self.max_size {
             Some(max_size) => self.curr_size >= max_size,
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 373196969a..81134f666b 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -1046,7 +1046,7 @@ fn named_associated_type_shorthand_candidates<R>(
                 ),
                 _ => None,
             });
-            if let Some(_) = res {
+            if let res @ Some(_) = res {
                 return res;
             }
             // Handle `Self::Type` referring to own associated type in trait definitions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index ae9be8adbd..23b995dbb8 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -152,7 +152,7 @@ pub(crate) fn hover(
         let res = descended
             .iter()
             .find_map(|token| hover_type_fallback(sema, config, token, &original_token));
-        if let Some(_) = res {
+        if let res @ Some(_) = res {
             return res;
         }
     }


Test patch:
diff --git a/crates/ide/src/doc_links/tests.rs b/crates/ide/src/doc_links/tests.rs
index 86fed390a8..477326c61f 100644
--- a/crates/ide/src/doc_links/tests.rs
+++ b/crates/ide/src/doc_links/tests.rs
@@ -299,107 +299,23 @@ fn foo() {
 }
 
 #[test]
-fn doc_links_items_simple() {
-    check_doc_links(
-        r#"
-//- /main.rs crate:main deps:krate
-/// [`krate`]
-//! [`Trait`]
-//! [`function`]
-//! [`CONST`]
-//! [`STATIC`]
-//! [`Struct`]
-//! [`Enum`]
-//! [`Union`]
-//! [`Type`]
-//! [`module`]
-use self$0;
-
-const CONST: () = ();
-   // ^^^^^ CONST
-static STATIC: () = ();
-    // ^^^^^^ STATIC
-trait Trait {
-   // ^^^^^ Trait
-}
-fn function() {}
-// ^^^^^^^^ function
-struct Struct;
-    // ^^^^^^ Struct
-enum Enum {}
-  // ^^^^ Enum
-union Union {__: ()}
-   // ^^^^^ Union
-type Type = ();
-  // ^^^^ Type
-mod module {}
- // ^^^^^^ module
-//- /krate.rs crate:krate
-// empty
-//^file krate
-"#,
-    )
-}
-
-#[test]
-fn doc_links_inherent_impl_items() {
-    check_doc_links(
-        r#"
-// /// [`Struct::CONST`]
-// /// [`Struct::function`]
-/// FIXME #9694
-struct Struct$0;
-
-impl Struct {
-    const CONST: () = ();
-    fn function() {}
-}
-"#,
-    )
-}
-
-#[test]
-fn doc_links_trait_impl_items() {
-    check_doc_links(
-        r#"
-trait Trait {
-    type Type;
-    const CONST: usize;
-    fn function();
-}
-// /// [`Struct::Type`]
-// /// [`Struct::CONST`]
-// /// [`Struct::function`]
-/// FIXME #9694
-struct Struct$0;
-
-impl Trait for Struct {
-    type Type = ();
-    const CONST: () = ();
-    fn function() {}
-}
-"#,
-    )
-}
-
-#[test]
-fn doc_links_trait_items() {
+fn test_trait_items() {
     check_doc_links(
         r#"
 /// [`Trait`]
 /// [`Trait::Type`]
 /// [`Trait::CONST`]
-/// [`Trait::function`]
+/// [`Trait::func`]
 trait Trait$0 {
    // ^^^^^ Trait
-type Type;
-  // ^^^^ Trait::Type
-const CONST: usize;
-   // ^^^^^ Trait::CONST
-fn function();
-// ^^^^^^^^ Trait::function
-}
-    "#,
+    type Type;
+      // ^^^^ Trait::Type
+    const CONST: usize;
+       // ^^^^^ Trait::CONST
+    fn func();
+    // ^^^^ Trait::func
+}
+        "#,
     )
 }
 
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
index 7bb7ddd280..1abb6eb8f3 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
@@ -118,7 +118,6 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="angle">&lt;</span><span class="keyword">const</span> <span class="const_param declaration">FOO</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">usize</span> <span class="brace">{</span>
-    <span class="function">const_param</span><span class="operator">::</span><span class="angle">&lt;</span><span class="brace">{</span> <span class="const_param">FOO</span> <span class="brace">}</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="const_param">FOO</span>
 <span class="brace">}</span>
 
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index e436a0574b..d768669594 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -172,7 +172,6 @@ fn never() -> ! {
 }
 
 fn const_param<const FOO: usize>() -> usize {
-    const_param::<{ FOO }>();
     FOO
 }