diff options
-rw-r--r-- | crates/assists/src/handlers/fill_match_arms.rs | 38 | ||||
-rw-r--r-- | crates/hir_def/src/nameres.rs | 11 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 5 | ||||
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 20 | ||||
-rw-r--r-- | crates/project_model/src/build_data.rs | 5 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/load_cargo.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 18 | ||||
-rw-r--r-- | crates/rust-analyzer/src/reload.rs | 16 | ||||
-rw-r--r-- | docs/user/generated_config.adoc | 2 | ||||
-rw-r--r-- | editors/code/package.json | 8 |
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 | // ``` |
39 | pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 39 | pub(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#" | ||
761 | macro_rules! m { ($expr:expr) => {$expr}} | ||
762 | enum Test { | ||
763 | A, | ||
764 | B, | ||
765 | C, | ||
766 | } | ||
767 | |||
768 | fn foo(t: Test) { | ||
769 | m!(match t$0 {}); | ||
770 | }"#, | ||
771 | r#"macro_rules! m { ($expr:expr) => {$expr}} | ||
772 | enum Test { | ||
773 | A, | ||
774 | B, | ||
775 | C, | ||
776 | } | ||
777 | |||
778 | fn 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] } | ||
1449 | fn 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> |
176 | fn inject_cargo_env(package: &cargo_metadata::Package, env: &mut Vec<(String, String)>) { | 176 | fn 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 | ||
10 | use std::{convert::TryFrom, ffi::OsString, iter, path::PathBuf}; | 10 | use std::{ffi::OsString, iter, path::PathBuf}; |
11 | 11 | ||
12 | use flycheck::FlycheckConfig; | 12 | use flycheck::FlycheckConfig; |
13 | use hir::PrefixKind; | 13 | use 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)] |
249 | pub struct FilesConfig { | 251 | pub 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 | ||
321 | impl ProjectFolders { | 322 | impl 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, |