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 { 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, 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