Skip to content

Commit ff72896

Browse files
committed
squashed commits
1 parent a31dcb7 commit ff72896

File tree

8 files changed

+145
-0
lines changed

8 files changed

+145
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3127,6 +3127,7 @@ Released 2018-09-13
31273127
[`duplicate_underscore_argument`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_underscore_argument
31283128
[`duration_subsec`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_subsec
31293129
[`else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else
3130+
[`empty_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_drop
31303131
[`empty_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum
31313132
[`empty_line_after_outer_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_outer_attr
31323133
[`empty_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_loop

clippy_lints/src/empty_drop.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use clippy_utils::{diagnostics::span_lint_and_sugg, peel_blocks};
2+
use if_chain::if_chain;
3+
use rustc_errors::Applicability;
4+
use rustc_hir::{Body, ExprKind, Impl, ImplItemKind, Item, ItemKind, Node};
5+
use rustc_lint::{LateContext, LateLintPass};
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
8+
declare_clippy_lint! {
9+
/// ### What it does
10+
/// Checks for empty `Drop` implementations.
11+
///
12+
/// ### Why is this bad?
13+
/// Empty `Drop` implementations have no effect when dropping an instance of the type. They are most likely useless.
14+
/// However, an empty `Drop` implementation prevents a type from being destructured, which might be the intention behind adding the implementation as a marker.
15+
///
16+
/// ### Example
17+
/// ```rust
18+
/// struct S;
19+
///
20+
/// impl Drop for S {
21+
/// fn drop(&mut self) {}
22+
/// }
23+
/// ```
24+
/// Use instead:
25+
/// ```rust
26+
/// struct S;
27+
/// ```
28+
#[clippy::version = "1.61.0"]
29+
pub EMPTY_DROP,
30+
restriction,
31+
"empty `Drop` implementations"
32+
}
33+
declare_lint_pass!(EmptyDrop => [EMPTY_DROP]);
34+
35+
impl LateLintPass<'_> for EmptyDrop {
36+
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
37+
if_chain! {
38+
if let ItemKind::Impl(Impl {
39+
of_trait: Some(ref trait_ref),
40+
items: [child],
41+
..
42+
}) = item.kind;
43+
if trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait();
44+
if let impl_item_hir = child.id.hir_id();
45+
if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir);
46+
if let ImplItemKind::Fn(_, b) = &impl_item.kind;
47+
if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b);
48+
let func_expr = peel_blocks(func_expr);
49+
if let ExprKind::Block(block, _) = func_expr.kind;
50+
if block.stmts.is_empty() && block.expr.is_none();
51+
then {
52+
span_lint_and_sugg(
53+
cx,
54+
EMPTY_DROP,
55+
item.span,
56+
"empty drop implementation",
57+
"try removing this impl",
58+
String::new(),
59+
Applicability::MaybeIncorrect
60+
);
61+
}
62+
}
63+
}
64+
}

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ store.register_lints(&[
127127
drop_forget_ref::FORGET_REF,
128128
duration_subsec::DURATION_SUBSEC,
129129
else_if_without_else::ELSE_IF_WITHOUT_ELSE,
130+
empty_drop::EMPTY_DROP,
130131
empty_enum::EMPTY_ENUM,
131132
entry::MAP_ENTRY,
132133
enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT,

clippy_lints/src/lib.register_restriction.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
1616
LintId::of(default_union_representation::DEFAULT_UNION_REPRESENTATION),
1717
LintId::of(disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS),
1818
LintId::of(else_if_without_else::ELSE_IF_WITHOUT_ELSE),
19+
LintId::of(empty_drop::EMPTY_DROP),
1920
LintId::of(exhaustive_items::EXHAUSTIVE_ENUMS),
2021
LintId::of(exhaustive_items::EXHAUSTIVE_STRUCTS),
2122
LintId::of(exit::EXIT),

clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ mod double_parens;
206206
mod drop_forget_ref;
207207
mod duration_subsec;
208208
mod else_if_without_else;
209+
mod empty_drop;
209210
mod empty_enum;
210211
mod entry;
211212
mod enum_clike;
@@ -866,6 +867,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
866867
ignore_publish: cargo_ignore_publish,
867868
})
868869
});
870+
store.register_late_pass(|| Box::new(empty_drop::EmptyDrop));
869871
// add lints here, do not remove this comment, it's used in `new_lint`
870872
}
871873

tests/ui/empty_drop.fixed

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// run-rustfix
2+
#![warn(clippy::empty_drop)]
3+
#![allow(unused)]
4+
5+
// should cause an error
6+
struct Foo;
7+
8+
9+
10+
// shouldn't cause an error
11+
struct Bar;
12+
13+
impl Drop for Bar {
14+
fn drop(&mut self) {
15+
println!("dropping bar!");
16+
}
17+
}
18+
19+
// should error
20+
struct Baz;
21+
22+
23+
24+
fn main() {}

tests/ui/empty_drop.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// run-rustfix
2+
#![warn(clippy::empty_drop)]
3+
#![allow(unused)]
4+
5+
// should cause an error
6+
struct Foo;
7+
8+
impl Drop for Foo {
9+
fn drop(&mut self) {}
10+
}
11+
12+
// shouldn't cause an error
13+
struct Bar;
14+
15+
impl Drop for Bar {
16+
fn drop(&mut self) {
17+
println!("dropping bar!");
18+
}
19+
}
20+
21+
// should error
22+
struct Baz;
23+
24+
impl Drop for Baz {
25+
fn drop(&mut self) {
26+
{}
27+
}
28+
}
29+
30+
fn main() {}

tests/ui/empty_drop.stderr

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error: empty drop implementation
2+
--> $DIR/empty_drop.rs:8:1
3+
|
4+
LL | / impl Drop for Foo {
5+
LL | | fn drop(&mut self) {}
6+
LL | | }
7+
| |_^ help: try removing this impl
8+
|
9+
= note: `-D clippy::empty-drop` implied by `-D warnings`
10+
11+
error: empty drop implementation
12+
--> $DIR/empty_drop.rs:24:1
13+
|
14+
LL | / impl Drop for Baz {
15+
LL | | fn drop(&mut self) {
16+
LL | | {}
17+
LL | | }
18+
LL | | }
19+
| |_^ help: try removing this impl
20+
21+
error: aborting due to 2 previous errors
22+

0 commit comments

Comments
 (0)