about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMahdi Dibaiee <mdibaiee@pm.me>2022-01-11 09:28:13 +0000
committerMahdi Dibaiee <mdibaiee@pm.me>2022-01-11 09:28:13 +0000
commita6762e962e50d5b6f864e33ebb27878e90651f22 (patch)
tree9c9ac8a3c059c4d84f3407d16611e63123c41458
parent71e33146734362984258df415ac8308618968ed4 (diff)
downloadrust-a6762e962e50d5b6f864e33ebb27878e90651f22.tar.gz
rust-a6762e962e50d5b6f864e33ebb27878e90651f22.zip
rustc_pass_by_value: allow types with no parameters on self
includes minor refactorings
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_lint/src/pass_by_value.rs18
-rw-r--r--src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs7
-rw-r--r--src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr8
4 files changed, 20 insertions, 15 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 88bf81864b2..46817bc9c3f 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -625,7 +625,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
     rustc_attr!(
         rustc_pass_by_value, Normal,
-        template!(Word, NameValueStr: "reason"), WarnFollowing,
+        template!(Word), WarnFollowing,
         "#[rustc_pass_by_value] is used to mark types that must be passed by value instead of reference."
     ),
     BuiltinAttribute {
diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs
index c689f34d9e3..00b023c26f3 100644
--- a/compiler/rustc_lint/src/pass_by_value.rs
+++ b/compiler/rustc_lint/src/pass_by_value.rs
@@ -2,7 +2,6 @@ use crate::{LateContext, LateLintPass, LintContext};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def::Res;
-use rustc_hir::def_id::DefId;
 use rustc_hir::{GenericArg, PathSegment, QPath, TyKind};
 use rustc_middle::ty;
 use rustc_span::symbol::sym;
@@ -50,15 +49,17 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue {
 fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<String> {
     if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind {
         match path.res {
-            Res::Def(_, def_id) if has_pass_by_value_attr(cx, def_id) => {
+            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())));
             }
             Res::SelfTy(None, Some((did, _))) => {
                 if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
-                    if has_pass_by_value_attr(cx, adt.did) {
+                    if cx.tcx.has_attr(adt.did, sym::rustc_pass_by_value) {
                         let name = cx.tcx.item_name(adt.did).to_ident_string();
-                        return Some(format!("{}<{}>", name, substs[0]));
+                        let param =
+                            substs.first().map(|s| format!("<{}>", s)).unwrap_or("".to_string());
+                        return Some(format!("{}{}", name, param));
                     }
                 }
             }
@@ -69,15 +70,6 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri
     None
 }
 
-fn has_pass_by_value_attr(cx: &LateContext<'_>, def_id: DefId) -> bool {
-    for attr in cx.tcx.get_attrs(def_id).iter() {
-        if attr.has_name(sym::rustc_pass_by_value) {
-            return true;
-        }
-    }
-    false
-}
-
 fn gen_args(segment: &PathSegment<'_>) -> String {
     if let Some(args) = &segment.args {
         let lifetimes = args
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 a4529f98563..1be01e21bd5 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
@@ -30,4 +30,11 @@ impl<'tcx> TyS<'tcx> {
     fn by_ref(self: &Ty<'tcx>) {} //~ ERROR passing `Ty<'tcx>` by reference
 }
 
+#[rustc_pass_by_value]
+struct Foo;
+
+impl Foo {
+    fn with_ref(&self) {} //~ ERROR passing `Foo` 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 ca47babd13d..965e79d962c 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
@@ -16,5 +16,11 @@ error: passing `Ty<'tcx>` by reference
 LL |     fn by_ref(self: &Ty<'tcx>) {}
    |                     ^^^^^^^^^ help: try passing by value: `Ty<'tcx>`
 
-error: aborting due to 2 previous errors
+error: passing `Foo` by reference
+  --> $DIR/rustc_pass_by_value_self.rs:37:17
+   |
+LL |     fn with_ref(&self) {}
+   |                 ^^^^^ help: try passing by value: `Foo`
+
+error: aborting due to 3 previous errors