Skip to content

Commit e11959a

Browse files
bors[bot]Veykril
andauthored
Merge #11942
11942: fix: Check whether a parameter can be converted to a local r=Veykril a=Veykril Fixes #11941 bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2 parents 399559e + 15e7112 commit e11959a

File tree

3 files changed

+41
-24
lines changed

3 files changed

+41
-24
lines changed

crates/hir/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,10 +1506,15 @@ impl Param {
15061506
db.function_data(self.func.id).params[self.idx].0.clone()
15071507
}
15081508

1509-
pub fn as_local(&self, db: &dyn HirDatabase) -> Local {
1509+
pub fn as_local(&self, db: &dyn HirDatabase) -> Option<Local> {
15101510
let parent = DefWithBodyId::FunctionId(self.func.into());
15111511
let body = db.body(parent);
1512-
Local { parent, pat_id: body.params[self.idx] }
1512+
let pat_id = body.params[self.idx];
1513+
if let Pat::Bind { .. } = &body[pat_id] {
1514+
Some(Local { parent, pat_id: body.params[self.idx] })
1515+
} else {
1516+
None
1517+
}
15131518
}
15141519

15151520
pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> {

crates/ide/src/rename.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,13 @@ fn rename_to_self(sema: &Semantics<RootDatabase>, local: hir::Local) -> RenameRe
219219
let first_param = params
220220
.first()
221221
.ok_or_else(|| format_err!("Cannot rename local to self unless it is a parameter"))?;
222-
if first_param.as_local(sema.db) != local {
223-
bail!("Only the first parameter may be renamed to self");
222+
match first_param.as_local(sema.db) {
223+
Some(plocal) => {
224+
if plocal != local {
225+
bail!("Only the first parameter may be renamed to self");
226+
}
227+
}
228+
None => bail!("rename_to_self invoked on destructuring parameter"),
224229
}
225230

226231
let assoc_item = fn_def

crates/ide_assists/src/handlers/inline_call.rs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -317,30 +317,37 @@ fn inline(
317317
if !matches!(pat, ast::Pat::IdentPat(pat) if pat.is_simple_ident()) {
318318
return Vec::new();
319319
}
320-
usages_for_locals(param.as_local(sema.db))
321-
.map(|FileReference { name, range, .. }| match name {
322-
ast::NameLike::NameRef(_) => body
323-
.syntax()
324-
.covering_element(range)
325-
.ancestors()
326-
.nth(3)
327-
.and_then(ast::PathExpr::cast),
328-
_ => None,
329-
})
330-
.collect::<Option<Vec<_>>>()
331-
.unwrap_or_default()
320+
// FIXME: we need to fetch all locals declared in the parameter here
321+
// not only the local if it is a simple binding
322+
match param.as_local(sema.db) {
323+
Some(l) => usages_for_locals(l)
324+
.map(|FileReference { name, range, .. }| match name {
325+
ast::NameLike::NameRef(_) => body
326+
.syntax()
327+
.covering_element(range)
328+
.ancestors()
329+
.nth(3)
330+
.and_then(ast::PathExpr::cast),
331+
_ => None,
332+
})
333+
.collect::<Option<Vec<_>>>()
334+
.unwrap_or_default(),
335+
None => Vec::new(),
336+
}
332337
})
333338
.collect();
334339
if function.self_param(sema.db).is_some() {
335340
let this = || make::name_ref("this").syntax().clone_for_update();
336-
usages_for_locals(params[0].2.as_local(sema.db))
337-
.flat_map(|FileReference { name, range, .. }| match name {
338-
ast::NameLike::NameRef(_) => Some(body.syntax().covering_element(range)),
339-
_ => None,
340-
})
341-
.for_each(|it| {
342-
ted::replace(it, &this());
343-
})
341+
if let Some(self_local) = params[0].2.as_local(sema.db) {
342+
usages_for_locals(self_local)
343+
.flat_map(|FileReference { name, range, .. }| match name {
344+
ast::NameLike::NameRef(_) => Some(body.syntax().covering_element(range)),
345+
_ => None,
346+
})
347+
.for_each(|it| {
348+
ted::replace(it, &this());
349+
})
350+
}
344351
}
345352
// Inline parameter expressions or generate `let` statements depending on whether inlining works or not.
346353
for ((pat, param_ty, _), usages, expr) in izip!(params, param_use_nodes, arguments).rev() {

0 commit comments

Comments
 (0)