aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src')
-rw-r--r--crates/ra_assists/src/assist_ctx.rs19
-rw-r--r--crates/ra_assists/src/doc_tests.rs6
-rw-r--r--crates/ra_assists/src/handlers/add_missing_impl_members.rs26
-rw-r--r--crates/ra_assists/src/handlers/add_new.rs4
-rw-r--r--crates/ra_assists/src/handlers/change_visibility.rs13
-rw-r--r--crates/ra_assists/src/lib.rs44
-rw-r--r--crates/ra_assists/src/utils.rs10
7 files changed, 65 insertions, 57 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs
index da2880037..83dd270c6 100644
--- a/crates/ra_assists/src/assist_ctx.rs
+++ b/crates/ra_assists/src/assist_ctx.rs
@@ -4,14 +4,13 @@ use ra_db::FileRange;
4use ra_fmt::{leading_indent, reindent}; 4use ra_fmt::{leading_indent, reindent};
5use ra_ide_db::RootDatabase; 5use ra_ide_db::RootDatabase;
6use ra_syntax::{ 6use ra_syntax::{
7 algo::{self, find_covering_element, find_node_at_offset}, 7 algo::{self, find_covering_element, find_node_at_offset, SyntaxRewriter},
8 AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize, 8 AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize,
9 TokenAtOffset, 9 TokenAtOffset,
10}; 10};
11use ra_text_edit::TextEditBuilder; 11use ra_text_edit::TextEditBuilder;
12 12
13use crate::{AssistAction, AssistFile, AssistId, AssistLabel, GroupLabel, ResolvedAssist}; 13use crate::{AssistAction, AssistFile, AssistId, AssistLabel, GroupLabel, ResolvedAssist};
14use algo::SyntaxRewriter;
15 14
16#[derive(Clone, Debug)] 15#[derive(Clone, Debug)]
17pub(crate) struct Assist(pub(crate) Vec<AssistInfo>); 16pub(crate) struct Assist(pub(crate) Vec<AssistInfo>);
@@ -38,13 +37,10 @@ impl AssistInfo {
38 37
39 pub(crate) fn into_resolved(self) -> Option<ResolvedAssist> { 38 pub(crate) fn into_resolved(self) -> Option<ResolvedAssist> {
40 let label = self.label; 39 let label = self.label;
41 let group_label = self.group_label; 40 self.action.map(|action| ResolvedAssist { label, action })
42 self.action.map(|action| ResolvedAssist { label, group_label, action })
43 } 41 }
44} 42}
45 43
46pub(crate) type AssistHandler = fn(AssistCtx) -> Option<Assist>;
47
48/// `AssistCtx` allows to apply an assist or check if it could be applied. 44/// `AssistCtx` allows to apply an assist or check if it could be applied.
49/// 45///
50/// Assists use a somewhat over-engineered approach, given the current needs. The 46/// Assists use a somewhat over-engineered approach, given the current needs. The
@@ -100,7 +96,7 @@ impl<'a> AssistCtx<'a> {
100 label: impl Into<String>, 96 label: impl Into<String>,
101 f: impl FnOnce(&mut ActionBuilder), 97 f: impl FnOnce(&mut ActionBuilder),
102 ) -> Option<Assist> { 98 ) -> Option<Assist> {
103 let label = AssistLabel::new(label.into(), id); 99 let label = AssistLabel::new(id, label.into(), None);
104 100
105 let mut info = AssistInfo::new(label); 101 let mut info = AssistInfo::new(label);
106 if self.should_compute_edit { 102 if self.should_compute_edit {
@@ -116,7 +112,8 @@ impl<'a> AssistCtx<'a> {
116 } 112 }
117 113
118 pub(crate) fn add_assist_group(self, group_name: impl Into<String>) -> AssistGroup<'a> { 114 pub(crate) fn add_assist_group(self, group_name: impl Into<String>) -> AssistGroup<'a> {
119 AssistGroup { ctx: self, group_name: group_name.into(), assists: Vec::new() } 115 let group = GroupLabel(group_name.into());
116 AssistGroup { ctx: self, group, assists: Vec::new() }
120 } 117 }
121 118
122 pub(crate) fn token_at_offset(&self) -> TokenAtOffset<SyntaxToken> { 119 pub(crate) fn token_at_offset(&self) -> TokenAtOffset<SyntaxToken> {
@@ -146,7 +143,7 @@ impl<'a> AssistCtx<'a> {
146 143
147pub(crate) struct AssistGroup<'a> { 144pub(crate) struct AssistGroup<'a> {
148 ctx: AssistCtx<'a>, 145 ctx: AssistCtx<'a>,
149 group_name: String, 146 group: GroupLabel,
150 assists: Vec<AssistInfo>, 147 assists: Vec<AssistInfo>,
151} 148}
152 149
@@ -157,9 +154,9 @@ impl<'a> AssistGroup<'a> {
157 label: impl Into<String>, 154 label: impl Into<String>,
158 f: impl FnOnce(&mut ActionBuilder), 155 f: impl FnOnce(&mut ActionBuilder),
159 ) { 156 ) {
160 let label = AssistLabel::new(label.into(), id); 157 let label = AssistLabel::new(id, label.into(), Some(self.group.clone()));
161 158
162 let mut info = AssistInfo::new(label).with_group(GroupLabel(self.group_name.clone())); 159 let mut info = AssistInfo::new(label).with_group(self.group.clone());
163 if self.ctx.should_compute_edit { 160 if self.ctx.should_compute_edit {
164 let action = { 161 let action = {
165 let mut edit = ActionBuilder::new(&self.ctx); 162 let mut edit = ActionBuilder::new(&self.ctx);
diff --git a/crates/ra_assists/src/doc_tests.rs b/crates/ra_assists/src/doc_tests.rs
index c0f9bc1fb..f627f31dc 100644
--- a/crates/ra_assists/src/doc_tests.rs
+++ b/crates/ra_assists/src/doc_tests.rs
@@ -30,6 +30,10 @@ fn check(assist_id: &str, before: &str, after: &str) {
30 ) 30 )
31 }); 31 });
32 32
33 let actual = assist.action.edit.apply(&before); 33 let actual = {
34 let mut actual = before.clone();
35 assist.action.edit.apply(&mut actual);
36 actual
37 };
34 assert_eq_text!(after, &actual); 38 assert_eq_text!(after, &actual);
35} 39}
diff --git a/crates/ra_assists/src/handlers/add_missing_impl_members.rs b/crates/ra_assists/src/handlers/add_missing_impl_members.rs
index e466c9a86..e47feda71 100644
--- a/crates/ra_assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/handlers/add_missing_impl_members.rs
@@ -10,7 +10,7 @@ use ra_syntax::{
10 10
11use crate::{ 11use crate::{
12 ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}, 12 ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams},
13 utils::{get_missing_impl_items, resolve_target_trait}, 13 utils::{get_missing_assoc_items, resolve_target_trait},
14 Assist, AssistCtx, AssistId, 14 Assist, AssistCtx, AssistId,
15}; 15};
16 16
@@ -112,25 +112,25 @@ fn add_missing_impl_members_inner(
112 112
113 let trait_ = resolve_target_trait(&ctx.sema, &impl_node)?; 113 let trait_ = resolve_target_trait(&ctx.sema, &impl_node)?;
114 114
115 let def_name = |item: &ast::ImplItem| -> Option<SmolStr> { 115 let def_name = |item: &ast::AssocItem| -> Option<SmolStr> {
116 match item { 116 match item {
117 ast::ImplItem::FnDef(def) => def.name(), 117 ast::AssocItem::FnDef(def) => def.name(),
118 ast::ImplItem::TypeAliasDef(def) => def.name(), 118 ast::AssocItem::TypeAliasDef(def) => def.name(),
119 ast::ImplItem::ConstDef(def) => def.name(), 119 ast::AssocItem::ConstDef(def) => def.name(),
120 } 120 }
121 .map(|it| it.text().clone()) 121 .map(|it| it.text().clone())
122 }; 122 };
123 123
124 let missing_items = get_missing_impl_items(&ctx.sema, &impl_node) 124 let missing_items = get_missing_assoc_items(&ctx.sema, &impl_node)
125 .iter() 125 .iter()
126 .map(|i| match i { 126 .map(|i| match i {
127 hir::AssocItem::Function(i) => ast::ImplItem::FnDef(i.source(ctx.db).value), 127 hir::AssocItem::Function(i) => ast::AssocItem::FnDef(i.source(ctx.db).value),
128 hir::AssocItem::TypeAlias(i) => ast::ImplItem::TypeAliasDef(i.source(ctx.db).value), 128 hir::AssocItem::TypeAlias(i) => ast::AssocItem::TypeAliasDef(i.source(ctx.db).value),
129 hir::AssocItem::Const(i) => ast::ImplItem::ConstDef(i.source(ctx.db).value), 129 hir::AssocItem::Const(i) => ast::AssocItem::ConstDef(i.source(ctx.db).value),
130 }) 130 })
131 .filter(|t| def_name(&t).is_some()) 131 .filter(|t| def_name(&t).is_some())
132 .filter(|t| match t { 132 .filter(|t| match t {
133 ast::ImplItem::FnDef(def) => match mode { 133 ast::AssocItem::FnDef(def) => match mode {
134 AddMissingImplMembersMode::DefaultMethodsOnly => def.body().is_some(), 134 AddMissingImplMembersMode::DefaultMethodsOnly => def.body().is_some(),
135 AddMissingImplMembersMode::NoDefaultMethods => def.body().is_none(), 135 AddMissingImplMembersMode::NoDefaultMethods => def.body().is_none(),
136 }, 136 },
@@ -145,7 +145,7 @@ fn add_missing_impl_members_inner(
145 let sema = ctx.sema; 145 let sema = ctx.sema;
146 146
147 ctx.add_assist(AssistId(assist_id), label, |edit| { 147 ctx.add_assist(AssistId(assist_id), label, |edit| {
148 let n_existing_items = impl_item_list.impl_items().count(); 148 let n_existing_items = impl_item_list.assoc_items().count();
149 let source_scope = sema.scope_for_def(trait_); 149 let source_scope = sema.scope_for_def(trait_);
150 let target_scope = sema.scope(impl_item_list.syntax()); 150 let target_scope = sema.scope(impl_item_list.syntax());
151 let ast_transform = QualifyPaths::new(&target_scope, &source_scope) 151 let ast_transform = QualifyPaths::new(&target_scope, &source_scope)
@@ -154,13 +154,13 @@ fn add_missing_impl_members_inner(
154 .into_iter() 154 .into_iter()
155 .map(|it| ast_transform::apply(&*ast_transform, it)) 155 .map(|it| ast_transform::apply(&*ast_transform, it))
156 .map(|it| match it { 156 .map(|it| match it {
157 ast::ImplItem::FnDef(def) => ast::ImplItem::FnDef(add_body(def)), 157 ast::AssocItem::FnDef(def) => ast::AssocItem::FnDef(add_body(def)),
158 _ => it, 158 _ => it,
159 }) 159 })
160 .map(|it| edit::remove_attrs_and_docs(&it)); 160 .map(|it| edit::remove_attrs_and_docs(&it));
161 let new_impl_item_list = impl_item_list.append_items(items); 161 let new_impl_item_list = impl_item_list.append_items(items);
162 let cursor_position = { 162 let cursor_position = {
163 let first_new_item = new_impl_item_list.impl_items().nth(n_existing_items).unwrap(); 163 let first_new_item = new_impl_item_list.assoc_items().nth(n_existing_items).unwrap();
164 first_new_item.syntax().text_range().start() 164 first_new_item.syntax().text_range().start()
165 }; 165 };
166 166
diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs
index 0f9174a29..e8a36c7de 100644
--- a/crates/ra_assists/src/handlers/add_new.rs
+++ b/crates/ra_assists/src/handlers/add_new.rs
@@ -162,8 +162,8 @@ fn find_struct_impl(ctx: &AssistCtx, strukt: &ast::StructDef) -> Option<Option<a
162 162
163fn has_new_fn(imp: &ast::ImplDef) -> bool { 163fn has_new_fn(imp: &ast::ImplDef) -> bool {
164 if let Some(il) = imp.item_list() { 164 if let Some(il) = imp.item_list() {
165 for item in il.impl_items() { 165 for item in il.assoc_items() {
166 if let ast::ImplItem::FnDef(f) = item { 166 if let ast::AssocItem::FnDef(f) = item {
167 if let Some(name) = f.name() { 167 if let Some(name) = f.name() {
168 if name.text().eq_ignore_ascii_case("new") { 168 if name.text().eq_ignore_ascii_case("new") {
169 return true; 169 return true;
diff --git a/crates/ra_assists/src/handlers/change_visibility.rs b/crates/ra_assists/src/handlers/change_visibility.rs
index 44f6a1dae..1cd532e80 100644
--- a/crates/ra_assists/src/handlers/change_visibility.rs
+++ b/crates/ra_assists/src/handlers/change_visibility.rs
@@ -47,8 +47,7 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
47 return None; 47 return None;
48 } 48 }
49 (vis_offset(&parent), keyword.text_range()) 49 (vis_offset(&parent), keyword.text_range())
50 } else { 50 } else if let Some(field_name) = ctx.find_node_at_offset::<ast::Name>() {
51 let field_name: ast::Name = ctx.find_node_at_offset()?;
52 let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?; 51 let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?;
53 if field.name()? != field_name { 52 if field.name()? != field_name {
54 tested_by!(change_visibility_field_false_positive); 53 tested_by!(change_visibility_field_false_positive);
@@ -58,6 +57,13 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
58 return None; 57 return None;
59 } 58 }
60 (vis_offset(field.syntax()), field_name.syntax().text_range()) 59 (vis_offset(field.syntax()), field_name.syntax().text_range())
60 } else if let Some(field) = ctx.find_node_at_offset::<ast::TupleFieldDef>() {
61 if field.visibility().is_some() {
62 return None;
63 }
64 (vis_offset(field.syntax()), field.syntax().text_range())
65 } else {
66 return None;
61 }; 67 };
62 68
63 ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub(crate)", |edit| { 69 ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub(crate)", |edit| {
@@ -129,7 +135,8 @@ mod tests {
129 change_visibility, 135 change_visibility,
130 r"struct S { <|>field: u32 }", 136 r"struct S { <|>field: u32 }",
131 r"struct S { <|>pub(crate) field: u32 }", 137 r"struct S { <|>pub(crate) field: u32 }",
132 ) 138 );
139 check_assist(change_visibility, r"struct S ( <|>u32 )", r"struct S ( <|>pub(crate) u32 )");
133 } 140 }
134 141
135 #[test] 142 #[test]
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index c5df86600..0f94f5ee8 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -17,13 +17,13 @@ mod doc_tests;
17pub mod utils; 17pub mod utils;
18pub mod ast_transform; 18pub mod ast_transform;
19 19
20use hir::Semantics;
20use ra_db::{FileId, FileRange}; 21use ra_db::{FileId, FileRange};
21use ra_ide_db::RootDatabase; 22use ra_ide_db::RootDatabase;
22use ra_syntax::{TextRange, TextSize}; 23use ra_syntax::{TextRange, TextSize};
23use ra_text_edit::TextEdit; 24use ra_text_edit::TextEdit;
24 25
25pub(crate) use crate::assist_ctx::{Assist, AssistCtx, AssistHandler}; 26pub(crate) use crate::assist_ctx::{Assist, AssistCtx};
26use hir::Semantics;
27 27
28/// Unique identifier of the assist, should not be shown to the user 28/// Unique identifier of the assist, should not be shown to the user
29/// directly. 29/// directly.
@@ -32,19 +32,20 @@ pub struct AssistId(pub &'static str);
32 32
33#[derive(Debug, Clone)] 33#[derive(Debug, Clone)]
34pub struct AssistLabel { 34pub struct AssistLabel {
35 pub id: AssistId,
35 /// Short description of the assist, as shown in the UI. 36 /// Short description of the assist, as shown in the UI.
36 pub label: String, 37 pub label: String,
37 pub id: AssistId, 38 pub group: Option<GroupLabel>,
38} 39}
39 40
40#[derive(Clone, Debug)] 41#[derive(Clone, Debug)]
41pub struct GroupLabel(pub String); 42pub struct GroupLabel(pub String);
42 43
43impl AssistLabel { 44impl AssistLabel {
44 pub(crate) fn new(label: String, id: AssistId) -> AssistLabel { 45 pub(crate) fn new(id: AssistId, label: String, group: Option<GroupLabel>) -> AssistLabel {
45 // FIXME: make fields private, so that this invariant can't be broken 46 // FIXME: make fields private, so that this invariant can't be broken
46 assert!(label.starts_with(|c: char| c.is_uppercase())); 47 assert!(label.starts_with(|c: char| c.is_uppercase()));
47 AssistLabel { label, id } 48 AssistLabel { id, label, group }
48 } 49 }
49} 50}
50 51
@@ -60,7 +61,6 @@ pub struct AssistAction {
60#[derive(Debug, Clone)] 61#[derive(Debug, Clone)]
61pub struct ResolvedAssist { 62pub struct ResolvedAssist {
62 pub label: AssistLabel, 63 pub label: AssistLabel,
63 pub group_label: Option<GroupLabel>,
64 pub action: AssistAction, 64 pub action: AssistAction,
65} 65}
66 66
@@ -109,7 +109,9 @@ pub fn resolved_assists(db: &RootDatabase, range: FileRange) -> Vec<ResolvedAssi
109} 109}
110 110
111mod handlers { 111mod handlers {
112 use crate::AssistHandler; 112 use crate::{Assist, AssistCtx};
113
114 pub(crate) type Handler = fn(AssistCtx) -> Option<Assist>;
113 115
114 mod add_custom_impl; 116 mod add_custom_impl;
115 mod add_derive; 117 mod add_derive;
@@ -145,12 +147,13 @@ mod handlers {
145 mod reorder_fields; 147 mod reorder_fields;
146 mod unwrap_block; 148 mod unwrap_block;
147 149
148 pub(crate) fn all() -> &'static [AssistHandler] { 150 pub(crate) fn all() -> &'static [Handler] {
149 &[ 151 &[
150 // These are alphabetic for the foolish consistency 152 // These are alphabetic for the foolish consistency
151 add_custom_impl::add_custom_impl, 153 add_custom_impl::add_custom_impl,
152 add_derive::add_derive, 154 add_derive::add_derive,
153 add_explicit_type::add_explicit_type, 155 add_explicit_type::add_explicit_type,
156 add_from_impl_for_enum::add_from_impl_for_enum,
154 add_function::add_function, 157 add_function::add_function,
155 add_impl::add_impl, 158 add_impl::add_impl,
156 add_new::add_new, 159 add_new::add_new,
@@ -176,17 +179,18 @@ mod handlers {
176 raw_string::remove_hash, 179 raw_string::remove_hash,
177 remove_dbg::remove_dbg, 180 remove_dbg::remove_dbg,
178 remove_mut::remove_mut, 181 remove_mut::remove_mut,
182 reorder_fields::reorder_fields,
179 replace_if_let_with_match::replace_if_let_with_match, 183 replace_if_let_with_match::replace_if_let_with_match,
180 replace_let_with_if_let::replace_let_with_if_let, 184 replace_let_with_if_let::replace_let_with_if_let,
181 replace_qualified_name_with_use::replace_qualified_name_with_use, 185 replace_qualified_name_with_use::replace_qualified_name_with_use,
182 replace_unwrap_with_match::replace_unwrap_with_match, 186 replace_unwrap_with_match::replace_unwrap_with_match,
183 split_import::split_import, 187 split_import::split_import,
184 add_from_impl_for_enum::add_from_impl_for_enum,
185 unwrap_block::unwrap_block, 188 unwrap_block::unwrap_block,
186 // These are manually sorted for better priorities 189 // These are manually sorted for better priorities
187 add_missing_impl_members::add_missing_impl_members, 190 add_missing_impl_members::add_missing_impl_members,
188 add_missing_impl_members::add_missing_default_members, 191 add_missing_impl_members::add_missing_default_members,
189 reorder_fields::reorder_fields, 192 // Are you sure you want to add new assist here, and not to the
193 // sorted list above?
190 ] 194 ]
191 } 195 }
192} 196}
@@ -195,12 +199,12 @@ mod handlers {
195mod helpers { 199mod helpers {
196 use std::sync::Arc; 200 use std::sync::Arc;
197 201
202 use hir::Semantics;
198 use ra_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}; 203 use ra_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt};
199 use ra_ide_db::{symbol_index::SymbolsDatabase, RootDatabase}; 204 use ra_ide_db::{symbol_index::SymbolsDatabase, RootDatabase};
200 use test_utils::{add_cursor, assert_eq_text, extract_range_or_offset, RangeOrOffset}; 205 use test_utils::{add_cursor, assert_eq_text, extract_range_or_offset, RangeOrOffset};
201 206
202 use crate::{AssistCtx, AssistFile, AssistHandler}; 207 use crate::{handlers::Handler, AssistCtx, AssistFile};
203 use hir::Semantics;
204 208
205 pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) { 209 pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
206 let (mut db, file_id) = RootDatabase::with_single_file(text); 210 let (mut db, file_id) = RootDatabase::with_single_file(text);
@@ -210,22 +214,18 @@ mod helpers {
210 (db, file_id) 214 (db, file_id)
211 } 215 }
212 216
213 pub(crate) fn check_assist( 217 pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) {
214 assist: AssistHandler,
215 ra_fixture_before: &str,
216 ra_fixture_after: &str,
217 ) {
218 check(assist, ra_fixture_before, ExpectedResult::After(ra_fixture_after)); 218 check(assist, ra_fixture_before, ExpectedResult::After(ra_fixture_after));
219 } 219 }
220 220
221 // FIXME: instead of having a separate function here, maybe use 221 // FIXME: instead of having a separate function here, maybe use
222 // `extract_ranges` and mark the target as `<target> </target>` in the 222 // `extract_ranges` and mark the target as `<target> </target>` in the
223 // fixuture? 223 // fixuture?
224 pub(crate) fn check_assist_target(assist: AssistHandler, ra_fixture: &str, target: &str) { 224 pub(crate) fn check_assist_target(assist: Handler, ra_fixture: &str, target: &str) {
225 check(assist, ra_fixture, ExpectedResult::Target(target)); 225 check(assist, ra_fixture, ExpectedResult::Target(target));
226 } 226 }
227 227
228 pub(crate) fn check_assist_not_applicable(assist: AssistHandler, ra_fixture: &str) { 228 pub(crate) fn check_assist_not_applicable(assist: Handler, ra_fixture: &str) {
229 check(assist, ra_fixture, ExpectedResult::NotApplicable); 229 check(assist, ra_fixture, ExpectedResult::NotApplicable);
230 } 230 }
231 231
@@ -235,7 +235,7 @@ mod helpers {
235 Target(&'a str), 235 Target(&'a str),
236 } 236 }
237 237
238 fn check(assist: AssistHandler, before: &str, expected: ExpectedResult) { 238 fn check(assist: Handler, before: &str, expected: ExpectedResult) {
239 let (text_without_caret, file_with_caret_id, range_or_offset, db) = 239 let (text_without_caret, file_with_caret_id, range_or_offset, db) =
240 if before.contains("//-") { 240 if before.contains("//-") {
241 let (mut db, position) = RootDatabase::with_position(before); 241 let (mut db, position) = RootDatabase::with_position(before);
@@ -261,13 +261,13 @@ mod helpers {
261 (Some(assist), ExpectedResult::After(after)) => { 261 (Some(assist), ExpectedResult::After(after)) => {
262 let action = assist.0[0].action.clone().unwrap(); 262 let action = assist.0[0].action.clone().unwrap();
263 263
264 let assisted_file_text = if let AssistFile::TargetFile(file_id) = action.file { 264 let mut actual = if let AssistFile::TargetFile(file_id) = action.file {
265 db.file_text(file_id).as_ref().to_owned() 265 db.file_text(file_id).as_ref().to_owned()
266 } else { 266 } else {
267 text_without_caret 267 text_without_caret
268 }; 268 };
269 action.edit.apply(&mut actual);
269 270
270 let mut actual = action.edit.apply(&assisted_file_text);
271 match action.cursor_position { 271 match action.cursor_position {
272 None => { 272 None => {
273 if let RangeOrOffset::Offset(before_cursor_pos) = range_or_offset { 273 if let RangeOrOffset::Offset(before_cursor_pos) = range_or_offset {
diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs
index 6be704ce3..2f15a3f15 100644
--- a/crates/ra_assists/src/utils.rs
+++ b/crates/ra_assists/src/utils.rs
@@ -13,7 +13,7 @@ use rustc_hash::FxHashSet;
13 13
14pub(crate) use insert_use::insert_use_statement; 14pub(crate) use insert_use::insert_use_statement;
15 15
16pub fn get_missing_impl_items( 16pub fn get_missing_assoc_items(
17 sema: &Semantics<RootDatabase>, 17 sema: &Semantics<RootDatabase>,
18 impl_def: &ast::ImplDef, 18 impl_def: &ast::ImplDef,
19) -> Vec<hir::AssocItem> { 19) -> Vec<hir::AssocItem> {
@@ -23,21 +23,21 @@ pub fn get_missing_impl_items(
23 let mut impl_type = FxHashSet::default(); 23 let mut impl_type = FxHashSet::default();
24 24
25 if let Some(item_list) = impl_def.item_list() { 25 if let Some(item_list) = impl_def.item_list() {
26 for item in item_list.impl_items() { 26 for item in item_list.assoc_items() {
27 match item { 27 match item {
28 ast::ImplItem::FnDef(f) => { 28 ast::AssocItem::FnDef(f) => {
29 if let Some(n) = f.name() { 29 if let Some(n) = f.name() {
30 impl_fns_consts.insert(n.syntax().to_string()); 30 impl_fns_consts.insert(n.syntax().to_string());
31 } 31 }
32 } 32 }
33 33
34 ast::ImplItem::TypeAliasDef(t) => { 34 ast::AssocItem::TypeAliasDef(t) => {
35 if let Some(n) = t.name() { 35 if let Some(n) = t.name() {
36 impl_type.insert(n.syntax().to_string()); 36 impl_type.insert(n.syntax().to_string());
37 } 37 }
38 } 38 }
39 39
40 ast::ImplItem::ConstDef(c) => { 40 ast::AssocItem::ConstDef(c) => {
41 if let Some(n) = c.name() { 41 if let Some(n) = c.name() {
42 impl_fns_consts.insert(n.syntax().to_string()); 42 impl_fns_consts.insert(n.syntax().to_string());
43 } 43 }