Skip to content

Commit 55c3023

Browse files
committed
move to types group
1 parent 4cd78ce commit 55c3023

File tree

6 files changed

+93
-88
lines changed

6 files changed

+93
-88
lines changed

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
483483
crate::non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS_INFO,
484484
crate::non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY_INFO,
485485
crate::nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES_INFO,
486-
crate::null_pointer_optimization::NULL_POINTER_OPTIMIZATION_INFO,
487486
crate::octal_escapes::OCTAL_ESCAPES_INFO,
488487
crate::only_used_in_recursion::ONLY_USED_IN_RECURSION_INFO,
489488
crate::operators::ABSURD_EXTREME_COMPARISONS_INFO,
@@ -622,6 +621,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
622621
crate::types::BORROWED_BOX_INFO,
623622
crate::types::BOX_COLLECTION_INFO,
624623
crate::types::LINKEDLIST_INFO,
624+
crate::types::NULL_POINTER_OPTIMIZATION_INFO,
625625
crate::types::OPTION_OPTION_INFO,
626626
crate::types::RC_BUFFER_INFO,
627627
crate::types::RC_MUTEX_INFO,

clippy_lints/src/lib.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ mod non_expressive_names;
241241
mod non_octal_unix_permissions;
242242
mod non_send_fields_in_send_ty;
243243
mod nonstandard_macro_braces;
244-
mod null_pointer_optimization;
245244
mod octal_escapes;
246245
mod only_used_in_recursion;
247246
mod operators;
@@ -1048,11 +1047,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10481047
let stack_size_threshold = conf.stack_size_threshold;
10491048
store.register_late_pass(move |_| Box::new(large_stack_frames::LargeStackFrames::new(stack_size_threshold)));
10501049
store.register_late_pass(|_| Box::new(single_range_in_vec_init::SingleRangeInVecInit));
1051-
store.register_late_pass(move |_| {
1052-
Box::new(null_pointer_optimization::NullPointerOptimization {
1053-
avoid_breaking_exported_api,
1054-
})
1055-
});
10561050
// add lints here, do not remove this comment, it's used in `new_lint`
10571051
}
10581052

clippy_lints/src/null_pointer_optimization.rs

Lines changed: 0 additions & 70 deletions
This file was deleted.

clippy_lints/src/types/mod.rs

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod borrowed_box;
22
mod box_collection;
33
mod linked_list;
4+
mod null_pointer_optimization;
45
mod option_option;
56
mod rc_buffer;
67
mod rc_mutex;
@@ -303,13 +304,46 @@ declare_clippy_lint! {
303304
"usage of `Rc<Mutex<T>>`"
304305
}
305306

307+
declare_clippy_lint! {
308+
/// ### What it does
309+
/// Checks for `T<Option<U>>` where `T` is a type that has
310+
/// [null pointer optimization](https://doc.rust-lang.org/core/option/#representation).
311+
///
312+
/// ### Why is this bad?
313+
/// It's slower, as `Option` can use `null` as `None`, instead of adding another layer of
314+
/// indirection.
315+
///
316+
/// ### Example
317+
/// ```rust
318+
/// struct MyWrapperType<T>(Box<Option<T>>);
319+
/// ```
320+
/// Use instead:
321+
/// ```rust
322+
/// struct MyWrapperType<T>(Option<Box<T>>);
323+
/// ```
324+
#[clippy::version = "1.72.0"]
325+
pub NULL_POINTER_OPTIMIZATION,
326+
perf,
327+
"checks for `U<Option<T>>` where `U` is a type that has null pointer optimization"
328+
}
306329
pub struct Types {
307330
vec_box_size_threshold: u64,
308331
type_complexity_threshold: u64,
309332
avoid_breaking_exported_api: bool,
310333
}
311334

312-
impl_lint_pass!(Types => [BOX_COLLECTION, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION, RC_BUFFER, RC_MUTEX, TYPE_COMPLEXITY]);
335+
impl_lint_pass!(Types => [
336+
BOX_COLLECTION,
337+
VEC_BOX,
338+
OPTION_OPTION,
339+
LINKEDLIST,
340+
BORROWED_BOX,
341+
REDUNDANT_ALLOCATION,
342+
RC_BUFFER,
343+
RC_MUTEX,
344+
TYPE_COMPLEXITY,
345+
NULL_POINTER_OPTIMIZATION,
346+
]);
313347

314348
impl<'tcx> LateLintPass<'tcx> for Types {
315349
fn check_fn(
@@ -349,10 +383,11 @@ impl<'tcx> LateLintPass<'tcx> for Types {
349383
let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
350384

351385
match item.kind {
352-
ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _) => self.check_ty(
386+
ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _) | ItemKind::TyAlias(ty, _) => self.check_ty(
353387
cx,
354388
ty,
355389
CheckTyContext {
390+
is_in_ty_alias: matches!(item.kind, ItemKind::TyAlias(..)),
356391
is_exported,
357392
..CheckTyContext::default()
358393
},
@@ -476,7 +511,10 @@ impl Types {
476511
return;
477512
}
478513

479-
if !context.is_nested_call && type_complexity::check(cx, hir_ty, self.type_complexity_threshold) {
514+
if !context.is_nested_call
515+
&& !context.is_in_ty_alias
516+
&& type_complexity::check(cx, hir_ty, self.type_complexity_threshold)
517+
{
480518
return;
481519
}
482520

@@ -492,13 +530,16 @@ impl Types {
492530
// in `clippy_lints::utils::conf.rs`
493531

494532
let mut triggered = false;
495-
triggered |= box_collection::check(cx, hir_ty, qpath, def_id);
496-
triggered |= redundant_allocation::check(cx, hir_ty, qpath, def_id);
497-
triggered |= rc_buffer::check(cx, hir_ty, qpath, def_id);
498-
triggered |= vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold);
499-
triggered |= option_option::check(cx, hir_ty, qpath, def_id);
500-
triggered |= linked_list::check(cx, hir_ty, def_id);
501-
triggered |= rc_mutex::check(cx, hir_ty, qpath, def_id);
533+
if !context.is_in_ty_alias {
534+
triggered |= box_collection::check(cx, hir_ty, qpath, def_id);
535+
triggered |= redundant_allocation::check(cx, hir_ty, qpath, def_id);
536+
triggered |= rc_buffer::check(cx, hir_ty, qpath, def_id);
537+
triggered |= vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold);
538+
triggered |= option_option::check(cx, hir_ty, qpath, def_id);
539+
triggered |= linked_list::check(cx, hir_ty, def_id);
540+
triggered |= rc_mutex::check(cx, hir_ty, qpath, def_id);
541+
}
542+
triggered |= null_pointer_optimization::check(cx, hir_ty, qpath, res);
502543

503544
if triggered {
504545
return;
@@ -580,6 +621,7 @@ impl Types {
580621
#[allow(clippy::struct_excessive_bools)]
581622
#[derive(Clone, Copy, Default)]
582623
struct CheckTyContext {
624+
is_in_ty_alias: bool,
583625
is_in_trait_impl: bool,
584626
/// `true` for types on local variables.
585627
is_local: bool,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use clippy_utils::{diagnostics::span_lint_and_help, is_lang_item_or_ctor, last_path_segment, match_def_path, paths};
2+
use rustc_hir::{
3+
def::{DefKind, Res},
4+
GenericArg, LangItem, QPath, Ty, TyKind,
5+
};
6+
use rustc_lint::LateContext;
7+
8+
use super::NULL_POINTER_OPTIMIZATION;
9+
10+
pub(super) fn check(cx: &LateContext<'_>, ty: &Ty<'_>, qpath: &QPath<'_>, res: Res) -> bool {
11+
if let Res::Def(DefKind::Struct, def_id) = res {
12+
if !(is_lang_item_or_ctor(cx, def_id, LangItem::OwnedBox) || match_def_path(cx, def_id, &paths::PTR_NON_NULL)) {
13+
return false;
14+
}
15+
16+
if let Some(args) = last_path_segment(qpath).args
17+
&& let GenericArg::Type(option_ty) = args.args[0]
18+
&& let TyKind::Path(option_qpath) = option_ty.kind
19+
&& let res = cx.qpath_res(&option_qpath, option_ty.hir_id)
20+
&& let Res::Def(.., def_id) = res
21+
&& is_lang_item_or_ctor(cx, def_id, LangItem::Option)
22+
{
23+
let outer_ty = last_path_segment(qpath).ident.name;
24+
span_lint_and_help(
25+
cx,
26+
NULL_POINTER_OPTIMIZATION,
27+
ty.span,
28+
&format!("usage of `{outer_ty}<Option<T>>`"),
29+
None,
30+
&format!("consider using `Option<{outer_ty}<T>>` instead, as it will grant better performance. For more information, see\n\
31+
https://doc.rust-lang.org/core/option/#representation"),
32+
);
33+
34+
return true;
35+
}
36+
}
37+
38+
false
39+
}

clippy_lints/src/utils/conf.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ define_Conf! {
289289
/// arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
290290
/// ```
291291
(arithmetic_side_effects_allowed_unary: rustc_data_structures::fx::FxHashSet<String> = <_>::default()),
292-
/// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX, UNNECESSARY_BOX_RETURNS.
292+
/// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX, UNNECESSARY_BOX_RETURNS, NULL_POINTER_OPTIMIZATION.
293293
///
294294
/// Suppress lints whenever the suggested change would cause breakage for other crates.
295295
(avoid_breaking_exported_api: bool = true),

0 commit comments

Comments
 (0)