Skip to content

Commit a6762e9

Browse files
committed
rustc_pass_by_value: allow types with no parameters on self
includes minor refactorings
1 parent 71e3314 commit a6762e9

File tree

4 files changed

+20
-15
lines changed

4 files changed

+20
-15
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
625625
),
626626
rustc_attr!(
627627
rustc_pass_by_value, Normal,
628-
template!(Word, NameValueStr: "reason"), WarnFollowing,
628+
template!(Word), WarnFollowing,
629629
"#[rustc_pass_by_value] is used to mark types that must be passed by value instead of reference."
630630
),
631631
BuiltinAttribute {

compiler/rustc_lint/src/pass_by_value.rs

+5-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use crate::{LateContext, LateLintPass, LintContext};
22
use rustc_errors::Applicability;
33
use rustc_hir as hir;
44
use rustc_hir::def::Res;
5-
use rustc_hir::def_id::DefId;
65
use rustc_hir::{GenericArg, PathSegment, QPath, TyKind};
76
use rustc_middle::ty;
87
use rustc_span::symbol::sym;
@@ -50,15 +49,17 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue {
5049
fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<String> {
5150
if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind {
5251
match path.res {
53-
Res::Def(_, def_id) if has_pass_by_value_attr(cx, def_id) => {
52+
Res::Def(_, def_id) if cx.tcx.has_attr(def_id, sym::rustc_pass_by_value) => {
5453
let name = cx.tcx.item_name(def_id).to_ident_string();
5554
return Some(format!("{}{}", name, gen_args(path.segments.last().unwrap())));
5655
}
5756
Res::SelfTy(None, Some((did, _))) => {
5857
if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
59-
if has_pass_by_value_attr(cx, adt.did) {
58+
if cx.tcx.has_attr(adt.did, sym::rustc_pass_by_value) {
6059
let name = cx.tcx.item_name(adt.did).to_ident_string();
61-
return Some(format!("{}<{}>", name, substs[0]));
60+
let param =
61+
substs.first().map(|s| format!("<{}>", s)).unwrap_or("".to_string());
62+
return Some(format!("{}{}", name, param));
6263
}
6364
}
6465
}
@@ -69,15 +70,6 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri
6970
None
7071
}
7172

72-
fn has_pass_by_value_attr(cx: &LateContext<'_>, def_id: DefId) -> bool {
73-
for attr in cx.tcx.get_attrs(def_id).iter() {
74-
if attr.has_name(sym::rustc_pass_by_value) {
75-
return true;
76-
}
77-
}
78-
false
79-
}
80-
8173
fn gen_args(segment: &PathSegment<'_>) -> String {
8274
if let Some(args) = &segment.args {
8375
let lifetimes = args

src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs

+7
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,11 @@ impl<'tcx> TyS<'tcx> {
3030
fn by_ref(self: &Ty<'tcx>) {} //~ ERROR passing `Ty<'tcx>` by reference
3131
}
3232

33+
#[rustc_pass_by_value]
34+
struct Foo;
35+
36+
impl Foo {
37+
fn with_ref(&self) {} //~ ERROR passing `Foo` by reference
38+
}
39+
3340
fn main() {}

src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,11 @@ error: passing `Ty<'tcx>` by reference
1616
LL | fn by_ref(self: &Ty<'tcx>) {}
1717
| ^^^^^^^^^ help: try passing by value: `Ty<'tcx>`
1818

19-
error: aborting due to 2 previous errors
19+
error: passing `Foo` by reference
20+
--> $DIR/rustc_pass_by_value_self.rs:37:17
21+
|
22+
LL | fn with_ref(&self) {}
23+
| ^^^^^ help: try passing by value: `Foo`
24+
25+
error: aborting due to 3 previous errors
2026

0 commit comments

Comments
 (0)