diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index c18c1c5873..d9ad8db6f7 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs @@ -1,6 +1,8 @@ //! FIXME: write short doc here pub use hir_def::diagnostics::{InactiveCode, UnresolvedModule}; -pub use hir_expand::diagnostics::{Diagnostic, DiagnosticSink, DiagnosticSinkBuilder}; +pub use hir_expand::diagnostics::{ + Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder, +}; pub use hir_ty::diagnostics::{ IncorrectCase, MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, NoSuchField, diff --git a/crates/hir_expand/src/diagnostics.rs b/crates/hir_expand/src/diagnostics.rs index 78ccc212c8..1043c6aeb5 100644 --- a/crates/hir_expand/src/diagnostics.rs +++ b/crates/hir_expand/src/diagnostics.rs @@ -20,7 +20,7 @@ use syntax::SyntaxNodePtr; use crate::InFile; -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq)] pub struct DiagnosticCode(pub &'static str); impl DiagnosticCode { diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 1c7f027632..3df73ed4fa 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs @@ -10,7 +10,7 @@ mod field_shorthand; use std::cell::RefCell; use hir::{ - diagnostics::{Diagnostic as _, DiagnosticSinkBuilder}, + diagnostics::{Diagnostic as _, DiagnosticCode, DiagnosticSinkBuilder}, Semantics, }; use ide_db::base_db::SourceDatabase; @@ -35,15 +35,23 @@ pub struct Diagnostic { pub severity: Severity, pub fix: Option, pub unused: bool, + pub code: Option, } impl Diagnostic { fn error(range: TextRange, message: String) -> Self { - Self { message, range, severity: Severity::Error, fix: None, unused: false } + Self { message, range, severity: Severity::Error, fix: None, unused: false, code: None } } fn hint(range: TextRange, message: String) -> Self { - Self { message, range, severity: Severity::WeakWarning, fix: None, unused: false } + Self { + message, + range, + severity: Severity::WeakWarning, + fix: None, + unused: false, + code: None, + } } fn with_fix(self, fix: Option) -> Self { @@ -53,6 +61,10 @@ impl Diagnostic { fn with_unused(self, unused: bool) -> Self { Self { unused, ..self } } + + fn with_code(self, code: Option) -> Self { + Self { code, ..self } + } } #[derive(Debug)] @@ -126,7 +138,8 @@ pub(crate) fn diagnostics( // Override severity and mark as unused. res.borrow_mut().push( Diagnostic::hint(sema.diagnostics_display_range(d).range, d.message()) - .with_unused(true), + .with_unused(true) + .with_code(Some(d.code())), ); }) // Only collect experimental diagnostics when they're enabled. @@ -137,8 +150,10 @@ pub(crate) fn diagnostics( let mut sink = sink_builder // Diagnostics not handled above get no fix and default treatment. .build(|d| { - res.borrow_mut() - .push(Diagnostic::error(sema.diagnostics_display_range(d).range, d.message())); + res.borrow_mut().push( + Diagnostic::error(sema.diagnostics_display_range(d).range, d.message()) + .with_code(Some(d.code())), + ); }); if let Some(m) = sema.to_module_def(file_id) { @@ -149,11 +164,15 @@ pub(crate) fn diagnostics( } fn diagnostic_with_fix(d: &D, sema: &Semantics) -> Diagnostic { - Diagnostic::error(sema.diagnostics_display_range(d).range, d.message()).with_fix(d.fix(&sema)) + Diagnostic::error(sema.diagnostics_display_range(d).range, d.message()) + .with_fix(d.fix(&sema)) + .with_code(Some(d.code())) } fn warning_with_fix(d: &D, sema: &Semantics) -> Diagnostic { - Diagnostic::hint(sema.diagnostics_display_range(d).range, d.message()).with_fix(d.fix(&sema)) + Diagnostic::hint(sema.diagnostics_display_range(d).range, d.message()) + .with_fix(d.fix(&sema)) + .with_code(Some(d.code())) } fn check_unnecessary_braces_in_use_statement( @@ -589,6 +608,11 @@ fn test_fn() { }, ), unused: false, + code: Some( + DiagnosticCode( + "unresolved-module", + ), + ), }, ] "#]], diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 782797e85f..a1057cc548 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -18,7 +18,7 @@ use lsp_types::{ CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams, CodeActionKind, CodeLens, Command, CompletionItem, Diagnostic, DiagnosticTag, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams, - HoverContents, Location, Position, PrepareRenameResponse, Range, RenameParams, + HoverContents, Location, NumberOrString, Position, PrepareRenameResponse, Range, RenameParams, SemanticTokensDeltaParams, SemanticTokensFullDeltaResult, SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit, @@ -1127,7 +1127,7 @@ pub(crate) fn publish_diagnostics( .map(|d| Diagnostic { range: to_proto::range(&line_index, d.range), severity: Some(to_proto::diagnostic_severity(d.severity)), - code: None, + code: d.code.map(|d| d.as_str().to_owned()).map(NumberOrString::String), code_description: None, source: Some("rust-analyzer".to_string()), message: d.message,