diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 281386e1364..6f2f70dd40a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -198,6 +198,7 @@ pub enum InferenceDiagnostic { NoSuchField { field: ExprOrPatId, private: bool, + variant: VariantId, }, PrivateField { expr: ExprId, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index d011a62e77a..38076fce8f8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -563,6 +563,7 @@ impl InferenceContext<'_> { InferenceDiagnostic::NoSuchField { field: field.expr.into(), private: true, + variant: def, }, ); } @@ -572,6 +573,7 @@ impl InferenceContext<'_> { self.push_diagnostic(InferenceDiagnostic::NoSuchField { field: field.expr.into(), private: false, + variant: def, }); None } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs index 1b354935a5b..dac5a5ea699 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs @@ -177,6 +177,7 @@ impl InferenceContext<'_> { self.push_diagnostic(InferenceDiagnostic::NoSuchField { field: inner.into(), private: true, + variant: def, }); } let f = field_types[local_id].clone(); @@ -190,6 +191,7 @@ impl InferenceContext<'_> { self.push_diagnostic(InferenceDiagnostic::NoSuchField { field: inner.into(), private: false, + variant: def, }); self.err_ty() } diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs index 4518422d27e..6e3d366c88b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs @@ -9,6 +9,7 @@ use hir_ty::{db::HirDatabase, diagnostics::BodyValidationDiagnostic, InferenceDi use base_db::CrateId; use cfg::{CfgExpr, CfgOptions}; use either::Either; +pub use hir_def::VariantId; use hir_def::{body::SyntheticSyntax, hir::ExprOrPatId, path::ModPath, AssocItemId, DefWithBodyId}; use hir_expand::{name::Name, HirFileId, InFile}; use syntax::{ast, AstPtr, SyntaxError, SyntaxNodePtr, TextRange}; @@ -200,6 +201,7 @@ pub struct MalformedDerive { pub struct NoSuchField { pub field: InFile>>, pub private: bool, + pub variant: VariantId, } #[derive(Debug)] @@ -525,7 +527,7 @@ impl AnyDiagnostic { source_map.pat_syntax(pat).inspect_err(|_| tracing::error!("synthetic syntax")).ok() }; Some(match d { - &InferenceDiagnostic::NoSuchField { field: expr, private } => { + &InferenceDiagnostic::NoSuchField { field: expr, private, variant } => { let expr_or_pat = match expr { ExprOrPatId::ExprId(expr) => { source_map.field_syntax(expr).map(AstPtr::wrap_left) @@ -534,7 +536,7 @@ impl AnyDiagnostic { source_map.pat_field_syntax(pat).map(AstPtr::wrap_right) } }; - NoSuchField { field: expr_or_pat, private }.into() + NoSuchField { field: expr_or_pat, private, variant }.into() } &InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => { MismatchedArgCount { call_expr: expr_syntax(call_expr)?, expected, found }.into() diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs index 8d77e566edc..5a3206445c5 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs @@ -1,5 +1,5 @@ use either::Either; -use hir::{db::ExpandDatabase, HasSource, HirDisplay, HirFileIdExt, Semantics}; +use hir::{db::ExpandDatabase, HasSource, HirDisplay, HirFileIdExt, Semantics, VariantId}; use ide_db::{base_db::FileId, source_change::SourceChange, RootDatabase}; use syntax::{ ast::{self, edit::IndentLevel, make}, @@ -25,7 +25,10 @@ pub(crate) fn no_such_field(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) } else { Diagnostic::new_with_syntax_node_ptr( ctx, - DiagnosticCode::RustcHardError("E0559"), + match d.variant { + VariantId::EnumVariantId(_) => DiagnosticCode::RustcHardError("E0559"), + _ => DiagnosticCode::RustcHardError("E0560"), + }, "no such field", node, )