about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMahdi Dibaiee <mdibaiee@pm.me>2022-01-11 19:59:06 +0000
committerMahdi Dibaiee <mdibaiee@pm.me>2022-01-11 19:59:06 +0000
commit959bf2bc2e79defd0fe7d3c9987a6023eb8503cd (patch)
treeb0e1b5402b5091c4c9132c8fa126302b91f67e3a
parenta6762e962e50d5b6f864e33ebb27878e90651f22 (diff)
downloadrust-959bf2bc2e79defd0fe7d3c9987a6023eb8503cd.tar.gz
rust-959bf2bc2e79defd0fe7d3c9987a6023eb8503cd.zip
rustc_pass_by_value: handle generic and const type parameters
-rw-r--r--compiler/rustc_lint/src/pass_by_value.rs33
-rw-r--r--src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.rs15
-rw-r--r--src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr14
-rw-r--r--src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs14
-rw-r--r--src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr14
5 files changed, 74 insertions, 16 deletions
diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs
index 00b023c26f3..3435a5a6c82 100644
--- a/compiler/rustc_lint/src/pass_by_value.rs
+++ b/compiler/rustc_lint/src/pass_by_value.rs
@@ -51,15 +51,13 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri
         match path.res {
             Res::Def(_, def_id) if cx.tcx.has_attr(def_id, sym::rustc_pass_by_value) => {
                 let name = cx.tcx.item_name(def_id).to_ident_string();
-                return Some(format!("{}{}", name, gen_args(path.segments.last().unwrap())));
+                let path_segment = path.segments.last().unwrap();
+                return Some(format!("{}{}", name, gen_args(cx, path_segment)));
             }
             Res::SelfTy(None, Some((did, _))) => {
                 if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
                     if cx.tcx.has_attr(adt.did, sym::rustc_pass_by_value) {
-                        let name = cx.tcx.item_name(adt.did).to_ident_string();
-                        let param =
-                            substs.first().map(|s| format!("<{}>", s)).unwrap_or("".to_string());
-                        return Some(format!("{}{}", name, param));
+                        return Some(cx.tcx.def_path_str_with_substs(adt.did, substs));
                     }
                 }
             }
@@ -70,22 +68,29 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri
     None
 }
 
-fn gen_args(segment: &PathSegment<'_>) -> String {
+fn gen_args(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> String {
     if let Some(args) = &segment.args {
-        let lifetimes = args
+        let params = args
             .args
             .iter()
-            .filter_map(|arg| {
-                if let GenericArg::Lifetime(lt) = arg {
-                    Some(lt.name.ident().to_string())
-                } else {
-                    None
+            .filter_map(|arg| match arg {
+                GenericArg::Lifetime(lt) => Some(lt.name.ident().to_string()),
+                GenericArg::Type(ty) => {
+                    let snippet =
+                        cx.tcx.sess.source_map().span_to_snippet(ty.span).unwrap_or_default();
+                    Some(snippet)
                 }
+                GenericArg::Const(c) => {
+                    let snippet =
+                        cx.tcx.sess.source_map().span_to_snippet(c.span).unwrap_or_default();
+                    Some(snippet)
+                }
+                _ => None,
             })
             .collect::<Vec<_>>();
 
-        if !lifetimes.is_empty() {
-            return format!("<{}>", lifetimes.join(", "));
+        if !params.is_empty() {
+            return format!("<{}>", params.join(", "));
         }
     }
 
diff --git a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.rs b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.rs
index 293464c07ef..f8ab0f056d7 100644
--- a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.rs
+++ b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.rs
@@ -98,4 +98,19 @@ impl CustomStruct {
     }
 }
 
+#[rustc_pass_by_value]
+struct WithParameters<T, const N: usize, M = u32> {
+    slice: [T; N],
+    m: M,
+}
+
+impl<T> WithParameters<T, 1> {
+    fn test(
+        value: WithParameters<T, 1>,
+        reference: &WithParameters<T, 1>, //~ ERROR passing `WithParameters<T, 1>` by reference
+        reference_with_m: &WithParameters<T, 1, u32>, //~ ERROR passing `WithParameters<T, 1, u32>` by reference
+    ) {
+    }
+}
+
 fn main() {}
diff --git a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr
index dbb9180ed7d..c5307f0f67d 100644
--- a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr
+++ b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr
@@ -100,5 +100,17 @@ error: passing `CustomAlias<>` by reference
 LL |         reference: &CustomAlias,
    |                    ^^^^^^^^^^^^ help: try passing by value: `CustomAlias<>`
 
-error: aborting due to 16 previous errors
+error: passing `WithParameters<T, 1>` by reference
+  --> $DIR/rustc_pass_by_value.rs:110:20
+   |
+LL |         reference: &WithParameters<T, 1>,
+   |                    ^^^^^^^^^^^^^^^^^^^^^ help: try passing by value: `WithParameters<T, 1>`
+
+error: passing `WithParameters<T, 1, u32>` by reference
+  --> $DIR/rustc_pass_by_value.rs:111:27
+   |
+LL |         reference_with_m: &WithParameters<T, 1, u32>,
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try passing by value: `WithParameters<T, 1, u32>`
+
+error: aborting due to 18 previous errors
 
diff --git a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs
index 1be01e21bd5..2868517774d 100644
--- a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs
+++ b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs
@@ -37,4 +37,18 @@ impl Foo {
     fn with_ref(&self) {} //~ ERROR passing `Foo` by reference
 }
 
+#[rustc_pass_by_value]
+struct WithParameters<T, const N: usize, M = u32> {
+    slice: [T; N],
+    m: M,
+}
+
+impl<T> WithParameters<T, 1> {
+    fn with_ref(&self) {} //~ ERROR passing `WithParameters<T, 1_usize>` by reference
+}
+
+impl<T> WithParameters<T, 1, u8> {
+    fn with_ref(&self) {} //~ ERROR passing `WithParameters<T, 1_usize, u8>` by reference
+}
+
 fn main() {}
diff --git a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr
index 965e79d962c..54a7cf7cab7 100644
--- a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr
+++ b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr
@@ -22,5 +22,17 @@ error: passing `Foo` by reference
 LL |     fn with_ref(&self) {}
    |                 ^^^^^ help: try passing by value: `Foo`
 
-error: aborting due to 3 previous errors
+error: passing `WithParameters<T, 1_usize>` by reference
+  --> $DIR/rustc_pass_by_value_self.rs:47:17
+   |
+LL |     fn with_ref(&self) {}
+   |                 ^^^^^ help: try passing by value: `WithParameters<T, 1_usize>`
+
+error: passing `WithParameters<T, 1_usize, u8>` by reference
+  --> $DIR/rustc_pass_by_value_self.rs:51:17
+   |
+LL |     fn with_ref(&self) {}
+   |                 ^^^^^ help: try passing by value: `WithParameters<T, 1_usize, u8>`
+
+error: aborting due to 5 previous errors