aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide/src/diagnostics.rs74
-rw-r--r--crates/ide/src/lib.rs13
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs7
-rw-r--r--crates/rust-analyzer/src/cli/diagnostics.rs5
-rw-r--r--crates/rust-analyzer/src/config.rs39
-rw-r--r--crates/rust-analyzer/src/diagnostics.rs2
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs18
-rw-r--r--crates/rust-analyzer/src/handlers.rs13
-rw-r--r--crates/rust-analyzer/src/main_loop.rs2
-rw-r--r--editors/code/package.json12
10 files changed, 90 insertions, 95 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs
index 606a6064b..89ff55490 100644
--- a/crates/ide/src/diagnostics.rs
+++ b/crates/ide/src/diagnostics.rs
@@ -4,12 +4,15 @@
4//! macro-expanded files, but we need to present them to the users in terms of 4//! macro-expanded files, but we need to present them to the users in terms of
5//! original files. So we need to map the ranges. 5//! original files. So we need to map the ranges.
6 6
7use std::{cell::RefCell, collections::HashSet}; 7mod diagnostics_with_fix;
8
9use std::cell::RefCell;
8 10
9use base_db::SourceDatabase; 11use base_db::SourceDatabase;
10use hir::{diagnostics::DiagnosticSinkBuilder, Semantics}; 12use hir::{diagnostics::DiagnosticSinkBuilder, Semantics};
11use ide_db::RootDatabase; 13use ide_db::RootDatabase;
12use itertools::Itertools; 14use itertools::Itertools;
15use rustc_hash::FxHashSet;
13use syntax::{ 16use syntax::{
14 ast::{self, AstNode}, 17 ast::{self, AstNode},
15 SyntaxNode, TextRange, T, 18 SyntaxNode, TextRange, T,
@@ -18,8 +21,7 @@ use text_edit::TextEdit;
18 21
19use crate::{Diagnostic, FileId, Fix, SourceFileEdit}; 22use crate::{Diagnostic, FileId, Fix, SourceFileEdit};
20 23
21mod diagnostics_with_fix; 24use self::diagnostics_with_fix::DiagnosticWithFix;
22use diagnostics_with_fix::DiagnosticWithFix;
23 25
24#[derive(Debug, Copy, Clone)] 26#[derive(Debug, Copy, Clone)]
25pub enum Severity { 27pub enum Severity {
@@ -27,11 +29,16 @@ pub enum Severity {
27 WeakWarning, 29 WeakWarning,
28} 30}
29 31
32#[derive(Default, Debug, Clone)]
33pub struct DiagnosticsConfig {
34 pub disable_experimental: bool,
35 pub disabled: FxHashSet<String>,
36}
37
30pub(crate) fn diagnostics( 38pub(crate) fn diagnostics(
31 db: &RootDatabase, 39 db: &RootDatabase,
40 config: &DiagnosticsConfig,
32 file_id: FileId, 41 file_id: FileId,
33 enable_experimental: bool,
34 disabled_diagnostics: Option<HashSet<String>>,
35) -> Vec<Diagnostic> { 42) -> Vec<Diagnostic> {
36 let _p = profile::span("diagnostics"); 43 let _p = profile::span("diagnostics");
37 let sema = Semantics::new(db); 44 let sema = Semantics::new(db);
@@ -52,7 +59,7 @@ pub(crate) fn diagnostics(
52 check_struct_shorthand_initialization(&mut res, file_id, &node); 59 check_struct_shorthand_initialization(&mut res, file_id, &node);
53 } 60 }
54 let res = RefCell::new(res); 61 let res = RefCell::new(res);
55 let mut sink_builder = DiagnosticSinkBuilder::new() 62 let sink_builder = DiagnosticSinkBuilder::new()
56 .on::<hir::diagnostics::UnresolvedModule, _>(|d| { 63 .on::<hir::diagnostics::UnresolvedModule, _>(|d| {
57 res.borrow_mut().push(diagnostic_with_fix(d, &sema)); 64 res.borrow_mut().push(diagnostic_with_fix(d, &sema));
58 }) 65 })
@@ -66,12 +73,8 @@ pub(crate) fn diagnostics(
66 res.borrow_mut().push(diagnostic_with_fix(d, &sema)); 73 res.borrow_mut().push(diagnostic_with_fix(d, &sema));
67 }) 74 })
68 // Only collect experimental diagnostics when they're enabled. 75 // Only collect experimental diagnostics when they're enabled.
69 .filter(|diag| !diag.is_experimental() || enable_experimental); 76 .filter(|diag| !(diag.is_experimental() && config.disable_experimental))
70 77 .filter(|diag| !config.disabled.contains(diag.name()));
71 if let Some(disabled_diagnostics) = disabled_diagnostics {
72 // Do not collect disabled diagnostics.
73 sink_builder = sink_builder.filter(move |diag| !disabled_diagnostics.contains(diag.name()));
74 }
75 78
76 // Finalize the `DiagnosticSink` building process. 79 // Finalize the `DiagnosticSink` building process.
77 let mut sink = sink_builder 80 let mut sink = sink_builder
@@ -187,12 +190,14 @@ fn check_struct_shorthand_initialization(
187 190
188#[cfg(test)] 191#[cfg(test)]
189mod tests { 192mod tests {
190 use std::collections::HashSet; 193 use expect::{expect, Expect};
191 use stdx::trim_indent; 194 use stdx::trim_indent;
192 use test_utils::assert_eq_text; 195 use test_utils::assert_eq_text;
193 196
194 use crate::mock_analysis::{analysis_and_position, single_file, MockAnalysis}; 197 use crate::{
195 use expect::{expect, Expect}; 198 mock_analysis::{analysis_and_position, single_file, MockAnalysis},
199 DiagnosticsConfig,
200 };
196 201
197 /// Takes a multi-file input fixture with annotated cursor positions, 202 /// Takes a multi-file input fixture with annotated cursor positions,
198 /// and checks that: 203 /// and checks that:
@@ -203,8 +208,11 @@ mod tests {
203 let after = trim_indent(ra_fixture_after); 208 let after = trim_indent(ra_fixture_after);
204 209
205 let (analysis, file_position) = analysis_and_position(ra_fixture_before); 210 let (analysis, file_position) = analysis_and_position(ra_fixture_before);
206 let diagnostic = 211 let diagnostic = analysis
207 analysis.diagnostics(file_position.file_id, true, None).unwrap().pop().unwrap(); 212 .diagnostics(&DiagnosticsConfig::default(), file_position.file_id)
213 .unwrap()
214 .pop()
215 .unwrap();
208 let mut fix = diagnostic.fix.unwrap(); 216 let mut fix = diagnostic.fix.unwrap();
209 let edit = fix.source_change.source_file_edits.pop().unwrap().edit; 217 let edit = fix.source_change.source_file_edits.pop().unwrap().edit;
210 let target_file_contents = analysis.file_text(file_position.file_id).unwrap(); 218 let target_file_contents = analysis.file_text(file_position.file_id).unwrap();
@@ -230,7 +238,11 @@ mod tests {
230 let ra_fixture_after = &trim_indent(ra_fixture_after); 238 let ra_fixture_after = &trim_indent(ra_fixture_after);
231 let (analysis, file_pos) = analysis_and_position(ra_fixture_before); 239 let (analysis, file_pos) = analysis_and_position(ra_fixture_before);
232 let current_file_id = file_pos.file_id; 240 let current_file_id = file_pos.file_id;
233 let diagnostic = analysis.diagnostics(current_file_id, true, None).unwrap().pop().unwrap(); 241 let diagnostic = analysis
242 .diagnostics(&DiagnosticsConfig::default(), current_file_id)
243 .unwrap()
244 .pop()
245 .unwrap();
234 let mut fix = diagnostic.fix.unwrap(); 246 let mut fix = diagnostic.fix.unwrap();
235 let edit = fix.source_change.source_file_edits.pop().unwrap(); 247 let edit = fix.source_change.source_file_edits.pop().unwrap();
236 let changed_file_id = edit.file_id; 248 let changed_file_id = edit.file_id;
@@ -251,7 +263,9 @@ mod tests {
251 let analysis = mock.analysis(); 263 let analysis = mock.analysis();
252 let diagnostics = files 264 let diagnostics = files
253 .into_iter() 265 .into_iter()
254 .flat_map(|file_id| analysis.diagnostics(file_id, true, None).unwrap()) 266 .flat_map(|file_id| {
267 analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap()
268 })
255 .collect::<Vec<_>>(); 269 .collect::<Vec<_>>();
256 assert_eq!(diagnostics.len(), 0, "unexpected diagnostics:\n{:#?}", diagnostics); 270 assert_eq!(diagnostics.len(), 0, "unexpected diagnostics:\n{:#?}", diagnostics);
257 } 271 }
@@ -259,8 +273,8 @@ mod tests {
259 /// Takes a multi-file input fixture with annotated cursor position and the list of disabled diagnostics, 273 /// Takes a multi-file input fixture with annotated cursor position and the list of disabled diagnostics,
260 /// and checks that provided diagnostics aren't spawned during analysis. 274 /// and checks that provided diagnostics aren't spawned during analysis.
261 fn check_disabled_diagnostics(ra_fixture: &str, disabled_diagnostics: &[&'static str]) { 275 fn check_disabled_diagnostics(ra_fixture: &str, disabled_diagnostics: &[&'static str]) {
262 let disabled_diagnostics: HashSet<_> = 276 let mut config = DiagnosticsConfig::default();
263 disabled_diagnostics.into_iter().map(|diag| diag.to_string()).collect(); 277 config.disabled = disabled_diagnostics.into_iter().map(|diag| diag.to_string()).collect();
264 278
265 let mock = MockAnalysis::with_files(ra_fixture); 279 let mock = MockAnalysis::with_files(ra_fixture);
266 let files = mock.files().map(|(it, _)| it).collect::<Vec<_>>(); 280 let files = mock.files().map(|(it, _)| it).collect::<Vec<_>>();
@@ -269,15 +283,17 @@ mod tests {
269 let diagnostics = files 283 let diagnostics = files
270 .clone() 284 .clone()
271 .into_iter() 285 .into_iter()
272 .flat_map(|file_id| { 286 .flat_map(|file_id| analysis.diagnostics(&config, file_id).unwrap())
273 analysis.diagnostics(file_id, true, Some(disabled_diagnostics.clone())).unwrap()
274 })
275 .collect::<Vec<_>>(); 287 .collect::<Vec<_>>();
276 288
277 // First, we have to check that diagnostic is not emitted when it's added to the disabled diagnostics list. 289 // First, we have to check that diagnostic is not emitted when it's added to the disabled diagnostics list.
278 for diagnostic in diagnostics { 290 for diagnostic in diagnostics {
279 if let Some(name) = diagnostic.name { 291 if let Some(name) = diagnostic.name {
280 assert!(!disabled_diagnostics.contains(&name), "Diagnostic {} is disabled", name); 292 assert!(
293 !disabled_diagnostics.contains(&name.as_str()),
294 "Diagnostic {} is disabled",
295 name
296 );
281 } 297 }
282 } 298 }
283 299
@@ -288,21 +304,23 @@ mod tests {
288 // will no longer exist. 304 // will no longer exist.
289 let diagnostics = files 305 let diagnostics = files
290 .into_iter() 306 .into_iter()
291 .flat_map(|file_id| analysis.diagnostics(file_id, true, None).unwrap()) 307 .flat_map(|file_id| {
308 analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap()
309 })
292 .collect::<Vec<_>>(); 310 .collect::<Vec<_>>();
293 311
294 assert!( 312 assert!(
295 diagnostics 313 diagnostics
296 .into_iter() 314 .into_iter()
297 .filter_map(|diag| diag.name) 315 .filter_map(|diag| diag.name)
298 .any(|name| disabled_diagnostics.contains(&name)), 316 .any(|name| disabled_diagnostics.contains(&name.as_str())),
299 "At least one of the diagnostics was not emitted even without config; are the diagnostics names correct?" 317 "At least one of the diagnostics was not emitted even without config; are the diagnostics names correct?"
300 ); 318 );
301 } 319 }
302 320
303 fn check_expect(ra_fixture: &str, expect: Expect) { 321 fn check_expect(ra_fixture: &str, expect: Expect) {
304 let (analysis, file_id) = single_file(ra_fixture); 322 let (analysis, file_id) = single_file(ra_fixture);
305 let diagnostics = analysis.diagnostics(file_id, true, None).unwrap(); 323 let diagnostics = analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap();
306 expect.assert_debug_eq(&diagnostics) 324 expect.assert_debug_eq(&diagnostics)
307 } 325 }
308 326
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 4b797f374..2a73abba2 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -44,7 +44,7 @@ mod syntax_highlighting;
44mod syntax_tree; 44mod syntax_tree;
45mod typing; 45mod typing;
46 46
47use std::{collections::HashSet, sync::Arc}; 47use std::sync::Arc;
48 48
49use base_db::{ 49use base_db::{
50 salsa::{self, ParallelDatabase}, 50 salsa::{self, ParallelDatabase},
@@ -65,7 +65,7 @@ pub use crate::{
65 completion::{ 65 completion::{
66 CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat, 66 CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat,
67 }, 67 },
68 diagnostics::Severity, 68 diagnostics::{DiagnosticsConfig, Severity},
69 display::NavigationTarget, 69 display::NavigationTarget,
70 expand_macro::ExpandedMacro, 70 expand_macro::ExpandedMacro,
71 file_structure::StructureNode, 71 file_structure::StructureNode,
@@ -148,7 +148,7 @@ pub struct AnalysisHost {
148} 148}
149 149
150impl AnalysisHost { 150impl AnalysisHost {
151 pub fn new(lru_capacity: Option<usize>) -> Self { 151 pub fn new(lru_capacity: Option<usize>) -> AnalysisHost {
152 AnalysisHost { db: RootDatabase::new(lru_capacity) } 152 AnalysisHost { db: RootDatabase::new(lru_capacity) }
153 } 153 }
154 154
@@ -495,13 +495,10 @@ impl Analysis {
495 /// Computes the set of diagnostics for the given file. 495 /// Computes the set of diagnostics for the given file.
496 pub fn diagnostics( 496 pub fn diagnostics(
497 &self, 497 &self,
498 config: &DiagnosticsConfig,
498 file_id: FileId, 499 file_id: FileId,
499 enable_experimental: bool,
500 disabled_diagnostics: Option<HashSet<String>>,
501 ) -> Cancelable<Vec<Diagnostic>> { 500 ) -> Cancelable<Vec<Diagnostic>> {
502 self.with_db(|db| { 501 self.with_db(|db| diagnostics::diagnostics(db, config, file_id))
503 diagnostics::diagnostics(db, file_id, enable_experimental, disabled_diagnostics)
504 })
505 } 502 }
506 503
507 /// Returns the edit required to rename reference at the position to the new 504 /// Returns the edit required to rename reference at the position to the new
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs
index 43f0196af..c312e0a2e 100644
--- a/crates/rust-analyzer/src/cli/analysis_bench.rs
+++ b/crates/rust-analyzer/src/cli/analysis_bench.rs
@@ -7,7 +7,10 @@ use base_db::{
7 salsa::{Database, Durability}, 7 salsa::{Database, Durability},
8 FileId, 8 FileId,
9}; 9};
10use ide::{Analysis, AnalysisChange, AnalysisHost, CompletionConfig, FilePosition, LineCol}; 10use ide::{
11 Analysis, AnalysisChange, AnalysisHost, CompletionConfig, DiagnosticsConfig, FilePosition,
12 LineCol,
13};
11use vfs::AbsPathBuf; 14use vfs::AbsPathBuf;
12 15
13use crate::{ 16use crate::{
@@ -71,7 +74,7 @@ impl BenchCmd {
71 match &self.what { 74 match &self.what {
72 BenchWhat::Highlight { .. } => { 75 BenchWhat::Highlight { .. } => {
73 let res = do_work(&mut host, file_id, |analysis| { 76 let res = do_work(&mut host, file_id, |analysis| {
74 analysis.diagnostics(file_id, true, None).unwrap(); 77 analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap();
75 analysis.highlight_as_html(file_id, false).unwrap() 78 analysis.highlight_as_html(file_id, false).unwrap()
76 }); 79 });
77 if verbosity.is_verbose() { 80 if verbosity.is_verbose() {
diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs
index 31eb7ff3f..c424aa6e2 100644
--- a/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -8,7 +8,7 @@ use rustc_hash::FxHashSet;
8 8
9use base_db::SourceDatabaseExt; 9use base_db::SourceDatabaseExt;
10use hir::Crate; 10use hir::Crate;
11use ide::Severity; 11use ide::{DiagnosticsConfig, Severity};
12 12
13use crate::cli::{load_cargo::load_cargo, Result}; 13use crate::cli::{load_cargo::load_cargo, Result};
14 14
@@ -47,7 +47,8 @@ pub fn diagnostics(
47 String::from("unknown") 47 String::from("unknown")
48 }; 48 };
49 println!("processing crate: {}, module: {}", crate_name, _vfs.file_path(file_id)); 49 println!("processing crate: {}, module: {}", crate_name, _vfs.file_path(file_id));
50 for diagnostic in analysis.diagnostics(file_id, true, None).unwrap() { 50 for diagnostic in analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap()
51 {
51 if matches!(diagnostic.severity, Severity::Error) { 52 if matches!(diagnostic.severity, Severity::Error) {
52 found_error = true; 53 found_error = true;
53 } 54 }
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 44fd7c286..99f7751ac 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -7,24 +7,25 @@
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::{collections::HashSet, ffi::OsString, path::PathBuf}; 10use std::{ffi::OsString, path::PathBuf};
11 11
12use flycheck::FlycheckConfig; 12use flycheck::FlycheckConfig;
13use ide::{AssistConfig, CompletionConfig, HoverConfig, InlayHintsConfig}; 13use ide::{AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig};
14use lsp_types::ClientCapabilities; 14use lsp_types::ClientCapabilities;
15use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest}; 15use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest};
16use rustc_hash::FxHashSet;
16use serde::Deserialize; 17use serde::Deserialize;
17use vfs::AbsPathBuf; 18use vfs::AbsPathBuf;
18 19
19use crate::diagnostics::DiagnosticsConfig; 20use crate::diagnostics::DiagnosticsMapConfig;
20 21
21#[derive(Debug, Clone)] 22#[derive(Debug, Clone)]
22pub struct Config { 23pub struct Config {
23 pub client_caps: ClientCapsConfig, 24 pub client_caps: ClientCapsConfig,
24 25
25 pub publish_diagnostics: bool, 26 pub publish_diagnostics: bool,
26 pub experimental_diagnostics: bool,
27 pub diagnostics: DiagnosticsConfig, 27 pub diagnostics: DiagnosticsConfig,
28 pub diagnostics_map: DiagnosticsMapConfig,
28 pub lru_capacity: Option<usize>, 29 pub lru_capacity: Option<usize>,
29 pub proc_macro_srv: Option<(PathBuf, Vec<OsString>)>, 30 pub proc_macro_srv: Option<(PathBuf, Vec<OsString>)>,
30 pub files: FilesConfig, 31 pub files: FilesConfig,
@@ -45,14 +46,6 @@ pub struct Config {
45 pub with_sysroot: bool, 46 pub with_sysroot: bool,
46 pub linked_projects: Vec<LinkedProject>, 47 pub linked_projects: Vec<LinkedProject>,
47 pub root_path: AbsPathBuf, 48 pub root_path: AbsPathBuf,
48
49 pub analysis: AnalysisConfig,
50}
51
52/// Configuration parameters for the analysis run.
53#[derive(Debug, Default, Clone)]
54pub struct AnalysisConfig {
55 pub disabled_diagnostics: HashSet<String>,
56} 49}
57 50
58#[derive(Debug, Clone, Eq, PartialEq)] 51#[derive(Debug, Clone, Eq, PartialEq)]
@@ -146,8 +139,8 @@ impl Config {
146 139
147 with_sysroot: true, 140 with_sysroot: true,
148 publish_diagnostics: true, 141 publish_diagnostics: true,
149 experimental_diagnostics: true,
150 diagnostics: DiagnosticsConfig::default(), 142 diagnostics: DiagnosticsConfig::default(),
143 diagnostics_map: DiagnosticsMapConfig::default(),
151 lru_capacity: None, 144 lru_capacity: None,
152 proc_macro_srv: None, 145 proc_macro_srv: None,
153 files: FilesConfig { watcher: FilesWatcher::Notify, exclude: Vec::new() }, 146 files: FilesConfig { watcher: FilesWatcher::Notify, exclude: Vec::new() },
@@ -184,8 +177,6 @@ impl Config {
184 hover: HoverConfig::default(), 177 hover: HoverConfig::default(),
185 linked_projects: Vec::new(), 178 linked_projects: Vec::new(),
186 root_path, 179 root_path,
187
188 analysis: AnalysisConfig::default(),
189 } 180 }
190 } 181 }
191 182
@@ -200,8 +191,11 @@ impl Config {
200 191
201 self.with_sysroot = data.withSysroot; 192 self.with_sysroot = data.withSysroot;
202 self.publish_diagnostics = data.diagnostics_enable; 193 self.publish_diagnostics = data.diagnostics_enable;
203 self.experimental_diagnostics = data.diagnostics_enableExperimental;
204 self.diagnostics = DiagnosticsConfig { 194 self.diagnostics = DiagnosticsConfig {
195 disable_experimental: !data.diagnostics_enableExperimental,
196 disabled: data.diagnostics_disabled,
197 };
198 self.diagnostics_map = DiagnosticsMapConfig {
205 warnings_as_info: data.diagnostics_warningsAsInfo, 199 warnings_as_info: data.diagnostics_warningsAsInfo,
206 warnings_as_hint: data.diagnostics_warningsAsHint, 200 warnings_as_hint: data.diagnostics_warningsAsHint,
207 }; 201 };
@@ -303,8 +297,6 @@ impl Config {
303 goto_type_def: data.hoverActions_enable && data.hoverActions_gotoTypeDef, 297 goto_type_def: data.hoverActions_enable && data.hoverActions_gotoTypeDef,
304 }; 298 };
305 299
306 self.analysis = AnalysisConfig { disabled_diagnostics: data.analysis_disabledDiagnostics };
307
308 log::info!("Config::update() = {:#?}", self); 300 log::info!("Config::update() = {:#?}", self);
309 } 301 }
310 302
@@ -369,14 +361,6 @@ impl Config {
369 self.client_caps.status_notification = get_bool("statusNotification"); 361 self.client_caps.status_notification = get_bool("statusNotification");
370 } 362 }
371 } 363 }
372
373 pub fn disabled_diagnostics(&self) -> Option<HashSet<String>> {
374 if self.analysis.disabled_diagnostics.is_empty() {
375 None
376 } else {
377 Some(self.analysis.disabled_diagnostics.clone())
378 }
379 }
380} 364}
381 365
382#[derive(Deserialize)] 366#[derive(Deserialize)]
@@ -434,6 +418,7 @@ config_data! {
434 418
435 diagnostics_enable: bool = true, 419 diagnostics_enable: bool = true,
436 diagnostics_enableExperimental: bool = true, 420 diagnostics_enableExperimental: bool = true,
421 diagnostics_disabled: FxHashSet<String> = FxHashSet::default(),
437 diagnostics_warningsAsHint: Vec<String> = Vec::new(), 422 diagnostics_warningsAsHint: Vec<String> = Vec::new(),
438 diagnostics_warningsAsInfo: Vec<String> = Vec::new(), 423 diagnostics_warningsAsInfo: Vec<String> = Vec::new(),
439 424
@@ -464,7 +449,5 @@ config_data! {
464 rustfmt_overrideCommand: Option<Vec<String>> = None, 449 rustfmt_overrideCommand: Option<Vec<String>> = None,
465 450
466 withSysroot: bool = true, 451 withSysroot: bool = true,
467
468 analysis_disabledDiagnostics: HashSet<String> = HashSet::new(),
469 } 452 }
470} 453}
diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs
index 108df3eb0..ee6f2a867 100644
--- a/crates/rust-analyzer/src/diagnostics.rs
+++ b/crates/rust-analyzer/src/diagnostics.rs
@@ -11,7 +11,7 @@ use crate::lsp_ext;
11pub(crate) type CheckFixes = Arc<FxHashMap<FileId, Vec<Fix>>>; 11pub(crate) type CheckFixes = Arc<FxHashMap<FileId, Vec<Fix>>>;
12 12
13#[derive(Debug, Default, Clone)] 13#[derive(Debug, Default, Clone)]
14pub struct DiagnosticsConfig { 14pub struct DiagnosticsMapConfig {
15 pub warnings_as_info: Vec<String>, 15 pub warnings_as_info: Vec<String>,
16 pub warnings_as_hint: Vec<String>, 16 pub warnings_as_hint: Vec<String>,
17} 17}
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index 6d5408156..df5583897 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -7,11 +7,11 @@ use stdx::format_to;
7 7
8use crate::{lsp_ext, to_proto::url_from_abs_path}; 8use crate::{lsp_ext, to_proto::url_from_abs_path};
9 9
10use super::DiagnosticsConfig; 10use super::DiagnosticsMapConfig;
11 11
12/// Determines the LSP severity from a diagnostic 12/// Determines the LSP severity from a diagnostic
13fn diagnostic_severity( 13fn diagnostic_severity(
14 config: &DiagnosticsConfig, 14 config: &DiagnosticsMapConfig,
15 level: flycheck::DiagnosticLevel, 15 level: flycheck::DiagnosticLevel,
16 code: Option<flycheck::DiagnosticCode>, 16 code: Option<flycheck::DiagnosticCode>,
17) -> Option<lsp_types::DiagnosticSeverity> { 17) -> Option<lsp_types::DiagnosticSeverity> {
@@ -141,7 +141,7 @@ pub(crate) struct MappedRustDiagnostic {
141/// 141///
142/// If the diagnostic has no primary span this will return `None` 142/// If the diagnostic has no primary span this will return `None`
143pub(crate) fn map_rust_diagnostic_to_lsp( 143pub(crate) fn map_rust_diagnostic_to_lsp(
144 config: &DiagnosticsConfig, 144 config: &DiagnosticsMapConfig,
145 rd: &flycheck::Diagnostic, 145 rd: &flycheck::Diagnostic,
146 workspace_root: &Path, 146 workspace_root: &Path,
147) -> Vec<MappedRustDiagnostic> { 147) -> Vec<MappedRustDiagnostic> {
@@ -259,10 +259,10 @@ mod tests {
259 use expect::{expect_file, ExpectFile}; 259 use expect::{expect_file, ExpectFile};
260 260
261 fn check(diagnostics_json: &str, expect: ExpectFile) { 261 fn check(diagnostics_json: &str, expect: ExpectFile) {
262 check_with_config(DiagnosticsConfig::default(), diagnostics_json, expect) 262 check_with_config(DiagnosticsMapConfig::default(), diagnostics_json, expect)
263 } 263 }
264 264
265 fn check_with_config(config: DiagnosticsConfig, diagnostics_json: &str, expect: ExpectFile) { 265 fn check_with_config(config: DiagnosticsMapConfig, diagnostics_json: &str, expect: ExpectFile) {
266 let diagnostic: flycheck::Diagnostic = serde_json::from_str(diagnostics_json).unwrap(); 266 let diagnostic: flycheck::Diagnostic = serde_json::from_str(diagnostics_json).unwrap();
267 let workspace_root = Path::new("/test/"); 267 let workspace_root = Path::new("/test/");
268 let actual = map_rust_diagnostic_to_lsp(&config, &diagnostic, workspace_root); 268 let actual = map_rust_diagnostic_to_lsp(&config, &diagnostic, workspace_root);
@@ -402,9 +402,9 @@ mod tests {
402 #[cfg(not(windows))] 402 #[cfg(not(windows))]
403 fn rustc_unused_variable_as_info() { 403 fn rustc_unused_variable_as_info() {
404 check_with_config( 404 check_with_config(
405 DiagnosticsConfig { 405 DiagnosticsMapConfig {
406 warnings_as_info: vec!["unused_variables".to_string()], 406 warnings_as_info: vec!["unused_variables".to_string()],
407 ..DiagnosticsConfig::default() 407 ..DiagnosticsMapConfig::default()
408 }, 408 },
409 r##"{ 409 r##"{
410 "message": "unused variable: `foo`", 410 "message": "unused variable: `foo`",
@@ -486,9 +486,9 @@ mod tests {
486 #[cfg(not(windows))] 486 #[cfg(not(windows))]
487 fn rustc_unused_variable_as_hint() { 487 fn rustc_unused_variable_as_hint() {
488 check_with_config( 488 check_with_config(
489 DiagnosticsConfig { 489 DiagnosticsMapConfig {
490 warnings_as_hint: vec!["unused_variables".to_string()], 490 warnings_as_hint: vec!["unused_variables".to_string()],
491 ..DiagnosticsConfig::default() 491 ..DiagnosticsMapConfig::default()
492 }, 492 },
493 r##"{ 493 r##"{
494 "message": "unused variable: `foo`", 494 "message": "unused variable: `foo`",
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 6510e8ccc..67ca9f055 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -775,11 +775,7 @@ fn handle_fixes(
775 None => {} 775 None => {}
776 }; 776 };
777 777
778 let diagnostics = snap.analysis.diagnostics( 778 let diagnostics = snap.analysis.diagnostics(&snap.config.diagnostics, file_id)?;
779 file_id,
780 snap.config.experimental_diagnostics,
781 snap.config.disabled_diagnostics(),
782 )?;
783 779
784 for fix in diagnostics 780 for fix in diagnostics
785 .into_iter() 781 .into_iter()
@@ -1051,13 +1047,10 @@ pub(crate) fn publish_diagnostics(
1051) -> Result<Vec<Diagnostic>> { 1047) -> Result<Vec<Diagnostic>> {
1052 let _p = profile::span("publish_diagnostics"); 1048 let _p = profile::span("publish_diagnostics");
1053 let line_index = snap.analysis.file_line_index(file_id)?; 1049 let line_index = snap.analysis.file_line_index(file_id)?;
1050
1054 let diagnostics: Vec<Diagnostic> = snap 1051 let diagnostics: Vec<Diagnostic> = snap
1055 .analysis 1052 .analysis
1056 .diagnostics( 1053 .diagnostics(&snap.config.diagnostics, file_id)?
1057 file_id,
1058 snap.config.experimental_diagnostics,
1059 snap.config.disabled_diagnostics(),
1060 )?
1061 .into_iter() 1054 .into_iter()
1062 .map(|d| Diagnostic { 1055 .map(|d| Diagnostic {
1063 range: to_proto::range(&line_index, d.range), 1056 range: to_proto::range(&line_index, d.range),
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 66e04653a..f039cdc31 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -248,7 +248,7 @@ impl GlobalState {
248 Event::Flycheck(task) => match task { 248 Event::Flycheck(task) => match task {
249 flycheck::Message::AddDiagnostic { workspace_root, diagnostic } => { 249 flycheck::Message::AddDiagnostic { workspace_root, diagnostic } => {
250 let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( 250 let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
251 &self.config.diagnostics, 251 &self.config.diagnostics_map,
252 &diagnostic, 252 &diagnostic,
253 &workspace_root, 253 &workspace_root,
254 ); 254 );
diff --git a/editors/code/package.json b/editors/code/package.json
index 429ff5def..f079f73b8 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -592,31 +592,31 @@
592 "default": true, 592 "default": true,
593 "markdownDescription": "Whether to show experimental rust-analyzer diagnostics that might have more false positives than usual." 593 "markdownDescription": "Whether to show experimental rust-analyzer diagnostics that might have more false positives than usual."
594 }, 594 },
595 "rust-analyzer.diagnostics.warningsAsInfo": { 595 "rust-analyzer.diagnostics.disabled": {
596 "type": "array", 596 "type": "array",
597 "uniqueItems": true, 597 "uniqueItems": true,
598 "items": { 598 "items": {
599 "type": "string" 599 "type": "string"
600 }, 600 },
601 "description": "List of warnings that should be displayed with info severity.\nThe warnings will be indicated by a blue squiggly underline in code and a blue icon in the problems panel.", 601 "description": "List of rust-analyzer diagnostics to disable",
602 "default": [] 602 "default": []
603 }, 603 },
604 "rust-analyzer.diagnostics.warningsAsHint": { 604 "rust-analyzer.diagnostics.warningsAsInfo": {
605 "type": "array", 605 "type": "array",
606 "uniqueItems": true, 606 "uniqueItems": true,
607 "items": { 607 "items": {
608 "type": "string" 608 "type": "string"
609 }, 609 },
610 "description": "List of warnings that should be displayed with hint severity.\nThe warnings will be indicated by faded text or three dots in code and will not show up in the problems panel.", 610 "description": "List of warnings that should be displayed with info severity.\nThe warnings will be indicated by a blue squiggly underline in code and a blue icon in the problems panel.",
611 "default": [] 611 "default": []
612 }, 612 },
613 "rust-analyzer.analysis.disabledDiagnostics": { 613 "rust-analyzer.diagnostics.warningsAsHint": {
614 "type": "array", 614 "type": "array",
615 "uniqueItems": true, 615 "uniqueItems": true,
616 "items": { 616 "items": {
617 "type": "string" 617 "type": "string"
618 }, 618 },
619 "description": "List of rust-analyzer diagnostics to disable", 619 "description": "List of warnings that should be displayed with hint severity.\nThe warnings will be indicated by faded text or three dots in code and will not show up in the problems panel.",
620 "default": [] 620 "default": []
621 } 621 }
622 } 622 }