Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #15223 - lowr:patch/no-unresolved-field-for-missing, r=HKalbasi
Don't show `unresolved-field` diagnostic for missing names I don't think reporting ``"no field `[missing name]` on type `SomeType`"`` makes much sense because it's a syntax error rather than a semantic error. We already report a syntax error for it and I find it sufficient.
bors 2023-07-06
parent 537f9b3 · parent 827a053 · commit db17f79
-rw-r--r--crates/hir-expand/src/name.rs9
-rw-r--r--crates/hir-ty/src/infer/expr.rs7
-rw-r--r--crates/ide-diagnostics/src/handlers/unresolved_field.rs12
3 files changed, 27 insertions, 1 deletions
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index 01e499f2ae..0ffce333f1 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -96,6 +96,15 @@ impl Name {
Name::new_inline("[missing name]")
}
+ /// Returns true if this is a fake name for things missing in the source code. See
+ /// [`missing()`][Self::missing] for details.
+ ///
+ /// Use this method instead of comparing with `Self::missing()` as missing names
+ /// (ideally should) have a `gensym` semantics.
+ pub fn is_missing(&self) -> bool {
+ self == &Name::missing()
+ }
+
/// Generates a new name which is only equal to itself, by incrementing a counter. Due
/// its implementation, it should not be used in things that salsa considers, like
/// type names or field names, and it should be only used in names of local variables
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 8377eb2349..fd9522e86a 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -1449,6 +1449,13 @@ impl InferenceContext<'_> {
fn infer_field_access(&mut self, tgt_expr: ExprId, receiver: ExprId, name: &Name) -> Ty {
let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none());
+
+ if name.is_missing() {
+ // Bail out early, don't even try to look up field. Also, we don't issue an unresolved
+ // field diagnostic because this is a syntax error rather than a semantic error.
+ return self.err_ty();
+ }
+
match self.lookup_field(&receiver_ty, name) {
Some((ty, field_id, adjustments, is_public)) => {
self.write_expr_adj(receiver, adjustments);
diff --git a/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/crates/ide-diagnostics/src/handlers/unresolved_field.rs
index 94d49d4d48..0758706e45 100644
--- a/crates/ide-diagnostics/src/handlers/unresolved_field.rs
+++ b/crates/ide-diagnostics/src/handlers/unresolved_field.rs
@@ -68,7 +68,10 @@ fn method_fix(
}
#[cfg(test)]
mod tests {
- use crate::tests::check_diagnostics;
+ use crate::{
+ tests::{check_diagnostics, check_diagnostics_with_config},
+ DiagnosticsConfig,
+ };
#[test]
fn smoke_test() {
@@ -146,4 +149,11 @@ fn foo() {
"#,
);
}
+
+ #[test]
+ fn no_diagnostic_for_missing_name() {
+ let mut config = DiagnosticsConfig::test_sample();
+ config.disabled.insert("syntax-error".to_owned());
+ check_diagnostics_with_config(config, "fn foo() { (). }");
+ }
}