134 lines
4.4 KiB
Rust
134 lines
4.4 KiB
Rust
use clippy_utils::diagnostics::span_lint_and_sugg;
|
|
use clippy_utils::source::snippet_opt;
|
|
use rustc_ast::ast::{Item, VisibilityKind};
|
|
use rustc_errors::Applicability;
|
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
|
use rustc_middle::lint::in_external_macro;
|
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|
use rustc_span::symbol::kw;
|
|
use rustc_span::Span;
|
|
|
|
declare_clippy_lint! {
|
|
/// ### What it does
|
|
/// Checks for usage of `pub(self)` and `pub(in self)`.
|
|
///
|
|
/// ### Why is this bad?
|
|
/// It's unnecessary, omitting the `pub` entirely will give the same results.
|
|
///
|
|
/// ### Example
|
|
/// ```rust,ignore
|
|
/// pub(self) type OptBox<T> = Option<Box<T>>;
|
|
/// ```
|
|
/// Use instead:
|
|
/// ```rust,ignore
|
|
/// type OptBox<T> = Option<Box<T>>;
|
|
/// ```
|
|
#[clippy::version = "1.72.0"]
|
|
pub NEEDLESS_PUB_SELF,
|
|
style,
|
|
"checks for usage of `pub(self)` and `pub(in self)`."
|
|
}
|
|
declare_clippy_lint! {
|
|
/// ### What it does
|
|
/// Checks for usage of `pub(<loc>)` with `in`.
|
|
///
|
|
/// ### Why is this bad?
|
|
/// Consistency. Use it or don't, just be consistent about it.
|
|
///
|
|
/// Also see the `pub_without_shorthand` lint for an alternative.
|
|
///
|
|
/// ### Example
|
|
/// ```rust,ignore
|
|
/// pub(super) type OptBox<T> = Option<Box<T>>;
|
|
/// ```
|
|
/// Use instead:
|
|
/// ```rust,ignore
|
|
/// pub(in super) type OptBox<T> = Option<Box<T>>;
|
|
/// ```
|
|
#[clippy::version = "1.72.0"]
|
|
pub PUB_WITH_SHORTHAND,
|
|
restriction,
|
|
"disallows usage of `pub(<loc>)`, without `in`"
|
|
}
|
|
declare_clippy_lint! {
|
|
/// ### What it does
|
|
/// Checks for usage of `pub(<loc>)` without `in`.
|
|
///
|
|
/// Note: As you cannot write a module's path in `pub(<loc>)`, this will only trigger on
|
|
/// `pub(super)` and the like.
|
|
///
|
|
/// ### Why is this bad?
|
|
/// Consistency. Use it or don't, just be consistent about it.
|
|
///
|
|
/// Also see the `pub_with_shorthand` lint for an alternative.
|
|
///
|
|
/// ### Example
|
|
/// ```rust,ignore
|
|
/// pub(in super) type OptBox<T> = Option<Box<T>>;
|
|
/// ```
|
|
/// Use instead:
|
|
/// ```rust,ignore
|
|
/// pub(super) type OptBox<T> = Option<Box<T>>;
|
|
/// ```
|
|
#[clippy::version = "1.72.0"]
|
|
pub PUB_WITHOUT_SHORTHAND,
|
|
restriction,
|
|
"disallows usage of `pub(in <loc>)` with `in`"
|
|
}
|
|
declare_lint_pass!(Visibility => [NEEDLESS_PUB_SELF, PUB_WITH_SHORTHAND, PUB_WITHOUT_SHORTHAND]);
|
|
|
|
impl EarlyLintPass for Visibility {
|
|
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
|
if !in_external_macro(cx.sess(), item.span)
|
|
&& let VisibilityKind::Restricted { path, shorthand, .. } = &item.vis.kind
|
|
{
|
|
if **path == kw::SelfLower && let Some(false) = is_from_proc_macro(cx, item.vis.span) {
|
|
span_lint_and_sugg(
|
|
cx,
|
|
NEEDLESS_PUB_SELF,
|
|
item.vis.span,
|
|
&format!("unnecessary `pub({}self)`", if *shorthand { "" } else { "in " }),
|
|
"remove it",
|
|
String::new(),
|
|
Applicability::MachineApplicable,
|
|
);
|
|
}
|
|
|
|
if (**path == kw::Super || **path == kw::SelfLower || **path == kw::Crate)
|
|
&& !*shorthand
|
|
&& let [.., last] = &*path.segments
|
|
&& let Some(false) = is_from_proc_macro(cx, item.vis.span)
|
|
{
|
|
span_lint_and_sugg(
|
|
cx,
|
|
PUB_WITHOUT_SHORTHAND,
|
|
item.vis.span,
|
|
"usage of `pub` with `in`",
|
|
"remove it",
|
|
format!("pub({})", last.ident),
|
|
Applicability::MachineApplicable,
|
|
);
|
|
}
|
|
|
|
if *shorthand
|
|
&& let [.., last] = &*path.segments
|
|
&& let Some(false) = is_from_proc_macro(cx, item.vis.span)
|
|
{
|
|
span_lint_and_sugg(
|
|
cx,
|
|
PUB_WITH_SHORTHAND,
|
|
item.vis.span,
|
|
"usage of `pub` without `in`",
|
|
"add it",
|
|
format!("pub(in {})", last.ident),
|
|
Applicability::MachineApplicable,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn is_from_proc_macro(cx: &EarlyContext<'_>, span: Span) -> Option<bool> {
|
|
snippet_opt(cx, span).map(|s| !s.starts_with("pub"))
|
|
}
|