ide_diagnostics/handlers/
private_assoc_item.rs

1use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
2
3// Diagnostic: private-assoc-item
4//
5// This diagnostic is triggered if the referenced associated item is not visible from the current
6// module.
7pub(crate) fn private_assoc_item(
8    ctx: &DiagnosticsContext<'_>,
9    d: &hir::PrivateAssocItem,
10) -> Diagnostic {
11    // FIXME: add quickfix
12    let name = d
13        .item
14        .name(ctx.sema.db)
15        .map(|name| format!("`{}` ", name.display(ctx.sema.db, ctx.edition)))
16        .unwrap_or_default();
17    Diagnostic::new_with_syntax_node_ptr(
18        ctx,
19        DiagnosticCode::RustcHardError("E0624"),
20        format!(
21            "{} {}is private",
22            match d.item {
23                hir::AssocItem::Function(_) => "function",
24                hir::AssocItem::Const(_) => "const",
25                hir::AssocItem::TypeAlias(_) => "type alias",
26            },
27            name,
28        ),
29        d.expr_or_pat.map(Into::into),
30    )
31    .stable()
32}
33
34#[cfg(test)]
35mod tests {
36    use crate::tests::check_diagnostics;
37
38    #[test]
39    fn private_method() {
40        check_diagnostics(
41            r#"
42mod module {
43    pub struct Struct;
44    impl Struct {
45        fn method(&self) {}
46    }
47}
48fn main(s: module::Struct) {
49    s.method();
50  //^^^^^^^^^^ error: function `method` is private
51}
52"#,
53        );
54    }
55
56    #[test]
57    fn private_func() {
58        check_diagnostics(
59            r#"
60mod module {
61    pub struct Struct;
62    impl Struct {
63        fn func() {}
64    }
65}
66fn main() {
67    module::Struct::func();
68  //^^^^^^^^^^^^^^^^^^^^ error: function `func` is private
69}
70"#,
71        );
72    }
73
74    #[test]
75    fn private_const() {
76        check_diagnostics(
77            r#"
78mod module {
79    pub struct Struct;
80    impl Struct {
81        const CONST: u32 = 0;
82    }
83}
84fn main() {
85    module::Struct::CONST;
86  //^^^^^^^^^^^^^^^^^^^^^ error: const `CONST` is private
87}
88"#,
89        );
90    }
91
92    #[test]
93    fn private_but_shadowed_in_deref() {
94        check_diagnostics(
95            r#"
96//- minicore: deref
97mod module {
98    pub struct Struct { field: Inner }
99    pub struct Inner;
100    impl core::ops::Deref for Struct {
101        type Target = Inner;
102        fn deref(&self) -> &Inner { &self.field }
103    }
104    impl Struct {
105        fn method(&self) {}
106    }
107    impl Inner {
108        pub fn method(&self) {}
109    }
110}
111fn main(s: module::Struct) {
112    s.method();
113}
114"#,
115        );
116    }
117
118    #[test]
119    fn can_see_through_top_level_anonymous_const() {
120        // regression test for #14046.
121        check_diagnostics(
122            r#"
123struct S;
124mod m {
125    const _: () = {
126        impl crate::S {
127            pub(crate) fn method(self) {}
128            pub(crate) const A: usize = 42;
129        }
130    };
131    mod inner {
132        const _: () = {
133            impl crate::S {
134                pub(crate) fn method2(self) {}
135                pub(crate) const B: usize = 42;
136                pub(super) fn private(self) {}
137                pub(super) const PRIVATE: usize = 42;
138            }
139        };
140    }
141}
142fn main() {
143    S.method();
144    S::A;
145    S.method2();
146    S::B;
147    S.private();
148  //^^^^^^^^^^^ error: function `private` is private
149    S::PRIVATE;
150  //^^^^^^^^^^ error: const `PRIVATE` is private
151}
152"#,
153        );
154    }
155}