Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-diagnostics/src/handlers/private_assoc_item.rs')
-rw-r--r--crates/ide-diagnostics/src/handlers/private_assoc_item.rs124
1 files changed, 124 insertions, 0 deletions
diff --git a/crates/ide-diagnostics/src/handlers/private_assoc_item.rs b/crates/ide-diagnostics/src/handlers/private_assoc_item.rs
new file mode 100644
index 0000000000..b363a516dd
--- /dev/null
+++ b/crates/ide-diagnostics/src/handlers/private_assoc_item.rs
@@ -0,0 +1,124 @@
+use either::Either;
+
+use crate::{Diagnostic, DiagnosticsContext};
+
+// Diagnostic: private-assoc-item
+//
+// This diagnostic is triggered if the referenced associated item is not visible from the current
+// module.
+pub(crate) fn private_assoc_item(
+ ctx: &DiagnosticsContext<'_>,
+ d: &hir::PrivateAssocItem,
+) -> Diagnostic {
+ // FIXME: add quickfix
+ let name = match d.item.name(ctx.sema.db) {
+ Some(name) => format!("`{}` ", name),
+ None => String::new(),
+ };
+ Diagnostic::new(
+ "private-assoc-item",
+ format!(
+ "{} {}is private",
+ match d.item {
+ hir::AssocItem::Function(_) => "function",
+ hir::AssocItem::Const(_) => "const",
+ hir::AssocItem::TypeAlias(_) => "type alias",
+ },
+ name,
+ ),
+ ctx.sema
+ .diagnostics_display_range(d.expr_or_pat.clone().map(|it| match it {
+ Either::Left(it) => it.into(),
+ Either::Right(it) => match it {
+ Either::Left(it) => it.into(),
+ Either::Right(it) => it.into(),
+ },
+ }))
+ .range,
+ )
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::check_diagnostics;
+
+ #[test]
+ fn private_method() {
+ check_diagnostics(
+ r#"
+mod module {
+ pub struct Struct;
+ impl Struct {
+ fn method(&self) {}
+ }
+}
+fn main(s: module::Struct) {
+ s.method();
+ //^^^^^^^^^^ error: function `method` is private
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn private_func() {
+ check_diagnostics(
+ r#"
+mod module {
+ pub struct Struct;
+ impl Struct {
+ fn func() {}
+ }
+}
+fn main() {
+ module::Struct::func();
+ //^^^^^^^^^^^^^^^^^^^^ error: function `func` is private
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn private_const() {
+ check_diagnostics(
+ r#"
+mod module {
+ pub struct Struct;
+ impl Struct {
+ const CONST: u32 = 0;
+ }
+}
+fn main() {
+ module::Struct::CONST;
+ //^^^^^^^^^^^^^^^^^^^^^ error: const `CONST` is private
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn private_but_shadowed_in_deref() {
+ check_diagnostics(
+ r#"
+//- minicore: deref
+mod module {
+ pub struct Struct { field: Inner }
+ pub struct Inner;
+ impl core::ops::Deref for Struct {
+ type Target = Inner;
+ fn deref(&self) -> &Inner { &self.field }
+ }
+ impl Struct {
+ fn method(&self) {}
+ }
+ impl Inner {
+ pub fn method(&self) {}
+ }
+}
+fn main(s: module::Struct) {
+ s.method();
+}
+"#,
+ );
+ }
+}