aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorZac Pullar-Strecker <[email protected]>2020-08-25 05:44:36 +0100
committerZac Pullar-Strecker <[email protected]>2020-08-25 05:44:36 +0100
commitb835f06cecd2189cb32a431fdb85245fbf53032a (patch)
tree8bb4ba65f4922e9cca571a7d4a7fa17d047ae779 /crates
parent452afaebe188251cd4403e56999bf8b58de4fba9 (diff)
parentef9cea945d5767e7c60d5931a7649a73caea23ad (diff)
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
Diffstat (limited to 'crates')
-rw-r--r--crates/arena/Cargo.toml1
-rw-r--r--crates/assists/Cargo.toml17
-rw-r--r--crates/assists/src/assist_context.rs4
-rw-r--r--crates/assists/src/handlers/expand_glob_import.rs732
-rw-r--r--crates/assists/src/handlers/invert_if.rs18
-rw-r--r--crates/assists/src/utils.rs21
-rw-r--r--crates/base_db/Cargo.toml15
-rw-r--r--crates/cfg/Cargo.toml3
-rw-r--r--crates/flycheck/Cargo.toml3
-rw-r--r--crates/hir/Cargo.toml17
-rw-r--r--crates/hir_def/Cargo.toml21
-rw-r--r--crates/hir_def/src/item_tree/lower.rs4
-rw-r--r--crates/hir_def/src/nameres/tests.rs2
-rw-r--r--crates/hir_expand/Cargo.toml17
-rw-r--r--crates/hir_ty/Cargo.toml17
-rw-r--r--crates/ide/Cargo.toml23
-rw-r--r--crates/ide/src/completion.rs2
-rw-r--r--crates/ide/src/runnables.rs26
-rw-r--r--crates/ide_db/Cargo.toml15
-rw-r--r--crates/mbe/Cargo.toml7
-rw-r--r--crates/parser/Cargo.toml1
-rw-r--r--crates/paths/Cargo.toml1
-rw-r--r--crates/proc_macro_api/Cargo.toml3
-rw-r--r--crates/proc_macro_srv/Cargo.toml9
-rw-r--r--crates/proc_macro_test/Cargo.toml1
-rw-r--r--crates/profile/Cargo.toml3
-rw-r--r--crates/project_model/Cargo.toml15
-rw-r--r--crates/rust-analyzer/Cargo.toml37
-rw-r--r--crates/ssr/Cargo.toml12
-rw-r--r--crates/stdx/Cargo.toml1
-rw-r--r--crates/syntax/Cargo.toml6
-rw-r--r--crates/syntax/src/algo.rs2
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs8
-rw-r--r--crates/syntax/src/ast/make.rs8
-rw-r--r--crates/test_utils/Cargo.toml3
-rw-r--r--crates/text_edit/Cargo.toml1
-rw-r--r--crates/toolchain/Cargo.toml1
-rw-r--r--crates/tt/Cargo.toml3
-rw-r--r--crates/vfs-notify/Cargo.toml5
-rw-r--r--crates/vfs/Cargo.toml3
40 files changed, 844 insertions, 244 deletions
diff --git a/crates/arena/Cargo.toml b/crates/arena/Cargo.toml
index f2bb5cc45..863eedf76 100644
--- a/crates/arena/Cargo.toml
+++ b/crates/arena/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "arena" 2name = "arena"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
diff --git a/crates/assists/Cargo.toml b/crates/assists/Cargo.toml
index a560a35c7..264125651 100644
--- a/crates/assists/Cargo.toml
+++ b/crates/assists/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "assists" 2name = "assists"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -13,11 +14,11 @@ rustc-hash = "1.1.0"
13itertools = "0.9.0" 14itertools = "0.9.0"
14either = "1.5.3" 15either = "1.5.3"
15 16
16stdx = { path = "../stdx" } 17stdx = { path = "../stdx", version = "0.0.0" }
17syntax = { path = "../syntax" } 18syntax = { path = "../syntax", version = "0.0.0" }
18text_edit = { path = "../text_edit" } 19text_edit = { path = "../text_edit", version = "0.0.0" }
19profile = { path = "../profile" } 20profile = { path = "../profile", version = "0.0.0" }
20base_db = { path = "../base_db" } 21base_db = { path = "../base_db", version = "0.0.0" }
21ide_db = { path = "../ide_db" } 22ide_db = { path = "../ide_db", version = "0.0.0" }
22hir = { path = "../hir" } 23hir = { path = "../hir", version = "0.0.0" }
23test_utils = { path = "../test_utils" } 24test_utils = { path = "../test_utils", version = "0.0.0" }
diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs
index 11c171fc2..bf520069e 100644
--- a/crates/assists/src/assist_context.rs
+++ b/crates/assists/src/assist_context.rs
@@ -73,10 +73,6 @@ impl<'a> AssistContext<'a> {
73 self.sema.db 73 self.sema.db
74 } 74 }
75 75
76 pub(crate) fn source_file(&self) -> &SourceFile {
77 &self.source_file
78 }
79
80 // NB, this ignores active selection. 76 // NB, this ignores active selection.
81 pub(crate) fn offset(&self) -> TextSize { 77 pub(crate) fn offset(&self) -> TextSize {
82 self.frange.range.start() 78 self.frange.range.start()
diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs
index 81d0af2f3..b39d040f6 100644
--- a/crates/assists/src/handlers/expand_glob_import.rs
+++ b/crates/assists/src/handlers/expand_glob_import.rs
@@ -1,10 +1,10 @@
1use either::Either; 1use either::Either;
2use hir::{AssocItem, MacroDef, ModuleDef, Name, PathResolution, ScopeDef, SemanticsScope}; 2use hir::{AssocItem, MacroDef, Module, ModuleDef, Name, PathResolution, ScopeDef};
3use ide_db::{ 3use ide_db::{
4 defs::{classify_name_ref, Definition, NameRefClass}, 4 defs::{classify_name_ref, Definition, NameRefClass},
5 RootDatabase, 5 search::SearchScope,
6}; 6};
7use syntax::{algo, ast, match_ast, AstNode, SyntaxNode, SyntaxToken, T}; 7use syntax::{algo, ast, AstNode, Direction, SyntaxNode, SyntaxToken, T};
8 8
9use crate::{ 9use crate::{
10 assist_context::{AssistBuilder, AssistContext, Assists}, 10 assist_context::{AssistBuilder, AssistContext, Assists},
@@ -38,140 +38,259 @@ use crate::{
38// ``` 38// ```
39pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 39pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
40 let star = ctx.find_token_at_offset(T![*])?; 40 let star = ctx.find_token_at_offset(T![*])?;
41 let mod_path = find_mod_path(&star)?; 41 let (parent, mod_path) = find_parent_and_path(&star)?;
42 let module = match ctx.sema.resolve_path(&mod_path)? { 42 let target_module = match ctx.sema.resolve_path(&mod_path)? {
43 PathResolution::Def(ModuleDef::Module(it)) => it, 43 PathResolution::Def(ModuleDef::Module(it)) => it,
44 _ => return None, 44 _ => return None,
45 }; 45 };
46 46
47 let source_file = ctx.source_file(); 47 let current_scope = ctx.sema.scope(&star.parent());
48 let scope = ctx.sema.scope_at_offset(source_file.syntax(), ctx.offset()); 48 let current_module = current_scope.module()?;
49 49
50 let defs_in_mod = find_defs_in_mod(ctx, scope, module)?; 50 let refs_in_target = find_refs_in_mod(ctx, target_module, Some(current_module))?;
51 let name_refs_in_source_file = 51 let imported_defs = find_imported_defs(ctx, star)?;
52 source_file.syntax().descendants().filter_map(ast::NameRef::cast).collect(); 52 let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs);
53 let used_names = find_used_names(ctx, defs_in_mod, name_refs_in_source_file);
54 53
55 let parent = star.parent().parent()?; 54 let target = parent.clone().either(|n| n.syntax().clone(), |n| n.syntax().clone());
56 acc.add( 55 acc.add(
57 AssistId("expand_glob_import", AssistKind::RefactorRewrite), 56 AssistId("expand_glob_import", AssistKind::RefactorRewrite),
58 "Expand glob import", 57 "Expand glob import",
59 parent.text_range(), 58 target.text_range(),
60 |builder| { 59 |builder| {
61 replace_ast(builder, &parent, mod_path, used_names); 60 replace_ast(builder, parent, mod_path, names_to_import);
62 }, 61 },
63 ) 62 )
64} 63}
65 64
66fn find_mod_path(star: &SyntaxToken) -> Option<ast::Path> { 65fn find_parent_and_path(
67 star.ancestors().find_map(|n| ast::UseTree::cast(n).and_then(|u| u.path())) 66 star: &SyntaxToken,
67) -> Option<(Either<ast::UseTree, ast::UseTreeList>, ast::Path)> {
68 return star.ancestors().find_map(|n| {
69 find_use_tree_list(n.clone())
70 .and_then(|(u, p)| Some((Either::Right(u), p)))
71 .or_else(|| find_use_tree(n).and_then(|(u, p)| Some((Either::Left(u), p))))
72 });
73
74 fn find_use_tree_list(n: SyntaxNode) -> Option<(ast::UseTreeList, ast::Path)> {
75 let use_tree_list = ast::UseTreeList::cast(n)?;
76 let path = use_tree_list.parent_use_tree().path()?;
77 Some((use_tree_list, path))
78 }
79
80 fn find_use_tree(n: SyntaxNode) -> Option<(ast::UseTree, ast::Path)> {
81 let use_tree = ast::UseTree::cast(n)?;
82 let path = use_tree.path()?;
83 Some((use_tree, path))
84 }
68} 85}
69 86
70#[derive(PartialEq)] 87#[derive(Debug, PartialEq, Clone)]
71enum Def { 88enum Def {
72 ModuleDef(ModuleDef), 89 ModuleDef(ModuleDef),
73 MacroDef(MacroDef), 90 MacroDef(MacroDef),
74} 91}
75 92
76impl Def { 93impl Def {
77 fn name(&self, db: &RootDatabase) -> Option<Name> { 94 fn is_referenced_in(&self, ctx: &AssistContext) -> bool {
78 match self { 95 let def = match self {
79 Def::ModuleDef(def) => def.name(db), 96 Def::ModuleDef(def) => Definition::ModuleDef(*def),
80 Def::MacroDef(def) => def.name(db), 97 Def::MacroDef(def) => Definition::Macro(*def),
98 };
99
100 let search_scope = SearchScope::single_file(ctx.frange.file_id);
101 def.usages(&ctx.sema).in_scope(search_scope).at_least_one()
102 }
103}
104
105#[derive(Debug, Clone)]
106struct Ref {
107 // could be alias
108 visible_name: Name,
109 def: Def,
110}
111
112impl Ref {
113 fn from_scope_def(name: Name, scope_def: ScopeDef) -> Option<Self> {
114 match scope_def {
115 ScopeDef::ModuleDef(def) => Some(Ref { visible_name: name, def: Def::ModuleDef(def) }),
116 ScopeDef::MacroDef(def) => Some(Ref { visible_name: name, def: Def::MacroDef(def) }),
117 _ => None,
81 } 118 }
82 } 119 }
83} 120}
84 121
85fn find_defs_in_mod( 122#[derive(Debug, Clone)]
123struct Refs(Vec<Ref>);
124
125impl Refs {
126 fn used_refs(&self, ctx: &AssistContext) -> Refs {
127 Refs(
128 self.0
129 .clone()
130 .into_iter()
131 .filter(|r| {
132 if let Def::ModuleDef(ModuleDef::Trait(tr)) = r.def {
133 if tr
134 .items(ctx.db())
135 .into_iter()
136 .find(|ai| {
137 if let AssocItem::Function(f) = *ai {
138 Def::ModuleDef(ModuleDef::Function(f)).is_referenced_in(ctx)
139 } else {
140 false
141 }
142 })
143 .is_some()
144 {
145 return true;
146 }
147 }
148
149 r.def.is_referenced_in(ctx)
150 })
151 .collect(),
152 )
153 }
154
155 fn filter_out_by_defs(&self, defs: Vec<Def>) -> Refs {
156 Refs(self.0.clone().into_iter().filter(|r| !defs.contains(&r.def)).collect())
157 }
158}
159
160fn find_refs_in_mod(
86 ctx: &AssistContext, 161 ctx: &AssistContext,
87 from: SemanticsScope<'_>, 162 module: Module,
88 module: hir::Module, 163 visible_from: Option<Module>,
89) -> Option<Vec<Def>> { 164) -> Option<Refs> {
90 let module_scope = module.scope(ctx.db(), from.module()); 165 if let Some(from) = visible_from {
91 166 if !is_mod_visible_from(ctx, module, from) {
92 let mut defs = vec![]; 167 return None;
93 for (_, def) in module_scope {
94 match def {
95 ScopeDef::ModuleDef(def) => defs.push(Def::ModuleDef(def)),
96 ScopeDef::MacroDef(def) => defs.push(Def::MacroDef(def)),
97 _ => continue,
98 } 168 }
99 } 169 }
100 170
101 Some(defs) 171 let module_scope = module.scope(ctx.db(), visible_from);
172 let refs = module_scope.into_iter().filter_map(|(n, d)| Ref::from_scope_def(n, d)).collect();
173 Some(Refs(refs))
102} 174}
103 175
104fn find_used_names( 176fn is_mod_visible_from(ctx: &AssistContext, module: Module, from: Module) -> bool {
105 ctx: &AssistContext, 177 match module.parent(ctx.db()) {
106 defs_in_mod: Vec<Def>, 178 Some(parent) => {
107 name_refs_in_source_file: Vec<ast::NameRef>, 179 parent.visibility_of(ctx.db(), &ModuleDef::Module(module)).map_or(true, |vis| {
108) -> Vec<Name> { 180 vis.is_visible_from(ctx.db(), from.into()) && is_mod_visible_from(ctx, parent, from)
109 let defs_in_source_file = name_refs_in_source_file 181 })
110 .iter() 182 }
111 .filter_map(|r| classify_name_ref(&ctx.sema, r)) 183 None => true,
112 .filter_map(|rc| match rc { 184 }
113 NameRefClass::Definition(Definition::ModuleDef(def)) => Some(Def::ModuleDef(def)), 185}
114 NameRefClass::Definition(Definition::Macro(def)) => Some(Def::MacroDef(def)),
115 _ => None,
116 })
117 .collect::<Vec<Def>>();
118 186
119 defs_in_mod 187// looks for name refs in parent use block's siblings
120 .iter() 188//
121 .filter(|def| { 189// mod bar {
122 if let Def::ModuleDef(ModuleDef::Trait(tr)) = def { 190// mod qux {
123 for item in tr.items(ctx.db()) { 191// struct Qux;
124 if let AssocItem::Function(f) = item { 192// }
125 if defs_in_source_file.contains(&Def::ModuleDef(ModuleDef::Function(f))) { 193//
126 return true; 194// pub use qux::Qux;
127 } 195// }
128 } 196//
129 } 197// ↓ ---------------
130 } 198// use foo::*<|>;
199// use baz::Baz;
200// ↑ ---------------
201fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option<Vec<Def>> {
202 let parent_use_item_syntax =
203 star.ancestors().find_map(|n| if ast::Use::can_cast(n.kind()) { Some(n) } else { None })?;
204
205 Some(
206 [Direction::Prev, Direction::Next]
207 .iter()
208 .map(|dir| {
209 parent_use_item_syntax
210 .siblings(dir.to_owned())
211 .filter(|n| ast::Use::can_cast(n.kind()))
212 })
213 .flatten()
214 .filter_map(|n| Some(n.descendants().filter_map(ast::NameRef::cast)))
215 .flatten()
216 .filter_map(|r| match classify_name_ref(&ctx.sema, &r)? {
217 NameRefClass::Definition(Definition::ModuleDef(def)) => Some(Def::ModuleDef(def)),
218 NameRefClass::Definition(Definition::Macro(def)) => Some(Def::MacroDef(def)),
219 _ => None,
220 })
221 .collect(),
222 )
223}
131 224
132 defs_in_source_file.contains(def) 225fn find_names_to_import(
133 }) 226 ctx: &AssistContext,
134 .filter_map(|d| d.name(ctx.db())) 227 refs_in_target: Refs,
135 .collect() 228 imported_defs: Vec<Def>,
229) -> Vec<Name> {
230 let used_refs = refs_in_target.used_refs(ctx).filter_out_by_defs(imported_defs);
231 used_refs.0.iter().map(|r| r.visible_name.clone()).collect()
136} 232}
137 233
138fn replace_ast( 234fn replace_ast(
139 builder: &mut AssistBuilder, 235 builder: &mut AssistBuilder,
140 node: &SyntaxNode, 236 parent: Either<ast::UseTree, ast::UseTreeList>,
141 path: ast::Path, 237 path: ast::Path,
142 used_names: Vec<Name>, 238 names_to_import: Vec<Name>,
143) { 239) {
144 let replacement: Either<ast::UseTree, ast::UseTreeList> = match used_names.as_slice() { 240 let existing_use_trees = match parent.clone() {
145 [name] => Either::Left(ast::make::use_tree( 241 Either::Left(_) => vec![],
146 ast::make::path_from_text(&format!("{}::{}", path, name)), 242 Either::Right(u) => u
147 None, 243 .use_trees()
148 None, 244 .filter(|n|
149 false, 245 // filter out star
150 )), 246 n.star_token().is_none())
151 names => Either::Right(ast::make::use_tree_list(names.iter().map(|n| { 247 .collect(),
152 ast::make::use_tree(ast::make::path_from_text(&n.to_string()), None, None, false)
153 }))),
154 }; 248 };
155 249
156 let mut replace_node = |replacement: Either<ast::UseTree, ast::UseTreeList>| { 250 let new_use_trees: Vec<ast::UseTree> = names_to_import
157 algo::diff(node, &replacement.either(|u| u.syntax().clone(), |ut| ut.syntax().clone())) 251 .iter()
252 .map(|n| ast::make::use_tree(ast::make::path_from_text(&n.to_string()), None, None, false))
253 .collect();
254
255 let use_trees = [&existing_use_trees[..], &new_use_trees[..]].concat();
256
257 match use_trees.as_slice() {
258 [name] => {
259 if let Some(end_path) = name.path() {
260 let replacement = ast::make::use_tree(
261 ast::make::path_from_text(&format!("{}::{}", path, end_path)),
262 None,
263 None,
264 false,
265 );
266
267 algo::diff(
268 &parent.either(|n| n.syntax().clone(), |n| n.syntax().clone()),
269 replacement.syntax(),
270 )
271 .into_text_edit(builder.text_edit_builder());
272 }
273 }
274 names => {
275 let replacement = match parent {
276 Either::Left(_) => ast::make::use_tree(
277 path,
278 Some(ast::make::use_tree_list(names.to_owned())),
279 None,
280 false,
281 )
282 .syntax()
283 .clone(),
284 Either::Right(_) => ast::make::use_tree_list(names.to_owned()).syntax().clone(),
285 };
286
287 algo::diff(
288 &parent.either(|n| n.syntax().clone(), |n| n.syntax().clone()),
289 &replacement,
290 )
158 .into_text_edit(builder.text_edit_builder()); 291 .into_text_edit(builder.text_edit_builder());
159 };
160
161 match_ast! {
162 match node {
163 ast::UseTree(use_tree) => {
164 replace_node(replacement);
165 },
166 ast::UseTreeList(use_tree_list) => {
167 replace_node(replacement);
168 },
169 ast::Use(use_item) => {
170 builder.replace_ast(use_item, ast::make::use_(replacement.left_or_else(|ut| ast::make::use_tree(path, Some(ut), None, false))));
171 },
172 _ => {},
173 } 292 }
174 } 293 };
175} 294}
176 295
177#[cfg(test)] 296#[cfg(test)]
@@ -245,7 +364,46 @@ mod foo {
245 pub fn f() {} 364 pub fn f() {}
246} 365}
247 366
248use foo::{Baz, Bar, f}; 367use foo::{f, Baz, Bar};
368
369fn qux(bar: Bar, baz: Baz) {
370 f();
371}
372",
373 )
374 }
375
376 #[test]
377 fn expanding_glob_import_with_existing_uses_in_same_module() {
378 check_assist(
379 expand_glob_import,
380 r"
381mod foo {
382 pub struct Bar;
383 pub struct Baz;
384 pub struct Qux;
385
386 pub fn f() {}
387}
388
389use foo::Bar;
390use foo::{*<|>, f};
391
392fn qux(bar: Bar, baz: Baz) {
393 f();
394}
395",
396 r"
397mod foo {
398 pub struct Bar;
399 pub struct Baz;
400 pub struct Qux;
401
402 pub fn f() {}
403}
404
405use foo::Bar;
406use foo::{f, Baz};
249 407
250fn qux(bar: Bar, baz: Baz) { 408fn qux(bar: Bar, baz: Baz) {
251 f(); 409 f();
@@ -260,7 +418,7 @@ fn qux(bar: Bar, baz: Baz) {
260 expand_glob_import, 418 expand_glob_import,
261 r" 419 r"
262mod foo { 420mod foo {
263 mod bar { 421 pub mod bar {
264 pub struct Bar; 422 pub struct Bar;
265 pub struct Baz; 423 pub struct Baz;
266 pub struct Qux; 424 pub struct Qux;
@@ -268,7 +426,7 @@ mod foo {
268 pub fn f() {} 426 pub fn f() {}
269 } 427 }
270 428
271 mod baz { 429 pub mod baz {
272 pub fn g() {} 430 pub fn g() {}
273 } 431 }
274} 432}
@@ -282,7 +440,7 @@ fn qux(bar: Bar, baz: Baz) {
282", 440",
283 r" 441 r"
284mod foo { 442mod foo {
285 mod bar { 443 pub mod bar {
286 pub struct Bar; 444 pub struct Bar;
287 pub struct Baz; 445 pub struct Baz;
288 pub struct Qux; 446 pub struct Qux;
@@ -290,55 +448,359 @@ mod foo {
290 pub fn f() {} 448 pub fn f() {}
291 } 449 }
292 450
293 mod baz { 451 pub mod baz {
294 pub fn g() {} 452 pub fn g() {}
295 } 453 }
296} 454}
297 455
298use foo::{bar::{Baz, Bar, f}, baz::*}; 456use foo::{bar::{f, Baz, Bar}, baz::*};
299 457
300fn qux(bar: Bar, baz: Baz) { 458fn qux(bar: Bar, baz: Baz) {
301 f(); 459 f();
302 g(); 460 g();
303} 461}
304", 462",
305 ) 463 );
464
465 check_assist(
466 expand_glob_import,
467 r"
468mod foo {
469 pub mod bar {
470 pub struct Bar;
471 pub struct Baz;
472 pub struct Qux;
473
474 pub fn f() {}
475 }
476
477 pub mod baz {
478 pub fn g() {}
479 }
480}
481
482use foo::{bar::{Bar, Baz, f}, baz::*<|>};
483
484fn qux(bar: Bar, baz: Baz) {
485 f();
486 g();
487}
488",
489 r"
490mod foo {
491 pub mod bar {
492 pub struct Bar;
493 pub struct Baz;
494 pub struct Qux;
495
496 pub fn f() {}
497 }
498
499 pub mod baz {
500 pub fn g() {}
501 }
502}
503
504use foo::{bar::{Bar, Baz, f}, baz::g};
505
506fn qux(bar: Bar, baz: Baz) {
507 f();
508 g();
509}
510",
511 );
512
513 check_assist(
514 expand_glob_import,
515 r"
516mod foo {
517 pub mod bar {
518 pub struct Bar;
519 pub struct Baz;
520 pub struct Qux;
521
522 pub fn f() {}
523 }
524
525 pub mod baz {
526 pub fn g() {}
527
528 pub mod qux {
529 pub fn h() {}
530 pub fn m() {}
531
532 pub mod q {
533 pub fn j() {}
534 }
535 }
536 }
537}
538
539use foo::{
540 bar::{*, f},
541 baz::{g, qux::*<|>}
542};
543
544fn qux(bar: Bar, baz: Baz) {
545 f();
546 g();
547 h();
548 q::j();
549}
550",
551 r"
552mod foo {
553 pub mod bar {
554 pub struct Bar;
555 pub struct Baz;
556 pub struct Qux;
557
558 pub fn f() {}
559 }
560
561 pub mod baz {
562 pub fn g() {}
563
564 pub mod qux {
565 pub fn h() {}
566 pub fn m() {}
567
568 pub mod q {
569 pub fn j() {}
570 }
571 }
572 }
573}
574
575use foo::{
576 bar::{*, f},
577 baz::{g, qux::{q, h}}
578};
579
580fn qux(bar: Bar, baz: Baz) {
581 f();
582 g();
583 h();
584 q::j();
585}
586",
587 );
588
589 check_assist(
590 expand_glob_import,
591 r"
592mod foo {
593 pub mod bar {
594 pub struct Bar;
595 pub struct Baz;
596 pub struct Qux;
597
598 pub fn f() {}
599 }
600
601 pub mod baz {
602 pub fn g() {}
603
604 pub mod qux {
605 pub fn h() {}
606 pub fn m() {}
607
608 pub mod q {
609 pub fn j() {}
610 }
611 }
612 }
613}
614
615use foo::{
616 bar::{*, f},
617 baz::{g, qux::{h, q::*<|>}}
618};
619
620fn qux(bar: Bar, baz: Baz) {
621 f();
622 g();
623 h();
624 j();
625}
626",
627 r"
628mod foo {
629 pub mod bar {
630 pub struct Bar;
631 pub struct Baz;
632 pub struct Qux;
633
634 pub fn f() {}
635 }
636
637 pub mod baz {
638 pub fn g() {}
639
640 pub mod qux {
641 pub fn h() {}
642 pub fn m() {}
643
644 pub mod q {
645 pub fn j() {}
646 }
647 }
648 }
649}
650
651use foo::{
652 bar::{*, f},
653 baz::{g, qux::{h, q::j}}
654};
655
656fn qux(bar: Bar, baz: Baz) {
657 f();
658 g();
659 h();
660 j();
661}
662",
663 );
664
665 check_assist(
666 expand_glob_import,
667 r"
668mod foo {
669 pub mod bar {
670 pub struct Bar;
671 pub struct Baz;
672 pub struct Qux;
673
674 pub fn f() {}
675 }
676
677 pub mod baz {
678 pub fn g() {}
679
680 pub mod qux {
681 pub fn h() {}
682 pub fn m() {}
683
684 pub mod q {
685 pub fn j() {}
686 }
687 }
688 }
689}
690
691use foo::{
692 bar::{*, f},
693 baz::{g, qux::{q::j, *<|>}}
694};
695
696fn qux(bar: Bar, baz: Baz) {
697 f();
698 g();
699 h();
700 j();
701}
702",
703 r"
704mod foo {
705 pub mod bar {
706 pub struct Bar;
707 pub struct Baz;
708 pub struct Qux;
709
710 pub fn f() {}
711 }
712
713 pub mod baz {
714 pub fn g() {}
715
716 pub mod qux {
717 pub fn h() {}
718 pub fn m() {}
719
720 pub mod q {
721 pub fn j() {}
722 }
723 }
724 }
725}
726
727use foo::{
728 bar::{*, f},
729 baz::{g, qux::{q::j, h}}
730};
731
732fn qux(bar: Bar, baz: Baz) {
733 f();
734 g();
735 h();
736 j();
737}
738",
739 );
306 } 740 }
307 741
308 #[test] 742 #[test]
309 fn expanding_glob_import_with_macro_defs() { 743 fn expanding_glob_import_with_macro_defs() {
744 // FIXME: this is currently fails because `Definition::find_usages` ignores macros
745 // https://github.com/rust-analyzer/rust-analyzer/issues/3484
746 //
747 // check_assist(
748 // expand_glob_import,
749 // r"
750 // //- /lib.rs crate:foo
751 // #[macro_export]
752 // macro_rules! bar {
753 // () => ()
754 // }
755
756 // pub fn baz() {}
757
758 // //- /main.rs crate:main deps:foo
759 // use foo::*<|>;
760
761 // fn main() {
762 // bar!();
763 // baz();
764 // }
765 // ",
766 // r"
767 // use foo::{bar, baz};
768
769 // fn main() {
770 // bar!();
771 // baz();
772 // }
773 // ",
774 // )
775 }
776
777 #[test]
778 fn expanding_glob_import_with_trait_method_uses() {
310 check_assist( 779 check_assist(
311 expand_glob_import, 780 expand_glob_import,
312 r" 781 r"
313//- /lib.rs crate:foo 782//- /lib.rs crate:foo
314#[macro_export] 783pub trait Tr {
315macro_rules! bar { 784 fn method(&self) {}
316 () => ()
317} 785}
318 786impl Tr for () {}
319pub fn baz() {}
320 787
321//- /main.rs crate:main deps:foo 788//- /main.rs crate:main deps:foo
322use foo::*<|>; 789use foo::*<|>;
323 790
324fn main() { 791fn main() {
325 bar!(); 792 ().method();
326 baz();
327} 793}
328", 794",
329 r" 795 r"
330use foo::{bar, baz}; 796use foo::Tr;
331 797
332fn main() { 798fn main() {
333 bar!(); 799 ().method();
334 baz();
335} 800}
336", 801",
337 ) 802 );
338 }
339 803
340 #[test]
341 fn expanding_glob_import_with_trait_method_uses() {
342 check_assist( 804 check_assist(
343 expand_glob_import, 805 expand_glob_import,
344 r" 806 r"
@@ -348,6 +810,11 @@ pub trait Tr {
348} 810}
349impl Tr for () {} 811impl Tr for () {}
350 812
813pub trait Tr2 {
814 fn method2(&self) {}
815}
816impl Tr2 for () {}
817
351//- /main.rs crate:main deps:foo 818//- /main.rs crate:main deps:foo
352use foo::*<|>; 819use foo::*<|>;
353 820
@@ -362,7 +829,42 @@ fn main() {
362 ().method(); 829 ().method();
363} 830}
364", 831",
365 ) 832 );
833 }
834
835 #[test]
836 fn expanding_is_not_applicable_if_target_module_is_not_accessible_from_current_scope() {
837 check_assist_not_applicable(
838 expand_glob_import,
839 r"
840mod foo {
841 mod bar {
842 pub struct Bar;
843 }
844}
845
846use foo::bar::*<|>;
847
848fn baz(bar: Bar) {}
849",
850 );
851
852 check_assist_not_applicable(
853 expand_glob_import,
854 r"
855mod foo {
856 mod bar {
857 pub mod baz {
858 pub struct Baz;
859 }
860 }
861}
862
863use foo::bar::baz::*<|>;
864
865fn qux(baz: Baz) {}
866",
867 );
366 } 868 }
367 869
368 #[test] 870 #[test]
diff --git a/crates/assists/src/handlers/invert_if.rs b/crates/assists/src/handlers/invert_if.rs
index f0e047538..294256297 100644
--- a/crates/assists/src/handlers/invert_if.rs
+++ b/crates/assists/src/handlers/invert_if.rs
@@ -106,4 +106,22 @@ mod tests {
106 "fn f() { i<|>f let Some(_) = Some(1) { 1 } else { 0 } }", 106 "fn f() { i<|>f let Some(_) = Some(1) { 1 } else { 0 } }",
107 ) 107 )
108 } 108 }
109
110 #[test]
111 fn invert_if_option_case() {
112 check_assist(
113 invert_if,
114 "fn f() { if<|> doc_style.is_some() { Class::DocComment } else { Class::Comment } }",
115 "fn f() { if doc_style.is_none() { Class::Comment } else { Class::DocComment } }",
116 )
117 }
118
119 #[test]
120 fn invert_if_result_case() {
121 check_assist(
122 invert_if,
123 "fn f() { i<|>f doc_style.is_err() { Class::Err } else { Class::Ok } }",
124 "fn f() { if doc_style.is_ok() { Class::Ok } else { Class::Err } }",
125 )
126 }
109} 127}
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs
index d071d6502..e15c982e7 100644
--- a/crates/assists/src/utils.rs
+++ b/crates/assists/src/utils.rs
@@ -11,7 +11,7 @@ use syntax::{
11 ast::{self, make, NameOwner}, 11 ast::{self, make, NameOwner},
12 AstNode, Direction, 12 AstNode, Direction,
13 SyntaxKind::*, 13 SyntaxKind::*,
14 SyntaxNode, TextSize, T, 14 SyntaxNode, SyntaxText, TextSize, T,
15}; 15};
16 16
17use crate::assist_config::SnippetCap; 17use crate::assist_config::SnippetCap;
@@ -179,6 +179,25 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
179 ast::BinOp::EqualityTest => bin.replace_op(T![!=]).map(|it| it.into()), 179 ast::BinOp::EqualityTest => bin.replace_op(T![!=]).map(|it| it.into()),
180 _ => None, 180 _ => None,
181 }, 181 },
182 ast::Expr::MethodCallExpr(mce) => {
183 const IS_SOME_TEXT: &str = "is_some";
184 const IS_NONE_TEXT: &str = "is_none";
185 const IS_OK_TEXT: &str = "is_ok";
186 const IS_ERR_TEXT: &str = "is_err";
187
188 let name = mce.name_ref()?;
189 let name_text = name.text();
190
191 let caller = || -> Option<SyntaxText> { Some(mce.receiver()?.syntax().text()) };
192
193 match name_text {
194 x if x == IS_SOME_TEXT => make::expr_method_call(IS_NONE_TEXT, caller),
195 x if x == IS_NONE_TEXT => make::expr_method_call(IS_SOME_TEXT, caller),
196 x if x == IS_OK_TEXT => make::expr_method_call(IS_ERR_TEXT, caller),
197 x if x == IS_ERR_TEXT => make::expr_method_call(IS_OK_TEXT, caller),
198 _ => None,
199 }
200 }
182 ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::PrefixOp::Not => pe.expr(), 201 ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::PrefixOp::Not => pe.expr(),
183 // FIXME: 202 // FIXME:
184 // ast::Expr::Literal(true | false ) 203 // ast::Expr::Literal(true | false )
diff --git a/crates/base_db/Cargo.toml b/crates/base_db/Cargo.toml
index 7347d7528..f7bfcb0d7 100644
--- a/crates/base_db/Cargo.toml
+++ b/crates/base_db/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "base_db" 2name = "base_db"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -12,10 +13,10 @@ doctest = false
12salsa = "0.15.2" 13salsa = "0.15.2"
13rustc-hash = "1.1.0" 14rustc-hash = "1.1.0"
14 15
15syntax = { path = "../syntax" } 16syntax = { path = "../syntax", version = "0.0.0" }
16cfg = { path = "../cfg" } 17cfg = { path = "../cfg", version = "0.0.0" }
17profile = { path = "../profile" } 18profile = { path = "../profile", version = "0.0.0" }
18tt = { path = "../tt" } 19tt = { path = "../tt", version = "0.0.0" }
19test_utils = { path = "../test_utils" } 20test_utils = { path = "../test_utils", version = "0.0.0" }
20vfs = { path = "../vfs" } 21vfs = { path = "../vfs", version = "0.0.0" }
21stdx = { path = "../stdx" } 22stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/crates/cfg/Cargo.toml b/crates/cfg/Cargo.toml
index d2ea551d1..a6785ee8e 100644
--- a/crates/cfg/Cargo.toml
+++ b/crates/cfg/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "cfg" 2name = "cfg"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -11,7 +12,7 @@ doctest = false
11[dependencies] 12[dependencies]
12rustc-hash = "1.1.0" 13rustc-hash = "1.1.0"
13 14
14tt = { path = "../tt" } 15tt = { path = "../tt", version = "0.0.0" }
15 16
16[dev-dependencies] 17[dev-dependencies]
17mbe = { path = "../mbe" } 18mbe = { path = "../mbe" }
diff --git a/crates/flycheck/Cargo.toml b/crates/flycheck/Cargo.toml
index 262a66e4e..c230fc1e2 100644
--- a/crates/flycheck/Cargo.toml
+++ b/crates/flycheck/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "flycheck" 2name = "flycheck"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -15,4 +16,4 @@ cargo_metadata = "0.11.1"
15serde_json = "1.0.48" 16serde_json = "1.0.48"
16jod-thread = "0.1.1" 17jod-thread = "0.1.1"
17 18
18toolchain = { path = "../toolchain" } 19toolchain = { path = "../toolchain", version = "0.0.0" }
diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml
index d0ddca27f..72f941c46 100644
--- a/crates/hir/Cargo.toml
+++ b/crates/hir/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "hir" 2name = "hir"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -16,11 +17,11 @@ arrayvec = "0.5.1"
16itertools = "0.9.0" 17itertools = "0.9.0"
17url = "2.1.1" 18url = "2.1.1"
18 19
19stdx = { path = "../stdx" } 20stdx = { path = "../stdx", version = "0.0.0" }
20syntax = { path = "../syntax" } 21syntax = { path = "../syntax", version = "0.0.0" }
21base_db = { path = "../base_db" } 22base_db = { path = "../base_db", version = "0.0.0" }
22profile = { path = "../profile" } 23profile = { path = "../profile", version = "0.0.0" }
23hir_expand = { path = "../hir_expand" } 24hir_expand = { path = "../hir_expand", version = "0.0.0" }
24hir_def = { path = "../hir_def" } 25hir_def = { path = "../hir_def", version = "0.0.0" }
25hir_ty = { path = "../hir_ty" } 26hir_ty = { path = "../hir_ty", version = "0.0.0" }
26tt = { path = "../tt" } 27tt = { path = "../tt", version = "0.0.0" }
diff --git a/crates/hir_def/Cargo.toml b/crates/hir_def/Cargo.toml
index 57745322f..011e4612c 100644
--- a/crates/hir_def/Cargo.toml
+++ b/crates/hir_def/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "hir_def" 2name = "hir_def"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -20,16 +21,16 @@ itertools = "0.9.0"
20indexmap = "1.4.0" 21indexmap = "1.4.0"
21smallvec = "1.4.0" 22smallvec = "1.4.0"
22 23
23stdx = { path = "../stdx" } 24stdx = { path = "../stdx", version = "0.0.0" }
24arena = { path = "../arena" } 25arena = { path = "../arena", version = "0.0.0" }
25base_db = { path = "../base_db" } 26base_db = { path = "../base_db", version = "0.0.0" }
26syntax = { path = "../syntax" } 27syntax = { path = "../syntax", version = "0.0.0" }
27profile = { path = "../profile" } 28profile = { path = "../profile", version = "0.0.0" }
28hir_expand = { path = "../hir_expand" } 29hir_expand = { path = "../hir_expand", version = "0.0.0" }
29test_utils = { path = "../test_utils" } 30test_utils = { path = "../test_utils", version = "0.0.0" }
30mbe = { path = "../mbe" } 31mbe = { path = "../mbe", version = "0.0.0" }
31cfg = { path = "../cfg" } 32cfg = { path = "../cfg", version = "0.0.0" }
32tt = { path = "../tt" } 33tt = { path = "../tt", version = "0.0.0" }
33 34
34[dev-dependencies] 35[dev-dependencies]
35expect-test = "0.1" 36expect-test = "0.1"
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 391ab5d39..6a503d785 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -557,6 +557,10 @@ impl Ctx {
557 let statik = self.lower_static(&ast)?; 557 let statik = self.lower_static(&ast)?;
558 statik.into() 558 statik.into()
559 } 559 }
560 ast::ExternItem::TypeAlias(ty) => {
561 let id = self.lower_type_alias(&ty)?;
562 id.into()
563 }
560 ast::ExternItem::MacroCall(_) => return None, 564 ast::ExternItem::MacroCall(_) => return None,
561 }; 565 };
562 self.add_attrs(id.into(), attrs); 566 self.add_attrs(id.into(), attrs);
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs
index 8aaf7a158..5ca30dac9 100644
--- a/crates/hir_def/src/nameres/tests.rs
+++ b/crates/hir_def/src/nameres/tests.rs
@@ -46,6 +46,7 @@ union U { to_be: bool, not_to_be: u8 }
46enum E { V } 46enum E { V }
47 47
48extern { 48extern {
49 type Ext;
49 static EXT: u8; 50 static EXT: u8;
50 fn ext(); 51 fn ext();
51} 52}
@@ -65,6 +66,7 @@ extern {
65 Baz: t v 66 Baz: t v
66 E: t 67 E: t
67 EXT: v 68 EXT: v
69 Ext: t
68 U: t 70 U: t
69 ext: v 71 ext: v
70 "#]], 72 "#]],
diff --git a/crates/hir_expand/Cargo.toml b/crates/hir_expand/Cargo.toml
index 1c4699291..9fad2ab94 100644
--- a/crates/hir_expand/Cargo.toml
+++ b/crates/hir_expand/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "hir_expand" 2name = "hir_expand"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -13,11 +14,11 @@ log = "0.4.8"
13either = "1.5.3" 14either = "1.5.3"
14rustc-hash = "1.0.0" 15rustc-hash = "1.0.0"
15 16
16arena = { path = "../arena" } 17arena = { path = "../arena", version = "0.0.0" }
17base_db = { path = "../base_db" } 18base_db = { path = "../base_db", version = "0.0.0" }
18syntax = { path = "../syntax" } 19syntax = { path = "../syntax", version = "0.0.0" }
19parser = { path = "../parser" } 20parser = { path = "../parser", version = "0.0.0" }
20profile = { path = "../profile" } 21profile = { path = "../profile", version = "0.0.0" }
21tt = { path = "../tt" } 22tt = { path = "../tt", version = "0.0.0" }
22mbe = { path = "../mbe" } 23mbe = { path = "../mbe", version = "0.0.0" }
23test_utils = { path = "../test_utils"} 24test_utils = { path = "../test_utils", version = "0.0.0" }
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 06da0d0ec..33e155a70 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "hir_ty" 2name = "hir_ty"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -20,14 +21,14 @@ chalk-solve = { version = "0.23.0" }
20chalk-ir = { version = "0.23.0" } 21chalk-ir = { version = "0.23.0" }
21chalk-recursive = { version = "0.23.0" } 22chalk-recursive = { version = "0.23.0" }
22 23
23stdx = { path = "../stdx" } 24stdx = { path = "../stdx", version = "0.0.0" }
24hir_def = { path = "../hir_def" } 25hir_def = { path = "../hir_def", version = "0.0.0" }
25hir_expand = { path = "../hir_expand" } 26hir_expand = { path = "../hir_expand", version = "0.0.0" }
26arena = { path = "../arena" } 27arena = { path = "../arena", version = "0.0.0" }
27base_db = { path = "../base_db" } 28base_db = { path = "../base_db", version = "0.0.0" }
28profile = { path = "../profile" } 29profile = { path = "../profile", version = "0.0.0" }
29syntax = { path = "../syntax" } 30syntax = { path = "../syntax", version = "0.0.0" }
30test_utils = { path = "../test_utils" } 31test_utils = { path = "../test_utils", version = "0.0.0" }
31 32
32[dev-dependencies] 33[dev-dependencies]
33expect-test = "0.1" 34expect-test = "0.1"
diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml
index 9ecf43e5a..e61c276df 100644
--- a/crates/ide/Cargo.toml
+++ b/crates/ide/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "ide" 2name = "ide"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -18,20 +19,20 @@ oorandom = "11.1.2"
18pulldown-cmark-to-cmark = "5.0.0" 19pulldown-cmark-to-cmark = "5.0.0"
19pulldown-cmark = {version = "0.7.2", default-features = false} 20pulldown-cmark = {version = "0.7.2", default-features = false}
20 21
21stdx = { path = "../stdx" } 22stdx = { path = "../stdx", version = "0.0.0" }
22syntax = { path = "../syntax" } 23syntax = { path = "../syntax", version = "0.0.0" }
23text_edit = { path = "../text_edit" } 24text_edit = { path = "../text_edit", version = "0.0.0" }
24base_db = { path = "../base_db" } 25base_db = { path = "../base_db", version = "0.0.0" }
25ide_db = { path = "../ide_db" } 26ide_db = { path = "../ide_db", version = "0.0.0" }
26cfg = { path = "../cfg" } 27cfg = { path = "../cfg", version = "0.0.0" }
27profile = { path = "../profile" } 28profile = { path = "../profile", version = "0.0.0" }
28test_utils = { path = "../test_utils" } 29test_utils = { path = "../test_utils", version = "0.0.0" }
29assists = { path = "../assists" } 30assists = { path = "../assists", version = "0.0.0" }
30ssr = { path = "../ssr" } 31ssr = { path = "../ssr", version = "0.0.0" }
31 32
32# ide should depend only on the top-level `hir` package. if you need 33# ide should depend only on the top-level `hir` package. if you need
33# something from some `hir_xxx` subpackage, reexport the API via `hir`. 34# something from some `hir_xxx` subpackage, reexport the API via `hir`.
34hir = { path = "../hir" } 35hir = { path = "../hir", version = "0.0.0" }
35 36
36[dev-dependencies] 37[dev-dependencies]
37expect-test = "0.1" 38expect-test = "0.1"
diff --git a/crates/ide/src/completion.rs b/crates/ide/src/completion.rs
index 25e580d80..33bed6991 100644
--- a/crates/ide/src/completion.rs
+++ b/crates/ide/src/completion.rs
@@ -92,7 +92,7 @@ pub use crate::completion::{
92/// already present, it should give all possible variants for the identifier at 92/// already present, it should give all possible variants for the identifier at
93/// the caret. In other words, for 93/// the caret. In other words, for
94/// 94///
95/// ```no-run 95/// ```no_run
96/// fn f() { 96/// fn f() {
97/// let foo = 92; 97/// let foo = 92;
98/// let _ = bar<|> 98/// let _ = bar<|>
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 4139f329e..dd59d9e70 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -160,7 +160,7 @@ fn runnable_fn(
160 RunnableKind::Test { test_id, attr } 160 RunnableKind::Test { test_id, attr }
161 } else if fn_def.has_atom_attr("bench") { 161 } else if fn_def.has_atom_attr("bench") {
162 RunnableKind::Bench { test_id } 162 RunnableKind::Bench { test_id }
163 } else if has_doc_test(&fn_def) { 163 } else if has_runnable_doc_test(&fn_def) {
164 RunnableKind::DocTest { test_id } 164 RunnableKind::DocTest { test_id }
165 } else { 165 } else {
166 return None; 166 return None;
@@ -211,8 +211,13 @@ fn has_test_related_attribute(fn_def: &ast::Fn) -> bool {
211 .any(|attribute_text| attribute_text.contains("test")) 211 .any(|attribute_text| attribute_text.contains("test"))
212} 212}
213 213
214fn has_doc_test(fn_def: &ast::Fn) -> bool { 214fn has_runnable_doc_test(fn_def: &ast::Fn) -> bool {
215 fn_def.doc_comment_text().map_or(false, |comment| comment.contains("```")) 215 fn_def.doc_comment_text().map_or(false, |comments_text| {
216 comments_text.contains("```")
217 && !comments_text.contains("```ignore")
218 && !comments_text.contains("```no_run")
219 && !comments_text.contains("```compile_fail")
220 })
216} 221}
217 222
218fn runnable_mod( 223fn runnable_mod(
@@ -417,6 +422,21 @@ fn main() {}
417/// let x = 5; 422/// let x = 5;
418/// ``` 423/// ```
419fn foo() {} 424fn foo() {}
425
426/// ```no_run
427/// let z = 55;
428/// ```
429fn should_have_no_runnable() {}
430
431/// ```ignore
432/// let z = 55;
433/// ```
434fn should_have_no_runnable_2() {}
435
436/// ```compile_fail
437/// let z = 55;
438/// ```
439fn should_have_no_runnable_3() {}
420"#, 440"#,
421 &[&BIN, &DOCTEST], 441 &[&BIN, &DOCTEST],
422 expect![[r#" 442 expect![[r#"
diff --git a/crates/ide_db/Cargo.toml b/crates/ide_db/Cargo.toml
index 692fb6415..320fb15e5 100644
--- a/crates/ide_db/Cargo.toml
+++ b/crates/ide_db/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "ide_db" 2name = "ide_db"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -19,12 +20,12 @@ rustc-hash = "1.1.0"
19once_cell = "1.3.1" 20once_cell = "1.3.1"
20either = "1.5.3" 21either = "1.5.3"
21 22
22stdx = { path = "../stdx" } 23stdx = { path = "../stdx", version = "0.0.0" }
23syntax = { path = "../syntax" } 24syntax = { path = "../syntax", version = "0.0.0" }
24text_edit = { path = "../text_edit" } 25text_edit = { path = "../text_edit", version = "0.0.0" }
25base_db = { path = "../base_db" } 26base_db = { path = "../base_db", version = "0.0.0" }
26profile = { path = "../profile" } 27profile = { path = "../profile", version = "0.0.0" }
27test_utils = { path = "../test_utils" } 28test_utils = { path = "../test_utils", version = "0.0.0" }
28# ide should depend only on the top-level `hir` package. if you need 29# ide should depend only on the top-level `hir` package. if you need
29# something from some `hir_xxx` subpackage, reexport the API via `hir`. 30# something from some `hir_xxx` subpackage, reexport the API via `hir`.
30hir = { path = "../hir" } 31hir = { path = "../hir", version = "0.0.0" }
diff --git a/crates/mbe/Cargo.toml b/crates/mbe/Cargo.toml
index 1aba8b7c4..af80e2be3 100644
--- a/crates/mbe/Cargo.toml
+++ b/crates/mbe/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "mbe" 2name = "mbe"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -13,9 +14,9 @@ rustc-hash = "1.1.0"
13smallvec = "1.2.0" 14smallvec = "1.2.0"
14log = "0.4.8" 15log = "0.4.8"
15 16
16syntax = { path = "../syntax" } 17syntax = { path = "../syntax", version = "0.0.0" }
17parser = { path = "../parser" } 18parser = { path = "../parser", version = "0.0.0" }
18tt = { path = "../tt" } 19tt = { path = "../tt", version = "0.0.0" }
19 20
20[dev-dependencies] 21[dev-dependencies]
21test_utils = { path = "../test_utils" } 22test_utils = { path = "../test_utils" }
diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml
index 358be92d1..1610e0d23 100644
--- a/crates/parser/Cargo.toml
+++ b/crates/parser/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "parser" 2name = "parser"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
diff --git a/crates/paths/Cargo.toml b/crates/paths/Cargo.toml
index 5ac18d63b..da26938c1 100644
--- a/crates/paths/Cargo.toml
+++ b/crates/paths/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "paths" 2name = "paths"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
diff --git a/crates/proc_macro_api/Cargo.toml b/crates/proc_macro_api/Cargo.toml
index a3a4c1103..75f67a22e 100644
--- a/crates/proc_macro_api/Cargo.toml
+++ b/crates/proc_macro_api/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "proc_macro_api" 2name = "proc_macro_api"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -15,4 +16,4 @@ log = "0.4.8"
15crossbeam-channel = "0.4.0" 16crossbeam-channel = "0.4.0"
16jod-thread = "0.1.1" 17jod-thread = "0.1.1"
17 18
18tt = { path = "../tt" } 19tt = { path = "../tt", version = "0.0.0" }
diff --git a/crates/proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml
index a468b5560..fb84e04ae 100644
--- a/crates/proc_macro_srv/Cargo.toml
+++ b/crates/proc_macro_srv/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "proc_macro_srv" 2name = "proc_macro_srv"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -13,10 +14,10 @@ goblin = "0.2.1"
13libloading = "0.6.0" 14libloading = "0.6.0"
14memmap = "0.7" 15memmap = "0.7"
15 16
16tt = { path = "../tt" } 17tt = { path = "../tt", version = "0.0.0" }
17mbe = { path = "../mbe" } 18mbe = { path = "../mbe", version = "0.0.0" }
18proc_macro_api = { path = "../proc_macro_api" } 19proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" }
19test_utils = { path = "../test_utils" } 20test_utils = { path = "../test_utils", version = "0.0.0" }
20 21
21[dev-dependencies] 22[dev-dependencies]
22cargo_metadata = "0.11.1" 23cargo_metadata = "0.11.1"
diff --git a/crates/proc_macro_test/Cargo.toml b/crates/proc_macro_test/Cargo.toml
index 7b0f64f31..753443be2 100644
--- a/crates/proc_macro_test/Cargo.toml
+++ b/crates/proc_macro_test/Cargo.toml
@@ -4,6 +4,7 @@ version = "0.0.0"
4license = "MIT OR Apache-2.0" 4license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 5authors = ["rust-analyzer developers"]
6edition = "2018" 6edition = "2018"
7publish = false
7 8
8[lib] 9[lib]
9doctest = false 10doctest = false
diff --git a/crates/profile/Cargo.toml b/crates/profile/Cargo.toml
index e271e3a56..261172d61 100644
--- a/crates/profile/Cargo.toml
+++ b/crates/profile/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "profile" 2name = "profile"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -14,7 +15,7 @@ cfg-if = "0.1.10"
14libc = "0.2.73" 15libc = "0.2.73"
15backtrace = { version = "0.3.44", optional = true } 16backtrace = { version = "0.3.44", optional = true }
16 17
17arena = { path = "../arena" } 18arena = { path = "../arena", version = "0.0.0" }
18 19
19[target.'cfg(target_os = "linux")'.dependencies] 20[target.'cfg(target_os = "linux")'.dependencies]
20perf-event = "0.4" 21perf-event = "0.4"
diff --git a/crates/project_model/Cargo.toml b/crates/project_model/Cargo.toml
index 386f72f41..8bee398d9 100644
--- a/crates/project_model/Cargo.toml
+++ b/crates/project_model/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "project_model" 2name = "project_model"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -16,10 +17,10 @@ serde = { version = "1.0.106", features = ["derive"] }
16serde_json = "1.0.48" 17serde_json = "1.0.48"
17anyhow = "1.0.26" 18anyhow = "1.0.26"
18 19
19arena = { path = "../arena" } 20arena = { path = "../arena", version = "0.0.0" }
20cfg = { path = "../cfg" } 21cfg = { path = "../cfg", version = "0.0.0" }
21base_db = { path = "../base_db" } 22base_db = { path = "../base_db", version = "0.0.0" }
22toolchain = { path = "../toolchain" } 23toolchain = { path = "../toolchain", version = "0.0.0" }
23proc_macro_api = { path = "../proc_macro_api" } 24proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" }
24paths = { path = "../paths" } 25paths = { path = "../paths", version = "0.0.0" }
25stdx = { path = "../stdx" } 26stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 068a961dc..044686a99 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "rust-analyzer" 2name = "rust-analyzer"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6autobins = false 7autobins = false
@@ -32,26 +33,26 @@ rayon = "1.3.1"
32mimalloc = { version = "0.1.19", default-features = false, optional = true } 33mimalloc = { version = "0.1.19", default-features = false, optional = true }
33lsp-server = "0.3.3" 34lsp-server = "0.3.3"
34 35
35stdx = { path = "../stdx" } 36stdx = { path = "../stdx", version = "0.0.0" }
36flycheck = { path = "../flycheck" } 37flycheck = { path = "../flycheck", version = "0.0.0" }
37ide = { path = "../ide" } 38ide = { path = "../ide", version = "0.0.0" }
38profile = { path = "../profile" } 39profile = { path = "../profile", version = "0.0.0" }
39project_model = { path = "../project_model" } 40project_model = { path = "../project_model", version = "0.0.0" }
40syntax = { path = "../syntax" } 41syntax = { path = "../syntax", version = "0.0.0" }
41text_edit = { path = "../text_edit" } 42text_edit = { path = "../text_edit", version = "0.0.0" }
42vfs = { path = "../vfs" } 43vfs = { path = "../vfs", version = "0.0.0" }
43vfs-notify = { path = "../vfs-notify" } 44vfs-notify = { path = "../vfs-notify", version = "0.0.0" }
44cfg = { path = "../cfg" } 45cfg = { path = "../cfg", version = "0.0.0" }
45toolchain = { path = "../toolchain" } 46toolchain = { path = "../toolchain", version = "0.0.0" }
46 47
47# This should only be used in CLI 48# This should only be used in CLI
48base_db = { path = "../base_db" } 49base_db = { path = "../base_db", version = "0.0.0" }
49ide_db = { path = "../ide_db" } 50ide_db = { path = "../ide_db", version = "0.0.0" }
50ssr = { path = "../ssr" } 51ssr = { path = "../ssr", version = "0.0.0" }
51hir = { path = "../hir" } 52hir = { path = "../hir", version = "0.0.0" }
52hir_def = { path = "../hir_def" } 53hir_def = { path = "../hir_def", version = "0.0.0" }
53hir_ty = { path = "../hir_ty" } 54hir_ty = { path = "../hir_ty", version = "0.0.0" }
54proc_macro_srv = { path = "../proc_macro_srv" } 55proc_macro_srv = { path = "../proc_macro_srv", version = "0.0.0" }
55 56
56[target.'cfg(windows)'.dependencies] 57[target.'cfg(windows)'.dependencies]
57winapi = "0.3.8" 58winapi = "0.3.8"
diff --git a/crates/ssr/Cargo.toml b/crates/ssr/Cargo.toml
index 22b6af0fa..6f0f53d70 100644
--- a/crates/ssr/Cargo.toml
+++ b/crates/ssr/Cargo.toml
@@ -14,12 +14,12 @@ doctest = false
14rustc-hash = "1.1.0" 14rustc-hash = "1.1.0"
15itertools = "0.9.0" 15itertools = "0.9.0"
16 16
17text_edit = { path = "../text_edit" } 17text_edit = { path = "../text_edit", version = "0.0.0" }
18syntax = { path = "../syntax" } 18syntax = { path = "../syntax", version = "0.0.0" }
19base_db = { path = "../base_db" } 19base_db = { path = "../base_db", version = "0.0.0" }
20ide_db = { path = "../ide_db" } 20ide_db = { path = "../ide_db", version = "0.0.0" }
21hir = { path = "../hir" } 21hir = { path = "../hir", version = "0.0.0" }
22test_utils = { path = "../test_utils" } 22test_utils = { path = "../test_utils", version = "0.0.0" }
23 23
24[dev-dependencies] 24[dev-dependencies]
25expect-test = "0.1" 25expect-test = "0.1"
diff --git a/crates/stdx/Cargo.toml b/crates/stdx/Cargo.toml
index b186b46f2..8d7a51156 100644
--- a/crates/stdx/Cargo.toml
+++ b/crates/stdx/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "stdx" 2name = "stdx"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml
index 6818f3ad8..2c1bdb295 100644
--- a/crates/syntax/Cargo.toml
+++ b/crates/syntax/Cargo.toml
@@ -23,9 +23,9 @@ once_cell = "1.3.1"
23smol_str = { version = "0.1.15", features = ["serde"] } 23smol_str = { version = "0.1.15", features = ["serde"] }
24serde = { version = "1.0.106", features = ["derive"] } 24serde = { version = "1.0.106", features = ["derive"] }
25 25
26stdx = { path = "../stdx" } 26stdx = { path = "../stdx", version = "0.0.0" }
27text_edit = { path = "../text_edit" } 27text_edit = { path = "../text_edit", version = "0.0.0" }
28parser = { path = "../parser" } 28parser = { path = "../parser", version = "0.0.0" }
29 29
30[dev-dependencies] 30[dev-dependencies]
31walkdir = "2.3.1" 31walkdir = "2.3.1"
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs
index 6254b38ba..ea199f9b8 100644
--- a/crates/syntax/src/algo.rs
+++ b/crates/syntax/src/algo.rs
@@ -32,7 +32,7 @@ pub fn ancestors_at_offset(
32/// imprecise: if the cursor is strictly between two nodes of the desired type, 32/// imprecise: if the cursor is strictly between two nodes of the desired type,
33/// as in 33/// as in
34/// 34///
35/// ```no-run 35/// ```no_run
36/// struct Foo {}|struct Bar; 36/// struct Foo {}|struct Bar;
37/// ``` 37/// ```
38/// 38///
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 6317407c6..d6af5755c 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -1380,6 +1380,7 @@ pub enum ExternItem {
1380 Fn(Fn), 1380 Fn(Fn),
1381 MacroCall(MacroCall), 1381 MacroCall(MacroCall),
1382 Static(Static), 1382 Static(Static),
1383 TypeAlias(TypeAlias),
1383} 1384}
1384impl ast::AttrsOwner for ExternItem {} 1385impl ast::AttrsOwner for ExternItem {}
1385impl ast::NameOwner for ExternItem {} 1386impl ast::NameOwner for ExternItem {}
@@ -3339,10 +3340,13 @@ impl From<MacroCall> for ExternItem {
3339impl From<Static> for ExternItem { 3340impl From<Static> for ExternItem {
3340 fn from(node: Static) -> ExternItem { ExternItem::Static(node) } 3341 fn from(node: Static) -> ExternItem { ExternItem::Static(node) }
3341} 3342}
3343impl From<TypeAlias> for ExternItem {
3344 fn from(node: TypeAlias) -> ExternItem { ExternItem::TypeAlias(node) }
3345}
3342impl AstNode for ExternItem { 3346impl AstNode for ExternItem {
3343 fn can_cast(kind: SyntaxKind) -> bool { 3347 fn can_cast(kind: SyntaxKind) -> bool {
3344 match kind { 3348 match kind {
3345 FN | MACRO_CALL | STATIC => true, 3349 FN | MACRO_CALL | STATIC | TYPE_ALIAS => true,
3346 _ => false, 3350 _ => false,
3347 } 3351 }
3348 } 3352 }
@@ -3351,6 +3355,7 @@ impl AstNode for ExternItem {
3351 FN => ExternItem::Fn(Fn { syntax }), 3355 FN => ExternItem::Fn(Fn { syntax }),
3352 MACRO_CALL => ExternItem::MacroCall(MacroCall { syntax }), 3356 MACRO_CALL => ExternItem::MacroCall(MacroCall { syntax }),
3353 STATIC => ExternItem::Static(Static { syntax }), 3357 STATIC => ExternItem::Static(Static { syntax }),
3358 TYPE_ALIAS => ExternItem::TypeAlias(TypeAlias { syntax }),
3354 _ => return None, 3359 _ => return None,
3355 }; 3360 };
3356 Some(res) 3361 Some(res)
@@ -3360,6 +3365,7 @@ impl AstNode for ExternItem {
3360 ExternItem::Fn(it) => &it.syntax, 3365 ExternItem::Fn(it) => &it.syntax,
3361 ExternItem::MacroCall(it) => &it.syntax, 3366 ExternItem::MacroCall(it) => &it.syntax,
3362 ExternItem::Static(it) => &it.syntax, 3367 ExternItem::Static(it) => &it.syntax,
3368 ExternItem::TypeAlias(it) => &it.syntax,
3363 } 3369 }
3364 } 3370 }
3365} 3371}
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index d20c085aa..7958721e2 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -7,7 +7,7 @@
7use itertools::Itertools; 7use itertools::Itertools;
8use stdx::format_to; 8use stdx::format_to;
9 9
10use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; 10use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxText, SyntaxToken};
11 11
12pub fn name(text: &str) -> ast::Name { 12pub fn name(text: &str) -> ast::Name {
13 ast_from_text(&format!("mod {};", text)) 13 ast_from_text(&format!("mod {};", text))
@@ -137,6 +137,12 @@ pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr {
137pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr { 137pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
138 expr_from_text(&format!("{}{}", f, arg_list)) 138 expr_from_text(&format!("{}{}", f, arg_list))
139} 139}
140pub fn expr_method_call<F>(text: &str, caller: F) -> Option<ast::Expr>
141where
142 F: FnOnce() -> Option<SyntaxText>,
143{
144 try_expr_from_text(&format!("{}.{}()", caller()?, text))
145}
140fn expr_from_text(text: &str) -> ast::Expr { 146fn expr_from_text(text: &str) -> ast::Expr {
141 ast_from_text(&format!("const C: () = {};", text)) 147 ast_from_text(&format!("const C: () = {};", text))
142} 148}
diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml
index 45e5fb97f..93eecc678 100644
--- a/crates/test_utils/Cargo.toml
+++ b/crates/test_utils/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "test_utils" 2name = "test_utils"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -15,4 +16,4 @@ text-size = "1.0.0"
15serde_json = "1.0.48" 16serde_json = "1.0.48"
16rustc-hash = "1.1.0" 17rustc-hash = "1.1.0"
17 18
18stdx = { path = "../stdx" } 19stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/crates/text_edit/Cargo.toml b/crates/text_edit/Cargo.toml
index a69b1ef2b..8aadc1875 100644
--- a/crates/text_edit/Cargo.toml
+++ b/crates/text_edit/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "text_edit" 2name = "text_edit"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
diff --git a/crates/toolchain/Cargo.toml b/crates/toolchain/Cargo.toml
index 4856668f8..dcf0bfca0 100644
--- a/crates/toolchain/Cargo.toml
+++ b/crates/toolchain/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "toolchain" 2name = "toolchain"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
diff --git a/crates/tt/Cargo.toml b/crates/tt/Cargo.toml
index dfcdcf03e..5b8972ea3 100644
--- a/crates/tt/Cargo.toml
+++ b/crates/tt/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "tt" 2name = "tt"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -13,4 +14,4 @@ doctest = false
13# to reduce number of compilations 14# to reduce number of compilations
14smol_str = { version = "0.1.15", features = ["serde"] } 15smol_str = { version = "0.1.15", features = ["serde"] }
15 16
16stdx = { path = "../stdx" } 17stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/crates/vfs-notify/Cargo.toml b/crates/vfs-notify/Cargo.toml
index c1e53f4b1..54b51faab 100644
--- a/crates/vfs-notify/Cargo.toml
+++ b/crates/vfs-notify/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "vfs-notify" 2name = "vfs-notify"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -16,5 +17,5 @@ walkdir = "2.3.1"
16crossbeam-channel = "0.4.0" 17crossbeam-channel = "0.4.0"
17notify = "5.0.0-pre.3" 18notify = "5.0.0-pre.3"
18 19
19vfs = { path = "../vfs" } 20vfs = { path = "../vfs", version = "0.0.0" }
20paths = { path = "../paths" } 21paths = { path = "../paths", version = "0.0.0" }
diff --git a/crates/vfs/Cargo.toml b/crates/vfs/Cargo.toml
index 9ae8f19b6..c318a68f7 100644
--- a/crates/vfs/Cargo.toml
+++ b/crates/vfs/Cargo.toml
@@ -1,6 +1,7 @@
1[package] 1[package]
2name = "vfs" 2name = "vfs"
3version = "0.0.0" 3version = "0.0.0"
4description = "TBD"
4license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"] 6authors = ["rust-analyzer developers"]
6edition = "2018" 7edition = "2018"
@@ -12,4 +13,4 @@ doctest = false
12rustc-hash = "1.0" 13rustc-hash = "1.0"
13fst = "0.4" 14fst = "0.4"
14 15
15paths = { path = "../paths" } 16paths = { path = "../paths", version = "0.0.0" }