Skip to content

Commit

Permalink
Add [extern_without_abi] lint
Browse files Browse the repository at this point in the history
  • Loading branch information
CBSpeir committed Sep 16, 2024
1 parent 2536745 commit 3d62203
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5456,6 +5456,7 @@ Released 2018-09-13
[`explicit_write`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_write
[`extend_from_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#extend_from_slice
[`extend_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#extend_with_drain
[`extern_without_abi`]: https://rust-lang.github.io/rust-clippy/master/index.html#extern_without_abi
[`extra_unused_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes
[`extra_unused_type_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_type_parameters
[`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#fallible_impl_from
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/declared_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
crate::exhaustive_items::EXHAUSTIVE_STRUCTS_INFO,
crate::exit::EXIT_INFO,
crate::explicit_write::EXPLICIT_WRITE_INFO,
crate::extern_without_abi::EXTERN_WITHOUT_ABI_INFO,
crate::extra_unused_type_parameters::EXTRA_UNUSED_TYPE_PARAMETERS_INFO,
crate::fallible_impl_from::FALLIBLE_IMPL_FROM_INFO,
crate::field_scoped_visibility_modifiers::FIELD_SCOPED_VISIBILITY_MODIFIERS_INFO,
Expand Down
61 changes: 61 additions & 0 deletions clippy_lints/src/extern_without_abi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use clippy_utils::diagnostics::span_lint;
use rustc_ast::visit::FnKind;
use rustc_ast::{Extern, FnHeader, FnSig, ForeignMod, Item, ItemKind, NodeId};
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::declare_lint_pass;
use rustc_span::Span;

const LINT_MSG: &str = "`extern` missing explicit ABI";

declare_clippy_lint! {
/// ### What it does
/// Checks for usage of `extern` without an explicit ABI.
///
/// ### Why is this bad?
/// Explicitly declaring the ABI improves readability.
//
/// ### Example
/// ```no_run
/// extern fn foo() {}
///
/// extern {
/// fn bar();
/// }
/// ```
/// Use instead:
/// ```no_run
/// extern "C" fn foo() {}
///
/// extern "C" {
/// fn bar();
/// }
/// ```
#[clippy::version = "1.83.0"]
pub EXTERN_WITHOUT_ABI,
style,
"`extern` missing explicit ABI"
}

declare_lint_pass!(ExternWithoutAbi => [EXTERN_WITHOUT_ABI]);

impl EarlyLintPass for ExternWithoutAbi {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
if let ItemKind::ForeignMod(ref foreign_mod) = item.kind
&& let ForeignMod { abi: None, .. } = foreign_mod
{
span_lint(cx, EXTERN_WITHOUT_ABI, item.span, LINT_MSG);
}
}

fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, _: Span, _: NodeId) {
if let FnKind::Fn(_, _, sig, ..) = kind
&& let FnSig { header, .. } = sig
&& let FnHeader {
ext: Extern::Implicit(span),
..
} = header
{
span_lint(cx, EXTERN_WITHOUT_ABI, *span, LINT_MSG);
}
}
}
2 changes: 2 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ mod excessive_nesting;
mod exhaustive_items;
mod exit;
mod explicit_write;
mod extern_without_abi;
mod extra_unused_type_parameters;
mod fallible_impl_from;
mod field_scoped_visibility_modifiers;
Expand Down Expand Up @@ -942,5 +943,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(move |_| Box::new(manual_div_ceil::ManualDivCeil::new(conf)));
store.register_late_pass(|_| Box::new(manual_is_power_of_two::ManualIsPowerOfTwo));
store.register_late_pass(|_| Box::new(non_zero_suggestions::NonZeroSuggestions));
store.register_early_pass(|| Box::new(extern_without_abi::ExternWithoutAbi));
// add lints here, do not remove this comment, it's used in `new_lint`
}
1 change: 1 addition & 0 deletions tests/ui/boxed_local.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(
clippy::borrowed_box,
clippy::extern_without_abi,
clippy::needless_pass_by_value,
clippy::unused_unit,
clippy::redundant_clone,
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/boxed_local.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: local variable doesn't need to be boxed here
--> tests/ui/boxed_local.rs:39:13
--> tests/ui/boxed_local.rs:40:13
|
LL | fn warn_arg(x: Box<A>) {
| ^
Expand All @@ -8,19 +8,19 @@ LL | fn warn_arg(x: Box<A>) {
= help: to override `-D warnings` add `#[allow(clippy::boxed_local)]`

error: local variable doesn't need to be boxed here
--> tests/ui/boxed_local.rs:122:12
--> tests/ui/boxed_local.rs:123:12
|
LL | pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}
| ^^^^^^^^^^^

error: local variable doesn't need to be boxed here
--> tests/ui/boxed_local.rs:187:44
--> tests/ui/boxed_local.rs:188:44
|
LL | fn default_impl_x(self: Box<Self>, x: Box<u32>) -> u32 {
| ^

error: local variable doesn't need to be boxed here
--> tests/ui/boxed_local.rs:195:16
--> tests/ui/boxed_local.rs:196:16
|
LL | fn foo(x: Box<u32>) {}
| ^
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/doc/doc-fixable.fixed
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

//! This file tests for the `DOC_MARKDOWN` lint.

#![allow(dead_code, incomplete_features)]
#![allow(dead_code, incomplete_features, clippy::extern_without_abi)]
#![warn(clippy::doc_markdown)]
#![feature(custom_inner_attributes, generic_const_exprs, const_option)]
#![rustfmt::skip]
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/doc/doc-fixable.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

//! This file tests for the `DOC_MARKDOWN` lint.

#![allow(dead_code, incomplete_features)]
#![allow(dead_code, incomplete_features, clippy::extern_without_abi)]
#![warn(clippy::doc_markdown)]
#![feature(custom_inner_attributes, generic_const_exprs, const_option)]
#![rustfmt::skip]
Expand Down
31 changes: 31 additions & 0 deletions tests/ui/extern_without_abi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#![warn(clippy::extern_without_abi)]

fn main() {}

#[rustfmt::skip]
extern fn foo() {}
//~^ ERROR: `extern` missing explicit ABI

extern "C" fn bar() {}

extern "system" fn baz() {}

#[rustfmt::skip]
extern {
//~^ ERROR: `extern` missing explicit ABI
static QUX: std::ffi::c_int;

fn quux();
}

extern "C" {
static CORGE: std::ffi::c_int;

fn grault();
}

extern "system" {
static GARPLY: std::ffi::c_int;

fn waldo();
}
21 changes: 21 additions & 0 deletions tests/ui/extern_without_abi.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error: `extern` missing explicit ABI
--> tests/ui/extern_without_abi.rs:6:1
|
LL | extern fn foo() {}
| ^^^^^^
|
= note: `-D clippy::extern-without-abi` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::extern_without_abi)]`

error: `extern` missing explicit ABI
--> tests/ui/extern_without_abi.rs:14:1
|
LL | / extern {
LL | |
LL | | static QUX: std::ffi::c_int;
... |
LL | | }
| |_^

error: aborting due to 2 previous errors

7 changes: 6 additions & 1 deletion tests/ui/missing_const_for_fn/could_be_const.fixed
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#![warn(clippy::missing_const_for_fn)]
#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
#![allow(
incomplete_features,
clippy::extern_without_abi,
clippy::let_and_return,
clippy::missing_transmute_annotations
)]
#![feature(const_mut_refs)]
#![feature(const_trait_impl)]

Expand Down
7 changes: 6 additions & 1 deletion tests/ui/missing_const_for_fn/could_be_const.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#![warn(clippy::missing_const_for_fn)]
#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
#![allow(
incomplete_features,
clippy::extern_without_abi,
clippy::let_and_return,
clippy::missing_transmute_annotations
)]
#![feature(const_mut_refs)]
#![feature(const_trait_impl)]

Expand Down
Loading

0 comments on commit 3d62203

Please sign in to comment.