Don't lint functions with "box" in their name

This commit is contained in:
Micha White 2023-03-26 11:00:10 -04:00
parent a143fb7a11
commit 76d13bb7fa
No known key found for this signature in database
GPG Key ID: AED94BFA1C301389
3 changed files with 25 additions and 14 deletions

View File

@ -3,6 +3,7 @@ use rustc_errors::Applicability;
use rustc_hir::{def_id::LocalDefId, FnDecl, FnRetTy, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind}; use rustc_hir::{def_id::LocalDefId, FnDecl, FnRetTy, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Symbol;
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
@ -46,12 +47,17 @@ impl UnnecessaryBoxReturns {
} }
} }
fn check_fn_decl(&mut self, cx: &LateContext<'_>, decl: &FnDecl<'_>, def_id: LocalDefId) { fn check_fn_item(&mut self, cx: &LateContext<'_>, decl: &FnDecl<'_>, def_id: LocalDefId, name: Symbol) {
// we don't want to tell someone to break an exported function if they ask us not to // we don't want to tell someone to break an exported function if they ask us not to
if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) { if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
return; return;
} }
// functions which contain the word "box" are exempt from this lint
if name.as_str().contains("box") {
return;
}
let FnRetTy::Return(return_ty_hir) = &decl.output else { return }; let FnRetTy::Return(return_ty_hir) = &decl.output else { return };
let return_ty = cx let return_ty = cx
@ -91,7 +97,7 @@ impl UnnecessaryBoxReturns {
impl LateLintPass<'_> for UnnecessaryBoxReturns { impl LateLintPass<'_> for UnnecessaryBoxReturns {
fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) { fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {
let TraitItemKind::Fn(signature, _) = &item.kind else { return }; let TraitItemKind::Fn(signature, _) = &item.kind else { return };
self.check_fn_decl(cx, signature.decl, item.owner_id.def_id); self.check_fn_item(cx, signature.decl, item.owner_id.def_id, item.ident.name);
} }
fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) { fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) {
@ -104,11 +110,11 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns {
} }
let ImplItemKind::Fn(signature, ..) = &item.kind else { return }; let ImplItemKind::Fn(signature, ..) = &item.kind else { return };
self.check_fn_decl(cx, signature.decl, item.owner_id.def_id); self.check_fn_item(cx, signature.decl, item.owner_id.def_id, item.ident.name);
} }
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
let ItemKind::Fn(signature, ..) = &item.kind else { return }; let ItemKind::Fn(signature, ..) = &item.kind else { return };
self.check_fn_decl(cx, signature.decl, item.owner_id.def_id); self.check_fn_item(cx, signature.decl, item.owner_id.def_id, item.ident.name);
} }
} }

View File

@ -22,25 +22,30 @@ impl Foo {
} }
// lint // lint
fn boxed_usize() -> Box<usize> { fn bxed_usize() -> Box<usize> {
Box::new(5) Box::new(5)
} }
// lint // lint
fn _boxed_foo() -> Box<Foo> { fn _bxed_foo() -> Box<Foo> {
Box::new(Foo {}) Box::new(Foo {})
} }
// don't lint: this is exported // don't lint: this is exported
pub fn boxed_foo() -> Box<Foo> { pub fn bxed_foo() -> Box<Foo> {
Box::new(Foo {}) Box::new(Foo {})
} }
// don't lint: str is unsized // don't lint: str is unsized
fn boxed_str() -> Box<str> { fn bxed_str() -> Box<str> {
"Hello, world!".to_string().into_boxed_str() "Hello, world!".to_string().into_boxed_str()
} }
// don't lint: function contains the word, "box"
fn boxed_usize() -> Box<usize> {
Box::new(7)
}
// don't lint: this has an unspecified return type // don't lint: this has an unspecified return type
fn default() {} fn default() {}

View File

@ -16,18 +16,18 @@ LL | fn baz(&self) -> Box<usize> {
= help: changing this also requires a change to the return expressions in this function = help: changing this also requires a change to the return expressions in this function
error: boxed return of the sized type `usize` error: boxed return of the sized type `usize`
--> $DIR/unnecessary_box_returns.rs:25:21 --> $DIR/unnecessary_box_returns.rs:25:20
| |
LL | fn boxed_usize() -> Box<usize> { LL | fn bxed_usize() -> Box<usize> {
| ^^^^^^^^^^ help: try: `usize` | ^^^^^^^^^^ help: try: `usize`
| |
= help: changing this also requires a change to the return expressions in this function = help: changing this also requires a change to the return expressions in this function
error: boxed return of the sized type `Foo` error: boxed return of the sized type `Foo`
--> $DIR/unnecessary_box_returns.rs:30:20 --> $DIR/unnecessary_box_returns.rs:30:19
| |
LL | fn _boxed_foo() -> Box<Foo> { LL | fn _bxed_foo() -> Box<Foo> {
| ^^^^^^^^ help: try: `Foo` | ^^^^^^^^ help: try: `Foo`
| |
= help: changing this also requires a change to the return expressions in this function = help: changing this also requires a change to the return expressions in this function