about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-07-22 17:12:55 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-07-22 17:14:17 +0200
commit83a3087f94b9f73efbb3d601693d8d168386b120 (patch)
tree8a09eeb2f4ed83cc311c83b8c6b4687be82dea37
parentbe1dc79ed9ecfe447f9e7b39fd708a2c443e4d44 (diff)
downloadrust-83a3087f94b9f73efbb3d601693d8d168386b120.tar.gz
rust-83a3087f94b9f73efbb3d601693d8d168386b120.zip
internal: Shrink size of `Binding`
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs15
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/hir.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs32
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs32
15 files changed, 94 insertions, 56 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
index ca4a3f5217c..3486928e414 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
@@ -6,13 +6,14 @@ pub mod scope;
 #[cfg(test)]
 mod tests;
 
-use std::ops::Index;
+use std::ops::{Deref, Index};
 
 use base_db::CrateId;
 use cfg::{CfgExpr, CfgOptions};
 use hir_expand::{name::Name, InFile};
 use la_arena::{Arena, ArenaMap};
 use rustc_hash::FxHashMap;
+use smallvec::SmallVec;
 use span::MacroFileId;
 use syntax::{ast, AstPtr, SyntaxNodePtr};
 use triomphe::Arc;
@@ -91,6 +92,7 @@ pub struct BodySourceMap {
     label_map_back: ArenaMap<LabelId, LabelSource>,
 
     self_param: Option<InFile<AstPtr<ast::SelfParam>>>,
+    binding_definitions: FxHashMap<BindingId, SmallVec<[PatId; 4]>>,
 
     /// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
     /// Instead, we use id of expression (`92`) to identify the field.
@@ -377,6 +379,10 @@ impl BodySourceMap {
         self.label_map_back[label]
     }
 
+    pub fn patterns_for_binding(&self, binding: BindingId) -> &[PatId] {
+        self.binding_definitions.get(&binding).map_or(&[], Deref::deref)
+    }
+
     pub fn node_label(&self, node: InFile<&ast::Label>) -> Option<LabelId> {
         let src = node.map(AstPtr::new);
         self.label_map.get(&src).cloned()
@@ -428,6 +434,7 @@ impl BodySourceMap {
             expansions,
             format_args_template_map,
             diagnostics,
+            binding_definitions,
         } = self;
         format_args_template_map.shrink_to_fit();
         expr_map.shrink_to_fit();
@@ -440,5 +447,6 @@ impl BodySourceMap {
         pat_field_map_back.shrink_to_fit();
         expansions.shrink_to_fit();
         diagnostics.shrink_to_fit();
+        binding_definitions.shrink_to_fit();
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
index e69f4129dd5..fe5264674a6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
@@ -11,7 +11,6 @@ use hir_expand::{
 };
 use intern::{sym, Interned, Symbol};
 use rustc_hash::FxHashMap;
-use smallvec::SmallVec;
 use span::AstIdMap;
 use stdx::never;
 use syntax::{
@@ -1437,11 +1436,12 @@ impl ExprCollector<'_> {
         args: AstChildren<ast::Pat>,
         has_leading_comma: bool,
         binding_list: &mut BindingList,
-    ) -> (Box<[PatId]>, Option<usize>) {
+    ) -> (Box<[PatId]>, Option<u32>) {
         let args: Vec<_> = args.map(|p| self.collect_pat_possibly_rest(p, binding_list)).collect();
         // Find the location of the `..`, if there is one. Note that we do not
         // consider the possibility of there being multiple `..` here.
-        let ellipsis = args.iter().position(|p| p.is_right());
+        let ellipsis = args.iter().position(|p| p.is_right()).map(|it| it as u32);
+
         // We want to skip the `..` pattern here, since we account for it above.
         let mut args: Vec<_> = args.into_iter().filter_map(Either::left).collect();
         // if there is a leading comma, the user is most likely to type out a leading pattern
@@ -1512,7 +1512,7 @@ impl ExprCollector<'_> {
     }
 
     fn add_definition_to_binding(&mut self, binding_id: BindingId, pat_id: PatId) {
-        self.body.bindings[binding_id].definitions.push(pat_id);
+        self.source_map.binding_definitions.entry(binding_id).or_default().push(pat_id);
     }
 
     // region: labels
@@ -2058,12 +2058,7 @@ impl ExprCollector<'_> {
     }
 
     fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId {
-        let binding = self.body.bindings.alloc(Binding {
-            name,
-            mode,
-            definitions: SmallVec::new(),
-            problems: None,
-        });
+        let binding = self.body.bindings.alloc(Binding { name, mode, problems: None });
         if let Some(owner) = self.current_binding_owner {
             self.body.binding_owners.insert(binding, owner);
         }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
index c48d16d0530..edaee60937d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
@@ -517,7 +517,7 @@ impl Printer<'_> {
                     if i != 0 {
                         w!(self, ", ");
                     }
-                    if *ellipsis == Some(i) {
+                    if *ellipsis == Some(i as u32) {
                         w!(self, ".., ");
                     }
                     self.print_pat(*pat);
@@ -595,7 +595,7 @@ impl Printer<'_> {
                     if i != 0 {
                         w!(self, ", ");
                     }
-                    if *ellipsis == Some(i) {
+                    if *ellipsis == Some(i as u32) {
                         w!(self, ", ..");
                     }
                     self.print_pat(*arg);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
index 404e5ba69c6..bf201ca8347 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
@@ -484,7 +484,7 @@ fn foo() {
         let function = find_function(&db, file_id.file_id());
 
         let scopes = db.expr_scopes(function.into());
-        let (body, source_map) = db.body_with_source_map(function.into());
+        let (_, source_map) = db.body_with_source_map(function.into());
 
         let expr_scope = {
             let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap();
@@ -495,7 +495,7 @@ fn foo() {
 
         let resolved = scopes.resolve_name_in_scope(expr_scope, &name_ref.as_name()).unwrap();
         let pat_src = source_map
-            .pat_syntax(*body.bindings[resolved.binding()].definitions.first().unwrap())
+            .pat_syntax(*source_map.binding_definitions[&resolved.binding()].first().unwrap())
             .unwrap();
 
         let local_name = pat_src.value.syntax_node_ptr().to_node(file.syntax());
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs
index d7eb80a88bf..86fd092603f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs
@@ -21,7 +21,6 @@ use hir_expand::name::Name;
 use intern::{Interned, Symbol};
 use la_arena::{Idx, RawIdx};
 use rustc_apfloat::ieee::{Half as f16, Quad as f128};
-use smallvec::SmallVec;
 use syntax::ast;
 
 use crate::{
@@ -525,7 +524,6 @@ pub enum BindingProblems {
 pub struct Binding {
     pub name: Name,
     pub mode: BindingAnnotation,
-    pub definitions: SmallVec<[PatId; 1]>,
     pub problems: Option<BindingProblems>,
 }
 
@@ -540,7 +538,7 @@ pub struct RecordFieldPat {
 pub enum Pat {
     Missing,
     Wild,
-    Tuple { args: Box<[PatId]>, ellipsis: Option<usize> },
+    Tuple { args: Box<[PatId]>, ellipsis: Option<u32> },
     Or(Box<[PatId]>),
     Record { path: Option<Box<Path>>, args: Box<[RecordFieldPat]>, ellipsis: bool },
     Range { start: Option<Box<LiteralOrConst>>, end: Option<Box<LiteralOrConst>> },
@@ -548,7 +546,7 @@ pub enum Pat {
     Path(Box<Path>),
     Lit(ExprId),
     Bind { id: BindingId, subpat: Option<PatId> },
-    TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<usize> },
+    TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<u32> },
     Ref { pat: PatId, mutability: Mutability },
     Box { inner: PatId },
     ConstBlock(ExprId),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
index 8dcc14feb27..a0ee7c0748b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
@@ -206,7 +206,7 @@ impl<'a> PatCtxt<'a> {
         &mut self,
         pats: &[PatId],
         expected_len: usize,
-        ellipsis: Option<usize>,
+        ellipsis: Option<u32>,
     ) -> Vec<FieldPat> {
         if pats.len() > expected_len {
             self.errors.push(PatternError::ExtraFields);
@@ -214,7 +214,7 @@ impl<'a> PatCtxt<'a> {
         }
 
         pats.iter()
-            .enumerate_and_adjust(expected_len, ellipsis)
+            .enumerate_and_adjust(expected_len, ellipsis.map(|it| it as usize))
             .map(|(i, &subpattern)| FieldPat {
                 field: LocalFieldId::from_raw((i as u32).into()),
                 pattern: self.lower_pattern(subpattern),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
index 417fca5dcd6..034ed2d691b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
@@ -889,7 +889,7 @@ impl InferenceContext<'_> {
         match &self.body[pat] {
             Pat::Missing | Pat::Wild => (),
             Pat::Tuple { args, ellipsis } => {
-                let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
+                let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
                 let field_count = match self.result[pat].kind(Interner) {
                     TyKind::Tuple(_, s) => s.len(Interner),
                     _ => return,
@@ -964,7 +964,7 @@ impl InferenceContext<'_> {
                     }
                     VariantId::StructId(s) => {
                         let vd = &*self.db.struct_data(s).variant_data;
-                        let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
+                        let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
                         let fields = vd.fields().iter();
                         let it =
                             al.iter().zip(fields.clone()).chain(ar.iter().rev().zip(fields.rev()));
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index 7857d207be7..87233fa0113 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -1170,7 +1170,7 @@ impl InferenceContext<'_> {
             Expr::Tuple { exprs, .. } => {
                 // We don't consider multiple ellipses. This is analogous to
                 // `hir_def::body::lower::ExprCollector::collect_tuple_pat()`.
-                let ellipsis = exprs.iter().position(|e| is_rest_expr(*e));
+                let ellipsis = exprs.iter().position(|e| is_rest_expr(*e)).map(|it| it as u32);
                 let exprs: Vec<_> = exprs.iter().filter(|e| !is_rest_expr(**e)).copied().collect();
 
                 self.infer_tuple_pat_like(&rhs_ty, (), ellipsis, &exprs)
@@ -1184,7 +1184,7 @@ impl InferenceContext<'_> {
 
                 // We don't consider multiple ellipses. This is analogous to
                 // `hir_def::body::lower::ExprCollector::collect_tuple_pat()`.
-                let ellipsis = args.iter().position(|e| is_rest_expr(*e));
+                let ellipsis = args.iter().position(|e| is_rest_expr(*e)).map(|it| it as u32);
                 let args: Vec<_> = args.iter().filter(|e| !is_rest_expr(**e)).copied().collect();
 
                 self.infer_tuple_struct_pat_like(path, &rhs_ty, (), lhs, ellipsis, &args)
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
index dac5a5ea699..f3c6f13a08d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
@@ -68,7 +68,7 @@ impl InferenceContext<'_> {
         expected: &Ty,
         default_bm: T::BindingMode,
         id: T,
-        ellipsis: Option<usize>,
+        ellipsis: Option<u32>,
         subs: &[T],
     ) -> Ty {
         let (ty, def) = self.resolve_variant(path, true);
@@ -98,7 +98,7 @@ impl InferenceContext<'_> {
                 let visibilities = self.db.field_visibilities(def);
 
                 let (pre, post) = match ellipsis {
-                    Some(idx) => subs.split_at(idx),
+                    Some(idx) => subs.split_at(idx as usize),
                     None => (subs, &[][..]),
                 };
                 let post_idx_offset = field_types.iter().count().saturating_sub(post.len());
@@ -219,7 +219,7 @@ impl InferenceContext<'_> {
         &mut self,
         expected: &Ty,
         default_bm: T::BindingMode,
-        ellipsis: Option<usize>,
+        ellipsis: Option<u32>,
         subs: &[T],
     ) -> Ty {
         let expected = self.resolve_ty_shallow(expected);
@@ -229,7 +229,9 @@ impl InferenceContext<'_> {
         };
 
         let ((pre, post), n_uncovered_patterns) = match ellipsis {
-            Some(idx) => (subs.split_at(idx), expectations.len().saturating_sub(subs.len())),
+            Some(idx) => {
+                (subs.split_at(idx as usize), expectations.len().saturating_sub(subs.len()))
+            }
             None => ((subs, &[][..]), 0),
         };
         let mut expectations_iter = expectations
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
index 2e106877cbc..06a4236e0ac 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
@@ -1164,6 +1164,7 @@ impl MirBody {
 pub enum MirSpan {
     ExprId(ExprId),
     PatId(PatId),
+    BindingId(BindingId),
     SelfParam,
     Unknown,
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index 26a49412e0f..f8083e89858 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -388,6 +388,16 @@ impl MirEvalError {
                         Ok(s) => s.map(|it| it.syntax_node_ptr()),
                         Err(_) => continue,
                     },
+                    MirSpan::BindingId(b) => {
+                        match source_map
+                            .patterns_for_binding(*b)
+                            .iter()
+                            .find_map(|p| source_map.pat_syntax(*p).ok())
+                        {
+                            Some(s) => s.map(|it| it.syntax_node_ptr()),
+                            None => continue,
+                        }
+                    }
                     MirSpan::SelfParam => match source_map.self_param_syntax() {
                         Some(s) => s.map(|it| it.syntax_node_ptr()),
                         None => continue,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index 11c1e8ce3cc..057f5533805 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -1720,14 +1720,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
     /// This function push `StorageLive` statement for the binding, and applies changes to add `StorageDead` and
     /// `Drop` in the appropriated places.
     fn push_storage_live(&mut self, b: BindingId, current: BasicBlockId) -> Result<()> {
-        let span = self.body.bindings[b]
-            .definitions
-            .first()
-            .copied()
-            .map(MirSpan::PatId)
-            .unwrap_or(MirSpan::Unknown);
         let l = self.binding_local(b)?;
-        self.push_storage_live_for_local(l, current, span)
+        self.push_storage_live_for_local(l, current, MirSpan::BindingId(b))
     }
 
     fn push_storage_live_for_local(
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
index 75969067943..34e0f30afb7 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
@@ -23,7 +23,7 @@ macro_rules! not_supported {
 }
 
 pub(super) enum AdtPatternShape<'a> {
-    Tuple { args: &'a [PatId], ellipsis: Option<usize> },
+    Tuple { args: &'a [PatId], ellipsis: Option<u32> },
     Record { args: &'a [RecordFieldPat] },
     Unit,
 }
@@ -627,12 +627,12 @@ impl MirLowerCtx<'_> {
         current: BasicBlockId,
         current_else: Option<BasicBlockId>,
         args: &[PatId],
-        ellipsis: Option<usize>,
+        ellipsis: Option<u32>,
         fields: impl DoubleEndedIterator<Item = PlaceElem> + Clone,
         cond_place: &Place,
         mode: MatchingMode,
     ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
-        let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
+        let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
         let it = al
             .iter()
             .zip(fields.clone())
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index bb149a01e83..32057fbaff0 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -1806,6 +1806,16 @@ impl DefWithBody {
                             Some(s) => s.map(|it| it.into()),
                             None => continue,
                         },
+                        mir::MirSpan::BindingId(b) => {
+                            match source_map
+                                .patterns_for_binding(b)
+                                .iter()
+                                .find_map(|p| source_map.pat_syntax(*p).ok())
+                            {
+                                Some(s) => s.map(|it| it.into()),
+                                None => continue,
+                            }
+                        }
                         mir::MirSpan::Unknown => continue,
                     };
                     acc.push(
@@ -1822,8 +1832,8 @@ impl DefWithBody {
                     let Some(&local) = mir_body.binding_locals.get(binding_id) else {
                         continue;
                     };
-                    if body[binding_id]
-                        .definitions
+                    if source_map
+                        .patterns_for_binding(binding_id)
                         .iter()
                         .any(|&pat| source_map.pat_syntax(pat).is_err())
                     {
@@ -1859,6 +1869,16 @@ impl DefWithBody {
                                         Ok(s) => s.map(|it| it.into()),
                                         Err(_) => continue,
                                     },
+                                    mir::MirSpan::BindingId(b) => {
+                                        match source_map
+                                            .patterns_for_binding(*b)
+                                            .iter()
+                                            .find_map(|p| source_map.pat_syntax(*p).ok())
+                                        {
+                                            Some(s) => s.map(|it| it.into()),
+                                            None => continue,
+                                        }
+                                    }
                                     mir::MirSpan::SelfParam => match source_map.self_param_syntax()
                                     {
                                         Some(s) => s.map(|it| it.into()),
@@ -3291,8 +3311,8 @@ impl Local {
                     source: source.map(|ast| Either::Right(ast.to_node(&root))),
                 }]
             }
-            _ => body[self.binding_id]
-                .definitions
+            _ => source_map
+                .patterns_for_binding(self.binding_id)
                 .iter()
                 .map(|&definition| {
                     let src = source_map.pat_syntax(definition).unwrap(); // Hmm...
@@ -3320,8 +3340,8 @@ impl Local {
                     source: source.map(|ast| Either::Right(ast.to_node(&root))),
                 }
             }
-            _ => body[self.binding_id]
-                .definitions
+            _ => source_map
+                .patterns_for_binding(self.binding_id)
                 .first()
                 .map(|&definition| {
                     let src = source_map.pat_syntax(definition).unwrap(); // Hmm...
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs
index 86075bd9bb7..7f901db28d3 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs
@@ -32,9 +32,8 @@ pub(super) fn hints(
     let def = sema.to_def(def)?;
     let def: DefWithBody = def.into();
 
-    let source_map = sema.db.body_with_source_map(def.into()).1;
+    let (hir, source_map) = sema.db.body_with_source_map(def.into());
 
-    let hir = sema.db.body(def.into());
     let mir = sema.db.mir_body(def.into()).ok()?;
 
     let local_to_binding = mir.local_to_binding_map();
@@ -74,22 +73,33 @@ pub(super) fn hints(
                     Ok(s) => s.value.text_range(),
                     Err(_) => continue,
                 },
+                MirSpan::BindingId(b) => {
+                    match source_map
+                        .patterns_for_binding(b)
+                        .iter()
+                        .find_map(|p| source_map.pat_syntax(*p).ok())
+                    {
+                        Some(s) => s.value.text_range(),
+                        None => continue,
+                    }
+                }
                 MirSpan::SelfParam => match source_map.self_param_syntax() {
                     Some(s) => s.value.text_range(),
                     None => continue,
                 },
                 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_source =
-                binding.definitions.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 name = binding.name.display_no_db().to_smolstr();
             if name.starts_with("<ra@") {
                 continue; // Ignore desugared variables