aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/handlers/add_explicit_type.rs4
-rw-r--r--crates/ra_assists/src/handlers/change_visibility.rs40
-rw-r--r--crates/ra_assists/src/marks.rs1
-rw-r--r--crates/ra_db/src/fixture.rs4
-rw-r--r--crates/ra_hir/src/code_model.rs2
-rw-r--r--crates/ra_hir/src/db.rs7
-rw-r--r--crates/ra_hir_def/src/body/lower.rs3
-rw-r--r--crates/ra_hir_def/src/db.rs7
-rw-r--r--crates/ra_hir_def/src/item_scope.rs2
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs11
-rw-r--r--crates/ra_hir_def/src/nameres/tests/incremental.rs16
-rw-r--r--crates/ra_hir_expand/src/ast_id_map.rs2
-rw-r--r--crates/ra_hir_ty/src/db.rs1
-rw-r--r--crates/ra_ide_db/src/change.rs12
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs20
-rw-r--r--crates/ra_syntax/src/ast/generated.rs10
-rw-r--r--crates/ra_syntax/src/ast/traits.rs31
-rw-r--r--crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt30
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt45
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs44
21 files changed, 178 insertions, 115 deletions
diff --git a/crates/ra_assists/src/handlers/add_explicit_type.rs b/crates/ra_assists/src/handlers/add_explicit_type.rs
index a63ef48b1..d86d804b2 100644
--- a/crates/ra_assists/src/handlers/add_explicit_type.rs
+++ b/crates/ra_assists/src/handlers/add_explicit_type.rs
@@ -130,8 +130,8 @@ mod tests {
130 fn add_explicit_type_works_for_macro_call() { 130 fn add_explicit_type_works_for_macro_call() {
131 check_assist( 131 check_assist(
132 add_explicit_type, 132 add_explicit_type,
133 "macro_rules! v { () => {0u64} } fn f() { let a<|> = v!(); }", 133 r"macro_rules! v { () => {0u64} } fn f() { let a<|> = v!(); }",
134 "macro_rules! v { () => {0u64} } fn f() { let a<|>: u64 = v!(); }", 134 r"macro_rules! v { () => {0u64} } fn f() { let a<|>: u64 = v!(); }",
135 ); 135 );
136 } 136 }
137 137
diff --git a/crates/ra_assists/src/handlers/change_visibility.rs b/crates/ra_assists/src/handlers/change_visibility.rs
index 54e0a6c84..cd6d1ee6c 100644
--- a/crates/ra_assists/src/handlers/change_visibility.rs
+++ b/crates/ra_assists/src/handlers/change_visibility.rs
@@ -2,13 +2,14 @@ use ra_syntax::{
2 ast::{self, NameOwner, VisibilityOwner}, 2 ast::{self, NameOwner, VisibilityOwner},
3 AstNode, 3 AstNode,
4 SyntaxKind::{ 4 SyntaxKind::{
5 ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, IDENT, MODULE, STRUCT_DEF, TRAIT_DEF, 5 ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, MODULE, STRUCT_DEF, TRAIT_DEF, VISIBILITY,
6 VISIBILITY, WHITESPACE, 6 WHITESPACE,
7 }, 7 },
8 SyntaxNode, TextUnit, T, 8 SyntaxNode, TextUnit, T,
9}; 9};
10 10
11use crate::{Assist, AssistCtx, AssistId}; 11use crate::{Assist, AssistCtx, AssistId};
12use test_utils::tested_by;
12 13
13// Assist: change_visibility 14// Assist: change_visibility
14// 15//
@@ -47,13 +48,16 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
47 } 48 }
48 (vis_offset(&parent), keyword.text_range()) 49 (vis_offset(&parent), keyword.text_range())
49 } else { 50 } else {
50 let ident = ctx.token_at_offset().find(|leaf| leaf.kind() == IDENT)?; 51 let field_name: ast::Name = ctx.find_node_at_offset()?;
51 let field = ident.parent().ancestors().find_map(ast::RecordFieldDef::cast)?; 52 let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?;
52 if field.name()?.syntax().text_range() != ident.text_range() && field.visibility().is_some() 53 if field.name()? != field_name {
53 { 54 tested_by!(change_visibility_field_false_positive);
54 return None; 55 return None;
55 } 56 }
56 (vis_offset(field.syntax()), ident.text_range()) 57 if field.visibility().is_some() {
58 return None;
59 }
60 (vis_offset(field.syntax()), field_name.syntax().text_range())
57 }; 61 };
58 62
59 ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub(crate)", |edit| { 63 ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub(crate)", |edit| {
@@ -98,8 +102,11 @@ fn change_vis(ctx: AssistCtx, vis: ast::Visibility) -> Option<Assist> {
98 102
99#[cfg(test)] 103#[cfg(test)]
100mod tests { 104mod tests {
105 use test_utils::covers;
106
107 use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_target};
108
101 use super::*; 109 use super::*;
102 use crate::helpers::{check_assist, check_assist_target};
103 110
104 #[test] 111 #[test]
105 fn change_visibility_adds_pub_crate_to_items() { 112 fn change_visibility_adds_pub_crate_to_items() {
@@ -120,8 +127,17 @@ mod tests {
120 fn change_visibility_works_with_struct_fields() { 127 fn change_visibility_works_with_struct_fields() {
121 check_assist( 128 check_assist(
122 change_visibility, 129 change_visibility,
123 "struct S { <|>field: u32 }", 130 r"struct S { <|>field: u32 }",
124 "struct S { <|>pub(crate) field: u32 }", 131 r"struct S { <|>pub(crate) field: u32 }",
132 )
133 }
134
135 #[test]
136 fn change_visibility_field_false_positive() {
137 covers!(change_visibility_field_false_positive);
138 check_assist_not_applicable(
139 change_visibility,
140 r"struct S { field: [(); { let <|>x = ();}] }",
125 ) 141 )
126 } 142 }
127 143
@@ -144,7 +160,7 @@ mod tests {
144 fn change_visibility_handles_comment_attrs() { 160 fn change_visibility_handles_comment_attrs() {
145 check_assist( 161 check_assist(
146 change_visibility, 162 change_visibility,
147 " 163 r"
148 /// docs 164 /// docs
149 165
150 // comments 166 // comments
@@ -152,7 +168,7 @@ mod tests {
152 #[derive(Debug)] 168 #[derive(Debug)]
153 <|>struct Foo; 169 <|>struct Foo;
154 ", 170 ",
155 " 171 r"
156 /// docs 172 /// docs
157 173
158 // comments 174 // comments
diff --git a/crates/ra_assists/src/marks.rs b/crates/ra_assists/src/marks.rs
index 22404ee80..6c2a2b8b6 100644
--- a/crates/ra_assists/src/marks.rs
+++ b/crates/ra_assists/src/marks.rs
@@ -7,4 +7,5 @@ test_utils::marks![
7 not_applicable_outside_of_bind_pat 7 not_applicable_outside_of_bind_pat
8 test_not_inline_mut_variable 8 test_not_inline_mut_variable
9 test_not_applicable_if_variable_unused 9 test_not_applicable_if_variable_unused
10 change_visibility_field_false_positive
10]; 11];
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index 3464f43df..5e3e9203c 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -28,9 +28,9 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
28 db 28 db
29 } 29 }
30 30
31 fn with_position(fixture: &str) -> (Self, FilePosition) { 31 fn with_position(ra_fixture: &str) -> (Self, FilePosition) {
32 let mut db = Self::default(); 32 let mut db = Self::default();
33 let pos = with_files(&mut db, fixture); 33 let pos = with_files(&mut db, ra_fixture);
34 (db, pos.unwrap()) 34 (db, pos.unwrap())
35 } 35 }
36 36
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 3f0ebca0d..cd2a8fc62 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -235,7 +235,7 @@ impl Module {
235 } 235 }
236 236
237 pub fn visibility_of(self, db: &dyn HirDatabase, def: &ModuleDef) -> Option<Visibility> { 237 pub fn visibility_of(self, db: &dyn HirDatabase, def: &ModuleDef) -> Option<Visibility> {
238 db.crate_def_map(self.id.krate)[self.id.local_id].scope.visbility_of(def.clone().into()) 238 db.crate_def_map(self.id.krate)[self.id.local_id].scope.visibility_of(def.clone().into())
239 } 239 }
240 240
241 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 241 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index fcba95091..ec931b34f 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -10,15 +10,16 @@ pub use hir_def::db::{
10 TraitDataQuery, TypeAliasDataQuery, UnionDataQuery, 10 TraitDataQuery, TypeAliasDataQuery, UnionDataQuery,
11}; 11};
12pub use hir_expand::db::{ 12pub use hir_expand::db::{
13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternMacroQuery, MacroArgQuery, MacroDefQuery, 13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery,
14 MacroExpandQuery, ParseMacroQuery, 14 MacroArgQuery, MacroDefQuery, MacroExpandQuery, ParseMacroQuery,
15}; 15};
16pub use hir_ty::db::{ 16pub use hir_ty::db::{
17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery, 17 AssociatedTyDataQuery, AssociatedTyValueQuery, CallableItemSignatureQuery, FieldTypesQuery,
18 GenericDefaultsQuery, GenericPredicatesForParamQuery, GenericPredicatesQuery, HirDatabase, 18 GenericDefaultsQuery, GenericPredicatesForParamQuery, GenericPredicatesQuery, HirDatabase,
19 HirDatabaseStorage, ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, ImplsForTraitQuery, 19 HirDatabaseStorage, ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, ImplsForTraitQuery,
20 ImplsInCrateQuery, InferQueryQuery, InternAssocTyValueQuery, InternChalkImplQuery, 20 ImplsInCrateQuery, InferQueryQuery, InternAssocTyValueQuery, InternChalkImplQuery,
21 InternTypeCtorQuery, StructDatumQuery, TraitDatumQuery, TraitSolveQuery, TyQuery, ValueTyQuery, 21 InternTypeCtorQuery, InternTypeParamIdQuery, StructDatumQuery, TraitDatumQuery,
22 TraitSolveQuery, TyQuery, ValueTyQuery,
22}; 23};
23 24
24#[test] 25#[test]
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 3cf0c66ea..e8443dde8 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -563,7 +563,8 @@ impl ExprCollector<'_> {
563 ast::ModuleItem::ImplDef(_) 563 ast::ModuleItem::ImplDef(_)
564 | ast::ModuleItem::UseItem(_) 564 | ast::ModuleItem::UseItem(_)
565 | ast::ModuleItem::ExternCrateItem(_) 565 | ast::ModuleItem::ExternCrateItem(_)
566 | ast::ModuleItem::Module(_) => continue, 566 | ast::ModuleItem::Module(_)
567 | ast::ModuleItem::MacroCall(_) => continue,
567 }; 568 };
568 self.body.item_scope.define_def(def); 569 self.body.item_scope.define_def(def);
569 if let Some(name) = name { 570 if let Some(name) = name {
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 7f8c1ea21..5dc7395f5 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -48,6 +48,7 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
48 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; 48 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
49 49
50 #[salsa::invoke(crate_def_map_wait)] 50 #[salsa::invoke(crate_def_map_wait)]
51 #[salsa::transparent]
51 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>; 52 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>;
52 53
53 #[salsa::invoke(CrateDefMap::crate_def_map_query)] 54 #[salsa::invoke(CrateDefMap::crate_def_map_query)]
@@ -109,12 +110,6 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
109 fn documentation(&self, def: AttrDefId) -> Option<Documentation>; 110 fn documentation(&self, def: AttrDefId) -> Option<Documentation>;
110} 111}
111 112
112// impl<T: DefDatabase> Upcast<dyn AstDatabase> for T {
113// fn upcast(&self) -> &dyn AstDatabase {
114// &*self
115// }
116// }
117
118fn crate_def_map_wait(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> { 113fn crate_def_map_wait(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> {
119 let _p = profile("crate_def_map:wait"); 114 let _p = profile("crate_def_map:wait");
120 db.crate_def_map_query(krate) 115 db.crate_def_map_query(krate)
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs
index ef1aaba6f..259b9ff03 100644
--- a/crates/ra_hir_def/src/item_scope.rs
+++ b/crates/ra_hir_def/src/item_scope.rs
@@ -68,7 +68,7 @@ impl ItemScope {
68 self.impls.iter().copied() 68 self.impls.iter().copied()
69 } 69 }
70 70
71 pub fn visbility_of(&self, def: ModuleDefId) -> Option<Visibility> { 71 pub fn visibility_of(&self, def: ModuleDefId) -> Option<Visibility> {
72 self.name_of(ItemInNs::Types(def)) 72 self.name_of(ItemInNs::Types(def))
73 .or_else(|| self.name_of(ItemInNs::Values(def))) 73 .or_else(|| self.name_of(ItemInNs::Values(def)))
74 .map(|(_, v)| v) 74 .map(|(_, v)| v)
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 1631e87b8..8f190e7f9 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -209,11 +209,8 @@ impl RawItemsCollector {
209 current_module: Option<Idx<ModuleData>>, 209 current_module: Option<Idx<ModuleData>>,
210 body: impl ast::ModuleItemOwner, 210 body: impl ast::ModuleItemOwner,
211 ) { 211 ) {
212 for item_or_macro in body.items_with_macros() { 212 for item in body.items() {
213 match item_or_macro { 213 self.add_item(current_module, item)
214 ast::ItemOrMacro::Macro(m) => self.add_macro(current_module, m),
215 ast::ItemOrMacro::Item(item) => self.add_item(current_module, item),
216 }
217 } 214 }
218 } 215 }
219 216
@@ -265,6 +262,10 @@ impl RawItemsCollector {
265 ast::ModuleItem::StaticDef(it) => { 262 ast::ModuleItem::StaticDef(it) => {
266 (DefKind::Static(self.source_ast_id_map.ast_id(&it)), it.name()) 263 (DefKind::Static(self.source_ast_id_map.ast_id(&it)), it.name())
267 } 264 }
265 ast::ModuleItem::MacroCall(it) => {
266 self.add_macro(current_module, it);
267 return;
268 }
268 }; 269 };
269 if let Some(name) = name { 270 if let Some(name) = name {
270 let name = name.as_name(); 271 let name = name.as_name();
diff --git a/crates/ra_hir_def/src/nameres/tests/incremental.rs b/crates/ra_hir_def/src/nameres/tests/incremental.rs
index 83f429c29..496fc6b08 100644
--- a/crates/ra_hir_def/src/nameres/tests/incremental.rs
+++ b/crates/ra_hir_def/src/nameres/tests/incremental.rs
@@ -4,8 +4,8 @@ use ra_db::SourceDatabaseExt;
4 4
5use super::*; 5use super::*;
6 6
7fn check_def_map_is_not_recomputed(initial: &str, file_change: &str) { 7fn check_def_map_is_not_recomputed(ra_fixture_initial: &str, ra_fixture_change: &str) {
8 let (mut db, pos) = TestDB::with_position(initial); 8 let (mut db, pos) = TestDB::with_position(ra_fixture_initial);
9 let krate = db.test_crate(); 9 let krate = db.test_crate();
10 { 10 {
11 let events = db.log_executed(|| { 11 let events = db.log_executed(|| {
@@ -13,7 +13,7 @@ fn check_def_map_is_not_recomputed(initial: &str, file_change: &str) {
13 }); 13 });
14 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) 14 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
15 } 15 }
16 db.set_file_text(pos.file_id, Arc::new(file_change.to_string())); 16 db.set_file_text(pos.file_id, Arc::new(ra_fixture_change.to_string()));
17 17
18 { 18 {
19 let events = db.log_executed(|| { 19 let events = db.log_executed(|| {
@@ -26,7 +26,7 @@ fn check_def_map_is_not_recomputed(initial: &str, file_change: &str) {
26#[test] 26#[test]
27fn typing_inside_a_function_should_not_invalidate_def_map() { 27fn typing_inside_a_function_should_not_invalidate_def_map() {
28 check_def_map_is_not_recomputed( 28 check_def_map_is_not_recomputed(
29 " 29 r"
30 //- /lib.rs 30 //- /lib.rs
31 mod foo;<|> 31 mod foo;<|>
32 32
@@ -41,7 +41,7 @@ fn typing_inside_a_function_should_not_invalidate_def_map() {
41 //- /foo/bar.rs 41 //- /foo/bar.rs
42 pub struct Baz; 42 pub struct Baz;
43 ", 43 ",
44 " 44 r"
45 mod foo; 45 mod foo;
46 46
47 use crate::foo::bar::Baz; 47 use crate::foo::bar::Baz;
@@ -54,7 +54,7 @@ fn typing_inside_a_function_should_not_invalidate_def_map() {
54#[test] 54#[test]
55fn adding_inner_items_should_not_invalidate_def_map() { 55fn adding_inner_items_should_not_invalidate_def_map() {
56 check_def_map_is_not_recomputed( 56 check_def_map_is_not_recomputed(
57 " 57 r"
58 //- /lib.rs 58 //- /lib.rs
59 struct S { a: i32} 59 struct S { a: i32}
60 enum E { A } 60 enum E { A }
@@ -72,7 +72,7 @@ fn adding_inner_items_should_not_invalidate_def_map() {
72 //- /foo/bar.rs 72 //- /foo/bar.rs
73 pub struct Baz; 73 pub struct Baz;
74 ", 74 ",
75 " 75 r"
76 struct S { a: i32, b: () } 76 struct S { a: i32, b: () }
77 enum E { A, B } 77 enum E { A, B }
78 trait T { 78 trait T {
@@ -92,7 +92,7 @@ fn adding_inner_items_should_not_invalidate_def_map() {
92#[test] 92#[test]
93fn typing_inside_a_macro_should_not_invalidate_def_map() { 93fn typing_inside_a_macro_should_not_invalidate_def_map() {
94 let (mut db, pos) = TestDB::with_position( 94 let (mut db, pos) = TestDB::with_position(
95 " 95 r"
96 //- /lib.rs 96 //- /lib.rs
97 macro_rules! m { 97 macro_rules! m {
98 ($ident:ident) => { 98 ($ident:ident) => {
diff --git a/crates/ra_hir_expand/src/ast_id_map.rs b/crates/ra_hir_expand/src/ast_id_map.rs
index a6644d55f..5643ecdce 100644
--- a/crates/ra_hir_expand/src/ast_id_map.rs
+++ b/crates/ra_hir_expand/src/ast_id_map.rs
@@ -68,8 +68,6 @@ impl AstIdMap {
68 bfs(node, |it| { 68 bfs(node, |it| {
69 if let Some(module_item) = ast::ModuleItem::cast(it.clone()) { 69 if let Some(module_item) = ast::ModuleItem::cast(it.clone()) {
70 res.alloc(module_item.syntax()); 70 res.alloc(module_item.syntax());
71 } else if let Some(macro_call) = ast::MacroCall::cast(it) {
72 res.alloc(macro_call.syntax());
73 } 71 }
74 }); 72 });
75 res 73 res
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index 11fc2ac3d..1462b053f 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -22,6 +22,7 @@ use hir_expand::name::Name;
22#[salsa::requires(salsa::Database)] 22#[salsa::requires(salsa::Database)]
23pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { 23pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
24 #[salsa::invoke(infer_wait)] 24 #[salsa::invoke(infer_wait)]
25 #[salsa::transparent]
25 fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>; 26 fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
26 27
27 #[salsa::invoke(crate::infer::infer_query)] 28 #[salsa::invoke(crate::infer::infer_query)]
diff --git a/crates/ra_ide_db/src/change.rs b/crates/ra_ide_db/src/change.rs
index 628cf6416..8446ef88e 100644
--- a/crates/ra_ide_db/src/change.rs
+++ b/crates/ra_ide_db/src/change.rs
@@ -311,6 +311,7 @@ impl RootDatabase {
311 hir::db::MacroDefQuery 311 hir::db::MacroDefQuery
312 hir::db::ParseMacroQuery 312 hir::db::ParseMacroQuery
313 hir::db::MacroExpandQuery 313 hir::db::MacroExpandQuery
314 hir::db::InternEagerExpansionQuery
314 315
315 // DefDatabase 316 // DefDatabase
316 hir::db::RawItemsQuery 317 hir::db::RawItemsQuery
@@ -359,14 +360,21 @@ impl RootDatabase {
359 hir::db::ImplsInCrateQuery 360 hir::db::ImplsInCrateQuery
360 hir::db::ImplsForTraitQuery 361 hir::db::ImplsForTraitQuery
361 hir::db::InternTypeCtorQuery 362 hir::db::InternTypeCtorQuery
363 hir::db::InternTypeParamIdQuery
362 hir::db::InternChalkImplQuery 364 hir::db::InternChalkImplQuery
363 hir::db::InternAssocTyValueQuery 365 hir::db::InternAssocTyValueQuery
364 hir::db::AssociatedTyDataQuery 366 hir::db::AssociatedTyDataQuery
365 hir::db::AssociatedTyValueQuery
366 hir::db::TraitSolveQuery
367 hir::db::TraitDatumQuery 367 hir::db::TraitDatumQuery
368 hir::db::StructDatumQuery 368 hir::db::StructDatumQuery
369 hir::db::ImplDatumQuery 369 hir::db::ImplDatumQuery
370 hir::db::AssociatedTyValueQuery
371 hir::db::TraitSolveQuery
372
373 // SymbolsDatabase
374 crate::symbol_index::FileSymbolsQuery
375
376 // LineIndexDatabase
377 crate::LineIndexQuery
370 ]; 378 ];
371 acc.sort_by_key(|it| std::cmp::Reverse(it.1)); 379 acc.sort_by_key(|it| std::cmp::Reverse(it.1));
372 acc 380 acc
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index 2335d99b3..0d277a586 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -230,14 +230,20 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
230 p.eat(T![async]); 230 p.eat(T![async]);
231 p.eat(T![move]); 231 p.eat(T![move]);
232 params::param_list_closure(p); 232 params::param_list_closure(p);
233 if opt_fn_ret_type(p) && !p.at(T!['{']) { 233 if opt_fn_ret_type(p) {
234 p.error("expected `{`"); 234 if p.at(T!['{']) {
235 } 235 // test lambda_ret_block
236 236 // fn main() { || -> i32 { 92 }(); }
237 if p.at_ts(EXPR_FIRST) { 237 block_expr(p, None);
238 expr(p); 238 } else {
239 p.error("expected `{`");
240 }
239 } else { 241 } else {
240 p.error("expected expression"); 242 if p.at_ts(EXPR_FIRST) {
243 expr(p);
244 } else {
245 p.error("expected expression");
246 }
241 } 247 }
242 m.complete(p, LAMBDA_EXPR) 248 m.complete(p, LAMBDA_EXPR)
243} 249}
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 002f453cd..7204ca5b1 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -4135,6 +4135,7 @@ pub enum ModuleItem {
4135 ConstDef(ConstDef), 4135 ConstDef(ConstDef),
4136 StaticDef(StaticDef), 4136 StaticDef(StaticDef),
4137 Module(Module), 4137 Module(Module),
4138 MacroCall(MacroCall),
4138} 4139}
4139impl From<StructDef> for ModuleItem { 4140impl From<StructDef> for ModuleItem {
4140 fn from(node: StructDef) -> ModuleItem { 4141 fn from(node: StructDef) -> ModuleItem {
@@ -4196,6 +4197,11 @@ impl From<Module> for ModuleItem {
4196 ModuleItem::Module(node) 4197 ModuleItem::Module(node)
4197 } 4198 }
4198} 4199}
4200impl From<MacroCall> for ModuleItem {
4201 fn from(node: MacroCall) -> ModuleItem {
4202 ModuleItem::MacroCall(node)
4203 }
4204}
4199impl std::fmt::Display for ModuleItem { 4205impl std::fmt::Display for ModuleItem {
4200 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 4206 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
4201 std::fmt::Display::fmt(self.syntax(), f) 4207 std::fmt::Display::fmt(self.syntax(), f)
@@ -4205,7 +4211,7 @@ impl AstNode for ModuleItem {
4205 fn can_cast(kind: SyntaxKind) -> bool { 4211 fn can_cast(kind: SyntaxKind) -> bool {
4206 match kind { 4212 match kind {
4207 STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_DEF 4213 STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_DEF
4208 | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true, 4214 | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE | MACRO_CALL => true,
4209 _ => false, 4215 _ => false,
4210 } 4216 }
4211 } 4217 }
@@ -4223,6 +4229,7 @@ impl AstNode for ModuleItem {
4223 CONST_DEF => ModuleItem::ConstDef(ConstDef { syntax }), 4229 CONST_DEF => ModuleItem::ConstDef(ConstDef { syntax }),
4224 STATIC_DEF => ModuleItem::StaticDef(StaticDef { syntax }), 4230 STATIC_DEF => ModuleItem::StaticDef(StaticDef { syntax }),
4225 MODULE => ModuleItem::Module(Module { syntax }), 4231 MODULE => ModuleItem::Module(Module { syntax }),
4232 MACRO_CALL => ModuleItem::MacroCall(MacroCall { syntax }),
4226 _ => return None, 4233 _ => return None,
4227 }; 4234 };
4228 Some(res) 4235 Some(res)
@@ -4241,6 +4248,7 @@ impl AstNode for ModuleItem {
4241 ModuleItem::ConstDef(it) => &it.syntax, 4248 ModuleItem::ConstDef(it) => &it.syntax,
4242 ModuleItem::StaticDef(it) => &it.syntax, 4249 ModuleItem::StaticDef(it) => &it.syntax,
4243 ModuleItem::Module(it) => &it.syntax, 4250 ModuleItem::Module(it) => &it.syntax,
4251 ModuleItem::MacroCall(it) => &it.syntax,
4244 } 4252 }
4245 } 4253 }
4246} 4254}
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index f8cf1e3eb..576378306 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -6,8 +6,7 @@ use itertools::Itertools;
6 6
7use crate::{ 7use crate::{
8 ast::{self, child_opt, children, AstChildren, AstNode, AstToken}, 8 ast::{self, child_opt, children, AstChildren, AstNode, AstToken},
9 match_ast, 9 syntax_node::SyntaxElementChildren,
10 syntax_node::{SyntaxElementChildren, SyntaxNodeChildren},
11}; 10};
12 11
13pub trait TypeAscriptionOwner: AstNode { 12pub trait TypeAscriptionOwner: AstNode {
@@ -46,38 +45,10 @@ pub trait FnDefOwner: AstNode {
46 } 45 }
47} 46}
48 47
49#[derive(Debug, Clone, PartialEq, Eq)]
50pub enum ItemOrMacro {
51 Item(ast::ModuleItem),
52 Macro(ast::MacroCall),
53}
54
55pub trait ModuleItemOwner: AstNode { 48pub trait ModuleItemOwner: AstNode {
56 fn items(&self) -> AstChildren<ast::ModuleItem> { 49 fn items(&self) -> AstChildren<ast::ModuleItem> {
57 children(self) 50 children(self)
58 } 51 }
59 fn items_with_macros(&self) -> ItemOrMacroIter {
60 ItemOrMacroIter(self.syntax().children())
61 }
62}
63
64#[derive(Debug)]
65pub struct ItemOrMacroIter(SyntaxNodeChildren);
66
67impl Iterator for ItemOrMacroIter {
68 type Item = ItemOrMacro;
69 fn next(&mut self) -> Option<ItemOrMacro> {
70 loop {
71 let n = self.0.next()?;
72 match_ast! {
73 match n {
74 ast::ModuleItem(it) => { return Some(ItemOrMacro::Item(it)) },
75 ast::MacroCall(it) => { return Some(ItemOrMacro::Macro(it)) },
76 _ => {},
77 }
78 }
79 }
80 }
81} 52}
82 53
83pub trait TypeParamsOwner: AstNode { 54pub trait TypeParamsOwner: AstNode {
diff --git a/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt b/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt
index e0edf6a2d..0ffbd25aa 100644
--- a/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt
+++ b/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt
@@ -12,8 +12,8 @@ SOURCE_FILE@[0; 42)
12 BLOCK@[10; 41) 12 BLOCK@[10; 41)
13 L_CURLY@[10; 11) "{" 13 L_CURLY@[10; 11) "{"
14 WHITESPACE@[11; 16) "\n " 14 WHITESPACE@[11; 16) "\n "
15 EXPR_STMT@[16; 39) 15 EXPR_STMT@[16; 24)
16 LAMBDA_EXPR@[16; 38) 16 LAMBDA_EXPR@[16; 24)
17 PARAM_LIST@[16; 18) 17 PARAM_LIST@[16; 18)
18 PIPE@[16; 17) "|" 18 PIPE@[16; 17) "|"
19 PIPE@[17; 18) "|" 19 PIPE@[17; 18) "|"
@@ -24,20 +24,22 @@ SOURCE_FILE@[0; 42)
24 TUPLE_TYPE@[22; 24) 24 TUPLE_TYPE@[22; 24)
25 L_PAREN@[22; 23) "(" 25 L_PAREN@[22; 23) "("
26 R_PAREN@[23; 24) ")" 26 R_PAREN@[23; 24) ")"
27 WHITESPACE@[24; 25) " " 27 WHITESPACE@[24; 25) " "
28 BLOCK_EXPR@[25; 38) 28 EXPR_STMT@[25; 39)
29 UNSAFE_KW@[25; 31) "unsafe" 29 BLOCK_EXPR@[25; 38)
30 WHITESPACE@[31; 32) " " 30 UNSAFE_KW@[25; 31) "unsafe"
31 BLOCK@[32; 38) 31 WHITESPACE@[31; 32) " "
32 L_CURLY@[32; 33) "{" 32 BLOCK@[32; 38)
33 WHITESPACE@[33; 34) " " 33 L_CURLY@[32; 33) "{"
34 TUPLE_EXPR@[34; 36) 34 WHITESPACE@[33; 34) " "
35 L_PAREN@[34; 35) "(" 35 TUPLE_EXPR@[34; 36)
36 R_PAREN@[35; 36) ")" 36 L_PAREN@[34; 35) "("
37 WHITESPACE@[36; 37) " " 37 R_PAREN@[35; 36) ")"
38 R_CURLY@[37; 38) "}" 38 WHITESPACE@[36; 37) " "
39 R_CURLY@[37; 38) "}"
39 SEMI@[38; 39) ";" 40 SEMI@[38; 39) ";"
40 WHITESPACE@[39; 40) "\n" 41 WHITESPACE@[39; 40) "\n"
41 R_CURLY@[40; 41) "}" 42 R_CURLY@[40; 41) "}"
42 WHITESPACE@[41; 42) "\n" 43 WHITESPACE@[41; 42) "\n"
43error [24; 24): expected `{` 44error [24; 24): expected `{`
45error [24; 24): expected SEMI
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rs b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rs
new file mode 100644
index 000000000..061118d3a
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rs
@@ -0,0 +1 @@
fn main() { || -> i32 { 92 }(); }
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt
new file mode 100644
index 000000000..ba8779094
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt
@@ -0,0 +1,45 @@
1SOURCE_FILE@[0; 34)
2 FN_DEF@[0; 33)
3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " "
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8) "("
9 R_PAREN@[8; 9) ")"
10 WHITESPACE@[9; 10) " "
11 BLOCK_EXPR@[10; 33)
12 BLOCK@[10; 33)
13 L_CURLY@[10; 11) "{"
14 WHITESPACE@[11; 12) " "
15 EXPR_STMT@[12; 31)
16 CALL_EXPR@[12; 30)
17 LAMBDA_EXPR@[12; 28)
18 PARAM_LIST@[12; 14)
19 PIPE@[12; 13) "|"
20 PIPE@[13; 14) "|"
21 WHITESPACE@[14; 15) " "
22 RET_TYPE@[15; 21)
23 THIN_ARROW@[15; 17) "->"
24 WHITESPACE@[17; 18) " "
25 PATH_TYPE@[18; 21)
26 PATH@[18; 21)
27 PATH_SEGMENT@[18; 21)
28 NAME_REF@[18; 21)
29 IDENT@[18; 21) "i32"
30 WHITESPACE@[21; 22) " "
31 BLOCK_EXPR@[22; 28)
32 BLOCK@[22; 28)
33 L_CURLY@[22; 23) "{"
34 WHITESPACE@[23; 24) " "
35 LITERAL@[24; 26)
36 INT_NUMBER@[24; 26) "92"
37 WHITESPACE@[26; 27) " "
38 R_CURLY@[27; 28) "}"
39 ARG_LIST@[28; 30)
40 L_PAREN@[28; 29) "("
41 R_PAREN@[29; 30) ")"
42 SEMI@[30; 31) ";"
43 WHITESPACE@[31; 32) " "
44 R_CURLY@[32; 33) "}"
45 WHITESPACE@[33; 34) "\n"
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index 1cc2f6571..1033d6de9 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -734,19 +734,29 @@ pub fn handle_code_action(
734 res.push(fix.action.clone()); 734 res.push(fix.action.clone());
735 } 735 }
736 736
737 let mut grouped_assists: FxHashMap<String, Vec<Assist>> = FxHashMap::default(); 737 let mut grouped_assists: FxHashMap<String, (usize, Vec<Assist>)> = FxHashMap::default();
738 for assist in world.analysis().assists(FileRange { file_id, range })?.into_iter() { 738 for assist in world.analysis().assists(FileRange { file_id, range })?.into_iter() {
739 match &assist.group_label { 739 match &assist.group_label {
740 Some(label) => grouped_assists.entry(label.to_owned()).or_default().push(assist), 740 Some(label) => grouped_assists
741 None => res.push(create_single_code_action(assist, &world)?.into()), 741 .entry(label.to_owned())
742 .or_insert_with(|| {
743 let idx = res.len();
744 let dummy = Command::new(String::new(), String::new(), None);
745 res.push(dummy.into());
746 (idx, Vec::new())
747 })
748 .1
749 .push(assist),
750 None => {
751 res.push(create_single_code_action(assist, &world)?.into());
752 }
742 } 753 }
743 } 754 }
744 755
745 for (group_label, assists) in grouped_assists { 756 for (group_label, (idx, assists)) in grouped_assists {
746 if assists.len() == 1 { 757 if assists.len() == 1 {
747 res.push( 758 res[idx] =
748 create_single_code_action(assists.into_iter().next().unwrap(), &world)?.into(), 759 create_single_code_action(assists.into_iter().next().unwrap(), &world)?.into();
749 );
750 } else { 760 } else {
751 let title = group_label; 761 let title = group_label;
752 762
@@ -760,17 +770,15 @@ pub fn handle_code_action(
760 command: "rust-analyzer.selectAndApplySourceChange".to_string(), 770 command: "rust-analyzer.selectAndApplySourceChange".to_string(),
761 arguments: Some(vec![serde_json::Value::Array(arguments)]), 771 arguments: Some(vec![serde_json::Value::Array(arguments)]),
762 }); 772 });
763 res.push( 773 res[idx] = CodeAction {
764 CodeAction { 774 title,
765 title, 775 kind: None,
766 kind: None, 776 diagnostics: None,
767 diagnostics: None, 777 edit: None,
768 edit: None, 778 command,
769 command, 779 is_preferred: None,
770 is_preferred: None, 780 }
771 } 781 .into();
772 .into(),
773 );
774 } 782 }
775 } 783 }
776 784