160 lines
3.3 KiB
Rust
160 lines
3.3 KiB
Rust
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 = d.item.name(ctx.sema.db).map(|name| format!("`{name}` ")).unwrap_or_default();
|
|
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();
|
|
}
|
|
"#,
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn can_see_through_top_level_anonymous_const() {
|
|
// regression test for #14046.
|
|
check_diagnostics(
|
|
r#"
|
|
struct S;
|
|
mod m {
|
|
const _: () = {
|
|
impl crate::S {
|
|
pub(crate) fn method(self) {}
|
|
pub(crate) const A: usize = 42;
|
|
}
|
|
};
|
|
mod inner {
|
|
const _: () = {
|
|
impl crate::S {
|
|
pub(crate) fn method2(self) {}
|
|
pub(crate) const B: usize = 42;
|
|
pub(super) fn private(self) {}
|
|
pub(super) const PRIVATE: usize = 42;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
fn main() {
|
|
S.method();
|
|
S::A;
|
|
S.method2();
|
|
S::B;
|
|
S.private();
|
|
//^^^^^^^^^^^ error: function `private` is private
|
|
S::PRIVATE;
|
|
//^^^^^^^^^^ error: const `PRIVATE` is private
|
|
}
|
|
"#,
|
|
);
|
|
}
|
|
}
|