aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/assists/src/handlers/fill_match_arms.rs38
-rw-r--r--crates/hir_def/src/nameres.rs11
-rw-r--r--crates/hir_def/src/nameres/collector.rs5
-rw-r--r--crates/ide/src/inlay_hints.rs20
-rw-r--r--crates/project_model/src/build_data.rs5
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs2
-rw-r--r--crates/rust-analyzer/src/config.rs18
-rw-r--r--crates/rust-analyzer/src/reload.rs16
-rw-r--r--docs/user/generated_config.adoc2
-rw-r--r--editors/code/package.json8
10 files changed, 107 insertions, 18 deletions
diff --git a/crates/assists/src/handlers/fill_match_arms.rs b/crates/assists/src/handlers/fill_match_arms.rs
index 4964ddc7d..7086e47d2 100644
--- a/crates/assists/src/handlers/fill_match_arms.rs
+++ b/crates/assists/src/handlers/fill_match_arms.rs
@@ -37,7 +37,7 @@ use crate::{
37// } 37// }
38// ``` 38// ```
39pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 39pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
40 let match_expr = ctx.find_node_at_offset::<ast::MatchExpr>()?; 40 let match_expr = ctx.find_node_at_offset_with_descend::<ast::MatchExpr>()?;
41 let match_arm_list = match_expr.match_arm_list()?; 41 let match_arm_list = match_expr.match_arm_list()?;
42 42
43 let expr = match_expr.expr()?; 43 let expr = match_expr.expr()?;
@@ -103,7 +103,7 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
103 return None; 103 return None;
104 } 104 }
105 105
106 let target = match_expr.syntax().text_range(); 106 let target = ctx.sema.original_range(match_expr.syntax()).range;
107 acc.add( 107 acc.add(
108 AssistId("fill_match_arms", AssistKind::QuickFix), 108 AssistId("fill_match_arms", AssistKind::QuickFix),
109 "Fill match arms", 109 "Fill match arms",
@@ -113,7 +113,7 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
113 let n_old_arms = new_arm_list.arms().count(); 113 let n_old_arms = new_arm_list.arms().count();
114 let new_arm_list = new_arm_list.append_arms(missing_arms); 114 let new_arm_list = new_arm_list.append_arms(missing_arms);
115 let first_new_arm = new_arm_list.arms().nth(n_old_arms); 115 let first_new_arm = new_arm_list.arms().nth(n_old_arms);
116 let old_range = match_arm_list.syntax().text_range(); 116 let old_range = ctx.sema.original_range(match_arm_list.syntax()).range;
117 match (first_new_arm, ctx.config.snippet_cap) { 117 match (first_new_arm, ctx.config.snippet_cap) {
118 (Some(first_new_arm), Some(cap)) => { 118 (Some(first_new_arm), Some(cap)) => {
119 let extend_lifetime; 119 let extend_lifetime;
@@ -752,4 +752,36 @@ fn foo(opt: Option<i32>) {
752"#, 752"#,
753 ); 753 );
754 } 754 }
755
756 #[test]
757 fn works_inside_macro_call() {
758 check_assist(
759 fill_match_arms,
760 r#"
761macro_rules! m { ($expr:expr) => {$expr}}
762enum Test {
763 A,
764 B,
765 C,
766}
767
768fn foo(t: Test) {
769 m!(match t$0 {});
770}"#,
771 r#"macro_rules! m { ($expr:expr) => {$expr}}
772enum Test {
773 A,
774 B,
775 C,
776}
777
778fn foo(t: Test) {
779 m!(match t {
780 $0Test::A => {}
781 Test::B => {}
782 Test::C => {}
783});
784}"#,
785 );
786 }
755} 787}
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 199771e9a..005b36e02 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -289,6 +289,17 @@ impl DefMap {
289 (res.resolved_def, res.segment_index) 289 (res.resolved_def, res.segment_index)
290 } 290 }
291 291
292 /// Iterates over the containing `DefMap`s, if `self` is a `DefMap` corresponding to a block
293 /// expression.
294 fn ancestor_maps(
295 &self,
296 local_mod: LocalModuleId,
297 ) -> impl Iterator<Item = (&DefMap, LocalModuleId)> {
298 std::iter::successors(Some((self, local_mod)), |(map, _)| {
299 map.block.as_ref().map(|block| (&*block.parent, block.parent_module))
300 })
301 }
302
292 // FIXME: this can use some more human-readable format (ideally, an IR 303 // FIXME: this can use some more human-readable format (ideally, an IR
293 // even), as this should be a great debugging aid. 304 // even), as this should be a great debugging aid.
294 pub fn dump(&self) -> String { 305 pub fn dump(&self) -> String {
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 393170b32..761b29c86 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -1443,7 +1443,10 @@ impl ModCollector<'_, '_> {
1443 if let Some(macro_call_id) = 1443 if let Some(macro_call_id) =
1444 ast_id.as_call_id(self.def_collector.db, self.def_collector.def_map.krate, |path| { 1444 ast_id.as_call_id(self.def_collector.db, self.def_collector.def_map.krate, |path| {
1445 path.as_ident().and_then(|name| { 1445 path.as_ident().and_then(|name| {
1446 self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) 1446 self.def_collector
1447 .def_map
1448 .ancestor_maps(self.module_id)
1449 .find_map(|(map, module)| map[module].scope.get_legacy_macro(&name))
1447 }) 1450 })
1448 }) 1451 })
1449 { 1452 {
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 54485fd30..2f37c8040 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -416,8 +416,11 @@ fn get_string_representation(expr: &ast::Expr) -> Option<String> {
416 name_ref => Some(name_ref.to_owned()), 416 name_ref => Some(name_ref.to_owned()),
417 } 417 }
418 } 418 }
419 ast::Expr::FieldExpr(field_expr) => Some(field_expr.name_ref()?.to_string()),
420 ast::Expr::PathExpr(path_expr) => Some(path_expr.to_string()),
421 ast::Expr::PrefixExpr(prefix_expr) => get_string_representation(&prefix_expr.expr()?),
419 ast::Expr::RefExpr(ref_expr) => get_string_representation(&ref_expr.expr()?), 422 ast::Expr::RefExpr(ref_expr) => get_string_representation(&ref_expr.expr()?),
420 _ => Some(expr.to_string()), 423 _ => None,
421 } 424 }
422} 425}
423 426
@@ -1438,4 +1441,19 @@ fn main() {
1438"#, 1441"#,
1439 ) 1442 )
1440 } 1443 }
1444
1445 #[test]
1446 fn param_name_hints_show_for_literals() {
1447 check(
1448 r#"pub fn test(a: i32, b: i32) -> [i32; 2] { [a, b] }
1449fn main() {
1450 test(
1451 0x0fab272b,
1452 //^^^^^^^^^^ a
1453 0x0fab272b
1454 //^^^^^^^^^^ b
1455 );
1456}"#,
1457 )
1458 }
1441} 1459}
diff --git a/crates/project_model/src/build_data.rs b/crates/project_model/src/build_data.rs
index cf32995e0..3ff347e2c 100644
--- a/crates/project_model/src/build_data.rs
+++ b/crates/project_model/src/build_data.rs
@@ -175,7 +175,7 @@ fn is_dylib(path: &Path) -> bool {
175/// Should be synced with <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates> 175/// Should be synced with <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates>
176fn inject_cargo_env(package: &cargo_metadata::Package, env: &mut Vec<(String, String)>) { 176fn inject_cargo_env(package: &cargo_metadata::Package, env: &mut Vec<(String, String)>) {
177 // FIXME: Missing variables: 177 // FIXME: Missing variables:
178 // CARGO, CARGO_PKG_HOMEPAGE, CARGO_CRATE_NAME, CARGO_BIN_NAME, CARGO_BIN_EXE_<name> 178 // CARGO_PKG_HOMEPAGE, CARGO_CRATE_NAME, CARGO_BIN_NAME, CARGO_BIN_EXE_<name>
179 179
180 let mut manifest_dir = package.manifest_path.clone(); 180 let mut manifest_dir = package.manifest_path.clone();
181 manifest_dir.pop(); 181 manifest_dir.pop();
@@ -183,6 +183,9 @@ fn inject_cargo_env(package: &cargo_metadata::Package, env: &mut Vec<(String, St
183 env.push(("CARGO_MANIFEST_DIR".into(), cargo_manifest_dir.into())); 183 env.push(("CARGO_MANIFEST_DIR".into(), cargo_manifest_dir.into()));
184 } 184 }
185 185
186 // Not always right, but works for common cases.
187 env.push(("CARGO".into(), "cargo".into()));
188
186 env.push(("CARGO_PKG_VERSION".into(), package.version.to_string())); 189 env.push(("CARGO_PKG_VERSION".into(), package.version.to_string()));
187 env.push(("CARGO_PKG_VERSION_MAJOR".into(), package.version.major.to_string())); 190 env.push(("CARGO_PKG_VERSION_MAJOR".into(), package.version.major.to_string()));
188 env.push(("CARGO_PKG_VERSION_MINOR".into(), package.version.minor.to_string())); 191 env.push(("CARGO_PKG_VERSION_MINOR".into(), package.version.minor.to_string()));
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index 16ccab781..dbab4f5f4 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -46,7 +46,7 @@ pub fn load_cargo(
46 vfs.file_id(&path) 46 vfs.file_id(&path)
47 }); 47 });
48 48
49 let project_folders = ProjectFolders::new(&[ws]); 49 let project_folders = ProjectFolders::new(&[ws], &[]);
50 loader.set_config(vfs::loader::Config { load: project_folders.load, watch: vec![] }); 50 loader.set_config(vfs::loader::Config { load: project_folders.load, watch: vec![] });
51 51
52 log::debug!("crate graph: {:?}", crate_graph); 52 log::debug!("crate graph: {:?}", crate_graph);
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 071fde64d..37487b6ac 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -7,7 +7,7 @@
7//! configure the server itself, feature flags are passed into analysis, and 7//! configure the server itself, feature flags are passed into analysis, and
8//! tweak things like automatic insertion of `()` in completions. 8//! tweak things like automatic insertion of `()` in completions.
9 9
10use std::{convert::TryFrom, ffi::OsString, iter, path::PathBuf}; 10use std::{ffi::OsString, iter, path::PathBuf};
11 11
12use flycheck::FlycheckConfig; 12use flycheck::FlycheckConfig;
13use hir::PrefixKind; 13use hir::PrefixKind;
@@ -105,6 +105,8 @@ config_data! {
105 105
106 /// Controls file watching implementation. 106 /// Controls file watching implementation.
107 files_watcher: String = "\"client\"", 107 files_watcher: String = "\"client\"",
108 /// These directories will be ignored by rust-analyzer.
109 files_excludeDirs: Vec<PathBuf> = "[]",
108 110
109 /// Whether to show `Debug` action. Only applies when 111 /// Whether to show `Debug` action. Only applies when
110 /// `#rust-analyzer.hoverActions.enable#` is set. 112 /// `#rust-analyzer.hoverActions.enable#` is set.
@@ -248,7 +250,7 @@ impl LensConfig {
248#[derive(Debug, Clone)] 250#[derive(Debug, Clone)]
249pub struct FilesConfig { 251pub struct FilesConfig {
250 pub watcher: FilesWatcher, 252 pub watcher: FilesWatcher,
251 pub exclude: Vec<String>, 253 pub exclude: Vec<AbsPathBuf>,
252} 254}
253 255
254#[derive(Debug, Clone)] 256#[derive(Debug, Clone)]
@@ -458,7 +460,7 @@ impl Config {
458 "notify" => FilesWatcher::Notify, 460 "notify" => FilesWatcher::Notify,
459 "client" | _ => FilesWatcher::Client, 461 "client" | _ => FilesWatcher::Client,
460 }, 462 },
461 exclude: Vec::new(), 463 exclude: self.data.files_excludeDirs.iter().map(|it| self.root_path.join(it)).collect(),
462 } 464 }
463 } 465 }
464 pub fn notifications(&self) -> NotificationsConfig { 466 pub fn notifications(&self) -> NotificationsConfig {
@@ -468,11 +470,7 @@ impl Config {
468 self.data.cargo_autoreload 470 self.data.cargo_autoreload
469 } 471 }
470 pub fn cargo(&self) -> CargoConfig { 472 pub fn cargo(&self) -> CargoConfig {
471 let rustc_source = self.data.rustcSource.clone().and_then(|it| { 473 let rustc_source = self.data.rustcSource.as_ref().map(|it| self.root_path.join(&it));
472 AbsPathBuf::try_from(it)
473 .map_err(|_| log::error!("rustc source directory must be an absolute path"))
474 .ok()
475 });
476 474
477 CargoConfig { 475 CargoConfig {
478 no_default_features: self.data.cargo_noDefaultFeatures, 476 no_default_features: self.data.cargo_noDefaultFeatures,
@@ -767,6 +765,10 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
767 "type": "array", 765 "type": "array",
768 "items": { "type": "string" }, 766 "items": { "type": "string" },
769 }, 767 },
768 "Vec<PathBuf>" => set! {
769 "type": "array",
770 "items": { "type": "string" },
771 },
770 "FxHashSet<String>" => set! { 772 "FxHashSet<String>" => set! {
771 "type": "array", 773 "type": "array",
772 "items": { "type": "string" }, 774 "items": { "type": "string" },
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index dabfb4241..0507186dc 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -214,7 +214,8 @@ impl GlobalState {
214 214
215 let mut change = Change::new(); 215 let mut change = Change::new();
216 216
217 let project_folders = ProjectFolders::new(&workspaces); 217 let files_config = self.config.files();
218 let project_folders = ProjectFolders::new(&workspaces, &files_config.exclude);
218 219
219 self.proc_macro_client = match self.config.proc_macro_srv() { 220 self.proc_macro_client = match self.config.proc_macro_srv() {
220 None => None, 221 None => None,
@@ -231,7 +232,7 @@ impl GlobalState {
231 }, 232 },
232 }; 233 };
233 234
234 let watch = match self.config.files().watcher { 235 let watch = match files_config.watcher {
235 FilesWatcher::Client => vec![], 236 FilesWatcher::Client => vec![],
236 FilesWatcher::Notify => project_folders.watch, 237 FilesWatcher::Notify => project_folders.watch,
237 }; 238 };
@@ -319,7 +320,10 @@ pub(crate) struct ProjectFolders {
319} 320}
320 321
321impl ProjectFolders { 322impl ProjectFolders {
322 pub(crate) fn new(workspaces: &[ProjectWorkspace]) -> ProjectFolders { 323 pub(crate) fn new(
324 workspaces: &[ProjectWorkspace],
325 global_excludes: &[AbsPathBuf],
326 ) -> ProjectFolders {
323 let mut res = ProjectFolders::default(); 327 let mut res = ProjectFolders::default();
324 let mut fsc = FileSetConfig::builder(); 328 let mut fsc = FileSetConfig::builder();
325 let mut local_filesets = vec![]; 329 let mut local_filesets = vec![];
@@ -333,6 +337,12 @@ impl ProjectFolders {
333 dirs.extensions.push("rs".into()); 337 dirs.extensions.push("rs".into());
334 dirs.include.extend(root.include); 338 dirs.include.extend(root.include);
335 dirs.exclude.extend(root.exclude); 339 dirs.exclude.extend(root.exclude);
340 for excl in global_excludes {
341 if dirs.include.iter().any(|incl| incl.starts_with(excl)) {
342 dirs.exclude.push(excl.clone());
343 }
344 }
345
336 vfs::loader::Entry::Directories(dirs) 346 vfs::loader::Entry::Directories(dirs)
337 }; 347 };
338 348
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index 1974082da..55178c84c 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -56,6 +56,8 @@
56 List of warnings that should be displayed with hint severity.\n\nThe warnings will be indicated by faded text or three dots in code and will not show up in the `Problems Panel`. 56 List of warnings that should be displayed with hint severity.\n\nThe warnings will be indicated by faded text or three dots in code and will not show up in the `Problems Panel`.
57[[rust-analyzer.files.watcher]]rust-analyzer.files.watcher (default: `"client"`):: 57[[rust-analyzer.files.watcher]]rust-analyzer.files.watcher (default: `"client"`)::
58 Controls file watching implementation. 58 Controls file watching implementation.
59[[rust-analyzer.files.excludeDirs]]rust-analyzer.files.excludeDirs (default: `[]`)::
60 These directories will be ignored by rust-analyzer.
59[[rust-analyzer.hoverActions.debug]]rust-analyzer.hoverActions.debug (default: `true`):: 61[[rust-analyzer.hoverActions.debug]]rust-analyzer.hoverActions.debug (default: `true`)::
60 Whether to show `Debug` action. Only applies when `#rust-analyzer.hoverActions.enable#` is set. 62 Whether to show `Debug` action. Only applies when `#rust-analyzer.hoverActions.enable#` is set.
61[[rust-analyzer.hoverActions.enable]]rust-analyzer.hoverActions.enable (default: `true`):: 63[[rust-analyzer.hoverActions.enable]]rust-analyzer.hoverActions.enable (default: `true`)::
diff --git a/editors/code/package.json b/editors/code/package.json
index ee54638f1..66af94186 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -555,6 +555,14 @@
555 "default": "client", 555 "default": "client",
556 "type": "string" 556 "type": "string"
557 }, 557 },
558 "rust-analyzer.files.excludeDirs": {
559 "markdownDescription": "These directories will be ignored by rust-analyzer.",
560 "default": [],
561 "type": "array",
562 "items": {
563 "type": "string"
564 }
565 },
558 "rust-analyzer.hoverActions.debug": { 566 "rust-analyzer.hoverActions.debug": {
559 "markdownDescription": "Whether to show `Debug` action. Only applies when `#rust-analyzer.hoverActions.enable#` is set.", 567 "markdownDescription": "Whether to show `Debug` action. Only applies when `#rust-analyzer.hoverActions.enable#` is set.",
560 "default": true, 568 "default": true,