aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/assists/src/handlers/extract_module_to_file.rs8
-rw-r--r--crates/completion/src/completions/qualified_path.rs29
-rw-r--r--crates/completion/src/completions/unqualified_path.rs27
-rw-r--r--crates/hir_def/src/nameres/mod_resolution.rs2
-rw-r--r--crates/hir_expand/src/builtin_macro.rs5
-rw-r--r--crates/hir_expand/src/db.rs9
-rw-r--r--crates/hir_expand/src/eager.rs14
-rw-r--r--crates/hir_expand/src/lib.rs27
-rw-r--r--crates/ide/src/goto_definition.rs25
-rw-r--r--crates/proc_macro_srv/Cargo.toml2
-rw-r--r--crates/rust-analyzer/src/config.rs4
-rw-r--r--crates/syntax/src/ast/make.rs8
12 files changed, 122 insertions, 38 deletions
diff --git a/crates/assists/src/handlers/extract_module_to_file.rs b/crates/assists/src/handlers/extract_module_to_file.rs
index 3e67fdca2..50bf67ef7 100644
--- a/crates/assists/src/handlers/extract_module_to_file.rs
+++ b/crates/assists/src/handlers/extract_module_to_file.rs
@@ -91,18 +91,18 @@ mod tests;
91 extract_module_to_file, 91 extract_module_to_file,
92 r#" 92 r#"
93//- /main.rs 93//- /main.rs
94mod submodule; 94mod submod;
95//- /submodule.rs 95//- /submod.rs
96mod inner<|> { 96mod inner<|> {
97 fn f() {} 97 fn f() {}
98} 98}
99fn g() {} 99fn g() {}
100"#, 100"#,
101 r#" 101 r#"
102//- /submodule.rs 102//- /submod.rs
103mod inner; 103mod inner;
104fn g() {} 104fn g() {}
105//- /submodule/inner.rs 105//- /submod/inner.rs
106fn f() {} 106fn f() {}
107"#, 107"#,
108 ); 108 );
diff --git a/crates/completion/src/completions/qualified_path.rs b/crates/completion/src/completions/qualified_path.rs
index 1300f00b2..882c4dcbc 100644
--- a/crates/completion/src/completions/qualified_path.rs
+++ b/crates/completion/src/completions/qualified_path.rs
@@ -118,6 +118,12 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
118 _ => return, 118 _ => return,
119 }; 119 };
120 120
121 if let Some(Adt::Enum(e)) = ty.as_adt() {
122 for variant in e.variants(ctx.db) {
123 acc.add_enum_variant(ctx, variant, None);
124 }
125 }
126
121 let traits_in_scope = ctx.scope.traits_in_scope(); 127 let traits_in_scope = ctx.scope.traits_in_scope();
122 let mut seen = FxHashSet::default(); 128 let mut seen = FxHashSet::default();
123 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { 129 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
@@ -752,4 +758,27 @@ fn main() {
752 "#]], 758 "#]],
753 ); 759 );
754 } 760 }
761
762 #[test]
763 fn completes_self_enum() {
764 check(
765 r#"
766enum Foo {
767 Bar,
768 Baz,
769}
770
771impl Foo {
772 fn foo(self) {
773 Self::<|>
774 }
775}
776"#,
777 expect![[r#"
778 ev Bar ()
779 ev Baz ()
780 me foo(…) fn foo(self)
781 "#]],
782 );
783 }
755} 784}
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
index 099ffb4d4..d09849752 100644
--- a/crates/completion/src/completions/unqualified_path.rs
+++ b/crates/completion/src/completions/unqualified_path.rs
@@ -1,5 +1,7 @@
1//! Completion of names from the current scope, e.g. locals and imported items. 1//! Completion of names from the current scope, e.g. locals and imported items.
2 2
3use std::iter;
4
3use either::Either; 5use either::Either;
4use hir::{Adt, ModPath, ModuleDef, ScopeDef, Type}; 6use hir::{Adt, ModPath, ModuleDef, ScopeDef, Type};
5use ide_db::helpers::insert_use::ImportScope; 7use ide_db::helpers::insert_use::ImportScope;
@@ -50,7 +52,9 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
50} 52}
51 53
52fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &Type) { 54fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &Type) {
53 if let Some(Adt::Enum(enum_data)) = ty.as_adt() { 55 if let Some(Adt::Enum(enum_data)) =
56 iter::successors(Some(ty.clone()), |ty| ty.remove_ref()).last().and_then(|ty| ty.as_adt())
57 {
54 let variants = enum_data.variants(ctx.db); 58 let variants = enum_data.variants(ctx.db);
55 59
56 let module = if let Some(module) = ctx.scope.module() { 60 let module = if let Some(module) = ctx.scope.module() {
@@ -701,6 +705,7 @@ fn main() { <|> }
701 "#]], 705 "#]],
702 ); 706 );
703 } 707 }
708
704 #[test] 709 #[test]
705 fn completes_enum_variant_matcharm() { 710 fn completes_enum_variant_matcharm() {
706 check( 711 check(
@@ -722,6 +727,26 @@ fn main() {
722 } 727 }
723 728
724 #[test] 729 #[test]
730 fn completes_enum_variant_matcharm_ref() {
731 check(
732 r#"
733enum Foo { Bar, Baz, Quux }
734
735fn main() {
736 let foo = Foo::Quux;
737 match &foo { Qu<|> }
738}
739"#,
740 expect![[r#"
741 ev Foo::Bar ()
742 ev Foo::Baz ()
743 ev Foo::Quux ()
744 en Foo
745 "#]],
746 )
747 }
748
749 #[test]
725 fn completes_enum_variant_iflet() { 750 fn completes_enum_variant_iflet() {
726 check( 751 check(
727 r#" 752 r#"
diff --git a/crates/hir_def/src/nameres/mod_resolution.rs b/crates/hir_def/src/nameres/mod_resolution.rs
index b4ccd4488..af3262439 100644
--- a/crates/hir_def/src/nameres/mod_resolution.rs
+++ b/crates/hir_def/src/nameres/mod_resolution.rs
@@ -79,7 +79,7 @@ impl ModDir {
79 for candidate in candidate_files.iter() { 79 for candidate in candidate_files.iter() {
80 let path = AnchoredPath { anchor: file_id, path: candidate.as_str() }; 80 let path = AnchoredPath { anchor: file_id, path: candidate.as_str() };
81 if let Some(file_id) = db.resolve_path(path) { 81 if let Some(file_id) = db.resolve_path(path) {
82 let is_mod_rs = candidate.ends_with("mod.rs"); 82 let is_mod_rs = candidate.ends_with("/mod.rs");
83 83
84 let (dir_path, root_non_dir_owner) = if is_mod_rs || attr_path.is_some() { 84 let (dir_path, root_non_dir_owner) = if is_mod_rs || attr_path.is_some() {
85 (DirPath::empty(), false) 85 (DirPath::empty(), false)
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index dddbbcdac..6382521fb 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -563,6 +563,7 @@ mod tests {
563 563
564 let args = macro_call.token_tree().unwrap(); 564 let args = macro_call.token_tree().unwrap();
565 let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; 565 let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0;
566 let call_id = AstId::new(file_id.into(), ast_id_map.ast_id(&macro_call));
566 567
567 let arg_id = db.intern_eager_expansion({ 568 let arg_id = db.intern_eager_expansion({
568 EagerCallLoc { 569 EagerCallLoc {
@@ -570,7 +571,7 @@ mod tests {
570 fragment: FragmentKind::Expr, 571 fragment: FragmentKind::Expr,
571 subtree: Arc::new(parsed_args.clone()), 572 subtree: Arc::new(parsed_args.clone()),
572 krate, 573 krate,
573 file_id: file_id.into(), 574 call: call_id,
574 } 575 }
575 }); 576 });
576 577
@@ -580,7 +581,7 @@ mod tests {
580 fragment, 581 fragment,
581 subtree: Arc::new(subtree), 582 subtree: Arc::new(subtree),
582 krate, 583 krate,
583 file_id: file_id.into(), 584 call: call_id,
584 }; 585 };
585 586
586 let id: MacroCallId = db.intern_eager_expansion(eager).into(); 587 let id: MacroCallId = db.intern_eager_expansion(eager).into();
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index 4477d867f..077de3727 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -5,7 +5,7 @@ use std::sync::Arc;
5use base_db::{salsa, SourceDatabase}; 5use base_db::{salsa, SourceDatabase};
6use mbe::{ExpandError, ExpandResult, MacroRules}; 6use mbe::{ExpandError, ExpandResult, MacroRules};
7use parser::FragmentKind; 7use parser::FragmentKind;
8use syntax::{algo::diff, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode}; 8use syntax::{algo::diff, ast::NameOwner, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode};
9 9
10use crate::{ 10use crate::{
11 ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, 11 ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId,
@@ -129,11 +129,11 @@ fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> {
129fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { 129fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> {
130 match id.kind { 130 match id.kind {
131 MacroDefKind::Declarative => { 131 MacroDefKind::Declarative => {
132 let macro_call = match id.ast_id?.to_node(db) { 132 let macro_rules = match id.ast_id?.to_node(db) {
133 syntax::ast::Macro::MacroRules(mac) => mac, 133 syntax::ast::Macro::MacroRules(mac) => mac,
134 syntax::ast::Macro::MacroDef(_) => return None, 134 syntax::ast::Macro::MacroDef(_) => return None,
135 }; 135 };
136 let arg = macro_call.token_tree()?; 136 let arg = macro_rules.token_tree()?;
137 let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { 137 let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| {
138 log::warn!("fail on macro_def to token tree: {:#?}", arg); 138 log::warn!("fail on macro_def to token tree: {:#?}", arg);
139 None 139 None
@@ -141,7 +141,8 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander,
141 let rules = match MacroRules::parse(&tt) { 141 let rules = match MacroRules::parse(&tt) {
142 Ok(it) => it, 142 Ok(it) => it,
143 Err(err) => { 143 Err(err) => {
144 log::warn!("fail on macro_def parse: error: {:#?} {:#?}", err, tt); 144 let name = macro_rules.name().map(|n| n.to_string()).unwrap_or_default();
145 log::warn!("fail on macro_def parse ({}): {:?} {:#?}", name, err, tt);
145 return None; 146 return None;
146 } 147 }
147 }; 148 };
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index 0229a836e..6354b090d 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -110,6 +110,9 @@ pub fn expand_eager_macro(
110 || err("malformed macro invocation"), 110 || err("malformed macro invocation"),
111 )?; 111 )?;
112 112
113 let ast_map = db.ast_id_map(macro_call.file_id);
114 let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(&macro_call.value));
115
113 // Note: 116 // Note:
114 // When `lazy_expand` is called, its *parent* file must be already exists. 117 // When `lazy_expand` is called, its *parent* file must be already exists.
115 // Here we store an eager macro id for the argument expanded subtree here 118 // Here we store an eager macro id for the argument expanded subtree here
@@ -120,7 +123,7 @@ pub fn expand_eager_macro(
120 fragment: FragmentKind::Expr, 123 fragment: FragmentKind::Expr,
121 subtree: Arc::new(parsed_args.clone()), 124 subtree: Arc::new(parsed_args.clone()),
122 krate, 125 krate,
123 file_id: macro_call.file_id, 126 call: call_id,
124 } 127 }
125 }); 128 });
126 let arg_file_id: MacroCallId = arg_id.into(); 129 let arg_file_id: MacroCallId = arg_id.into();
@@ -141,13 +144,8 @@ pub fn expand_eager_macro(
141 let res = eager.expand(db, arg_id, &subtree); 144 let res = eager.expand(db, arg_id, &subtree);
142 145
143 let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?; 146 let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?;
144 let eager = EagerCallLoc { 147 let eager =
145 def, 148 EagerCallLoc { def, fragment, subtree: Arc::new(subtree), krate, call: call_id };
146 fragment,
147 subtree: Arc::new(subtree),
148 krate,
149 file_id: macro_call.file_id,
150 };
151 149
152 Ok(db.intern_eager_expansion(eager)) 150 Ok(db.intern_eager_expansion(eager))
153 } else { 151 } else {
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index d486186e5..3fa1b1d77 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -83,7 +83,7 @@ impl HirFileId {
83 } 83 }
84 MacroCallId::EagerMacro(id) => { 84 MacroCallId::EagerMacro(id) => {
85 let loc = db.lookup_intern_eager_expansion(id); 85 let loc = db.lookup_intern_eager_expansion(id);
86 loc.file_id 86 loc.call.file_id
87 } 87 }
88 }; 88 };
89 file_id.original_file(db) 89 file_id.original_file(db)
@@ -103,7 +103,7 @@ impl HirFileId {
103 } 103 }
104 MacroCallId::EagerMacro(id) => { 104 MacroCallId::EagerMacro(id) => {
105 let loc = db.lookup_intern_eager_expansion(id); 105 let loc = db.lookup_intern_eager_expansion(id);
106 loc.file_id 106 loc.call.file_id
107 } 107 }
108 }; 108 };
109 } 109 }
@@ -114,17 +114,16 @@ impl HirFileId {
114 pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> { 114 pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> {
115 match self.0 { 115 match self.0 {
116 HirFileIdRepr::FileId(_) => None, 116 HirFileIdRepr::FileId(_) => None,
117 HirFileIdRepr::MacroFile(macro_file) => { 117 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
118 let lazy_id = match macro_file.macro_call_id { 118 MacroCallId::LazyMacro(lazy_id) => {
119 MacroCallId::LazyMacro(id) => id, 119 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
120 MacroCallId::EagerMacro(_id) => { 120 Some(loc.kind.node(db))
121 // FIXME: handle call node for eager macro 121 }
122 return None; 122 MacroCallId::EagerMacro(id) => {
123 } 123 let loc: EagerCallLoc = db.lookup_intern_eager_expansion(id);
124 }; 124 Some(loc.call.with_value(loc.call.to_node(db).syntax().clone()))
125 let loc = db.lookup_intern_macro(lazy_id); 125 }
126 Some(loc.kind.node(db)) 126 },
127 }
128 } 127 }
129 } 128 }
130 129
@@ -304,7 +303,7 @@ pub struct EagerCallLoc {
304 pub(crate) fragment: FragmentKind, 303 pub(crate) fragment: FragmentKind,
305 pub(crate) subtree: Arc<tt::Subtree>, 304 pub(crate) subtree: Arc<tt::Subtree>,
306 pub(crate) krate: CrateId, 305 pub(crate) krate: CrateId,
307 pub(crate) file_id: HirFileId, 306 pub(crate) call: AstId<ast::MacroCall>,
308} 307}
309 308
310/// ExpansionInfo mainly describes how to map text range between src and expanded macro 309/// ExpansionInfo mainly describes how to map text range between src and expanded macro
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 431da5d9c..47dd85ceb 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -750,6 +750,31 @@ fn test() {
750 } 750 }
751 751
752 #[test] 752 #[test]
753 fn goto_through_included_file() {
754 check(
755 r#"
756//- /main.rs
757#[rustc_builtin_macro]
758macro_rules! include {}
759
760 include!("foo.rs");
761//^^^^^^^^^^^^^^^^^^^
762
763fn f() {
764 foo<|>();
765}
766
767mod confuse_index {
768 pub fn foo() {}
769}
770
771//- /foo.rs
772fn foo() {}
773 "#,
774 );
775 }
776
777 #[test]
753 fn goto_for_type_param() { 778 fn goto_for_type_param() {
754 check( 779 check(
755 r#" 780 r#"
diff --git a/crates/proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml
index 1bfa6c3fc..df9a55c10 100644
--- a/crates/proc_macro_srv/Cargo.toml
+++ b/crates/proc_macro_srv/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2018"
10doctest = false 10doctest = false
11 11
12[dependencies] 12[dependencies]
13object = { version = "0.23", default-features = false, features = ["std", "read_core", "elf", "macho", "pe", "unaligned"] } 13object = { version = "0.23", default-features = false, features = ["std", "read_core", "elf", "macho", "pe"] }
14libloading = "0.6.0" 14libloading = "0.6.0"
15memmap = "0.7" 15memmap = "0.7"
16 16
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 11cdae57f..1db5b4e7d 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -349,12 +349,12 @@ impl Config {
349 res 349 res
350 } 350 }
351 pub fn update(&mut self, json: serde_json::Value) { 351 pub fn update(&mut self, json: serde_json::Value) {
352 log::info!("Config::update({:#})", json); 352 log::info!("updating config from JSON: {:#}", json);
353 if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) { 353 if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) {
354 return; 354 return;
355 } 355 }
356 self.do_update(json); 356 self.do_update(json);
357 log::info!("Config::update() = {:#?}", self); 357 log::info!("updated config: {:#?}", self);
358 } 358 }
359 fn do_update(&mut self, json: serde_json::Value) { 359 fn do_update(&mut self, json: serde_json::Value) {
360 let data = ConfigData::from_json(json); 360 let data = ConfigData::from_json(json);
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index ba7e5d2fb..cafa4c198 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -4,6 +4,11 @@
4//! Note that all functions here intended to be stupid constructors, which just 4//! Note that all functions here intended to be stupid constructors, which just
5//! assemble a finish node from immediate children. If you want to do something 5//! assemble a finish node from immediate children. If you want to do something
6//! smarter than that, it probably doesn't belong in this module. 6//! smarter than that, it probably doesn't belong in this module.
7//!
8//! Keep in mind that `from_text` functions should be kept private. The public
9//! API should require to assemble every node piecewise. The trick of
10//! `parse(format!())` we use internally is an implementation detail -- long
11//! term, it will be replaced with direct tree manipulation.
7use itertools::Itertools; 12use itertools::Itertools;
8use stdx::format_to; 13use stdx::format_to;
9 14
@@ -16,7 +21,8 @@ pub fn name(text: &str) -> ast::Name {
16pub fn name_ref(text: &str) -> ast::NameRef { 21pub fn name_ref(text: &str) -> ast::NameRef {
17 ast_from_text(&format!("fn f() {{ {}; }}", text)) 22 ast_from_text(&format!("fn f() {{ {}; }}", text))
18} 23}
19 24// FIXME: replace stringly-typed constructor with a family of typed ctors, a-la
25// `expr_xxx`.
20pub fn ty(text: &str) -> ast::Type { 26pub fn ty(text: &str) -> ast::Type {
21 ast_from_text(&format!("impl {} for D {{}};", text)) 27 ast_from_text(&format!("impl {} for D {{}};", text))
22} 28}