about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-24 18:08:39 +0000
committerbors <bors@rust-lang.org>2020-08-24 18:08:39 +0000
commit8d9a485ef11c3c30fb87f35f61278027e7370510 (patch)
treeffde6c701c34a752bc091a3c03461aa1670ca05c
parent27ae4d303ce9103a104c57088913741ab17f4d36 (diff)
parente9964f2e8a1903d46e576f67122e234f719a90f0 (diff)
downloadrust-8d9a485ef11c3c30fb87f35f61278027e7370510.tar.gz
rust-8d9a485ef11c3c30fb87f35f61278027e7370510.zip
Auto merge of #5935 - matthiaskrgr:unstable_sort_ty_name, r=flip1995
stable_sort_primitive: print the type that is being sorted in the lint message

changelog: stable_sort_primitive: print the type that is being sorted in the lint message
-rw-r--r--clippy_lints/src/stable_sort_primitive.rs10
-rw-r--r--clippy_lints/src/utils/mod.rs27
-rw-r--r--tests/ui/stable_sort_primitive.stderr14
3 files changed, 36 insertions, 15 deletions
diff --git a/clippy_lints/src/stable_sort_primitive.rs b/clippy_lints/src/stable_sort_primitive.rs
index 22c49a20451..99e4b293ac6 100644
--- a/clippy_lints/src/stable_sort_primitive.rs
+++ b/clippy_lints/src/stable_sort_primitive.rs
@@ -86,6 +86,7 @@ struct LintDetection {
     slice_name: String,
     method: SortingKind,
     method_args: String,
+    slice_type: String,
 }
 
 fn detect_stable_sort_primitive(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintDetection> {
@@ -93,10 +94,10 @@ fn detect_stable_sort_primitive(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option
         if let ExprKind::MethodCall(method_name, _, args, _) = &expr.kind;
         if let Some(slice) = &args.get(0);
         if let Some(method) = SortingKind::from_stable_name(&method_name.ident.name.as_str());
-        if is_slice_of_primitives(cx, slice);
+        if let Some(slice_type) = is_slice_of_primitives(cx, slice);
         then {
             let args_str = args.iter().skip(1).map(|arg| Sugg::hir(cx, arg, "..").to_string()).collect::<Vec<String>>().join(", ");
-            Some(LintDetection { slice_name: Sugg::hir(cx, slice, "..").to_string(), method, method_args: args_str })
+            Some(LintDetection { slice_name: Sugg::hir(cx, slice, "..").to_string(), method, method_args: args_str, slice_type })
         } else {
             None
         }
@@ -111,9 +112,10 @@ impl LateLintPass<'_> for StableSortPrimitive {
                 STABLE_SORT_PRIMITIVE,
                 expr.span,
                 format!(
-                    "used {} instead of {}",
+                    "used {} instead of {} to sort primitive type `{}`",
                     detection.method.stable_name(),
-                    detection.method.unstable_name()
+                    detection.method.unstable_name(),
+                    detection.slice_type,
                 )
                 .as_str(),
                 "try",
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 2aef995cec4..25301d6dede 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -1409,11 +1409,13 @@ pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool {
     }
 }
 
-/// Returns true iff the given expression is a slice of primitives (as defined in the
-/// `is_recursively_primitive_type` function).
-pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+/// Returns Option<String> where String is a textual representation of the type encapsulated in the
+/// slice iff the given expression is a slice of primitives (as defined in the
+/// `is_recursively_primitive_type` function) and None otherwise.
+pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
     let expr_type = cx.typeck_results().expr_ty_adjusted(expr);
-    match expr_type.kind {
+    let expr_kind = &expr_type.kind;
+    let is_primitive = match expr_kind {
         ty::Slice(ref element_type)
         | ty::Ref(
             _,
@@ -1424,7 +1426,24 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
             _,
         ) => is_recursively_primitive_type(element_type),
         _ => false,
+    };
+
+    if is_primitive {
+        // if we have wrappers like Array, Slice or Tuple, print these
+        // and get the type enclosed in the slice ref
+        match expr_type.peel_refs().walk().nth(1).unwrap().expect_ty().kind {
+            ty::Slice(..) => return Some("slice".into()),
+            ty::Array(..) => return Some("array".into()),
+            ty::Tuple(..) => return Some("tuple".into()),
+            _ => {
+                // is_recursively_primitive_type() should have taken care
+                // of the rest and we can rely on the type that is found
+                let refs_peeled = expr_type.peel_refs();
+                return Some(refs_peeled.walk().last().unwrap().to_string());
+            },
+        }
     }
+    None
 }
 
 #[macro_export]
diff --git a/tests/ui/stable_sort_primitive.stderr b/tests/ui/stable_sort_primitive.stderr
index b73012a4691..780389f32bc 100644
--- a/tests/ui/stable_sort_primitive.stderr
+++ b/tests/ui/stable_sort_primitive.stderr
@@ -1,4 +1,4 @@
-error: used sort instead of sort_unstable
+error: used sort instead of sort_unstable to sort primitive type `i32`
   --> $DIR/stable_sort_primitive.rs:7:5
    |
 LL |     vec.sort();
@@ -6,37 +6,37 @@ LL |     vec.sort();
    |
    = note: `-D clippy::stable-sort-primitive` implied by `-D warnings`
 
-error: used sort instead of sort_unstable
+error: used sort instead of sort_unstable to sort primitive type `bool`
   --> $DIR/stable_sort_primitive.rs:9:5
    |
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
 
-error: used sort instead of sort_unstable
+error: used sort instead of sort_unstable to sort primitive type `char`
   --> $DIR/stable_sort_primitive.rs:11:5
    |
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
 
-error: used sort instead of sort_unstable
+error: used sort instead of sort_unstable to sort primitive type `str`
   --> $DIR/stable_sort_primitive.rs:13:5
    |
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
 
-error: used sort instead of sort_unstable
+error: used sort instead of sort_unstable to sort primitive type `tuple`
   --> $DIR/stable_sort_primitive.rs:15:5
    |
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
 
-error: used sort instead of sort_unstable
+error: used sort instead of sort_unstable to sort primitive type `array`
   --> $DIR/stable_sort_primitive.rs:17:5
    |
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
 
-error: used sort instead of sort_unstable
+error: used sort instead of sort_unstable to sort primitive type `i32`
   --> $DIR/stable_sort_primitive.rs:19:5
    |
 LL |     arr.sort();