Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit e9964f2

Browse files
committed
stable_sort_primitive: print the type that is being sorted in the lint message
1 parent 27ae4d3 commit e9964f2

File tree

3 files changed

+36
-15
lines changed

3 files changed

+36
-15
lines changed

clippy_lints/src/stable_sort_primitive.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,18 @@ struct LintDetection {
8686
slice_name: String,
8787
method: SortingKind,
8888
method_args: String,
89+
slice_type: String,
8990
}
9091

9192
fn detect_stable_sort_primitive(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintDetection> {
9293
if_chain! {
9394
if let ExprKind::MethodCall(method_name, _, args, _) = &expr.kind;
9495
if let Some(slice) = &args.get(0);
9596
if let Some(method) = SortingKind::from_stable_name(&method_name.ident.name.as_str());
96-
if is_slice_of_primitives(cx, slice);
97+
if let Some(slice_type) = is_slice_of_primitives(cx, slice);
9798
then {
9899
let args_str = args.iter().skip(1).map(|arg| Sugg::hir(cx, arg, "..").to_string()).collect::<Vec<String>>().join(", ");
99-
Some(LintDetection { slice_name: Sugg::hir(cx, slice, "..").to_string(), method, method_args: args_str })
100+
Some(LintDetection { slice_name: Sugg::hir(cx, slice, "..").to_string(), method, method_args: args_str, slice_type })
100101
} else {
101102
None
102103
}
@@ -111,9 +112,10 @@ impl LateLintPass<'_> for StableSortPrimitive {
111112
STABLE_SORT_PRIMITIVE,
112113
expr.span,
113114
format!(
114-
"used {} instead of {}",
115+
"used {} instead of {} to sort primitive type `{}`",
115116
detection.method.stable_name(),
116-
detection.method.unstable_name()
117+
detection.method.unstable_name(),
118+
detection.slice_type,
117119
)
118120
.as_str(),
119121
"try",

clippy_lints/src/utils/mod.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,11 +1409,13 @@ pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool {
14091409
}
14101410
}
14111411

1412-
/// Returns true iff the given expression is a slice of primitives (as defined in the
1413-
/// `is_recursively_primitive_type` function).
1414-
pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
1412+
/// Returns Option<String> where String is a textual representation of the type encapsulated in the
1413+
/// slice iff the given expression is a slice of primitives (as defined in the
1414+
/// `is_recursively_primitive_type` function) and None otherwise.
1415+
pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
14151416
let expr_type = cx.typeck_results().expr_ty_adjusted(expr);
1416-
match expr_type.kind {
1417+
let expr_kind = &expr_type.kind;
1418+
let is_primitive = match expr_kind {
14171419
ty::Slice(ref element_type)
14181420
| ty::Ref(
14191421
_,
@@ -1424,7 +1426,24 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
14241426
_,
14251427
) => is_recursively_primitive_type(element_type),
14261428
_ => false,
1429+
};
1430+
1431+
if is_primitive {
1432+
// if we have wrappers like Array, Slice or Tuple, print these
1433+
// and get the type enclosed in the slice ref
1434+
match expr_type.peel_refs().walk().nth(1).unwrap().expect_ty().kind {
1435+
ty::Slice(..) => return Some("slice".into()),
1436+
ty::Array(..) => return Some("array".into()),
1437+
ty::Tuple(..) => return Some("tuple".into()),
1438+
_ => {
1439+
// is_recursively_primitive_type() should have taken care
1440+
// of the rest and we can rely on the type that is found
1441+
let refs_peeled = expr_type.peel_refs();
1442+
return Some(refs_peeled.walk().last().unwrap().to_string());
1443+
},
1444+
}
14271445
}
1446+
None
14281447
}
14291448

14301449
#[macro_export]

tests/ui/stable_sort_primitive.stderr

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
1-
error: used sort instead of sort_unstable
1+
error: used sort instead of sort_unstable to sort primitive type `i32`
22
--> $DIR/stable_sort_primitive.rs:7:5
33
|
44
LL | vec.sort();
55
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
66
|
77
= note: `-D clippy::stable-sort-primitive` implied by `-D warnings`
88

9-
error: used sort instead of sort_unstable
9+
error: used sort instead of sort_unstable to sort primitive type `bool`
1010
--> $DIR/stable_sort_primitive.rs:9:5
1111
|
1212
LL | vec.sort();
1313
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
1414

15-
error: used sort instead of sort_unstable
15+
error: used sort instead of sort_unstable to sort primitive type `char`
1616
--> $DIR/stable_sort_primitive.rs:11:5
1717
|
1818
LL | vec.sort();
1919
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
2020

21-
error: used sort instead of sort_unstable
21+
error: used sort instead of sort_unstable to sort primitive type `str`
2222
--> $DIR/stable_sort_primitive.rs:13:5
2323
|
2424
LL | vec.sort();
2525
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
2626

27-
error: used sort instead of sort_unstable
27+
error: used sort instead of sort_unstable to sort primitive type `tuple`
2828
--> $DIR/stable_sort_primitive.rs:15:5
2929
|
3030
LL | vec.sort();
3131
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
3232

33-
error: used sort instead of sort_unstable
33+
error: used sort instead of sort_unstable to sort primitive type `array`
3434
--> $DIR/stable_sort_primitive.rs:17:5
3535
|
3636
LL | vec.sort();
3737
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
3838

39-
error: used sort instead of sort_unstable
39+
error: used sort instead of sort_unstable to sort primitive type `i32`
4040
--> $DIR/stable_sort_primitive.rs:19:5
4141
|
4242
LL | arr.sort();

0 commit comments

Comments
 (0)