diff --git a/crates/ide-assists/src/handlers/convert_let_else_to_match.rs b/crates/ide-assists/src/handlers/convert_let_else_to_match.rs index cfd176fcf253..e7560b0c18bf 100644 --- a/crates/ide-assists/src/handlers/convert_let_else_to_match.rs +++ b/crates/ide-assists/src/handlers/convert_let_else_to_match.rs @@ -1,73 +1,77 @@ -use syntax::ast::{edit::AstNodeEdit, AstNode, HasName, LetStmt, Pat}; +use hir::Semantics; +use ide_db::RootDatabase; +use syntax::ast::{edit::AstNodeEdit, AstNode, HasName, LetStmt, Name, Pat}; use syntax::T; use crate::{AssistContext, AssistId, AssistKind, Assists}; /// Gets a list of binders in a pattern, and whether they are mut. -fn binders_in_pat(pat: &Pat) -> Option> { +fn binders_in_pat( + acc: &mut Vec<(Name, bool)>, + pat: &Pat, + sem: &Semantics, +) -> Option<()> { use Pat::*; match pat { IdentPat(p) => { - let ident = p.name()?.text().to_string(); + let ident = p.name()?; let ismut = p.ref_token().is_none() && p.mut_token().is_some(); - let mut res = vec![(ident, ismut)]; + acc.push((ident, ismut)); if let Some(inner) = p.pat() { - res.extend(binders_in_pat(&inner)?); + binders_in_pat(acc, &inner, sem)?; } - Some(res) + Some(()) } - BoxPat(p) => p.pat().and_then(|p| binders_in_pat(&p)), - RestPat(_) | LiteralPat(_) | PathPat(_) | WildcardPat(_) | ConstBlockPat(_) => Some(vec![]), + BoxPat(p) => p.pat().and_then(|p| binders_in_pat(acc, &p, sem)), + RestPat(_) | LiteralPat(_) | PathPat(_) | WildcardPat(_) | ConstBlockPat(_) => Some(()), OrPat(p) => { - let mut v = vec![]; for p in p.pats() { - v.extend(binders_in_pat(&p)?); + binders_in_pat(acc, &p, sem)?; } - Some(v) + Some(()) } - ParenPat(p) => p.pat().and_then(|p| binders_in_pat(&p)), + ParenPat(p) => p.pat().and_then(|p| binders_in_pat(acc, &p, sem)), RangePat(p) => { - let mut start = if let Some(st) = p.start() { binders_in_pat(&st)? } else { vec![] }; - let end = if let Some(st) = p.end() { binders_in_pat(&st)? } else { vec![] }; - start.extend(end); - Some(start) + if let Some(st) = p.start() { + binders_in_pat(acc, &st, sem)? + } + if let Some(ed) = p.end() { + binders_in_pat(acc, &ed, sem)? + } + Some(()) } RecordPat(p) => { - let mut v = vec![]; for f in p.record_pat_field_list()?.fields() { let pat = f.pat()?; - v.extend(binders_in_pat(&pat)?); + binders_in_pat(acc, &pat, sem)?; } - Some(v) + Some(()) } - RefPat(p) => p.pat().and_then(|p| binders_in_pat(&p)), + RefPat(p) => p.pat().and_then(|p| binders_in_pat(acc, &p, sem)), SlicePat(p) => { - let mut v = vec![]; for p in p.pats() { - v.extend(binders_in_pat(&p)?); + binders_in_pat(acc, &p, sem)?; } - Some(v) + Some(()) } TuplePat(p) => { - let mut v = vec![]; for p in p.fields() { - v.extend(binders_in_pat(&p)?); + binders_in_pat(acc, &p, sem)?; } - Some(v) + Some(()) } TupleStructPat(p) => { - let mut v = vec![]; for p in p.fields() { - v.extend(binders_in_pat(&p)?); + binders_in_pat(acc, &p, sem)?; } - Some(v) + Some(()) } // don't support macro pat yet MacroPat(_) => None, } } -fn binders_to_str(binders: &[(String, bool)], addmut: bool) -> String { +fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String { let vars = binders .iter() .map( @@ -119,7 +123,8 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext) return None; } let pat = let_stmt.pat()?; - let binders = binders_in_pat(&pat)?; + let mut binders = Vec::new(); + binders_in_pat(&mut binders, &pat, &ctx.sema)?; let target = let_stmt.syntax().text_range(); acc.add( @@ -139,7 +144,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext) // remove the mut from the pattern for (b, ismut) in binders.iter() { if *ismut { - pat_no_mut = pat_no_mut.replace(&format!("mut {b}"), b); + pat_no_mut = pat_no_mut.replace(&format!("mut {b}"), &b.to_string()); } }