mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
rustc_pass_by_value: allow types with no parameters on self
includes minor refactorings
This commit is contained in:
parent
71e3314673
commit
a6762e962e
@ -625,7 +625,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
),
|
),
|
||||||
rustc_attr!(
|
rustc_attr!(
|
||||||
rustc_pass_by_value, Normal,
|
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."
|
"#[rustc_pass_by_value] is used to mark types that must be passed by value instead of reference."
|
||||||
),
|
),
|
||||||
BuiltinAttribute {
|
BuiltinAttribute {
|
||||||
|
@ -2,7 +2,6 @@ use crate::{LateContext, LateLintPass, LintContext};
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::Res;
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_hir::{GenericArg, PathSegment, QPath, TyKind};
|
use rustc_hir::{GenericArg, PathSegment, QPath, TyKind};
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_span::symbol::sym;
|
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> {
|
fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<String> {
|
||||||
if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind {
|
if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind {
|
||||||
match path.res {
|
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();
|
let name = cx.tcx.item_name(def_id).to_ident_string();
|
||||||
return Some(format!("{}{}", name, gen_args(path.segments.last().unwrap())));
|
return Some(format!("{}{}", name, gen_args(path.segments.last().unwrap())));
|
||||||
}
|
}
|
||||||
Res::SelfTy(None, Some((did, _))) => {
|
Res::SelfTy(None, Some((did, _))) => {
|
||||||
if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
|
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();
|
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
|
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 {
|
fn gen_args(segment: &PathSegment<'_>) -> String {
|
||||||
if let Some(args) = &segment.args {
|
if let Some(args) = &segment.args {
|
||||||
let lifetimes = args
|
let lifetimes = args
|
||||||
|
@ -30,4 +30,11 @@ impl<'tcx> TyS<'tcx> {
|
|||||||
fn by_ref(self: &Ty<'tcx>) {} //~ ERROR passing `Ty<'tcx>` by reference
|
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() {}
|
fn main() {}
|
||||||
|
@ -16,5 +16,11 @@ error: passing `Ty<'tcx>` by reference
|
|||||||
LL | fn by_ref(self: &Ty<'tcx>) {}
|
LL | fn by_ref(self: &Ty<'tcx>) {}
|
||||||
| ^^^^^^^^^ help: try passing by value: `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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user