diff options
| -rw-r--r-- | compiler/rustc_lint/src/pass_by_value.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 11 | ||||
| -rw-r--r-- | src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.rs | 40 | ||||
| -rw-r--r-- | src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr | 52 |
4 files changed, 82 insertions, 22 deletions
diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index 0bfa2a673c2..0847f600f9d 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -11,6 +11,7 @@ declare_tool_lint! { /// The `rustc_pass_by_value` lint marks a type with `#[rustc_pass_by_value]` requiring it to always be passed by value. /// This is usually used for types that are thin wrappers around references, so there is no benefit to an extra /// layer of indirection. (Example: `Ty` which is a reference to a `TyS`) + /// This lint relies on `#[rustc_diagnostic_item]` being available for the target. pub rustc::PASS_BY_VALUE, Warn, "pass by reference of a type flagged as `#[rustc_pass_by_value]`", diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2febb2e56ec..e700a61ce48 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1070,20 +1070,15 @@ impl CheckAttrVisitor<'_> { /// Warns against some misuses of `#[pass_by_value]` fn check_pass_by_value(&self, attr: &Attribute, span: &Span, target: Target) -> bool { match target { - Target::Struct - | Target::Enum - | Target::Union - | Target::Trait - | Target::TraitAlias - | Target::TyAlias => true, + Target::Struct | Target::Enum | Target::TyAlias => true, _ => { self.tcx .sess .struct_span_err( attr.span, - "`pass_by_value` attribute should be applied to a struct, enum, trait or type alias.", + "`pass_by_value` attribute should be applied to a struct, enum or type alias.", ) - .span_label(*span, "is not a struct, enum, trait or type alias") + .span_label(*span, "is not a struct, enum or type alias") .emit(); false } 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 783019d8945..bf2b1fbaf45 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 @@ -1,5 +1,6 @@ // compile-flags: -Z unstable-options +#![feature(rustc_attrs)] #![feature(rustc_private)] #![deny(rustc::pass_by_value)] #![allow(unused)] @@ -61,4 +62,43 @@ impl Foo { //~^^ ERROR passing `TyCtxt<'_>` by reference } +#[rustc_diagnostic_item = "CustomEnum"] +#[rustc_pass_by_value] +enum CustomEnum { + A, + B, +} + +impl CustomEnum { + fn test( + value: CustomEnum, + reference: &CustomEnum, //~ ERROR passing `CustomEnum` by reference + ) { + } +} + +#[rustc_diagnostic_item = "CustomStruct"] +#[rustc_pass_by_value] +struct CustomStruct { + s: u8, +} + +#[rustc_diagnostic_item = "CustomAlias"] +#[rustc_pass_by_value] +type CustomAlias<'a> = &'a CustomStruct; //~ ERROR passing `CustomStruct` by reference + +impl CustomStruct { + fn test( + value: CustomStruct, + reference: &CustomStruct, //~ ERROR passing `CustomStruct` by reference + ) { + } + + fn test_alias( + value: CustomAlias, + reference: &CustomAlias, //~ ERROR passing `CustomAlias<>` 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 5fbde938789..c59c1adf899 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 @@ -1,80 +1,104 @@ error: passing `Ty<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:13:13 + --> $DIR/rustc_pass_by_value.rs:14:13 | LL | ty_ref: &Ty<'_>, | ^^^^^^^ help: try passing by value: `Ty<'_>` | note: the lint level is defined here - --> $DIR/rustc_pass_by_value.rs:4:9 + --> $DIR/rustc_pass_by_value.rs:5:9 | LL | #![deny(rustc::pass_by_value)] | ^^^^^^^^^^^^^^^^^^^^ error: passing `TyCtxt<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:15:18 + --> $DIR/rustc_pass_by_value.rs:16:18 | LL | ty_ctxt_ref: &TyCtxt<'_>, | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>` error: passing `Ty<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:19:28 + --> $DIR/rustc_pass_by_value.rs:20:28 | LL | fn ty_multi_ref(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {} | ^^^^^^^ help: try passing by value: `Ty<'_>` error: passing `TyCtxt<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:19:55 + --> $DIR/rustc_pass_by_value.rs:20:55 | LL | fn ty_multi_ref(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {} | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>` error: passing `Ty<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:26:17 + --> $DIR/rustc_pass_by_value.rs:27:17 | LL | ty_ref: &Ty<'_>, | ^^^^^^^ help: try passing by value: `Ty<'_>` error: passing `TyCtxt<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:28:22 + --> $DIR/rustc_pass_by_value.rs:29:22 | LL | ty_ctxt_ref: &TyCtxt<'_>, | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>` error: passing `Ty<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:31:41 + --> $DIR/rustc_pass_by_value.rs:32:41 | LL | fn ty_multi_ref_in_trait(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>); | ^^^^^^^ help: try passing by value: `Ty<'_>` error: passing `TyCtxt<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:31:68 + --> $DIR/rustc_pass_by_value.rs:32:68 | LL | fn ty_multi_ref_in_trait(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>); | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>` error: passing `Ty<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:53:17 + --> $DIR/rustc_pass_by_value.rs:54:17 | LL | ty_ref: &Ty<'_>, | ^^^^^^^ help: try passing by value: `Ty<'_>` error: passing `TyCtxt<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:55:22 + --> $DIR/rustc_pass_by_value.rs:56:22 | LL | ty_ctxt_ref: &TyCtxt<'_>, | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>` error: passing `Ty<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:59:38 + --> $DIR/rustc_pass_by_value.rs:60:38 | LL | fn ty_multi_ref_assoc(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {} | ^^^^^^^ help: try passing by value: `Ty<'_>` error: passing `TyCtxt<'_>` by reference - --> $DIR/rustc_pass_by_value.rs:59:65 + --> $DIR/rustc_pass_by_value.rs:60:65 | LL | fn ty_multi_ref_assoc(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {} | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>` -error: aborting due to 12 previous errors +error: passing `CustomEnum` by reference + --> $DIR/rustc_pass_by_value.rs:75:20 + | +LL | reference: &CustomEnum, + | ^^^^^^^^^^^ help: try passing by value: `CustomEnum` + +error: passing `CustomStruct` by reference + --> $DIR/rustc_pass_by_value.rs:88:24 + | +LL | type CustomAlias<'a> = &'a CustomStruct; + | ^^^^^^^^^^^^^^^^ help: try passing by value: `CustomStruct` + +error: passing `CustomStruct` by reference + --> $DIR/rustc_pass_by_value.rs:93:20 + | +LL | reference: &CustomStruct, + | ^^^^^^^^^^^^^ help: try passing by value: `CustomStruct` + +error: passing `CustomAlias<>` by reference + --> $DIR/rustc_pass_by_value.rs:99:20 + | +LL | reference: &CustomAlias, + | ^^^^^^^^^^^^ help: try passing by value: `CustomAlias<>` + +error: aborting due to 16 previous errors |
