aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs28
1 files changed, 19 insertions, 9 deletions
diff --git a/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs
index ee6ddfbc6..086a44425 100644
--- a/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs
+++ b/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -1,4 +1,4 @@
1use hir::{Adt, ModuleDef}; 1use hir::{Adt, ModuleDef, Struct};
2use ide_db::defs::{Definition, NameRefClass}; 2use ide_db::defs::{Definition, NameRefClass};
3use syntax::{ 3use syntax::{
4 ast::{self, AstNode, GenericParamsOwner, VisibilityOwner}, 4 ast::{self, AstNode, GenericParamsOwner, VisibilityOwner},
@@ -55,6 +55,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
55 ast::FieldList::TupleFieldList(it) => it, 55 ast::FieldList::TupleFieldList(it) => it,
56 ast::FieldList::RecordFieldList(_) => return None, 56 ast::FieldList::RecordFieldList(_) => return None,
57 }; 57 };
58 let strukt_def = ctx.sema.to_def(&strukt)?;
58 59
59 let target = strukt.syntax().text_range(); 60 let target = strukt.syntax().text_range();
60 acc.add( 61 acc.add(
@@ -64,7 +65,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
64 |edit| { 65 |edit| {
65 let names = generate_names(tuple_fields.fields()); 66 let names = generate_names(tuple_fields.fields());
66 edit_field_references(ctx, edit, tuple_fields.fields(), &names); 67 edit_field_references(ctx, edit, tuple_fields.fields(), &names);
67 edit_struct_references(ctx, edit, &strukt, &names); 68 edit_struct_references(ctx, edit, strukt_def, &names);
68 edit_struct_def(ctx, edit, &strukt, tuple_fields, names); 69 edit_struct_def(ctx, edit, &strukt, tuple_fields, names);
69 }, 70 },
70 ) 71 )
@@ -80,7 +81,7 @@ fn edit_struct_def(
80 let record_fields = tuple_fields 81 let record_fields = tuple_fields
81 .fields() 82 .fields()
82 .zip(names) 83 .zip(names)
83 .map(|(f, name)| ast::make::record_field(f.visibility(), name, f.ty().unwrap())); 84 .filter_map(|(f, name)| Some(ast::make::record_field(f.visibility(), name, f.ty()?)));
84 let record_fields = ast::make::record_field_list(record_fields); 85 let record_fields = ast::make::record_field_list(record_fields);
85 let tuple_fields_text_range = tuple_fields.syntax().text_range(); 86 let tuple_fields_text_range = tuple_fields.syntax().text_range();
86 87
@@ -103,10 +104,9 @@ fn edit_struct_def(
103fn edit_struct_references( 104fn edit_struct_references(
104 ctx: &AssistContext, 105 ctx: &AssistContext,
105 edit: &mut AssistBuilder, 106 edit: &mut AssistBuilder,
106 strukt: &ast::Struct, 107 strukt: Struct,
107 names: &[ast::Name], 108 names: &[ast::Name],
108) { 109) {
109 let strukt = ctx.sema.to_def(strukt).unwrap();
110 let strukt_def = Definition::ModuleDef(ModuleDef::Adt(Adt::Struct(strukt))); 110 let strukt_def = Definition::ModuleDef(ModuleDef::Adt(Adt::Struct(strukt)));
111 let usages = strukt_def.usages(&ctx.sema).include_self_kw_refs(true).all(); 111 let usages = strukt_def.usages(&ctx.sema).include_self_kw_refs(true).all();
112 112
@@ -117,10 +117,15 @@ fn edit_struct_references(
117 match_ast! { 117 match_ast! {
118 match node { 118 match node {
119 ast::TupleStructPat(tuple_struct_pat) => { 119 ast::TupleStructPat(tuple_struct_pat) => {
120 let path = match tuple_struct_pat.path() {
121 Some(it) => it,
122 None => continue,
123 };
124
120 edit.replace( 125 edit.replace(
121 tuple_struct_pat.syntax().text_range(), 126 tuple_struct_pat.syntax().text_range(),
122 ast::make::record_pat_with_fields( 127 ast::make::record_pat_with_fields(
123 tuple_struct_pat.path().unwrap(), 128 path,
124 ast::make::record_pat_field_list(tuple_struct_pat.fields().zip(names).map( 129 ast::make::record_pat_field_list(tuple_struct_pat.fields().zip(names).map(
125 |(pat, name)| { 130 |(pat, name)| {
126 ast::make::record_pat_field( 131 ast::make::record_pat_field(
@@ -135,7 +140,10 @@ fn edit_struct_references(
135 }, 140 },
136 // for tuple struct creations like Foo(42) 141 // for tuple struct creations like Foo(42)
137 ast::CallExpr(call_expr) => { 142 ast::CallExpr(call_expr) => {
138 let path = call_expr.syntax().descendants().find_map(ast::PathExpr::cast).unwrap().path().unwrap(); 143 let path = match call_expr.syntax().descendants().find_map(ast::PathExpr::cast).map(|expr| expr.path()) {
144 Some(Some(it)) => it,
145 _ => continue,
146 };
139 147
140 // this also includes method calls like Foo::new(42), we should skip them 148 // this also includes method calls like Foo::new(42), we should skip them
141 if let Some(Some(name_ref)) = path.segment().map(|s| s.name_ref()) { 149 if let Some(Some(name_ref)) = path.segment().map(|s| s.name_ref()) {
@@ -146,8 +154,10 @@ fn edit_struct_references(
146 }; 154 };
147 } 155 }
148 156
149 let arg_list = 157 let arg_list = match call_expr.syntax().descendants().find_map(ast::ArgList::cast) {
150 call_expr.syntax().descendants().find_map(ast::ArgList::cast).unwrap(); 158 Some(it) => it,
159 None => continue,
160 };
151 161
152 edit.replace( 162 edit.replace(
153 call_expr.syntax().text_range(), 163 call_expr.syntax().text_range(),