aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ide/src/hover.rs40
-rw-r--r--crates/ide/src/inlay_hints.rs38
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs3
-rw-r--r--crates/rust-analyzer/src/cli.rs2
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs8
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs7
-rw-r--r--crates/rust-analyzer/src/cli/diagnostics.rs11
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs39
-rw-r--r--crates/rust-analyzer/src/cli/ssr.rs24
-rw-r--r--crates/rust-analyzer/src/diagnostics.rs11
10 files changed, 123 insertions, 60 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 00745238a..69b828f47 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -2,8 +2,8 @@ use hir::{
2 Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource, 2 Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource,
3 HirDisplay, Module, ModuleDef, ModuleSource, Semantics, 3 HirDisplay, Module, ModuleDef, ModuleSource, Semantics,
4}; 4};
5use ide_db::base_db::SourceDatabase;
6use ide_db::{ 5use ide_db::{
6 base_db::SourceDatabase,
7 defs::{Definition, NameClass, NameRefClass}, 7 defs::{Definition, NameClass, NameRefClass},
8 RootDatabase, 8 RootDatabase,
9}; 9};
@@ -94,7 +94,12 @@ pub(crate) fn hover(
94 let node = token.parent(); 94 let node = token.parent();
95 let definition = match_ast! { 95 let definition = match_ast! {
96 match node { 96 match node {
97 ast::Name(name) => NameClass::classify(&sema, &name).and_then(|d| d.defined(sema.db)), 97 // we don't use NameClass::referenced_or_defined here as we do not want to resolve
98 // field pattern shorthands to their definition
99 ast::Name(name) => NameClass::classify(&sema, &name).and_then(|class| match class {
100 NameClass::ConstReference(def) => Some(def),
101 def => def.defined(sema.db),
102 }),
98 ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)), 103 ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)),
99 ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime) 104 ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime)
100 .map_or_else(|| NameRefClass::classify_lifetime(&sema, &lifetime).map(|d| d.referenced(sema.db)), |d| d.defined(sema.db)), 105 .map_or_else(|| NameRefClass::classify_lifetime(&sema, &lifetime).map(|d| d.referenced(sema.db)), |d| d.defined(sema.db)),
@@ -3446,6 +3451,37 @@ impl<const LEN: usize> Foo<LEN$0> {}
3446 } 3451 }
3447 3452
3448 #[test] 3453 #[test]
3454 fn hover_const_pat() {
3455 check(
3456 r#"
3457/// This is a doc
3458const FOO: usize = 3;
3459fn foo() {
3460 match 5 {
3461 FOO$0 => (),
3462 _ => ()
3463 }
3464}
3465"#,
3466 expect![[r#"
3467 *FOO*
3468
3469 ```rust
3470 test
3471 ```
3472
3473 ```rust
3474 const FOO: usize = 3
3475 ```
3476
3477 ---
3478
3479 This is a doc
3480 "#]],
3481 );
3482 }
3483
3484 #[test]
3449 fn hover_mod_def() { 3485 fn hover_mod_def() {
3450 check( 3486 check(
3451 r#" 3487 r#"
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 42d0a38e8..4ceb20742 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -109,26 +109,31 @@ fn get_chaining_hints(
109 // Chaining can be defined as an expression whose next sibling tokens are newline and dot 109 // Chaining can be defined as an expression whose next sibling tokens are newline and dot
110 // Ignoring extra whitespace and comments 110 // Ignoring extra whitespace and comments
111 let next = tokens.next()?.kind(); 111 let next = tokens.next()?.kind();
112 let next_next = tokens.next()?.kind(); 112 if next == SyntaxKind::WHITESPACE {
113 if next == SyntaxKind::WHITESPACE && next_next == T![.] { 113 let mut next_next = tokens.next()?.kind();
114 let ty = sema.type_of_expr(&expr)?; 114 while next_next == SyntaxKind::WHITESPACE {
115 if ty.is_unknown() { 115 next_next = tokens.next()?.kind();
116 return None;
117 } 116 }
118 if matches!(expr, ast::Expr::PathExpr(_)) { 117 if next_next == T![.] {
119 if let Some(hir::Adt::Struct(st)) = ty.as_adt() { 118 let ty = sema.type_of_expr(&expr)?;
120 if st.fields(sema.db).is_empty() { 119 if ty.is_unknown() {
121 return None; 120 return None;
121 }
122 if matches!(expr, ast::Expr::PathExpr(_)) {
123 if let Some(hir::Adt::Struct(st)) = ty.as_adt() {
124 if st.fields(sema.db).is_empty() {
125 return None;
126 }
122 } 127 }
123 } 128 }
129 acc.push(InlayHint {
130 range: expr.syntax().text_range(),
131 kind: InlayKind::ChainingHint,
132 label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| {
133 ty.display_truncated(sema.db, config.max_length).to_string().into()
134 }),
135 });
124 } 136 }
125 acc.push(InlayHint {
126 range: expr.syntax().text_range(),
127 kind: InlayKind::ChainingHint,
128 label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| {
129 ty.display_truncated(sema.db, config.max_length).to_string().into()
130 }),
131 });
132 } 137 }
133 Some(()) 138 Some(())
134} 139}
@@ -983,6 +988,7 @@ struct C;
983fn main() { 988fn main() {
984 let c = A(B(C)) 989 let c = A(B(C))
985 .into_b() // This is a comment 990 .into_b() // This is a comment
991 // This is another comment
986 .into_c(); 992 .into_c();
987} 993}
988"#, 994"#,
diff --git a/crates/proc_macro_srv/src/rustc_server.rs b/crates/proc_macro_srv/src/rustc_server.rs
index e6006a3c8..25606da60 100644
--- a/crates/proc_macro_srv/src/rustc_server.rs
+++ b/crates/proc_macro_srv/src/rustc_server.rs
@@ -10,9 +10,10 @@
10 10
11use crate::proc_macro::bridge::{self, server}; 11use crate::proc_macro::bridge::{self, server};
12 12
13use std::collections::{Bound, HashMap}; 13use std::collections::HashMap;
14use std::hash::Hash; 14use std::hash::Hash;
15use std::iter::FromIterator; 15use std::iter::FromIterator;
16use std::ops::Bound;
16use std::str::FromStr; 17use std::str::FromStr;
17use std::{ascii, vec::IntoIter}; 18use std::{ascii, vec::IntoIter};
18 19
diff --git a/crates/rust-analyzer/src/cli.rs b/crates/rust-analyzer/src/cli.rs
index 6879a462d..ed732eb38 100644
--- a/crates/rust-analyzer/src/cli.rs
+++ b/crates/rust-analyzer/src/cli.rs
@@ -18,7 +18,7 @@ pub use self::{
18 analysis_bench::{BenchCmd, BenchWhat, Position}, 18 analysis_bench::{BenchCmd, BenchWhat, Position},
19 analysis_stats::AnalysisStatsCmd, 19 analysis_stats::AnalysisStatsCmd,
20 diagnostics::diagnostics, 20 diagnostics::diagnostics,
21 load_cargo::load_cargo, 21 load_cargo::{load_workspace, load_workspace_at, LoadCargoConfig},
22 ssr::{apply_ssr_rules, search_for_patterns}, 22 ssr::{apply_ssr_rules, search_for_patterns},
23}; 23};
24 24
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs
index 877abd12b..8991f3bdb 100644
--- a/crates/rust-analyzer/src/cli/analysis_bench.rs
+++ b/crates/rust-analyzer/src/cli/analysis_bench.rs
@@ -17,7 +17,7 @@ use ide_db::{
17use vfs::AbsPathBuf; 17use vfs::AbsPathBuf;
18 18
19use crate::cli::{ 19use crate::cli::{
20 load_cargo::{load_cargo, LoadCargoConfig}, 20 load_cargo::{load_workspace_at, LoadCargoConfig},
21 print_memory_usage, Verbosity, 21 print_memory_usage, Verbosity,
22}; 22};
23 23
@@ -63,13 +63,13 @@ impl BenchCmd {
63 let start = Instant::now(); 63 let start = Instant::now();
64 eprint!("loading: "); 64 eprint!("loading: ");
65 65
66 let cargo_config = Default::default();
66 let load_cargo_config = LoadCargoConfig { 67 let load_cargo_config = LoadCargoConfig {
67 cargo_config: Default::default(),
68 load_out_dirs_from_check: self.load_output_dirs, 68 load_out_dirs_from_check: self.load_output_dirs,
69 with_proc_macro: self.with_proc_macro, 69 with_proc_macro: self.with_proc_macro,
70 }; 70 };
71 71 let (mut host, vfs) =
72 let (mut host, vfs) = load_cargo(&self.path, &load_cargo_config)?; 72 load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?;
73 eprintln!("{:?}\n", start.elapsed()); 73 eprintln!("{:?}\n", start.elapsed());
74 74
75 let file_id = { 75 let file_id = {
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 6d6f398f4..9072d8944 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -25,7 +25,7 @@ use stdx::format_to;
25use syntax::AstNode; 25use syntax::AstNode;
26 26
27use crate::cli::{ 27use crate::cli::{
28 load_cargo::{load_cargo, LoadCargoConfig}, 28 load_cargo::{load_workspace_at, LoadCargoConfig},
29 print_memory_usage, 29 print_memory_usage,
30 progress_report::ProgressReport, 30 progress_report::ProgressReport,
31 report_metric, Result, Verbosity, 31 report_metric, Result, Verbosity,
@@ -59,12 +59,13 @@ impl AnalysisStatsCmd {
59 }; 59 };
60 60
61 let mut db_load_sw = self.stop_watch(); 61 let mut db_load_sw = self.stop_watch();
62 let cargo_config = Default::default();
62 let load_cargo_config = LoadCargoConfig { 63 let load_cargo_config = LoadCargoConfig {
63 cargo_config: Default::default(),
64 load_out_dirs_from_check: self.load_output_dirs, 64 load_out_dirs_from_check: self.load_output_dirs,
65 with_proc_macro: self.with_proc_macro, 65 with_proc_macro: self.with_proc_macro,
66 }; 66 };
67 let (host, vfs) = load_cargo(&self.path, &load_cargo_config)?; 67 let (host, vfs) =
68 load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?;
68 let db = host.raw_database(); 69 let db = host.raw_database();
69 eprintln!("{:<20} {}", "Database loaded:", db_load_sw.elapsed()); 70 eprintln!("{:<20} {}", "Database loaded:", db_load_sw.elapsed());
70 71
diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs
index c60374c24..876f6c44f 100644
--- a/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -11,7 +11,7 @@ use ide::{DiagnosticsConfig, Severity};
11use ide_db::base_db::SourceDatabaseExt; 11use ide_db::base_db::SourceDatabaseExt;
12 12
13use crate::cli::{ 13use crate::cli::{
14 load_cargo::{load_cargo, LoadCargoConfig}, 14 load_cargo::{load_workspace_at, LoadCargoConfig},
15 Result, 15 Result,
16}; 16};
17 17
@@ -33,12 +33,9 @@ pub fn diagnostics(
33 load_out_dirs_from_check: bool, 33 load_out_dirs_from_check: bool,
34 with_proc_macro: bool, 34 with_proc_macro: bool,
35) -> Result<()> { 35) -> Result<()> {
36 let load_cargo_config = LoadCargoConfig { 36 let cargo_config = Default::default();
37 cargo_config: Default::default(), 37 let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check, with_proc_macro };
38 load_out_dirs_from_check, 38 let (host, _vfs) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {})?;
39 with_proc_macro,
40 };
41 let (host, _vfs) = load_cargo(path, &load_cargo_config)?;
42 let db = host.raw_database(); 39 let db = host.raw_database();
43 let analysis = host.analysis(); 40 let analysis = host.analysis();
44 41
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index cf0cd81de..23442afac 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -14,16 +14,28 @@ use vfs::{loader::Handle, AbsPath, AbsPathBuf};
14use crate::reload::{ProjectFolders, SourceRootConfig}; 14use crate::reload::{ProjectFolders, SourceRootConfig};
15 15
16pub struct LoadCargoConfig { 16pub struct LoadCargoConfig {
17 pub cargo_config: CargoConfig,
18 pub load_out_dirs_from_check: bool, 17 pub load_out_dirs_from_check: bool,
19 pub with_proc_macro: bool, 18 pub with_proc_macro: bool,
20} 19}
21 20
22pub fn load_cargo(root: &Path, config: &LoadCargoConfig) -> Result<(AnalysisHost, vfs::Vfs)> { 21pub fn load_workspace_at(
22 root: &Path,
23 cargo_config: &CargoConfig,
24 load_config: &LoadCargoConfig,
25 progress: &dyn Fn(String),
26) -> Result<(AnalysisHost, vfs::Vfs)> {
23 let root = AbsPathBuf::assert(std::env::current_dir()?.join(root)); 27 let root = AbsPathBuf::assert(std::env::current_dir()?.join(root));
24 let root = ProjectManifest::discover_single(&root)?; 28 let root = ProjectManifest::discover_single(&root)?;
25 let ws = ProjectWorkspace::load(root, &config.cargo_config, &|_| {})?; 29 let workspace = ProjectWorkspace::load(root, cargo_config, progress)?;
26 30
31 load_workspace(workspace, load_config, progress)
32}
33
34pub fn load_workspace(
35 ws: ProjectWorkspace,
36 config: &LoadCargoConfig,
37 progress: &dyn Fn(String),
38) -> Result<(AnalysisHost, vfs::Vfs)> {
27 let (sender, receiver) = unbounded(); 39 let (sender, receiver) = unbounded();
28 let mut vfs = vfs::Vfs::default(); 40 let mut vfs = vfs::Vfs::default();
29 let mut loader = { 41 let mut loader = {
@@ -42,7 +54,7 @@ pub fn load_cargo(root: &Path, config: &LoadCargoConfig) -> Result<(AnalysisHost
42 let build_data = if config.load_out_dirs_from_check { 54 let build_data = if config.load_out_dirs_from_check {
43 let mut collector = BuildDataCollector::default(); 55 let mut collector = BuildDataCollector::default();
44 ws.collect_build_data_configs(&mut collector); 56 ws.collect_build_data_configs(&mut collector);
45 Some(collector.collect(&|_| {})?) 57 Some(collector.collect(progress)?)
46 } else { 58 } else {
47 None 59 None
48 }; 60 };
@@ -66,11 +78,12 @@ pub fn load_cargo(root: &Path, config: &LoadCargoConfig) -> Result<(AnalysisHost
66 }); 78 });
67 79
68 log::debug!("crate graph: {:?}", crate_graph); 80 log::debug!("crate graph: {:?}", crate_graph);
69 let host = load(crate_graph, project_folders.source_root_config, &mut vfs, &receiver); 81 let host =
82 load_crate_graph(crate_graph, project_folders.source_root_config, &mut vfs, &receiver);
70 Ok((host, vfs)) 83 Ok((host, vfs))
71} 84}
72 85
73fn load( 86fn load_crate_graph(
74 crate_graph: CrateGraph, 87 crate_graph: CrateGraph,
75 source_root_config: SourceRootConfig, 88 source_root_config: SourceRootConfig,
76 vfs: &mut vfs::Vfs, 89 vfs: &mut vfs::Vfs,
@@ -120,17 +133,17 @@ mod tests {
120 use hir::Crate; 133 use hir::Crate;
121 134
122 #[test] 135 #[test]
123 fn test_loading_rust_analyzer() { 136 fn test_loading_rust_analyzer() -> Result<()> {
124 let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); 137 let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap();
125 let load_cargo_config = LoadCargoConfig { 138 let cargo_config = Default::default();
126 cargo_config: Default::default(), 139 let load_cargo_config =
127 load_out_dirs_from_check: false, 140 LoadCargoConfig { load_out_dirs_from_check: false, with_proc_macro: false };
128 with_proc_macro: false, 141 let (host, _vfs) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {})?;
129 };
130 142
131 let (host, _vfs) = load_cargo(path, &load_cargo_config).unwrap();
132 let n_crates = Crate::all(host.raw_database()).len(); 143 let n_crates = Crate::all(host.raw_database()).len();
133 // RA has quite a few crates, but the exact count doesn't matter 144 // RA has quite a few crates, but the exact count doesn't matter
134 assert!(n_crates > 20); 145 assert!(n_crates > 20);
146
147 Ok(())
135 } 148 }
136} 149}
diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs
index 8729ff0d9..71c61ed58 100644
--- a/crates/rust-analyzer/src/cli/ssr.rs
+++ b/crates/rust-analyzer/src/cli/ssr.rs
@@ -1,19 +1,18 @@
1//! Applies structured search replace rules from the command line. 1//! Applies structured search replace rules from the command line.
2 2
3use crate::cli::{ 3use crate::cli::{
4 load_cargo::{load_cargo, LoadCargoConfig}, 4 load_cargo::{load_workspace_at, LoadCargoConfig},
5 Result, 5 Result,
6}; 6};
7use ssr::{MatchFinder, SsrPattern, SsrRule}; 7use ssr::{MatchFinder, SsrPattern, SsrRule};
8 8
9pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> { 9pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
10 use ide_db::base_db::SourceDatabaseExt; 10 use ide_db::base_db::SourceDatabaseExt;
11 let load_cargo_config = LoadCargoConfig { 11 let cargo_config = Default::default();
12 cargo_config: Default::default(), 12 let load_cargo_config =
13 load_out_dirs_from_check: true, 13 LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro: true };
14 with_proc_macro: true, 14 let (host, vfs) =
15 }; 15 load_workspace_at(&std::env::current_dir()?, &cargo_config, &load_cargo_config, &|_| {})?;
16 let (host, vfs) = load_cargo(&std::env::current_dir()?, &load_cargo_config)?;
17 let db = host.raw_database(); 16 let db = host.raw_database();
18 let mut match_finder = MatchFinder::at_first_file(db)?; 17 let mut match_finder = MatchFinder::at_first_file(db)?;
19 for rule in rules { 18 for rule in rules {
@@ -36,12 +35,11 @@ pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
36pub fn search_for_patterns(patterns: Vec<SsrPattern>, debug_snippet: Option<String>) -> Result<()> { 35pub fn search_for_patterns(patterns: Vec<SsrPattern>, debug_snippet: Option<String>) -> Result<()> {
37 use ide_db::base_db::SourceDatabaseExt; 36 use ide_db::base_db::SourceDatabaseExt;
38 use ide_db::symbol_index::SymbolsDatabase; 37 use ide_db::symbol_index::SymbolsDatabase;
39 let load_cargo_config = LoadCargoConfig { 38 let cargo_config = Default::default();
40 cargo_config: Default::default(), 39 let load_cargo_config =
41 load_out_dirs_from_check: true, 40 LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro: true };
42 with_proc_macro: true, 41 let (host, _vfs) =
43 }; 42 load_workspace_at(&std::env::current_dir()?, &cargo_config, &load_cargo_config, &|_| {})?;
44 let (host, _vfs) = load_cargo(&std::env::current_dir()?, &load_cargo_config)?;
45 let db = host.raw_database(); 43 let db = host.raw_database();
46 let mut match_finder = MatchFinder::at_first_file(db)?; 44 let mut match_finder = MatchFinder::at_first_file(db)?;
47 for pattern in patterns { 45 for pattern in patterns {
diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs
index ee6f2a867..f01548c50 100644
--- a/crates/rust-analyzer/src/diagnostics.rs
+++ b/crates/rust-analyzer/src/diagnostics.rs
@@ -65,6 +65,17 @@ impl DiagnosticCollection {
65 file_id: FileId, 65 file_id: FileId,
66 diagnostics: Vec<lsp_types::Diagnostic>, 66 diagnostics: Vec<lsp_types::Diagnostic>,
67 ) { 67 ) {
68 if let Some(existing_diagnostics) = self.native.get(&file_id) {
69 if existing_diagnostics.len() == diagnostics.len()
70 && diagnostics
71 .iter()
72 .zip(existing_diagnostics)
73 .all(|(new, existing)| are_diagnostics_equal(new, existing))
74 {
75 return;
76 }
77 }
78
68 self.native.insert(file_id, diagnostics); 79 self.native.insert(file_id, diagnostics);
69 self.changes.insert(file_id); 80 self.changes.insert(file_id);
70 } 81 }