Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-diagnostics/src/handlers/private_field.rs')
-rw-r--r--crates/ide-diagnostics/src/handlers/private_field.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/crates/ide-diagnostics/src/handlers/private_field.rs b/crates/ide-diagnostics/src/handlers/private_field.rs
new file mode 100644
index 0000000000..e630ae3686
--- /dev/null
+++ b/crates/ide-diagnostics/src/handlers/private_field.rs
@@ -0,0 +1,68 @@
+use crate::{Diagnostic, DiagnosticsContext};
+
+// Diagnostic: private-field
+//
+// This diagnostic is triggered if the accessed field is not visible from the current module.
+pub(crate) fn private_field(ctx: &DiagnosticsContext<'_>, d: &hir::PrivateField) -> Diagnostic {
+ // FIXME: add quickfix
+ Diagnostic::new(
+ "private-field",
+ format!(
+ "field `{}` of `{}` is private",
+ d.field.name(ctx.sema.db),
+ d.field.parent_def(ctx.sema.db).name(ctx.sema.db)
+ ),
+ ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range,
+ )
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::check_diagnostics;
+
+ #[test]
+ fn private_field() {
+ check_diagnostics(
+ r#"
+mod module { pub struct Struct { field: u32 } }
+fn main(s: module::Struct) {
+ s.field;
+ //^^^^^^^ error: field `field` of `Struct` is private
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn private_tuple_field() {
+ check_diagnostics(
+ r#"
+mod module { pub struct Struct(u32); }
+fn main(s: module::Struct) {
+ s.0;
+ //^^^ error: field `0` of `Struct` is private
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn private_but_shadowed_in_deref() {
+ check_diagnostics(
+ r#"
+//- minicore: deref
+mod module {
+ pub struct Struct { field: Inner }
+ pub struct Inner { pub field: u32 }
+ impl core::ops::Deref for Struct {
+ type Target = Inner;
+ fn deref(&self) -> &Inner { &self.field }
+ }
+}
+fn main(s: module::Struct) {
+ s.field;
+}
+"#,
+ );
+ }
+}