Auto merge of #17131 - bzy-debug:issue-17107, r=lnicola

different error code of "no such field" error based on variant type

fix #17107

Pass variant information down to diagnostic, so that we can get different error code based on variant type.

After fix:

- structure

  <img width="868" alt="Screenshot 2024-04-23 at 21 03 27" src="https://github.com/rust-lang/rust-analyzer/assets/71200607/c2d1e389-5b62-4e9a-a133-9ae41f80615f">

- enum's structure variant

  <img width="937" alt="Screenshot 2024-04-23 at 21 04 41" src="https://github.com/rust-lang/rust-analyzer/assets/71200607/ad8558a7-d809-4968-b290-2f6bbb8d6b8c">
This commit is contained in:
bors 2024-04-24 07:46:09 +00:00
commit 73a427588a
5 changed files with 14 additions and 4 deletions

View file

@ -198,6 +198,7 @@ pub enum InferenceDiagnostic {
NoSuchField {
field: ExprOrPatId,
private: bool,
variant: VariantId,
},
PrivateField {
expr: ExprId,

View file

@ -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
}

View file

@ -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()
}

View file

@ -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<AstPtr<Either<ast::RecordExprField, ast::RecordPatField>>>,
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()

View file

@ -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,
)