Repository: rust-lang/rust-analyzer
Pull request #18991 (2025-01-21 12:13:45)

Keep already computed inlay hint properties instead of late resolving them
Now that we do lazy properties here properly we can keep the ones that we can't resolve lazily (which almost never happens)


Patch:
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index 16c7b5ca00..1327bb3ab5 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -1381,9 +1381,6 @@ impl ExprCollector<'_> {
                 }
             }
             ast::Stmt::Item(ast::Item::MacroDef(macro_)) => {
-                if self.check_cfg(&macro_).is_none() {
-                    return;
-                }
                 let Some(name) = macro_.name() else {
                     statements.push(Statement::Item(Item::Other));
                     return;
@@ -1393,9 +1390,6 @@ impl ExprCollector<'_> {
                 self.collect_macro_def(statements, macro_id);
             }
             ast::Stmt::Item(ast::Item::MacroRules(macro_)) => {
-                if self.check_cfg(&macro_).is_none() {
-                    return;
-                }
                 let Some(name) = macro_.name() else {
                     statements.push(Statement::Item(Item::Other));
                     return;
diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs
index bb780277ef..a3ffdf770e 100644
--- a/crates/hir-def/src/import_map.rs
+++ b/crates/hir-def/src/import_map.rs
@@ -168,7 +168,6 @@ impl ImportMap {
                         match import {
                             ImportOrExternCrate::ExternCrate(id) => Some(id.into()),
                             ImportOrExternCrate::Import(id) => Some(id.import.into()),
-                            ImportOrExternCrate::Glob(id) => Some(id.into()),
                         }
                     } else {
                         match item {
diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs
index 0ece878b83..0fec767410 100644
--- a/crates/hir-def/src/item_scope.rs
+++ b/crates/hir-def/src/item_scope.rs
@@ -31,88 +31,32 @@ pub struct PerNsGlobImports {
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub enum ImportOrExternCrate {
-    Glob(UseId),
     Import(ImportId),
     ExternCrate(ExternCrateId),
 }
 
-impl From<ImportOrGlob> for ImportOrExternCrate {
-    fn from(value: ImportOrGlob) -> Self {
-        match value {
-            ImportOrGlob::Glob(it) => ImportOrExternCrate::Glob(it),
-            ImportOrGlob::Import(it) => ImportOrExternCrate::Import(it),
-        }
-    }
-}
-
-impl From<ImportType> for ImportOrExternCrate {
-    fn from(value: ImportType) -> Self {
-        match value {
-            ImportType::Glob(it) => ImportOrExternCrate::Glob(it),
-            ImportType::Import(it) => ImportOrExternCrate::Import(it),
-            ImportType::ExternCrate(it) => ImportOrExternCrate::ExternCrate(it),
-        }
-    }
-}
-
-impl ImportOrExternCrate {
-    pub fn into_import(self) -> Option<ImportOrGlob> {
-        match self {
-            ImportOrExternCrate::Import(it) => Some(ImportOrGlob::Import(it)),
-            ImportOrExternCrate::Glob(it) => Some(ImportOrGlob::Glob(it)),
-            _ => None,
-        }
-    }
-}
-
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum ImportOrGlob {
-    Glob(UseId),
+pub(crate) enum ImportType {
     Import(ImportId),
+    Glob(UseId),
+    ExternCrate(ExternCrateId),
 }
 
-impl ImportOrGlob {
+impl ImportOrExternCrate {
     pub fn into_import(self) -> Option<ImportId> {
         match self {
-            ImportOrGlob::Import(it) => Some(it),
+            ImportOrExternCrate::Import(it) => Some(it),
             _ => None,
         }
     }
 }
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub(crate) enum ImportType {
-    Import(ImportId),
-    Glob(UseId),
-    ExternCrate(ExternCrateId),
-}
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub enum ImportOrDef {
     Import(ImportId),
-    Glob(UseId),
     ExternCrate(ExternCrateId),
     Def(ModuleDefId),
 }
-
-impl From<ImportOrExternCrate> for ImportOrDef {
-    fn from(value: ImportOrExternCrate) -> Self {
-        match value {
-            ImportOrExternCrate::Import(it) => ImportOrDef::Import(it),
-            ImportOrExternCrate::Glob(it) => ImportOrDef::Glob(it),
-            ImportOrExternCrate::ExternCrate(it) => ImportOrDef::ExternCrate(it),
-        }
-    }
-}
-
-impl From<ImportOrGlob> for ImportOrDef {
-    fn from(value: ImportOrGlob) -> Self {
-        match value {
-            ImportOrGlob::Import(it) => ImportOrDef::Import(it),
-            ImportOrGlob::Glob(it) => ImportOrDef::Glob(it),
-        }
-    }
-}
-
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
 pub struct ImportId {
     pub import: UseId,
@@ -152,8 +96,8 @@ pub struct ItemScope {
 
     // the resolutions of the imports of this scope
     use_imports_types: FxHashMap<ImportOrExternCrate, ImportOrDef>,
-    use_imports_values: FxHashMap<ImportOrGlob, ImportOrDef>,
-    use_imports_macros: FxHashMap<ImportOrGlob, ImportOrDef>,
+    use_imports_values: FxHashMap<ImportId, ImportOrDef>,
+    use_imports_macros: FxHashMap<ImportId, ImportOrDef>,
 
     use_decls: Vec<UseId>,
     extern_crate_decls: Vec<ExternCrateId>,
@@ -218,7 +162,7 @@ impl ItemScope {
             .map(move |name| (name, self.get(name)))
     }
 
-    pub fn values(&self) -> impl Iterator<Item = (&Name, Item<ModuleDefId, ImportOrGlob>)> + '_ {
+    pub fn values(&self) -> impl Iterator<Item = (&Name, Item<ModuleDefId, ImportId>)> + '_ {
         self.values.iter().map(|(n, &i)| (n, i))
     }
 
@@ -228,7 +172,7 @@ impl ItemScope {
         self.types.iter().map(|(n, &i)| (n, i))
     }
 
-    pub fn macros(&self) -> impl Iterator<Item = (&Name, Item<MacroId, ImportOrGlob>)> + '_ {
+    pub fn macros(&self) -> impl Iterator<Item = (&Name, Item<MacroId, ImportId>)> + '_ {
         self.macros.iter().map(|(n, &i)| (n, i))
     }
 
@@ -239,7 +183,6 @@ impl ItemScope {
             .filter_map(ImportOrExternCrate::into_import)
             .chain(self.use_imports_values.keys().copied())
             .chain(self.use_imports_macros.keys().copied())
-            .filter_map(ImportOrGlob::into_import)
             .sorted()
             .dedup()
     }
@@ -249,7 +192,7 @@ impl ItemScope {
 
         let mut def_map;
         let mut scope = self;
-        while let Some(&m) = scope.use_imports_macros.get(&ImportOrGlob::Import(import)) {
+        while let Some(&m) = scope.use_imports_macros.get(&import) {
             match m {
                 ImportOrDef::Import(i) => {
                     let module_id = i.import.lookup(db).container;
@@ -281,7 +224,7 @@ impl ItemScope {
             }
         }
         let mut scope = self;
-        while let Some(&m) = scope.use_imports_values.get(&ImportOrGlob::Import(import)) {
+        while let Some(&m) = scope.use_imports_values.get(&import) {
             match m {
                 ImportOrDef::Import(i) => {
                     let module_id = i.import.lookup(db).container;
@@ -571,11 +514,29 @@ impl ItemScope {
                         }
                         _ => _ = glob_imports.types.remove(&lookup),
                     }
-                    let import = import.map(Into::into);
+                    let import = match import {
+                        Some(ImportType::ExternCrate(extern_crate)) => {
+                            Some(ImportOrExternCrate::ExternCrate(extern_crate))
+                        }
+                        Some(ImportType::Import(import)) => {
+                            Some(ImportOrExternCrate::Import(import))
+                        }
+                        None | Some(ImportType::Glob(_)) => None,
+                    };
                     let prev = std::mem::replace(&mut fld.import, import);
                     if let Some(import) = import {
-                        self.use_imports_types
-                            .insert(import, prev.map_or(ImportOrDef::Def(fld.def), Into::into));
+                        self.use_imports_types.insert(
+                            import,
+                            match prev {
+                                Some(ImportOrExternCrate::Import(import)) => {
+                                    ImportOrDef::Import(import)
+                                }
+                                Some(ImportOrExternCrate::ExternCrate(import)) => {
+                                    ImportOrDef::ExternCrate(import)
+                                }
+                                None => ImportOrDef::Def(fld.def),
+                            },
+                        );
                     }
                     entry.insert(fld);
                     changed = true;
@@ -591,12 +552,28 @@ impl ItemScope {
                         }
                         _ => {
                             if glob_imports.types.remove(&lookup) {
-                                let import = import.map(Into::into);
+                                let import = match import {
+                                    Some(ImportType::ExternCrate(extern_crate)) => {
+                                        Some(ImportOrExternCrate::ExternCrate(extern_crate))
+                                    }
+                                    Some(ImportType::Import(import)) => {
+                                        Some(ImportOrExternCrate::Import(import))
+                                    }
+                                    None | Some(ImportType::Glob(_)) => None,
+                                };
                                 let prev = std::mem::replace(&mut fld.import, import);
                                 if let Some(import) = import {
                                     self.use_imports_types.insert(
                                         import,
-                                        prev.map_or(ImportOrDef::Def(fld.def), Into::into),
+                                        match prev {
+                                            Some(ImportOrExternCrate::Import(import)) => {
+                                                ImportOrDef::Import(import)
+                                            }
+                                            Some(ImportOrExternCrate::ExternCrate(import)) => {
+                                                ImportOrDef::ExternCrate(import)
+                                            }
+                                            None => ImportOrDef::Def(fld.def),
+                                        },
                                     );
                                 }
                                 cov_mark::hit!(import_shadowed);
@@ -620,14 +597,18 @@ impl ItemScope {
                         _ => _ = glob_imports.values.remove(&lookup),
                     }
                     let import = match import {
-                        Some(ImportType::Import(import)) => Some(ImportOrGlob::Import(import)),
-                        Some(ImportType::Glob(u)) => Some(ImportOrGlob::Glob(u)),
+                        Some(ImportType::Import(import)) => Some(import),
                         _ => None,
                     };
                     let prev = std::mem::replace(&mut fld.import, import);
                     if let Some(import) = import {
-                        self.use_imports_values
-                            .insert(import, prev.map_or(ImportOrDef::Def(fld.def), Into::into));
+                        self.use_imports_values.insert(
+                            import,
+                            match prev {
+                                Some(import) => ImportOrDef::Import(import),
+                                None => ImportOrDef::Def(fld.def),
+                            },
+                        );
                     }
                     entry.insert(fld);
                     changed = true;
@@ -635,16 +616,19 @@ impl ItemScope {
                 Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
                     if glob_imports.values.remove(&lookup) {
                         cov_mark::hit!(import_shadowed);
-
                         let import = match import {
-                            Some(ImportType::Import(import)) => Some(ImportOrGlob::Import(import)),
-                            Some(ImportType::Glob(u)) => Some(ImportOrGlob::Glob(u)),
+                            Some(ImportType::Import(import)) => Some(import),
                             _ => None,
                         };
                         let prev = std::mem::replace(&mut fld.import, import);
                         if let Some(import) = import {
-                            self.use_imports_values
-                                .insert(import, prev.map_or(ImportOrDef::Def(fld.def), Into::into));
+                            self.use_imports_values.insert(
+                                import,
+                                match prev {
+                                    Some(import) => ImportOrDef::Import(import),
+                                    None => ImportOrDef::Def(fld.def),
+                                },
+                            );
                         }
                         entry.insert(fld);
                         changed = true;
@@ -665,15 +649,17 @@ impl ItemScope {
                         _ => _ = glob_imports.macros.remove(&lookup),
                     }
                     let import = match import {
-                        Some(ImportType::Import(import)) => Some(ImportOrGlob::Import(import)),
-                        Some(ImportType::Glob(u)) => Some(ImportOrGlob::Glob(u)),
+                        Some(ImportType::Import(import)) => Some(import),
                         _ => None,
                     };
                     let prev = std::mem::replace(&mut fld.import, import);
                     if let Some(import) = import {
                         self.use_imports_macros.insert(
                             import,
-                            prev.map_or_else(|| ImportOrDef::Def(fld.def.into()), Into::into),
+                            match prev {
+                                Some(import) => ImportOrDef::Import(import),
+                                None => ImportOrDef::Def(fld.def.into()),
+                            },
                         );
                     }
                     entry.insert(fld);
@@ -683,15 +669,17 @@ impl ItemScope {
                     if glob_imports.macros.remove(&lookup) {
                         cov_mark::hit!(import_shadowed);
                         let import = match import {
-                            Some(ImportType::Import(import)) => Some(ImportOrGlob::Import(import)),
-                            Some(ImportType::Glob(u)) => Some(ImportOrGlob::Glob(u)),
+                            Some(ImportType::Import(import)) => Some(import),
                             _ => None,
                         };
                         let prev = std::mem::replace(&mut fld.import, import);
                         if let Some(import) = import {
                             self.use_imports_macros.insert(
                                 import,
-                                prev.map_or_else(|| ImportOrDef::Def(fld.def.into()), Into::into),
+                                match prev {
+                                    Some(import) => ImportOrDef::Import(import),
+                                    None => ImportOrDef::Def(fld.def.into()),
+                                },
                             );
                         }
                         entry.insert(fld);
@@ -716,27 +704,16 @@ impl ItemScope {
             .map(|def| &mut def.vis)
             .chain(self.values.values_mut().map(|def| &mut def.vis))
             .chain(self.unnamed_trait_imports.values_mut().map(|def| &mut def.vis))
-            .for_each(|vis| match vis {
-                &mut Visibility::Module(_, visibility_explicitness) => {
-                    *vis = Visibility::Module(this_module, visibility_explicitness)
-                }
-                Visibility::Public => {
-                    *vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit)
-                }
+            .for_each(|vis| {
+                *vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit)
             });
 
         for mac in self.macros.values_mut() {
             if matches!(mac.def, MacroId::ProcMacroId(_) if mac.import.is_none()) {
                 continue;
             }
-            match mac.vis {
-                Visibility::Module(_, visibility_explicitness) => {
-                    mac.vis = Visibility::Module(this_module, visibility_explicitness)
-                }
-                Visibility::Public => {
-                    mac.vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit)
-                }
-            }
+
+            mac.vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit);
         }
     }
 
@@ -755,25 +732,20 @@ impl ItemScope {
                 buf.push_str(" t");
                 match import {
                     Some(ImportOrExternCrate::Import(_)) => buf.push('i'),
-                    Some(ImportOrExternCrate::Glob(_)) => buf.push('g'),
                     Some(ImportOrExternCrate::ExternCrate(_)) => buf.push('e'),
                     None => (),
                 }
             }
             if let Some(Item { import, .. }) = def.values {
                 buf.push_str(" v");
-                match import {
-                    Some(ImportOrGlob::Import(_)) => buf.push('i'),
-                    Some(ImportOrGlob::Glob(_)) => buf.push('g'),
-                    None => (),
+                if import.is_some() {
+                    buf.push('i');
                 }
             }
             if let Some(Item { import, .. }) = def.macros {
                 buf.push_str(" m");
-                match import {
-                    Some(ImportOrGlob::Import(_)) => buf.push('i'),
-                    Some(ImportOrGlob::Glob(_)) => buf.push('g'),
-                    None => (),
+                if import.is_some() {
+                    buf.push('i');
                 }
             }
             if def.is_none() {
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 5058d15f34..1e4b42dff5 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -28,7 +28,7 @@ use triomphe::Arc;
 use crate::{
     attr::Attrs,
     db::DefDatabase,
-    item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob, ImportType, PerNsGlobImports},
+    item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
     item_tree::{
         self, AttrOwner, FieldsShape, FileItemTreeId, ImportKind, ItemTree, ItemTreeId,
         ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, UseTreeKind,
@@ -527,10 +527,7 @@ impl DefCollector<'_> {
                 // FIXME: This should specifically look for a glob import somehow and record that here
                 self.def_map.prelude = Some((
                     m,
-                    import
-                        .and_then(ImportOrExternCrate::into_import)
-                        .and_then(ImportOrGlob::into_import)
-                        .map(|it| it.import),
+                    import.and_then(ImportOrExternCrate::into_import).map(|it| it.import),
                 ));
             }
             types => {
diff --git a/crates/hir-def/src/per_ns.rs b/crates/hir-def/src/per_ns.rs
index 339786fc01..899dd4afff 100644
--- a/crates/hir-def/src/per_ns.rs
+++ b/crates/hir-def/src/per_ns.rs
@@ -6,7 +6,7 @@
 use bitflags::bitflags;
 
 use crate::{
-    item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob, ItemInNs},
+    item_scope::{ImportId, ImportOrExternCrate, ItemInNs},
     visibility::Visibility,
     MacroId, ModuleDefId,
 };
@@ -36,8 +36,8 @@ pub struct Item<Def, Import = ImportId> {
 }
 
 pub type TypesItem = Item<ModuleDefId, ImportOrExternCrate>;
-pub type ValuesItem = Item<ModuleDefId, ImportOrGlob>;
-pub type MacrosItem = Item<MacroId, ImportOrGlob>;
+pub type ValuesItem = Item<ModuleDefId>;
+pub type MacrosItem = Item<MacroId>;
 
 #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
 pub struct PerNs {
@@ -59,7 +59,7 @@ impl PerNs {
         PerNs { types: None, values: None, macros: None }
     }
 
-    pub fn values(def: ModuleDefId, vis: Visibility, import: Option<ImportOrGlob>) -> PerNs {
+    pub fn values(def: ModuleDefId, vis: Visibility, import: Option<ImportId>) -> PerNs {
         PerNs { types: None, values: Some(Item { def, vis, import }), macros: None }
     }
 
@@ -84,7 +84,7 @@ impl PerNs {
         }
     }
 
-    pub fn macros(def: MacroId, vis: Visibility, import: Option<ImportOrGlob>) -> PerNs {
+    pub fn macros(def: MacroId, vis: Visibility, import: Option<ImportId>) -> PerNs {
         PerNs { types: None, values: None, macros: Some(Item { def, vis, import }) }
     }
 
@@ -108,7 +108,7 @@ impl PerNs {
         self.values.map(|it| it.def)
     }
 
-    pub fn take_values_import(self) -> Option<(ModuleDefId, Option<ImportOrGlob>)> {
+    pub fn take_values_import(self) -> Option<(ModuleDefId, Option<ImportId>)> {
         self.values.map(|it| (it.def, it.import))
     }
 
@@ -116,7 +116,7 @@ impl PerNs {
         self.macros.map(|it| it.def)
     }
 
-    pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportOrGlob>)> {
+    pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportId>)> {
         self.macros.map(|it| (it.def, it.import))
     }
 
@@ -159,12 +159,14 @@ impl PerNs {
             .map(|it| (ItemInNs::Types(it.def), it.import))
             .into_iter()
             .chain(
-                self.values
-                    .map(|it| (ItemInNs::Values(it.def), it.import.map(ImportOrExternCrate::from))),
+                self.values.map(|it| {
+                    (ItemInNs::Values(it.def), it.import.map(ImportOrExternCrate::Import))
+                }),
             )
             .chain(
-                self.macros
-                    .map(|it| (ItemInNs::Macros(it.def), it.import.map(ImportOrExternCrate::from))),
+                self.macros.map(|it| {
+                    (ItemInNs::Macros(it.def), it.import.map(ImportOrExternCrate::Import))
+                }),
             )
     }
 }
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 8c556d8a8c..0b9b6da8d5 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -19,7 +19,7 @@ use crate::{
     db::DefDatabase,
     generics::{GenericParams, TypeOrConstParamData},
     hir::{BindingId, ExprId, LabelId},
-    item_scope::{BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, BUILTIN_SCOPE},
+    item_scope::{BuiltinShadowMode, ImportId, ImportOrExternCrate, BUILTIN_SCOPE},
     lang_item::LangItemTarget,
     nameres::{DefMap, MacroSubNs, ResolvePathResultPrefixInfo},
     path::{ModPath, Path, PathKind},
@@ -107,7 +107,7 @@ pub enum TypeNs {
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum ResolveValueResult {
-    ValueNs(ValueNs, Option<ImportOrGlob>),
+    ValueNs(ValueNs, Option<ImportId>),
     Partial(TypeNs, usize, Option<ImportOrExternCrate>),
 }
 
@@ -485,7 +485,7 @@ impl Resolver {
         db: &dyn DefDatabase,
         path: &ModPath,
         expected_macro_kind: Option<MacroSubNs>,
-    ) -> Option<(MacroId, Option<ImportOrGlob>)> {
+    ) -> Option<(MacroId, Option<ImportId>)> {
         let (item_map, module) = self.item_scope();
         item_map
             .resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind)
@@ -1014,7 +1014,7 @@ impl ModuleItemMap {
     }
 }
 
-fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportOrGlob>)> {
+fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportId>)> {
     let (def, import) = per_ns.take_values_import()?;
     let res = match def {
         ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
diff --git a/crates/hir-ty/src/autoderef.rs b/crates/hir-ty/src/autoderef.rs
index 2c7076da11..2b5342314a 100644
--- a/crates/hir-ty/src/autoderef.rs
+++ b/crates/hir-ty/src/autoderef.rs
@@ -17,7 +17,7 @@ use crate::{
     TraitEnvironment, Ty, TyBuilder, TyKind,
 };
 
-static AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(20);
+static AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(10);
 
 #[derive(Debug)]
 pub(crate) enum AutoderefKind {
@@ -49,7 +49,7 @@ pub fn autoderef(
         // If the deref chain contains a cycle (e.g. `A` derefs to `B` and `B` derefs to `A`), we
         // would revisit some already visited types. Stop here to avoid duplication.
         //
-        // XXX: The recursion limit for `Autoderef` is currently 20, so `Vec::contains()` shouldn't
+        // XXX: The recursion limit for `Autoderef` is currently 10, so `Vec::contains()` shouldn't
         // be too expensive. Replace this duplicate check with `FxHashSet` if it proves to be more
         // performant.
         if v.contains(&resolved) {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4938478bb1..0cbc75726b 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -45,7 +45,7 @@ use hir_def::{
     body::BodyDiagnostic,
     data::{adt::VariantData, TraitFlags},
     generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
-    hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, Pat},
+    hir::{BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat},
     item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode},
     lang_item::LangItemTarget,
     layout::{self, ReprOptions, TargetDataLayout},
@@ -2470,20 +2470,31 @@ impl Param {
     }
 
     pub fn as_local(&self, db: &dyn HirDatabase) -> Option<Local> {
-        let parent = match self.func {
-            Callee::Def(CallableDefId::FunctionId(it)) => DefWithBodyId::FunctionId(it),
-            Callee::Closure(closure, _) => db.lookup_intern_closure(closure.into()).0,
-            _ => return None,
-        };
-        let body = db.body(parent);
-        if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) {
-            Some(Local { parent, binding_id: self_param })
-        } else if let Pat::Bind { id, .. } =
-            &body[body.params[self.idx - body.self_param.is_some() as usize]]
-        {
-            Some(Local { parent, binding_id: *id })
-        } else {
-            None
+        match self.func {
+            Callee::Def(CallableDefId::FunctionId(it)) => {
+                let parent = DefWithBodyId::FunctionId(it);
+                let body = db.body(parent);
+                if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) {
+                    Some(Local { parent, binding_id: self_param })
+                } else if let Pat::Bind { id, .. } =
+                    &body[body.params[self.idx - body.self_param.is_some() as usize]]
+                {
+                    Some(Local { parent, binding_id: *id })
+                } else {
+                    None
+                }
+            }
+            Callee::Closure(closure, _) => {
+                let c = db.lookup_intern_closure(closure.into());
+                let body = db.body(c.0);
+                if let Expr::Closure { args, .. } = &body[c.1] {
+                    if let Pat::Bind { id, .. } = &body[args[self.idx]] {
+                        return Some(Local { parent: c.0, binding_id: *id });
+                    }
+                }
+                None
+            }
+            _ => None,
         }
     }
 
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 09470bed9c..708db2c08d 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -1483,8 +1483,6 @@ impl<'db> SemanticsImpl<'db> {
         self.analyze(try_expr.syntax())?.resolve_try_expr(self.db, try_expr)
     }
 
-    // This does not resolve the method call to the correct trait impl!
-    // We should probably fix that.
     pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
         self.analyze(call.syntax())?.resolve_method_call_as_callable(self.db, call)
     }
diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs
index f379a2d4d6..a6b8ed70c3 100644
--- a/crates/hir/src/symbols.rs
+++ b/crates/hir/src/symbols.rs
@@ -3,7 +3,7 @@
 use either::Either;
 use hir_def::{
     db::DefDatabase,
-    item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob},
+    item_scope::{ImportId, ImportOrExternCrate},
     per_ns::Item,
     src::{HasChildSource, HasSource},
     visibility::{Visibility, VisibilityExplicitness},
@@ -55,10 +55,9 @@ impl DeclarationLocation {
 }
 
 /// Represents an outstanding module that the symbol collector must collect symbols from.
-#[derive(Debug)]
 struct SymbolCollectorWork {
     module_id: ModuleId,
-    parent: Option<Name>,
+    parent: Option<DefWithBodyId>,
 }
 
 pub struct SymbolCollector<'a> {
@@ -82,15 +81,7 @@ impl<'a> SymbolCollector<'a> {
         }
     }
 
-    pub fn new_module(db: &dyn HirDatabase, module: Module) -> Box<[FileSymbol]> {
-        let mut symbol_collector = SymbolCollector::new(db);
-        symbol_collector.collect(module);
-        symbol_collector.finish()
-    }
-
     pub fn collect(&mut self, module: Module) {
-        let _p = tracing::info_span!("SymbolCollector::collect", ?module).entered();
-        tracing::info!(?module, "SymbolCollector::collect",);
         self.edition = module.krate().edition(self.db);
 
         // The initial work is the root module we're collecting, additional work will
@@ -106,12 +97,16 @@ impl<'a> SymbolCollector<'a> {
         self.symbols.into_iter().collect()
     }
 
+    pub fn collect_module(db: &dyn HirDatabase, module: Module) -> Box<[FileSymbol]> {
+        let mut symbol_collector = SymbolCollector::new(db);
+        symbol_collector.collect(module);
+        symbol_collector.finish()
+    }
+
     fn do_work(&mut self, work: SymbolCollectorWork) {
-        let _p = tracing::info_span!("SymbolCollector::do_work", ?work).entered();
-        tracing::info!(?work, "SymbolCollector::do_work");
         self.db.unwind_if_cancelled();
 
-        let parent_name = work.parent.map(|name| name.as_str().to_smolstr());
+        let parent_name = work.parent.and_then(|id| self.def_with_body_id_name(id));
         self.with_container_name(parent_name, |s| s.collect_from_module(work.module_id));
     }
 
@@ -121,18 +116,18 @@ impl<'a> SymbolCollector<'a> {
                 ModuleDefId::ModuleId(id) => this.push_module(id, name),
                 ModuleDefId::FunctionId(id) => {
                     this.push_decl(id, name, false);
-                    this.collect_from_body(id, Some(name.clone()));
+                    this.collect_from_body(id);
                 }
                 ModuleDefId::AdtId(AdtId::StructId(id)) => this.push_decl(id, name, false),
                 ModuleDefId::AdtId(AdtId::EnumId(id)) => this.push_decl(id, name, false),
                 ModuleDefId::AdtId(AdtId::UnionId(id)) => this.push_decl(id, name, false),
                 ModuleDefId::ConstId(id) => {
                     this.push_decl(id, name, false);
-                    this.collect_from_body(id, Some(name.clone()));
+                    this.collect_from_body(id);
                 }
                 ModuleDefId::StaticId(id) => {
                     this.push_decl(id, name, false);
-                    this.collect_from_body(id, Some(name.clone()));
+                    this.collect_from_body(id);
                 }
                 ModuleDefId::TraitId(id) => {
                     this.push_decl(id, name, false);
@@ -240,7 +235,6 @@ impl<'a> SymbolCollector<'a> {
                 if is_explicit_import(vis) {
                     match i {
                         ImportOrExternCrate::Import(i) => push_import(self, i, name, def),
-                        ImportOrExternCrate::Glob(_) => (),
                         ImportOrExternCrate::ExternCrate(i) => {
                             push_extern_crate(self, i, name, def)
                         }
@@ -255,10 +249,7 @@ impl<'a> SymbolCollector<'a> {
         for (name, Item { def, vis, import }) in scope.macros() {
             if let Some(i) = import {
                 if is_explicit_import(vis) {
-                    match i {
-                        ImportOrGlob::Import(i) => push_import(self, i, name, def.into()),
-                        ImportOrGlob::Glob(_) => (),
-                    }
+                    push_import(self, i, name, def.into());
                 }
                 continue;
             }
@@ -269,10 +260,7 @@ impl<'a> SymbolCollector<'a> {
         for (name, Item { def, vis, import }) in scope.values() {
             if let Some(i) = import {
                 if is_explicit_import(vis) {
-                    match i {
-                        ImportOrGlob::Import(i) => push_import(self, i, name, def),
-                        ImportOrGlob::Glob(_) => (),
-                    }
+                    push_import(self, i, name, def);
                 }
                 continue;
             }
@@ -281,7 +269,7 @@ impl<'a> SymbolCollector<'a> {
         }
 
         for const_id in scope.unnamed_consts() {
-            self.collect_from_body(const_id, None);
+            self.collect_from_body(const_id);
         }
 
         for (name, id) in scope.legacy_macros() {
@@ -297,7 +285,7 @@ impl<'a> SymbolCollector<'a> {
         }
     }
 
-    fn collect_from_body(&mut self, body_id: impl Into<DefWithBodyId>, name: Option<Name>) {
+    fn collect_from_body(&mut self, body_id: impl Into<DefWithBodyId>) {
         let body_id = body_id.into();
         let body = self.db.body(body_id);
 
@@ -306,7 +294,7 @@ impl<'a> SymbolCollector<'a> {
             for (id, _) in def_map.modules() {
                 self.work.push(SymbolCollectorWork {
                     module_id: def_map.module_id(id),
-                    parent: name.clone(),
+                    parent: Some(body_id),
                 });
             }
         }
@@ -345,6 +333,24 @@ impl<'a> SymbolCollector<'a> {
         }
     }
 
+    fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option<SmolStr> {
+        match body_id {
+            DefWithBodyId::FunctionId(id) => {
+                Some(self.db.function_data(id).name.display_no_db(self.edition).to_smolstr())
+            }
+            DefWithBodyId::StaticId(id) => {
+                Some(self.db.static_data(id).name.display_no_db(self.edition).to_smolstr())
+            }
+            DefWithBodyId::ConstId(id) => {
+                Some(self.db.const_data(id).name.as_ref()?.display_no_db(self.edition).to_smolstr())
+            }
+            DefWithBodyId::VariantId(id) => {
+                Some(self.db.enum_variant_data(id).name.display_no_db(self.edition).to_smolstr())
+            }
+            DefWithBodyId::InTypeConstId(_) => Some("in type const".into()),
+        }
+    }
+
     fn push_assoc_item(&mut self, assoc_item_id: AssocItemId, name: &Name) {
         match assoc_item_id {
             AssocItemId::FunctionId(id) => self.push_decl(id, name, true),
diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs
index 0d1765a7b7..7679d9076d 100644
--- a/crates/ide-completion/src/completions/dot.rs
+++ b/crates/ide-completion/src/completions/dot.rs
@@ -42,38 +42,31 @@ pub(crate) fn complete_dot(
         item.detail("expr.await");
         item.add_to(acc, ctx.db);
 
-        if ctx.config.enable_auto_await {
-            // Completions that skip `.await`, e.g. `.await.foo()`.
-            let dot_access_kind = match &dot_access.kind {
-                DotAccessKind::Field { receiver_is_ambiguous_float_literal: _ } => {
-                    DotAccessKind::Field { receiver_is_ambiguous_float_literal: false }
-                }
-                it @ DotAccessKind::Method { .. } => *it,
-            };
-            let dot_access = DotAccess {
-                receiver: dot_access.receiver.clone(),
-                receiver_ty: Some(hir::TypeInfo {
-                    original: future_output.clone(),
-                    adjusted: None,
-                }),
-                kind: dot_access_kind,
-                ctx: dot_access.ctx,
-            };
-            complete_fields(
-                acc,
-                ctx,
-                &future_output,
-                |acc, field, ty| {
-                    acc.add_field(ctx, &dot_access, Some(await_str.clone()), field, &ty)
-                },
-                |acc, field, ty| acc.add_tuple_field(ctx, Some(await_str.clone()), field, &ty),
-                is_field_access,
-                is_method_access_with_parens,
-            );
-            complete_methods(ctx, &future_output, &traits_in_scope, |func| {
-                acc.add_method(ctx, &dot_access, func, Some(await_str.clone()), None)
-            });
-        }
+        // Completions that skip `.await`, e.g. `.await.foo()`.
+        let dot_access_kind = match &dot_access.kind {
+            DotAccessKind::Field { receiver_is_ambiguous_float_literal: _ } => {
+                DotAccessKind::Field { receiver_is_ambiguous_float_literal: false }
+            }
+            it @ DotAccessKind::Method { .. } => *it,
+        };
+        let dot_access = DotAccess {
+            receiver: dot_access.receiver.clone(),
+            receiver_ty: Some(hir::TypeInfo { original: future_output.clone(), adjusted: None }),
+            kind: dot_access_kind,
+            ctx: dot_access.ctx,
+        };
+        complete_fields(
+            acc,
+            ctx,
+            &future_output,
+            |acc, field, ty| acc.add_field(ctx, &dot_access, Some(await_str.clone()), field, &ty),
+            |acc, field, ty| acc.add_tuple_field(ctx, Some(await_str.clone()), field, &ty),
+            is_field_access,
+            is_method_access_with_parens,
+        );
+        complete_methods(ctx, &future_output, &traits_in_scope, |func| {
+            acc.add_method(ctx, &dot_access, func, Some(await_str.clone()), None)
+        });
     }
 
     complete_fields(
@@ -89,41 +82,39 @@ pub(crate) fn complete_dot(
         acc.add_method(ctx, dot_access, func, None, None)
     });
 
-    if ctx.config.enable_auto_iter {
-        // FIXME:
-        // Checking for the existence of `iter()` is complicated in our setup, because we need to substitute
-        // its return type, so we instead check for `<&Self as IntoIterator>::IntoIter`.
-        // Does <&receiver_ty as IntoIterator>::IntoIter` exist? Assume `iter` is valid
-        let iter = receiver_ty
-            .strip_references()
-            .add_reference(hir::Mutability::Shared)
+    // FIXME:
+    // Checking for the existence of `iter()` is complicated in our setup, because we need to substitute
+    // its return type, so we instead check for `<&Self as IntoIterator>::IntoIter`.
+    // Does <&receiver_ty as IntoIterator>::IntoIter` exist? Assume `iter` is valid
+    let iter = receiver_ty
+        .strip_references()
+        .add_reference(hir::Mutability::Shared)
+        .into_iterator_iter(ctx.db)
+        .map(|ty| (ty, SmolStr::new_static("iter()")));
+    // Does <receiver_ty as IntoIterator>::IntoIter` exist?
+    let into_iter = || {
+        receiver_ty
+            .clone()
             .into_iterator_iter(ctx.db)
-            .map(|ty| (ty, SmolStr::new_static("iter()")));
-        // Does <receiver_ty as IntoIterator>::IntoIter` exist?
-        let into_iter = || {
-            receiver_ty
-                .clone()
-                .into_iterator_iter(ctx.db)
-                .map(|ty| (ty, SmolStr::new_static("into_iter()")))
+            .map(|ty| (ty, SmolStr::new_static("into_iter()")))
+    };
+    if let Some((iter, iter_sym)) = iter.or_else(into_iter) {
+        // Skip iterators, e.g. complete `.iter().filter_map()`.
+        let dot_access_kind = match &dot_access.kind {
+            DotAccessKind::Field { receiver_is_ambiguous_float_literal: _ } => {
+                DotAccessKind::Field { receiver_is_ambiguous_float_literal: false }
+            }
+            it @ DotAccessKind::Method { .. } => *it,
         };
-        if let Some((iter, iter_sym)) = iter.or_else(into_iter) {
-            // Skip iterators, e.g. complete `.iter().filter_map()`.
-            let dot_access_kind = match &dot_access.kind {
-                DotAccessKind::Field { receiver_is_ambiguous_float_literal: _ } => {
-                    DotAccessKind::Field { receiver_is_ambiguous_float_literal: false }
-                }
-                it @ DotAccessKind::Method { .. } => *it,
-            };
-            let dot_access = DotAccess {
-                receiver: dot_access.receiver.clone(),
-                receiver_ty: Some(hir::TypeInfo { original: iter.clone(), adjusted: None }),
-                kind: dot_access_kind,
-                ctx: dot_access.ctx,
-            };
-            complete_methods(ctx, &iter, &traits_in_scope, |func| {
-                acc.add_method(ctx, &dot_access, func, Some(iter_sym.clone()), None)
-            });
-        }
+        let dot_access = DotAccess {
+            receiver: dot_access.receiver.clone(),
+            receiver_ty: Some(hir::TypeInfo { original: iter.clone(), adjusted: None }),
+            kind: dot_access_kind,
+            ctx: dot_access.ctx,
+        };
+        complete_methods(ctx, &iter, &traits_in_scope, |func| {
+            acc.add_method(ctx, &dot_access, func, Some(iter_sym.clone()), None)
+        });
     }
 }
 
diff --git a/crates/ide-completion/src/config.rs b/crates/ide-completion/src/config.rs
index c641df38ff..8b1ce11e8a 100644
--- a/crates/ide-completion/src/config.rs
+++ b/crates/ide-completion/src/config.rs
@@ -14,8 +14,6 @@ pub struct CompletionConfig<'a> {
     pub enable_postfix_completions: bool,
     pub enable_imports_on_the_fly: bool,
     pub enable_self_on_the_fly: bool,
-    pub enable_auto_iter: bool,
-    pub enable_auto_await: bool,
     pub enable_private_editable: bool,
     pub enable_term_search: bool,
     pub term_search_fuel: u64,
diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs
index b0a096b64a..dc2f9a7680 100644
--- a/crates/ide-completion/src/item.rs
+++ b/crates/ide-completion/src/item.rs
@@ -181,8 +181,6 @@ pub struct CompletionRelevance {
     pub postfix_match: Option<CompletionRelevancePostfixMatch>,
     /// This is set for items that are function (associated or method)
     pub function: Option<CompletionRelevanceFn>,
-    /// true when there is an `await.method()` or `iter().method()` completion.
-    pub is_skipping_completion: bool,
 }
 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
 pub struct CompletionRelevanceTraitInfo {
@@ -271,7 +269,6 @@ impl CompletionRelevance {
             postfix_match,
             trait_,
             function,
-            is_skipping_completion,
         } = self;
 
         // only applicable for completions within use items
@@ -299,12 +296,6 @@ impl CompletionRelevance {
                 score -= 5;
             }
         }
-
-        // Lower rank for completions that skip `await` and `iter()`.
-        if is_skipping_completion {
-            score -= 7;
-        }
-
         // lower rank for items that need an import
         if requires_import {
             score -= 1;
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs
index 1b7adf1adb..ec26e311e8 100644
--- a/crates/ide-completion/src/render.rs
+++ b/crates/ide-completion/src/render.rs
@@ -141,7 +141,6 @@ pub(crate) fn render_field(
     item.set_relevance(CompletionRelevance {
         type_match: compute_type_match(ctx.completion, ty),
         exact_name_match: compute_exact_name_match(ctx.completion, &name),
-        is_skipping_completion: receiver.is_some(),
         ..CompletionRelevance::default()
     });
     item.detail(ty.display(db, ctx.completion.edition).to_string())
@@ -214,10 +213,6 @@ pub(crate) fn render_tuple_field(
     );
     item.detail(ty.display(ctx.db(), ctx.completion.edition).to_string())
         .lookup_by(field.to_string());
-    item.set_relevance(CompletionRelevance {
-        is_skipping_completion: receiver.is_some(),
-        ..ctx.completion_relevance()
-    });
     item.build(ctx.db())
 }
 
@@ -1338,7 +1333,6 @@ fn main() { let _: m::Spam = S$0 }
                             is_private_editable: false,
                             postfix_match: None,
                             function: None,
-                            is_skipping_completion: false,
                         },
                         trigger_call_info: true,
                     },
@@ -1368,7 +1362,6 @@ fn main() { let _: m::Spam = S$0 }
                             is_private_editable: false,
                             postfix_match: None,
                             function: None,
-                            is_skipping_completion: false,
                         },
                         trigger_call_info: true,
                     },
@@ -1458,7 +1451,6 @@ fn foo() { A { the$0 } }
                             is_private_editable: false,
                             postfix_match: None,
                             function: None,
-                            is_skipping_completion: false,
                         },
                     },
                 ]
@@ -1517,7 +1509,6 @@ impl S {
                                     return_type: Other,
                                 },
                             ),
-                            is_skipping_completion: false,
                         },
                     },
                     CompletionItem {
@@ -1660,7 +1651,6 @@ fn foo(s: S) { s.$0 }
                                     return_type: Other,
                                 },
                             ),
-                            is_skipping_completion: false,
                         },
                     },
                 ]
@@ -1872,7 +1862,6 @@ fn f() -> i32 {
                             is_private_editable: false,
                             postfix_match: None,
                             function: None,
-                            is_skipping_completion: false,
                         },
                     },
                 ]
@@ -2633,7 +2622,6 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
                                     return_type: Other,
                                 },
                             ),
-                            is_skipping_completion: false,
                         },
                         ref_match: "&@107",
                     },
@@ -2719,7 +2707,6 @@ fn foo() {
                             is_private_editable: false,
                             postfix_match: None,
                             function: None,
-                            is_skipping_completion: false,
                         },
                     },
                 ]
@@ -2777,7 +2764,6 @@ fn main() {
                                     return_type: Other,
                                 },
                             ),
-                            is_skipping_completion: false,
                         },
                         ref_match: "&@92",
                     },
@@ -3152,7 +3138,6 @@ fn main() {
                             is_private_editable: false,
                             postfix_match: None,
                             function: None,
-                            is_skipping_completion: false,
                         },
                     },
                     CompletionItem {
@@ -3186,7 +3171,6 @@ fn main() {
                             is_private_editable: false,
                             postfix_match: None,
                             function: None,
-                            is_skipping_completion: false,
                         },
                     },
                 ]
diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs
index c3354902c3..317c93b10f 100644
--- a/crates/ide-completion/src/render/function.rs
+++ b/crates/ide-completion/src/render/function.rs
@@ -123,7 +123,6 @@ fn render(
         exact_name_match: compute_exact_name_match(completion, &call),
         function,
         trait_: trait_info,
-        is_skipping_completion: matches!(func_kind, FuncKind::Method(_, Some(_))),
         ..ctx.completion_relevance()
     });
 
diff --git a/crates/ide-db/src/famous_defs.rs b/crates/ide-db/src/famous_defs.rs
index 2f4d07446f..9b76baf487 100644
--- a/crates/ide-db/src/famous_defs.rs
+++ b/crates/ide-db/src/famous_defs.rs
@@ -142,13 +142,6 @@ impl FamousDefs<'_, '_> {
         self.find_macro("core:unimplemented")
     }
 
-    pub fn core_fmt_Display(&self) -> Option<Trait> {
-        self.find_trait("core:fmt:Display")
-    }
-
-    pub fn alloc_string_ToString(&self) -> Option<Trait> {
-        self.find_trait("alloc:string:ToString")
-    }
     pub fn builtin_crates(&self) -> impl Iterator<Item = Crate> {
         IntoIterator::into_iter([
             self.std(),
diff --git a/crates/ide-db/src/symbol_index.rs b/crates/ide-db/src/symbol_index.rs
index e5ce10a771..c94644eeb8 100644
--- a/crates/ide-db/src/symbol_index.rs
+++ b/crates/ide-db/src/symbol_index.rs
@@ -143,7 +143,7 @@ fn library_symbols(db: &dyn SymbolsDatabase, source_root_id: SourceRootId) -> Ar
 fn module_symbols(db: &dyn SymbolsDatabase, module: Module) -> Arc<SymbolIndex> {
     let _p = tracing::info_span!("module_symbols").entered();
 
-    Arc::new(SymbolIndex::new(SymbolCollector::new_module(db.upcast(), module)))
+    Arc::new(SymbolIndex::new(SymbolCollector::collect_module(db.upcast(), module)))
 }
 
 pub fn crate_symbols(db: &dyn SymbolsDatabase, krate: Crate) -> Box<[Arc<SymbolIndex>]> {
@@ -284,15 +284,13 @@ impl SymbolIndex {
             builder.insert(key, value).unwrap();
         }
 
-        let map = builder
-            .into_inner()
-            .and_then(|mut buf| {
-                fst::Map::new({
-                    buf.shrink_to_fit();
-                    buf
-                })
-            })
-            .unwrap();
+        // FIXME: fst::Map should ideally have a way to shrink the backing buffer without the unwrap dance
+        let map = fst::Map::new({
+            let mut buf = builder.into_inner().unwrap();
+            buf.shrink_to_fit();
+            buf
+        })
+        .unwrap();
         SymbolIndex { symbols, map }
     }
 
@@ -493,7 +491,7 @@ pub(self) use crate::Trait as IsThisJustATrait;
             .modules(&db)
             .into_iter()
             .map(|module_id| {
-                let mut symbols = SymbolCollector::new_module(&db, module_id);
+                let mut symbols = SymbolCollector::collect_module(&db, module_id);
                 symbols.sort_by_key(|it| it.name.as_str().to_owned());
                 (module_id, symbols)
             })
@@ -520,7 +518,7 @@ struct Duplicate;
             .modules(&db)
             .into_iter()
             .map(|module_id| {
-                let mut symbols = SymbolCollector::new_module(&db, module_id);
+                let mut symbols = SymbolCollector::collect_module(&db, module_id);
                 symbols.sort_by_key(|it| it.name.as_str().to_owned());
                 (module_id, symbols)
             })
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index d18732a6b8..99d0d6af71 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -185,15 +185,6 @@ fn find_definition_for_known_blanket_dual_impls(
             // Extract the `T` from `Result<T, ..>`
             [return_type.type_arguments().next()?, callable.receiver_param(sema.db)?.1],
         )?
-    } else if fn_name == sym::to_string && fd.alloc_string_ToString() == Some(t) {
-        let dual = fd.core_fmt_Display()?;
-        let dual_f = dual.function(sema.db, &sym::fmt)?;
-        sema.resolve_trait_impl_method(
-            return_type.clone(),
-            dual,
-            dual_f,
-            [callable.receiver_param(sema.db)?.1.strip_reference()],
-        )?
     } else {
         return None;
     };
@@ -3240,36 +3231,6 @@ impl FromStr for A {
 }
 fn f() {
     let a: Result<A, _> = "aaaaaa".parse$0();
-}
-        "#,
-        );
-    }
-
-    #[test]
-    fn to_string_call_to_display_definition() {
-        check(
-            r#"
-//- minicore:fmt
-//- /alloc.rs crate:alloc
-pub mod string {
-    pub struct String;
-    pub trait ToString {
-        fn to_string(&self) -> String;
-    }
-
-    impl<T: core::fmt::Display> ToString for T {
-        fn to_string(&self) -> String { String }
-    }
-}
-//- /lib.rs crate:lib deps:alloc
-use alloc::string::ToString;
-struct A;
-impl core::fmt::Display for A {
-    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {}
-    // ^^^
-}
-fn f() {
-    A.to_string$0();
 }
         "#,
         );
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 6d83a747d7..1f723c85df 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -209,7 +209,7 @@ fn hints(
 ) {
     closing_brace::hints(hints, sema, config, file_id, node.clone());
     if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) {
-        generic_param::hints(hints, sema, config, any_has_generic_args);
+        generic_param::hints(hints, famous_defs, config, any_has_generic_args);
     }
 
     match_ast! {
@@ -300,22 +300,23 @@ pub struct InlayHintsConfig {
     pub closing_brace_hints_min_lines: Option<usize>,
     pub fields_to_resolve: InlayFieldsToResolve,
 }
+
 impl InlayHintsConfig {
-    fn lazy_text_edit(&self, finish: impl FnOnce() -> TextEdit) -> Lazy<TextEdit> {
+    fn lazy_text_edit(&self, finish: impl FnOnce() -> TextEdit) -> LazyProperty<TextEdit> {
         if self.fields_to_resolve.resolve_text_edits {
-            Lazy::Lazy
+            LazyProperty::Lazy
         } else {
             let edit = finish();
             never!(edit.is_empty(), "inlay hint produced an empty text edit");
-            Lazy::Computed(edit)
+            LazyProperty::Computed(edit)
         }
     }
 
-    fn lazy_tooltip(&self, finish: impl FnOnce() -> InlayTooltip) -> Lazy<InlayTooltip> {
+    fn lazy_tooltip(&self, finish: impl FnOnce() -> InlayTooltip) -> LazyProperty<InlayTooltip> {
         if self.fields_to_resolve.resolve_hint_tooltip
             && self.fields_to_resolve.resolve_label_tooltip
         {
-            Lazy::Lazy
+            LazyProperty::Lazy
         } else {
             let tooltip = finish();
             never!(
@@ -326,7 +327,20 @@ impl InlayHintsConfig {
                 .is_empty(),
                 "inlay hint produced an empty tooltip"
             );
-            Lazy::Computed(tooltip)
+            LazyProperty::Computed(tooltip)
+        }
+    }
+
+    /// This always reports a resolvable location, so only use this when it is very likely for a
+    /// location link to actually resolve but where computing `finish` would be costly.
+    fn lazy_location_opt(
+        &self,
+        finish: impl FnOnce() -> Option<FileRange>,
+    ) -> Option<LazyProperty<FileRange>> {
+        if self.fields_to_resolve.resolve_label_location {
+            Some(LazyProperty::Lazy)
+        } else {
+            finish().map(LazyProperty::Computed)
         }
     }
 }
@@ -441,7 +455,7 @@ pub struct InlayHint {
     /// The actual label to show in the inlay hint.
     pub label: InlayHintLabel,
     /// Text edit to apply when "accepting" this inlay hint.
-    pub text_edit: Option<Lazy<TextEdit>>,
+    pub text_edit: Option<LazyProperty<TextEdit>>,
     /// Range to recompute inlay hints when trying to resolve for this hint. If this is none, the
     /// hint does not support resolving.
     pub resolve_parent: Option<TextRange>,
@@ -449,15 +463,15 @@ pub struct InlayHint {
 
 /// A type signaling that a value is either computed, or is available for computation.
 #[derive(Clone, Debug)]
-pub enum Lazy<T> {
+pub enum LazyProperty<T> {
     Computed(T),
     Lazy,
 }
 
-impl<T> Lazy<T> {
+impl<T> LazyProperty<T> {
     pub fn computed(self) -> Option<T> {
         match self {
-            Lazy::Computed(it) => Some(it),
+            LazyProperty::Computed(it) => Some(it),
             _ => None,
         }
     }
@@ -508,8 +522,8 @@ pub struct InlayHintLabel {
 impl InlayHintLabel {
     pub fn simple(
         s: impl Into<String>,
-        tooltip: Option<Lazy<InlayTooltip>>,
-        linked_location: Option<FileRange>,
+        tooltip: Option<LazyProperty<InlayTooltip>>,
+        linked_location: Option<LazyProperty<FileRange>>,
     ) -> InlayHintLabel {
         InlayHintLabel {
             parts: smallvec![InlayHintLabelPart { text: s.into(), linked_location, tooltip }],
@@ -593,16 +607,16 @@ pub struct InlayHintLabelPart {
     /// refers to (not necessarily the location itself).
     /// When setting this, no tooltip must be set on the containing hint, or VS Code will display
     /// them both.
-    pub linked_location: Option<FileRange>,
+    pub linked_location: Option<LazyProperty<FileRange>>,
     /// The tooltip to show when hovering over the inlay hint, this may invoke other actions like
     /// hover requests to show.
-    pub tooltip: Option<Lazy<InlayTooltip>>,
+    pub tooltip: Option<LazyProperty<InlayTooltip>>,
 }
 
 impl std::hash::Hash for InlayHintLabelPart {
     fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
         self.text.hash(state);
-        self.linked_location.hash(state);
+        self.linked_location.is_some().hash(state);
         self.tooltip.is_some().hash(state);
     }
 }
@@ -610,7 +624,9 @@ impl std::hash::Hash for InlayHintLabelPart {
 impl fmt::Debug for InlayHintLabelPart {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
-            Self { text, linked_location: None, tooltip: None | Some(Lazy::Lazy) } => text.fmt(f),
+            Self { text, linked_location: None, tooltip: None | Some(LazyProperty::Lazy) } => {
+                text.fmt(f)
+            }
             Self { text, linked_location, tooltip } => f
                 .debug_struct("InlayHintLabelPart")
                 .field("text", text)
@@ -618,8 +634,10 @@ impl fmt::Debug for InlayHintLabelPart {
                 .field(
                     "tooltip",
                     &tooltip.as_ref().map_or("", |it| match it {
-                        Lazy::Computed(InlayTooltip::String(it) | InlayTooltip::Markdown(it)) => it,
-                        Lazy::Lazy => "",
+                        LazyProperty::Computed(
+                            InlayTooltip::String(it) | InlayTooltip::Markdown(it),
+                        ) => it,
+                        LazyProperty::Lazy => "",
                     }),
                 )
                 .finish(),
@@ -632,7 +650,8 @@ struct InlayHintLabelBuilder<'a> {
     db: &'a RootDatabase,
     result: InlayHintLabel,
     last_part: String,
-    location: Option<FileRange>,
+    resolve: bool,
+    location: Option<LazyProperty<FileRange>>,
 }
 
 impl fmt::Write for InlayHintLabelBuilder<'_> {
@@ -645,11 +664,16 @@ impl HirWrite for InlayHintLabelBuilder<'_> {
     fn start_location_link(&mut self, def: ModuleDefId) {
         never!(self.location.is_some(), "location link is already started");
         self.make_new_part();
-        let Some(location) = ModuleDef::from(def).try_to_nav(self.db) else { return };
-        let location = location.call_site();
-        let location =
-            FileRange { file_id: location.file_id, range: location.focus_or_full_range() };
-        self.location = Some(location);
+
+        self.location = Some(if self.resolve {
+            LazyProperty::Lazy
+        } else {
+            LazyProperty::Computed({
+                let Some(location) = ModuleDef::from(def).try_to_nav(self.db) else { return };
+                let location = location.call_site();
+                FileRange { file_id: location.file_id, range: location.focus_or_full_range() }
+            })
+        });
     }
 
     fn end_location_link(&mut self) {
@@ -735,6 +759,7 @@ fn label_of_ty(
         last_part: String::new(),
         location: None,
         result: InlayHintLabel::default(),
+        resolve: config.fields_to_resolve.resolve_label_location,
     };
     let _ = rec(sema, famous_defs, config.max_length, ty, &mut label_builder, config, edition);
     let r = label_builder.finish();
@@ -783,7 +808,7 @@ fn ty_to_text_edit(
     ty: &hir::Type,
     offset_to_insert: TextSize,
     prefix: impl Into<String>,
-) -> Option<Lazy<TextEdit>> {
+) -> Option<LazyProperty<TextEdit>> {
     // FIXME: Limit the length and bail out on excess somehow?
     let rendered = sema
         .scope(node_for_hint)
diff --git a/crates/ide/src/inlay_hints/bounds.rs b/crates/ide/src/inlay_hints/bounds.rs
index 429ddd31cb..e9b728bcaa 100644
--- a/crates/ide/src/inlay_hints/bounds.rs
+++ b/crates/ide/src/inlay_hints/bounds.rs
@@ -22,11 +22,7 @@ pub(super) fn hints(
         return None;
     }
 
-    let linked_location =
-        famous_defs.core_marker_Sized().and_then(|it| it.try_to_nav(sema.db)).map(|it| {
-            let n = it.call_site();
-            FileRange { file_id: n.file_id, range: n.focus_or_full_range() }
-        });
+    let sized_trait = famous_defs.core_marker_Sized();
 
     for param in params.type_or_const_params() {
         match param {
@@ -48,7 +44,17 @@ pub(super) fn hints(
                         }
                         hint.parts.push(InlayHintLabelPart {
                             text: "Sized".to_owned(),
-                            linked_location,
+                            linked_location: sized_trait.and_then(|it| {
+                                config.lazy_location_opt(|| {
+                                    it.try_to_nav(sema.db).map(|it| {
+                                        let n = it.call_site();
+                                        FileRange {
+                                            file_id: n.file_id,
+                                            range: n.focus_or_full_range(),
+                                        }
+                                    })
+                                })
+                            }),
                             tooltip: None,
                         });
                         if has_bounds {
@@ -134,12 +140,14 @@ fn foo<T>() {}
                             InlayHintLabelPart {
                                 text: "Sized",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            1,
-                                        ),
-                                        range: 135..140,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                1,
+                                            ),
+                                            range: 135..140,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index 7fa7ab1a94..8471547727 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -81,7 +81,10 @@ mod tests {
 
     use crate::{
         fixture,
-        inlay_hints::tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG},
+        inlay_hints::{
+            tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG},
+            LazyProperty,
+        },
         InlayHintsConfig,
     };
 
@@ -99,7 +102,7 @@ mod tests {
         let (analysis, file_id) = fixture::file(ra_fixture);
         let mut inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap();
         inlay_hints.iter_mut().flat_map(|hint| &mut hint.label.parts).for_each(|hint| {
-            if let Some(loc) = &mut hint.linked_location {
+            if let Some(LazyProperty::Computed(loc)) = &mut hint.linked_location {
                 loc.range = TextRange::empty(TextSize::from(0));
             }
         });
@@ -134,12 +137,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 63..64,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 63..64,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -151,12 +156,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "A",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..8,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 7..8,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -213,12 +220,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "C",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 51..52,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 51..52,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -230,12 +239,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 29..30,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 29..30,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -276,12 +287,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "C",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 51..52,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 51..52,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -293,12 +306,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 29..30,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 29..30,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -340,12 +355,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 23..24,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 23..24,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -353,12 +370,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "X",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 55..56,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 55..56,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -371,12 +390,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "A",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..8,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 7..8,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -384,12 +405,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "X",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 55..56,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 55..56,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -435,12 +458,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Iterator",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            1,
-                                        ),
-                                        range: 0..0,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                1,
+                                            ),
+                                            range: 0..0,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -448,12 +473,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Item",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            1,
-                                        ),
-                                        range: 0..0,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                1,
+                                            ),
+                                            range: 0..0,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -467,12 +494,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Iterator",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            1,
-                                        ),
-                                        range: 0..0,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                1,
+                                            ),
+                                            range: 0..0,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -480,12 +509,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Item",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            1,
-                                        ),
-                                        range: 0..0,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                1,
+                                            ),
+                                            range: 0..0,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -499,12 +530,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Iterator",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            1,
-                                        ),
-                                        range: 0..0,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                1,
+                                            ),
+                                            range: 0..0,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -512,12 +545,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Item",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            1,
-                                        ),
-                                        range: 0..0,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                1,
+                                            ),
+                                            range: 0..0,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -531,12 +566,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "MyIter",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 0..0,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 0..0,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -577,12 +614,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Struct",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..13,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 7..13,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -594,12 +633,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Struct",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..13,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 7..13,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -611,12 +652,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Struct",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..13,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 7..13,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
@@ -628,12 +671,14 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "self",
                                 linked_location: Some(
-                                    FileRangeWrapper {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 42..46,
-                                    },
+                                    Computed(
+                                        FileRangeWrapper {
+                                            file_id: FileId(
+                                                0,
+                                            ),
+                                            range: 42..46,
+                                        },
+                                    ),
                                 ),
                                 tooltip: "",
                             },
diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs
index 90b8be64a4..3767d34e2c 100644
--- a/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/crates/ide/src/inlay_hints/closing_brace.rs
@@ -11,7 +11,10 @@ use syntax::{
     match_ast, SyntaxKind, SyntaxNode, T,
 };
 
-use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind};
+use crate::{
+    inlay_hints::LazyProperty, InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig,
+    InlayKind,
+};
 
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
@@ -141,7 +144,7 @@ pub(super) fn hints(
     acc.push(InlayHint {
         range: closing_token.text_range(),
         kind: InlayKind::ClosingBrace,
-        label: InlayHintLabel::simple(label, None, linked_location),
+        label: InlayHintLabel::simple(label, None, linked_location.map(LazyProperty::Computed)),
         text_edit: None,
         position: InlayHintPosition::After,
         pad_left: true,
diff --git a/crates/ide/src/inlay_hints/closure_captures.rs b/crates/ide/src/inlay_hints/closure_captures.rs
index 906f2acf0c..3e91618d08 100644
--- a/crates/ide/src/inlay_hints/closure_captures.rs
+++ b/crates/ide/src/inlay_hints/closure_captures.rs
@@ -53,10 +53,6 @@ pub(super) fn hints(
     let last = captures.len() - 1;
     for (idx, capture) in captures.into_iter().enumerate() {
         let local = capture.local();
-        let source = local.primary_source(sema.db);
-
-        // force cache the source file, otherwise sema lookup will potentially panic
-        _ = sema.parse_or_expand(source.file());
 
         let label = format!(
             "{}{}",
@@ -73,8 +69,17 @@ pub(super) fn hints(
         }
         hint.label.append_part(InlayHintLabelPart {
             text: label,
-            linked_location: source.name().and_then(|name| {
-                name.syntax().original_file_range_opt(sema.db).map(TupleExt::head).map(Into::into)
+            linked_location: config.lazy_location_opt(|| {
+                let source = local.primary_source(sema.db);
+
+                // force cache the source file, otherwise sema lookup will potentially panic
+                _ = sema.parse_or_expand(source.file());
+                source.name().and_then(|name| {
+                    name.syntax()
+                        .original_file_range_opt(sema.db)
+                        .map(TupleExt::head)
+                        .map(Into::into)
+                })
             }),
             tooltip: None,
         });
diff --git a/crates/ide/src/inlay_hints/generic_param.rs b/crates/ide/src/inlay_hints/generic_param.rs
index 037b328d97..762a4c2655 100644
--- a/crates/ide/src/inlay_hints/generic_param.rs
+++ b/crates/ide/src/inlay_hints/generic_param.rs
@@ -1,17 +1,19 @@
 //! Implementation of inlay hints for generic parameters.
-use ide_db::{active_parameter::generic_def_for_node, RootDatabase};
+use ide_db::{active_parameter::generic_def_for_node, famous_defs::FamousDefs};
 use syntax::{
     ast::{self, AnyHasGenericArgs, HasGenericArgs, HasName},
     AstNode,
 };
 
-use crate::{inlay_hints::GenericParameterHints, InlayHint, InlayHintsConfig, InlayKind};
+use crate::{
+    inlay_hints::GenericParameterHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind,
+};
 
-use super::param_name::{is_argument_similar_to_param_name, render_label};
+use super::param_name::is_argument_similar_to_param_name;
 
 pub(crate) fn hints(
     acc: &mut Vec<InlayHint>,
-    sema: &hir::Semantics<'_, RootDatabase>,
+    FamousDefs(sema, krate): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
     node: AnyHasGenericArgs,
 ) -> Option<()> {
@@ -45,12 +47,23 @@ pub(crate) fn hints(
             return None;
         }
 
-        let name = param.name(sema.db);
-        let param_name = name.as_str();
+        let allowed = match (param, &arg) {
+            (hir::GenericParam::TypeParam(_), ast::GenericArg::TypeArg(_)) => type_hints,
+            (hir::GenericParam::ConstParam(_), ast::GenericArg::ConstArg(_)) => const_hints,
+            (hir::GenericParam::LifetimeParam(_), ast::GenericArg::LifetimeArg(_)) => {
+                lifetime_hints
+            }
+            _ => false,
+        };
+        if !allowed {
+            return None;
+        }
+
+        let param_name = param.name(sema.db);
 
         let should_hide = {
             let argument = get_string_representation(&arg)?;
-            is_argument_similar_to_param_name(&argument, param_name)
+            is_argument_similar_to_param_name(&argument, param_name.as_str())
         };
 
         if should_hide {
@@ -59,30 +72,28 @@ pub(crate) fn hints(
 
         let range = sema.original_range_opt(arg.syntax())?.range;
 
-        let source_syntax = match param {
-            hir::GenericParam::TypeParam(it) => {
-                if !type_hints || !matches!(arg, ast::GenericArg::TypeArg(_)) {
-                    return None;
-                }
-                sema.source(it.merge())?.value.syntax().clone()
-            }
-            hir::GenericParam::ConstParam(it) => {
-                if !const_hints || !matches!(arg, ast::GenericArg::ConstArg(_)) {
-                    return None;
-                }
-                let syntax = sema.source(it.merge())?.value.syntax().clone();
-                let const_param = ast::ConstParam::cast(syntax)?;
-                const_param.name()?.syntax().clone()
-            }
-            hir::GenericParam::LifetimeParam(it) => {
-                if !lifetime_hints || !matches!(arg, ast::GenericArg::LifetimeArg(_)) {
-                    return None;
-                }
-                sema.source(it)?.value.syntax().clone()
-            }
-        };
-        let linked_location = sema.original_range_opt(&source_syntax);
-        let label = render_label(param_name, config, linked_location);
+        let colon = if config.render_colons { ":" } else { "" };
+        let label = InlayHintLabel::simple(
+            format!("{}{colon}", param_name.display(sema.db, krate.edition(sema.db))),
+            None,
+            config.lazy_location_opt(|| {
+                let source_syntax = match param {
+                    hir::GenericParam::TypeParam(it) => {
+                        sema.source(it.merge()).map(|it| it.value.syntax().clone())
+                    }
+                    hir::GenericParam::ConstParam(it) => {
+                        let syntax = sema.source(it.merge())?.value.syntax().clone();
+                        let const_param = ast::ConstParam::cast(syntax)?;
+                        const_param.name().map(|it| it.syntax().clone())
+                    }
+                    hir::GenericParam::LifetimeParam(it) => {
+                        sema.source(it).map(|it| it.value.syntax().clone())
+                    }
+                };
+                let linked_location = source_syntax.and_then(|it| sema.original_range_opt(&it));
+                linked_location.map(Into::into)
+            }),
+        );
 
         Some(InlayHint {
             range,
diff --git a/crates/ide/src/inlay_hints/implicit_drop.rs b/crates/ide/src/inlay_hints/implicit_drop.rs
index 1358d3722f..27c7c3d498 100644
--- a/crates/ide/src/inlay_hints/implicit_drop.rs
+++ b/crates/ide/src/inlay_hints/implicit_drop.rs
@@ -49,7 +49,7 @@ pub(super) fn hints(
             if mir.locals[place.local].ty.adt_id(ChalkTyInterner).is_none() {
                 continue; // Arguably only ADTs have significant drop impls
             }
-            let Some(binding) = local_to_binding.get(place.local) else {
+            let Some(&binding_idx) = local_to_binding.get(place.local) else {
                 continue; // Ignore temporary values
             };
             let range = match terminator.span {
@@ -91,25 +91,26 @@ pub(super) fn hints(
                 },
                 MirSpan::Unknown => continue,
             };
-            let binding_source = source_map
-                .patterns_for_binding(*binding)
-                .first()
-                .and_then(|d| source_map.pat_syntax(*d).ok())
-                .and_then(|d| {
-                    Some(FileRange {
-                        file_id: d.file_id.file_id()?.into(),
-                        range: d.value.text_range(),
-                    })
-                });
-            let binding = &hir.bindings[*binding];
+            let binding = &hir.bindings[binding_idx];
             let name = binding.name.display_no_db(file_id.edition()).to_smolstr();
             if name.starts_with("<ra@") {
                 continue; // Ignore desugared variables
             }
             let mut label = InlayHintLabel::simple(
                 name,
-                Some(config.lazy_tooltip(|| crate::InlayTooltip::String("moz".into()))),
-                binding_source,
+                None,
+                config.lazy_location_opt(|| {
+                    source_map
+                        .patterns_for_binding(binding_idx)
+                        .first()
+                        .and_then(|d| source_map.pat_syntax(*d).ok())
+                        .and_then(|d| {
+                            Some(FileRange {
+                                file_id: d.file_id.file_id()?.into(),
+                                range: d.value.text_range(),
+                            })
+                        })
+                }),
             );
             label.prepend_str("drop(");
             label.append_str(")");
diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs
index a6f7e0c184..8f01b1bd38 100644
--- a/crates/ide/src/inlay_hints/param_name.rs
+++ b/crates/ide/src/inlay_hints/param_name.rs
@@ -3,7 +3,6 @@
 //! fn max(x: i32, y: i32) -> i32 { x + y }
 //! _ = max(/*x*/4, /*y*/4);
 //! ```
-use std::fmt::Display;
 
 use either::Either;
 use hir::{Callable, Semantics};
@@ -20,7 +19,7 @@ use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, Inla
 
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
-    FamousDefs(sema, _): &FamousDefs<'_, '_>,
+    FamousDefs(sema, krate): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
     _file_id: EditionedFileId,
     expr: ast::Expr,
@@ -37,23 +36,29 @@ pub(super) fn hints(
         .filter_map(|(p, arg)| {
             // Only annotate hints for expressions that exist in the original file
             let range = sema.original_range_opt(arg.syntax())?;
-            let source = sema.source(p)?;
-            let (param_name, name_syntax) = match source.value.as_ref() {
-                Either::Left(pat) => (pat.name()?, pat.name()),
-                Either::Right(param) => match param.pat()? {
-                    ast::Pat::IdentPat(it) => (it.name()?, it.name()),
-                    _ => return None,
-                },
-            };
-            Some((name_syntax, param_name, arg, range))
+            let param_name = p.name(sema.db)?;
+            Some((p, param_name, arg, range))
         })
         .filter(|(_, param_name, arg, _)| {
-            !should_hide_param_name_hint(sema, &callable, &param_name.text(), arg)
+            !should_hide_param_name_hint(sema, &callable, param_name.as_str(), arg)
         })
         .map(|(param, param_name, _, hir::FileRange { range, .. })| {
-            let linked_location = param.and_then(|name| sema.original_range_opt(name.syntax()));
-
-            let label = render_label(&param_name, config, linked_location);
+            let colon = if config.render_colons { ":" } else { "" };
+            let label = InlayHintLabel::simple(
+                format!("{}{colon}", param_name.display(sema.db, krate.edition(sema.db))),
+                None,
+                config.lazy_location_opt(|| {
+                    let source = sema.source(param)?;
+                    let name_syntax = match source.value.as_ref() {
+                        Either::Left(pat) => pat.name(),
+                        Either::Right(param) => match param.pat()? {
+                            ast::Pat::IdentPat(it) => it.name(),
+                            _ => None,
+                        },
+                    }?;
+                    sema.original_range_opt(name_syntax.syntax()).map(Into::into)
+                }),
+            );
             InlayHint {
                 range,
                 kind: InlayKind::Parameter,
@@ -70,16 +75,6 @@ pub(super) fn hints(
     Some(())
 }
 
-pub(super) fn render_label(
-    param_name: impl Display,
-    config: &InlayHintsConfig,
-    linked_location: Option<hir::FileRange>,
-) -> InlayHintLabel {
-    let colon = if config.render_colons { ":" } else { "" };
-
-    InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location.map(Into::into))
-}
-
 fn get_callable(
     sema: &Semantics<'_, RootDatabase>,
     expr: &ast::Expr,
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 346e2862b0..41a3302c09 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -91,7 +91,8 @@ pub use crate::{
     inlay_hints::{
         AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
         GenericParameterHints, InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart,
-        InlayHintPosition, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
+        InlayHintPosition, InlayHintsConfig, InlayKind, InlayTooltip, LazyProperty,
+        LifetimeElisionHints,
     },
     join_lines::JoinLinesConfig,
     markup::Markup,
diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs
index 7a090a6b6b..0f80891404 100644
--- a/crates/intern/src/symbol/symbols.rs
+++ b/crates/intern/src/symbol/symbols.rs
@@ -461,7 +461,6 @@ define_symbols! {
     test,
     then,
     thiscall,
-    to_string,
     trace_macros,
     transmute_opts,
     transmute_trait,
diff --git a/crates/project-model/src/project_json.rs b/crates/project-model/src/project_json.rs
index a396396761..6a88cf022d 100644
--- a/crates/project-model/src/project_json.rs
+++ b/crates/project-model/src/project_json.rs
@@ -63,7 +63,7 @@ use crate::{ManifestPath, TargetKind};
 pub struct ProjectJson {
     /// e.g. `path/to/sysroot`
     pub(crate) sysroot: Option<AbsPathBuf>,
-    /// e.g. `path/to/sysroot/lib/rustlib/src/rust/library`
+    /// e.g. `path/to/sysroot/lib/rustlib/src/rust`
     pub(crate) sysroot_src: Option<AbsPathBuf>,
     project_root: AbsPathBuf,
     /// The path to the rust-project.json file. May be None if this
diff --git a/crates/project-model/src/toolchain_info/rustc_cfg.rs b/crates/project-model/src/toolchain_info/rustc_cfg.rs
index e472da0c89..4bf9b59e7d 100644
--- a/crates/project-model/src/toolchain_info/rustc_cfg.rs
+++ b/crates/project-model/src/toolchain_info/rustc_cfg.rs
@@ -19,7 +19,7 @@ pub fn get(
     let rustc_cfgs = match rustc_cfgs {
         Ok(cfgs) => cfgs,
         Err(e) => {
-            tracing::warn!(?e, "failed to get rustc cfgs");
+            tracing::error!(?e, "failed to get rustc cfgs");
             return vec![];
         }
     };
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 44325fa1a2..3dc4379258 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -453,10 +453,6 @@ config_data! {
         ///
         /// In `match` arms it completes a comma instead.
         completion_addSemicolonToUnit: bool = true,
-        /// Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.
-        completion_autoAwait_enable: bool        = true,
-        /// Toggles the additional completions that automatically show method calls with `iter()` or `into_iter()` prefixed to them when completing on a type that has them.
-        completion_autoIter_enable: bool        = true,
         /// Toggles the additional completions that automatically add imports when completed.
         /// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
         completion_autoimport_enable: bool       = true,
@@ -1488,8 +1484,6 @@ impl Config {
             enable_imports_on_the_fly: self.completion_autoimport_enable(source_root).to_owned()
                 && self.caps.completion_item_edit_resolve(),
             enable_self_on_the_fly: self.completion_autoself_enable(source_root).to_owned(),
-            enable_auto_iter: *self.completion_autoIter_enable(source_root),
-            enable_auto_await: *self.completion_autoAwait_enable(source_root),
             enable_private_editable: self.completion_privateEditable_enable(source_root).to_owned(),
             full_function_signatures: self
                 .completion_fullFunctionSignatures_enable(source_root)
diff --git a/crates/rust-analyzer/src/flycheck.rs b/crates/rust-analyzer/src/flycheck.rs
index 2309f94a74..22f06d68d8 100644
--- a/crates/rust-analyzer/src/flycheck.rs
+++ b/crates/rust-analyzer/src/flycheck.rs
@@ -88,17 +88,6 @@ pub(crate) enum FlycheckConfig {
     },
 }
 
-impl FlycheckConfig {
-    pub(crate) fn invocation_strategy_once(&self) -> bool {
-        match self {
-            FlycheckConfig::CargoCommand { .. } => false,
-            FlycheckConfig::CustomCommand { invocation_strategy, .. } => {
-                *invocation_strategy == InvocationStrategy::Once
-            }
-        }
-    }
-}
-
 impl fmt::Display for FlycheckConfig {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs
index 84ba89d9f3..98efc637c2 100644
--- a/crates/rust-analyzer/src/handlers/notification.rs
+++ b/crates/rust-analyzer/src/handlers/notification.rs
@@ -291,15 +291,9 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
     let file_id = state.vfs.read().0.file_id(&vfs_path);
     if let Some(file_id) = file_id {
         let world = state.snapshot();
-        let invocation_strategy_once = state.config.flycheck(None).invocation_strategy_once();
         let may_flycheck_workspace = state.config.flycheck_workspace(None);
         let mut updated = false;
         let task = move || -> std::result::Result<(), ide::Cancelled> {
-            if invocation_strategy_once {
-                let saved_file = vfs_path.as_path().map(|p| p.to_owned());
-                world.flycheck[0].restart_workspace(saved_file.clone());
-            }
-
             let target = TargetSpec::for_file(&world, file_id)?.and_then(|it| {
                 let tgt_kind = it.target_kind();
                 let (tgt_name, root, package) = match it {
@@ -326,15 +320,16 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
                 // the user opted into package checks then
                 let package_check_allowed = target.is_some() || !may_flycheck_workspace;
                 if package_check_allowed {
-                    let workspace = world.workspaces.iter().position(|ws| match &ws.kind {
-                        project_model::ProjectWorkspaceKind::Cargo { cargo, .. }
-                        | project_model::ProjectWorkspaceKind::DetachedFile {
-                            cargo: Some((cargo, _, _)),
-                            ..
-                        } => *cargo.workspace_root() == root,
-                        _ => false,
-                    });
-                    if let Some(idx) = workspace {
+                    let workspace =
+                        world.workspaces.iter().enumerate().find(|(_, ws)| match &ws.kind {
+                            project_model::ProjectWorkspaceKind::Cargo { cargo, .. }
+                            | project_model::ProjectWorkspaceKind::DetachedFile {
+                                cargo: Some((cargo, _, _)),
+                                ..
+                            } => *cargo.workspace_root() == root,
+                            _ => false,
+                        });
+                    if let Some((idx, _)) = workspace {
                         world.flycheck[idx].restart_for_package(package, target);
                     }
                 }
diff --git a/crates/rust-analyzer/src/integrated_benchmarks.rs b/crates/rust-analyzer/src/integrated_benchmarks.rs
index 5cdc51a1c1..fcfd06679b 100644
--- a/crates/rust-analyzer/src/integrated_benchmarks.rs
+++ b/crates/rust-analyzer/src/integrated_benchmarks.rs
@@ -176,8 +176,6 @@ fn integrated_completion_benchmark() {
             fields_to_resolve: CompletionFieldsToResolve::empty(),
             exclude_flyimport: vec![],
             exclude_traits: &[],
-            enable_auto_await: true,
-            enable_auto_iter: true,
         };
         let position =
             FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
@@ -228,8 +226,6 @@ fn integrated_completion_benchmark() {
             fields_to_resolve: CompletionFieldsToResolve::empty(),
             exclude_flyimport: vec![],
             exclude_traits: &[],
-            enable_auto_await: true,
-            enable_auto_iter: true,
         };
         let position =
             FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
@@ -278,8 +274,6 @@ fn integrated_completion_benchmark() {
             fields_to_resolve: CompletionFieldsToResolve::empty(),
             exclude_flyimport: vec![],
             exclude_traits: &[],
-            enable_auto_await: true,
-            enable_auto_iter: true,
         };
         let position =
             FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs
index a5516e7f9d..2a7d95d560 100644
--- a/crates/rust-analyzer/src/lsp/to_proto.rs
+++ b/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -11,8 +11,8 @@ use ide::{
     Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionFieldsToResolve,
     CompletionItem, CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange,
     FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel,
-    InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, Markup,
-    NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
+    InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, LazyProperty,
+    Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
     SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
 };
 use ide_db::{assists, rust_doc::format_docs, FxHasher};
@@ -549,12 +549,11 @@ pub(crate) fn inlay_hint(
 ) -> Cancellable<lsp_types::InlayHint> {
     let hint_needs_resolve = |hint: &InlayHint| -> Option<TextRange> {
         hint.resolve_parent.filter(|_| {
-            hint.text_edit.is_some()
-                || hint
-                    .label
-                    .parts
-                    .iter()
-                    .any(|part| part.linked_location.is_some() || part.tooltip.is_some())
+            hint.text_edit.as_ref().is_some_and(LazyProperty::is_lazy)
+                || hint.label.parts.iter().any(|part| {
+                    part.linked_location.as_ref().is_some_and(LazyProperty::is_lazy)
+                        || part.tooltip.as_ref().is_some_and(LazyProperty::is_lazy)
+                })
         })
     };
 
@@ -569,22 +568,21 @@ pub(crate) fn inlay_hint(
     });
 
     let mut something_to_resolve = false;
-    let text_edits = if snap
-        .config
-        .visual_studio_code_version()
-        .is_none_or(|version| VersionReq::parse(">=1.86.0").unwrap().matches(version))
-        && resolve_range_and_hash.is_some()
-        && fields_to_resolve.resolve_text_edits
-    {
-        something_to_resolve |= inlay_hint.text_edit.is_some();
-        None
-    } else {
-        inlay_hint
-            .text_edit
-            .take()
-            .and_then(|it| it.computed())
-            .map(|it| text_edit_vec(line_index, it))
-    };
+    let text_edits = inlay_hint
+        .text_edit
+        .take()
+        .and_then(|it| match it {
+            LazyProperty::Computed(it) => Some(it),
+            LazyProperty::Lazy => {
+                something_to_resolve |=
+                    snap.config.visual_studio_code_version().is_none_or(|version| {
+                        VersionReq::parse(">=1.86.0").unwrap().matches(version)
+                    }) && resolve_range_and_hash.is_some()
+                        && fields_to_resolve.resolve_text_edits;
+                None
+            }
+        })
+        .map(|it| text_edit_vec(line_index, it));
     let (label, tooltip) = inlay_hint_label(
         snap,
         fields_to_resolve,
@@ -637,22 +635,23 @@ fn inlay_hint_label(
     let (label, tooltip) = match &*label.parts {
         [InlayHintLabelPart { linked_location: None, .. }] => {
             let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap();
-            let hint_tooltip = if needs_resolve && fields_to_resolve.resolve_hint_tooltip {
-                *something_to_resolve |= tooltip.is_some();
-                None
-            } else {
-                match tooltip.and_then(|it| it.computed()) {
-                    Some(ide::InlayTooltip::String(s)) => {
-                        Some(lsp_types::InlayHintTooltip::String(s))
-                    }
-                    Some(ide::InlayTooltip::Markdown(s)) => {
-                        Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent {
-                            kind: lsp_types::MarkupKind::Markdown,
-                            value: s,
-                        }))
-                    }
-                    None => None,
+            let tooltip = tooltip.and_then(|it| match it {
+                LazyProperty::Computed(it) => Some(it),
+                LazyProperty::Lazy => {
+                    *something_to_resolve |=
+                        needs_resolve && fields_to_resolve.resolve_hint_tooltip;
+                    None
                 }
+            });
+            let hint_tooltip = match tooltip {
+                Some(ide::InlayTooltip::String(s)) => Some(lsp_types::InlayHintTooltip::String(s)),
+                Some(ide::InlayTooltip::Markdown(s)) => {
+                    Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent {
+                        kind: lsp_types::MarkupKind::Markdown,
+                        value: s,
+                    }))
+                }
+                None => None,
             };
             (lsp_types::InlayHintLabel::String(text), hint_tooltip)
         }
@@ -661,31 +660,38 @@ fn inlay_hint_label(
                 .parts
                 .into_iter()
                 .map(|part| {
-                    let tooltip = if needs_resolve && fields_to_resolve.resolve_label_tooltip {
-                        *something_to_resolve |= part.tooltip.is_some();
-                        None
-                    } else {
-                        match part.tooltip.and_then(|it| it.computed()) {
-                            Some(ide::InlayTooltip::String(s)) => {
-                                Some(lsp_types::InlayHintLabelPartTooltip::String(s))
-                            }
-                            Some(ide::InlayTooltip::Markdown(s)) => {
-                                Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent(
-                                    lsp_types::MarkupContent {
-                                        kind: lsp_types::MarkupKind::Markdown,
-                                        value: s,
-                                    },
-                                ))
-                            }
-                            None => None,
+                    let tooltip = part.tooltip.and_then(|it| match it {
+                        LazyProperty::Computed(it) => Some(it),
+                        LazyProperty::Lazy => {
+                            *something_to_resolve |= fields_to_resolve.resolve_label_tooltip;
+                            None
                         }
+                    });
+                    let tooltip = match tooltip {
+                        Some(ide::InlayTooltip::String(s)) => {
+                            Some(lsp_types::InlayHintLabelPartTooltip::String(s))
+                        }
+                        Some(ide::InlayTooltip::Markdown(s)) => {
+                            Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent(
+                                lsp_types::MarkupContent {
+                                    kind: lsp_types::MarkupKind::Markdown,
+                                    value: s,
+                                },
+                            ))
+                        }
+                        None => None,
                     };
-                    let location = if needs_resolve && fields_to_resolve.resolve_label_location {
-                        *something_to_resolve |= part.linked_location.is_some();
-                        None
-                    } else {
-                        part.linked_location.map(|range| location(snap, range)).transpose()?
-                    };
+                    let location = part
+                        .linked_location
+                        .and_then(|it| match it {
+                            LazyProperty::Computed(it) => Some(it),
+                            LazyProperty::Lazy => {
+                                *something_to_resolve |= fields_to_resolve.resolve_label_location;
+                                None
+                            }
+                        })
+                        .map(|range| location(snap, range))
+                        .transpose()?;
                     Ok(lsp_types::InlayHintLabelPart {
                         value: part.text,
                         tooltip,
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index b33de1956b..bd091db58d 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -274,16 +274,6 @@ Whether to automatically add a semicolon when completing unit-returning function
 
 In `match` arms it completes a comma instead.
 --
-[[rust-analyzer.completion.autoAwait.enable]]rust-analyzer.completion.autoAwait.enable (default: `true`)::
-+
---
-Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.
---
-[[rust-analyzer.completion.autoIter.enable]]rust-analyzer.completion.autoIter.enable (default: `true`)::
-+
---
-Toggles the additional completions that automatically show method calls with `iter()` or `into_iter()` prefixed to them when completing on a type that has them.
---
 [[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`)::
 +
 --
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc
index 4a2a6f2e36..ffc820e9b7 100644
--- a/docs/user/manual.adoc
+++ b/docs/user/manual.adoc
@@ -716,32 +716,6 @@ interface JsonProject {
     /// dependencies as well as sysroot crate (libstd,
     /// libcore and such).
     crates: Crate[];
-    /// Configuration for CLI commands.
-    ///
-    /// These are used for running and debugging binaries
-    /// and tests without encoding build system-specific
-    /// knowledge into rust-analyzer.
-    ///
-    /// # Example
-    ///
-    /// Below is an example of a test runnable. `{label}` and `{test_id}`
-    /// are explained in `Runnable::args`'s documentation below.
-    ///
-    /// ```json
-    /// {
-    ///     "program": "buck",
-    ///     "args": [
-    ///         "test",
-    ///          "{label}",
-    ///          "--",
-    ///          "{test_id}",
-    ///          "--print-passing-details"
-    ///     ],
-    ///     "cwd": "/home/user/repo-root/",
-    ///     "kind": "testOne"
-    /// }
-    /// ```
-    runnables?: Runnable[];
 }
 
 interface Crate {
@@ -752,10 +726,7 @@ interface Crate {
     /// Path to the root module of the crate.
     root_module: string;
     /// Edition of the crate.
-    edition: '2015' | '2018' | '2021' | '2024';
-    /// The version of the crate. Used for calculating
-    /// the correct docs.rs URL.
-    version?: string;
+    edition: "2015" | "2018" | "2021";
     /// Dependencies
     deps: Dep[];
     /// Should this crate be treated as a member of
@@ -786,9 +757,9 @@ interface Crate {
     /// rust-analyzer assumes that files from one
     /// source can't refer to files in another source.
     source?: {
-        include_dirs: string[];
-        exclude_dirs: string[];
-    };
+        include_dirs: string[],
+        exclude_dirs: string[],
+    },
     /// List of cfg groups this crate inherits.
     ///
     /// All cfg in these groups will be concatenated to
@@ -805,68 +776,21 @@ interface Crate {
     target?: string;
     /// Environment variables, used for
     /// the `env!` macro
-    env: { [key: string]: string; };
+    env: { [key: string]: string; },
 
     /// Whether the crate is a proc-macro crate.
     is_proc_macro: boolean;
     /// For proc-macro crates, path to compiled
     /// proc-macro (.so file).
     proc_macro_dylib_path?: string;
-
-    /// Repository, matching the URL that would be used
-    /// in Cargo.toml.
-    repository?: string;
-
-    /// Build-specific data about this crate.
-    build?: BuildInfo;
 }
 
 interface Dep {
     /// Index of a crate in the `crates` array.
-    crate: number;
+    crate: number,
     /// Name as should appear in the (implicit)
     /// `extern crate name` declaration.
-    name: string;
-}
-
-interface BuildInfo {
-    /// The name associated with this crate.
-    ///
-    /// This is determined by the build system that produced
-    /// the `rust-project.json` in question. For instance, if buck were used,
-    /// the label might be something like `//ide/rust/rust-analyzer:rust-analyzer`.
-    ///
-    /// Do not attempt to parse the contents of this string; it is a build system-specific
-    /// identifier similar to `Crate::display_name`.
-    label: string;
-    /// Path corresponding to the build system-specific file defining the crate.
-    build_file: string;
-    /// The kind of target.
-    ///
-    /// This information is used to determine what sort
-    /// of runnable codelens to provide, if any.
-    target_kind: 'bin' | 'lib' | 'test';
-}
-
-interface Runnable {
-    /// The program invoked by the runnable.
-    ///
-    /// For example, this might be `cargo`, `buck`, or `bazel`.
-    program: string;
-    /// The arguments passed to `program`.
-    args: string[];
-    /// The current working directory of the runnable.
-    cwd: string;
-    /// Used to decide what code lens to offer.
-    ///
-    /// `testOne`: This runnable will be used when the user clicks the 'Run Test'
-    /// CodeLens above a test.
-    ///
-    /// The args for testOne can contain two template strings:
-    /// `{label}` and `{test_id}`. `{label}` will be replaced
-    /// with the `Build::label` and `{test_id}` will be replaced
-    /// with the test name.
-    kind: 'testOne' | string;
+    name: string,
 }
 ----
 
diff --git a/editors/code/package.json b/editors/code/package.json
index f148041ac3..8b066377f2 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -1143,26 +1143,6 @@
                     }
                 }
             },
-            {
-                "title": "completion",
-                "properties": {
-                    "rust-analyzer.completion.autoAwait.enable": {
-                        "markdownDescription": "Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.",
-                        "default": true,
-                        "type": "boolean"
-                    }
-                }
-            },
-            {
-                "title": "completion",
-                "properties": {
-                    "rust-analyzer.completion.autoIter.enable": {
-                        "markdownDescription": "Toggles the additional completions that automatically show method calls with `iter()` or `into_iter()` prefixed to them when completing on a type that has them.",
-                        "default": true,
-                        "type": "boolean"
-                    }
-                }
-            },
             {
                 "title": "completion",
                 "properties": {
diff --git a/lib/lsp-server/src/msg.rs b/lib/lsp-server/src/msg.rs
index 2749557b91..074bc43388 100644
--- a/lib/lsp-server/src/msg.rs
+++ b/lib/lsp-server/src/msg.rs
@@ -80,9 +80,9 @@ pub struct Request {
 
 #[derive(Debug, Serialize, Deserialize, Clone)]
 pub struct Response {
-    // JSON-RPC allows this to be null if we can't find or parse the
-    // request id. We fail deserialization in that case, so we just
-    // make this field mandatory.
+    // JSON RPC allows this to be null if it was impossible
+    // to decode the request's id. Ignore this special case
+    // and just die horribly.
     pub id: RequestId,
     #[serde(skip_serializing_if = "Option::is_none")]
     pub result: Option<serde_json::Value>,


Test patch:
diff --git a/crates/hir-def/src/body/tests/block.rs b/crates/hir-def/src/body/tests/block.rs
index e136dd18a5..f483efa851 100644
--- a/crates/hir-def/src/body/tests/block.rs
+++ b/crates/hir-def/src/body/tests/block.rs
@@ -475,7 +475,7 @@ fn outer() {
 
             block scope::tests
             name: _
-            outer: vg
+            outer: v
 
             crate
             outer: v
diff --git a/crates/hir-def/src/nameres/tests.rs b/crates/hir-def/src/nameres/tests.rs
index 73fc6787bf..318aee04f7 100644
--- a/crates/hir-def/src/nameres/tests.rs
+++ b/crates/hir-def/src/nameres/tests.rs
@@ -103,8 +103,8 @@ mod a {
             c: t
 
             crate::a::b::c
-            A: vg
-            b: tg
+            A: v
+            b: t
         "#]],
     );
 }
@@ -256,8 +256,8 @@ pub enum Foo { Bar, Baz }
 "#,
         expect![[r#"
             crate
-            Bar: tg vg
-            Baz: tg vg
+            Bar: t v
+            Baz: t v
         "#]],
     );
 }
@@ -421,10 +421,10 @@ pub struct NotExported;
 "#,
         expect![[r#"
             crate
-            Exported: tg vg
-            PublicItem: tg vg
-            allowed_reexport: tg
-            exported: tg
+            Exported: t v
+            PublicItem: t v
+            allowed_reexport: t
+            exported: t
             not_allowed_reexport1: _
             not_allowed_reexport2: _
         "#]],
@@ -692,7 +692,7 @@ mod b {
             b: t
 
             crate::a
-            T: t vg
+            T: t v
 
             crate::b
             T: v
diff --git a/crates/hir-def/src/nameres/tests/globs.rs b/crates/hir-def/src/nameres/tests/globs.rs
index ddb9d4a134..8963a57679 100644
--- a/crates/hir-def/src/nameres/tests/globs.rs
+++ b/crates/hir-def/src/nameres/tests/globs.rs
@@ -18,9 +18,9 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Baz: tg vg
-            Foo: tg vg
-            bar: tg
+            Baz: t v
+            Foo: t v
+            bar: t
             foo: t
 
             crate::foo
@@ -53,20 +53,20 @@ pub use super::*;
 "#,
         expect![[r#"
             crate
-            Baz: tg vg
-            Foo: tg vg
-            bar: tg
+            Baz: t v
+            Foo: t v
+            bar: t
             foo: t
 
             crate::foo
-            Baz: tg vg
+            Baz: t v
             Foo: t v
             bar: t
 
             crate::foo::bar
             Baz: t v
-            Foo: tg vg
-            bar: tg
+            Foo: t v
+            bar: t
         "#]],
     );
 }
@@ -91,20 +91,20 @@ pub use super::*;
 ",
         expect![[r#"
             crate
-            Baz: tg vg
-            bar: tg
+            Baz: t v
+            bar: t
             foo: t
 
             crate::foo
-            Baz: tg vg
+            Baz: t v
             PrivateStructFoo: t v
             bar: t
 
             crate::foo::bar
             Baz: t v
             PrivateStructBar: t v
-            PrivateStructFoo: tg vg
-            bar: tg
+            PrivateStructFoo: t v
+            bar: t
         "#]],
     );
 }
@@ -130,9 +130,9 @@ pub(crate) struct PubCrateStruct;
 ",
         expect![[r#"
             crate
-            Foo: tg
-            PubCrateStruct: tg vg
-            bar: tg
+            Foo: t
+            PubCrateStruct: t v
+            bar: t
             foo: t
 
             crate::foo
@@ -160,7 +160,7 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Baz: tg vg
+            Baz: t v
         "#]],
     );
 }
@@ -178,7 +178,7 @@ struct Foo;
 "#,
         expect![[r#"
             crate
-            Baz: tg vg
+            Baz: t v
         "#]],
     );
 }
@@ -193,8 +193,8 @@ use self::Foo::*;
 "#,
         expect![[r#"
             crate
-            Bar: tg vg
-            Baz: tg vg
+            Bar: t v
+            Baz: t v
             Foo: t
         "#]],
     );
@@ -210,8 +210,8 @@ use self::Foo::{*};
 "#,
         expect![[r#"
             crate
-            Bar: tg vg
-            Baz: tg vg
+            Bar: t v
+            Baz: t v
             Foo: t
         "#]],
     );
@@ -359,7 +359,7 @@ use event::Event;
             event: t
 
             crate::event
-            Event: t vg
+            Event: t v
             serenity: t
 
             crate::event::serenity
@@ -388,10 +388,10 @@ use reexport::*;
 "#,
         expect![[r#"
             crate
-            Trait: tg
+            Trait: t
             defs: t
-            function: vg
-            makro: mg
+            function: v
+            makro: m
             reexport: t
 
             crate::defs
@@ -400,10 +400,10 @@ use reexport::*;
             makro: m
 
             crate::reexport
-            Trait: tg
-            function: vg
+            Trait: t
+            function: v
             inner: t
-            makro: mg
+            makro: m
 
             crate::reexport::inner
             Trait: ti
@@ -442,12 +442,12 @@ mod glob_target {
             ShouldBePrivate: t v
 
             crate::outer
-            ShouldBePrivate: tg vg
+            ShouldBePrivate: t v
             inner_superglob: t
 
             crate::outer::inner_superglob
-            ShouldBePrivate: tg vg
-            inner_superglob: tg
+            ShouldBePrivate: t v
+            inner_superglob: t
         "#]],
     );
 }
@@ -473,20 +473,20 @@ use reexport_2::*;
 "#,
         expect![[r#"
             crate
-            Placeholder: tg vg
+            Placeholder: t v
             libs: t
-            reexport_1: tg
+            reexport_1: t
             reexport_2: t
 
             crate::libs
             Placeholder: t v
 
             crate::reexport_2
-            Placeholder: tg vg
+            Placeholder: t v
             reexport_1: t
 
             crate::reexport_2::reexport_1
-            Placeholder: tg vg
+            Placeholder: t v
         "#]],
     );
 }
diff --git a/crates/hir-def/src/nameres/tests/macros.rs b/crates/hir-def/src/nameres/tests/macros.rs
index 610886d55f..a05c4dcf9b 100644
--- a/crates/hir-def/src/nameres/tests/macros.rs
+++ b/crates/hir-def/src/nameres/tests/macros.rs
@@ -97,9 +97,9 @@ macro_rules! structs {
             bar: t
 
             crate::bar
-            Bar: tg
-            Foo: tg
-            bar: tg
+            Bar: t
+            Foo: t
+            bar: t
         "#]],
     );
 }
@@ -130,9 +130,9 @@ macro_rules! structs {
             bar: t
 
             crate::bar
-            Bar: tg
-            Foo: tg
-            bar: tg
+            Bar: t
+            Foo: t
+            bar: t
         "#]],
     );
 }
@@ -169,9 +169,9 @@ macro_rules! inner {
             bar: t
 
             crate::bar
-            Bar: tg
-            Foo: tg
-            bar: tg
+            Bar: t
+            Foo: t
+            bar: t
         "#]],
     );
 }
@@ -794,7 +794,7 @@ pub trait Clone {}
 "#,
         expect![[r#"
             crate
-            Clone: tg mg
+            Clone: t m
         "#]],
     );
 }
@@ -1075,9 +1075,9 @@ macro_rules! mbe {
 "#,
         expect![[r#"
             crate
-            DummyTrait: mg
-            attribute_macro: mg
-            function_like_macro: mg
+            DummyTrait: m
+            attribute_macro: m
+            function_like_macro: m
         "#]],
     );
 }
diff --git a/crates/ide-completion/src/tests.rs b/crates/ide-completion/src/tests.rs
index 9d91f95eb6..b7dbf0a630 100644
--- a/crates/ide-completion/src/tests.rs
+++ b/crates/ide-completion/src/tests.rs
@@ -87,8 +87,6 @@ pub(crate) const TEST_CONFIG: CompletionConfig<'_> = CompletionConfig {
     fields_to_resolve: CompletionFieldsToResolve::empty(),
     exclude_flyimport: vec![],
     exclude_traits: &[],
-    enable_auto_await: true,
-    enable_auto_iter: true,
 };
 
 pub(crate) fn completion_list(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String {