summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs')
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs101
1 files changed, 87 insertions, 14 deletions
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 a34a5824f..290c16c9d 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,3 +1,4 @@
+use either::Either;
use hir::{db::ExpandDatabase, HasSource, HirDisplay, Semantics};
use ide_db::{base_db::FileId, source_change::SourceChange, RootDatabase};
use syntax::{
@@ -12,22 +13,39 @@ use crate::{fix, Assist, Diagnostic, DiagnosticCode, DiagnosticsContext};
//
// This diagnostic is triggered if created structure does not have field provided in record.
pub(crate) fn no_such_field(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Diagnostic {
- Diagnostic::new_with_syntax_node_ptr(
- ctx,
- DiagnosticCode::RustcHardError("E0559"),
- "no such field",
- d.field.clone().map(|it| it.into()),
- )
- .with_fixes(fixes(ctx, d))
+ let node = d.field.clone().map(|it| it.either(Into::into, Into::into));
+ if d.private {
+ // FIXME: quickfix to add required visibility
+ Diagnostic::new_with_syntax_node_ptr(
+ ctx,
+ DiagnosticCode::RustcHardError("E0451"),
+ "field is private",
+ node,
+ )
+ } else {
+ Diagnostic::new_with_syntax_node_ptr(
+ ctx,
+ DiagnosticCode::RustcHardError("E0559"),
+ "no such field",
+ node,
+ )
+ .with_fixes(fixes(ctx, d))
+ }
}
fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Option<Vec<Assist>> {
- let root = ctx.sema.db.parse_or_expand(d.field.file_id);
- missing_record_expr_field_fixes(
- &ctx.sema,
- d.field.file_id.original_file(ctx.sema.db),
- &d.field.value.to_node(&root),
- )
+ // FIXME: quickfix for pattern
+ match &d.field.value {
+ Either::Left(ptr) => {
+ let root = ctx.sema.db.parse_or_expand(d.field.file_id);
+ missing_record_expr_field_fixes(
+ &ctx.sema,
+ d.field.file_id.original_file(ctx.sema.db),
+ &ptr.to_node(&root),
+ )
+ }
+ _ => None,
+ }
}
fn missing_record_expr_field_fixes(
@@ -118,13 +136,34 @@ mod tests {
r#"
struct S { foo: i32, bar: () }
impl S {
- fn new() -> S {
+ fn new(
+ s@S {
+ //^ 💡 error: missing structure fields:
+ //| - bar
+ foo,
+ baz: baz2,
+ //^^^^^^^^^ error: no such field
+ qux
+ //^^^ error: no such field
+ }: S
+ ) -> S {
+ S {
+ //^ 💡 error: missing structure fields:
+ //| - bar
+ foo,
+ baz: baz2,
+ //^^^^^^^^^ error: no such field
+ qux
+ //^^^ error: no such field
+ } = s;
S {
//^ 💡 error: missing structure fields:
//| - bar
foo: 92,
baz: 62,
//^^^^^^^ 💡 error: no such field
+ qux
+ //^^^ error: no such field
}
}
}
@@ -295,4 +334,38 @@ fn main() {
"#,
)
}
+
+ #[test]
+ fn test_struct_field_private() {
+ check_diagnostics(
+ r#"
+mod m {
+ pub struct Struct {
+ field: u32,
+ field2: u32,
+ }
+}
+fn f(s@m::Struct {
+ field: f,
+ //^^^^^^^^ error: field is private
+ field2
+ //^^^^^^ error: field is private
+}: m::Struct) {
+ // assignee expression
+ m::Struct {
+ field: 0,
+ //^^^^^^^^ error: field is private
+ field2
+ //^^^^^^ error: field is private
+ } = s;
+ m::Struct {
+ field: 0,
+ //^^^^^^^^ error: field is private
+ field2
+ //^^^^^^ error: field is private
+ };
+}
+"#,
+ )
+ }
}