Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #16222 - rosefromthedead:unresolved-assoc-item, r=Veykril
add unresolved-assoc-item assist I tried to copy from private-assoc-item for this
bors 2024-01-02
parent 86e559b · parent 5878651 · commit 426d284
-rw-r--r--crates/hir-ty/src/infer.rs3
-rw-r--r--crates/hir-ty/src/infer/path.rs3
-rw-r--r--crates/hir/src/diagnostics.rs6
-rw-r--r--crates/hir/src/lib.rs7
-rw-r--r--crates/ide-diagnostics/src/handlers/unresolved_assoc_item.rs52
-rw-r--r--crates/ide-diagnostics/src/lib.rs4
6 files changed, 74 insertions, 1 deletions
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 428cedbb49..8053300ad2 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -219,6 +219,9 @@ pub enum InferenceDiagnostic {
field_with_same_name: Option<Ty>,
assoc_func_with_same_name: Option<AssocItemId>,
},
+ UnresolvedAssocItem {
+ id: ExprOrPatId,
+ },
// FIXME: This should be emitted in body lowering
BreakOutsideOfLoop {
expr: ExprId,
diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs
index 49fb78f67a..e61a070265 100644
--- a/crates/hir-ty/src/infer/path.rs
+++ b/crates/hir-ty/src/infer/path.rs
@@ -340,6 +340,9 @@ impl InferenceContext<'_> {
},
);
let res = res.or(not_visible);
+ if res.is_none() {
+ self.push_diagnostic(InferenceDiagnostic::UnresolvedAssocItem { id });
+ }
let (item, visible) = res?;
let (def, container) = match item {
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index ba591e1892..bf29a53913 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -62,6 +62,7 @@ diagnostics![
UndeclaredLabel,
UnimplementedBuiltinMacro,
UnreachableLabel,
+ UnresolvedAssocItem,
UnresolvedExternCrate,
UnresolvedField,
UnresolvedImport,
@@ -219,6 +220,11 @@ pub struct UnresolvedMethodCall {
}
#[derive(Debug)]
+pub struct UnresolvedAssocItem {
+ pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, Either<ast::Pat, ast::SelfParam>>>>,
+}
+
+#[derive(Debug)]
pub struct PrivateField {
pub expr: InFile<AstPtr<ast::Expr>>,
pub field: Field,
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 087404ccb0..09b56e1382 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1697,6 +1697,13 @@ impl DefWithBody {
.into(),
)
}
+ &hir_ty::InferenceDiagnostic::UnresolvedAssocItem { id } => {
+ let expr_or_pat = match id {
+ ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(AstPtr::wrap_left),
+ ExprOrPatId::PatId(pat) => pat_syntax(pat).map(AstPtr::wrap_right),
+ };
+ acc.push(UnresolvedAssocItem { expr_or_pat }.into())
+ }
&hir_ty::InferenceDiagnostic::BreakOutsideOfLoop {
expr,
is_break,
diff --git a/crates/ide-diagnostics/src/handlers/unresolved_assoc_item.rs b/crates/ide-diagnostics/src/handlers/unresolved_assoc_item.rs
new file mode 100644
index 0000000000..f1c95993c8
--- /dev/null
+++ b/crates/ide-diagnostics/src/handlers/unresolved_assoc_item.rs
@@ -0,0 +1,52 @@
+use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
+
+// Diagnostic: unresolved-assoc-item
+//
+// This diagnostic is triggered if the referenced associated item does not exist.
+pub(crate) fn unresolved_assoc_item(
+ ctx: &DiagnosticsContext<'_>,
+ d: &hir::UnresolvedAssocItem,
+) -> Diagnostic {
+ Diagnostic::new_with_syntax_node_ptr(
+ ctx,
+ DiagnosticCode::RustcHardError("E0599"),
+ "no such associated item",
+ d.expr_or_pat.clone().map(Into::into),
+ )
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::check_diagnostics;
+
+ #[test]
+ fn bare() {
+ check_diagnostics(
+ r#"
+struct S;
+
+fn main() {
+ let _ = S::Assoc;
+ //^^^^^^^^ error: no such associated item
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn unimplemented_trait() {
+ check_diagnostics(
+ r#"
+struct S;
+trait Foo {
+ const X: u32;
+}
+
+fn main() {
+ let _ = S::X;
+ //^^^^ error: no such associated item
+}
+"#,
+ );
+ }
+}
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs
index 579386c72e..c7ad09e7eb 100644
--- a/crates/ide-diagnostics/src/lib.rs
+++ b/crates/ide-diagnostics/src/lib.rs
@@ -51,6 +51,7 @@ mod handlers {
pub(crate) mod typed_hole;
pub(crate) mod type_mismatch;
pub(crate) mod unimplemented_builtin_macro;
+ pub(crate) mod unresolved_assoc_item;
pub(crate) mod unresolved_extern_crate;
pub(crate) mod unresolved_field;
pub(crate) mod unresolved_method;
@@ -371,7 +372,8 @@ pub fn diagnostics(
AnyDiagnostic::TypeMismatch(d) => handlers::type_mismatch::type_mismatch(&ctx, &d),
AnyDiagnostic::UndeclaredLabel(d) => handlers::undeclared_label::undeclared_label(&ctx, &d),
AnyDiagnostic::UnimplementedBuiltinMacro(d) => handlers::unimplemented_builtin_macro::unimplemented_builtin_macro(&ctx, &d),
- AnyDiagnostic::UnreachableLabel(d) => handlers::unreachable_label:: unreachable_label(&ctx, &d),
+ AnyDiagnostic::UnreachableLabel(d) => handlers::unreachable_label::unreachable_label(&ctx, &d),
+ AnyDiagnostic::UnresolvedAssocItem(d) => handlers::unresolved_assoc_item::unresolved_assoc_item(&ctx, &d),
AnyDiagnostic::UnresolvedExternCrate(d) => handlers::unresolved_extern_crate::unresolved_extern_crate(&ctx, &d),
AnyDiagnostic::UnresolvedField(d) => handlers::unresolved_field::unresolved_field(&ctx, &d),
AnyDiagnostic::UnresolvedImport(d) => handlers::unresolved_import::unresolved_import(&ctx, &d),