diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index 00b023c26f3..3435a5a6c82 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -51,15 +51,13 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option { let name = cx.tcx.item_name(def_id).to_ident_string(); - return Some(format!("{}{}", name, gen_args(path.segments.last().unwrap()))); + let path_segment = path.segments.last().unwrap(); + return Some(format!("{}{}", name, gen_args(cx, path_segment))); } Res::SelfTy(None, Some((did, _))) => { if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() { if cx.tcx.has_attr(adt.did, sym::rustc_pass_by_value) { - let name = cx.tcx.item_name(adt.did).to_ident_string(); - let param = - substs.first().map(|s| format!("<{}>", s)).unwrap_or("".to_string()); - return Some(format!("{}{}", name, param)); + return Some(cx.tcx.def_path_str_with_substs(adt.did, substs)); } } } @@ -70,22 +68,29 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option) -> String { +fn gen_args(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> String { if let Some(args) = &segment.args { - let lifetimes = args + let params = args .args .iter() - .filter_map(|arg| { - if let GenericArg::Lifetime(lt) = arg { - Some(lt.name.ident().to_string()) - } else { - None + .filter_map(|arg| match arg { + GenericArg::Lifetime(lt) => Some(lt.name.ident().to_string()), + GenericArg::Type(ty) => { + let snippet = + cx.tcx.sess.source_map().span_to_snippet(ty.span).unwrap_or_default(); + Some(snippet) } + GenericArg::Const(c) => { + let snippet = + cx.tcx.sess.source_map().span_to_snippet(c.span).unwrap_or_default(); + Some(snippet) + } + _ => None, }) .collect::>(); - if !lifetimes.is_empty() { - return format!("<{}>", lifetimes.join(", ")); + if !params.is_empty() { + return format!("<{}>", params.join(", ")); } } 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 293464c07ef..f8ab0f056d7 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 @@ -98,4 +98,19 @@ impl CustomStruct { } } +#[rustc_pass_by_value] +struct WithParameters { + slice: [T; N], + m: M, +} + +impl WithParameters { + fn test( + value: WithParameters, + reference: &WithParameters, //~ ERROR passing `WithParameters` by reference + reference_with_m: &WithParameters, //~ ERROR passing `WithParameters` 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 dbb9180ed7d..c5307f0f67d 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 @@ -100,5 +100,17 @@ error: passing `CustomAlias<>` by reference LL | reference: &CustomAlias, | ^^^^^^^^^^^^ help: try passing by value: `CustomAlias<>` -error: aborting due to 16 previous errors +error: passing `WithParameters` by reference + --> $DIR/rustc_pass_by_value.rs:110:20 + | +LL | reference: &WithParameters, + | ^^^^^^^^^^^^^^^^^^^^^ help: try passing by value: `WithParameters` + +error: passing `WithParameters` by reference + --> $DIR/rustc_pass_by_value.rs:111:27 + | +LL | reference_with_m: &WithParameters, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try passing by value: `WithParameters` + +error: aborting due to 18 previous errors 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 1be01e21bd5..2868517774d 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 @@ -37,4 +37,18 @@ impl Foo { fn with_ref(&self) {} //~ ERROR passing `Foo` by reference } +#[rustc_pass_by_value] +struct WithParameters { + slice: [T; N], + m: M, +} + +impl WithParameters { + fn with_ref(&self) {} //~ ERROR passing `WithParameters` by reference +} + +impl WithParameters { + fn with_ref(&self) {} //~ ERROR passing `WithParameters` 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 965e79d962c..54a7cf7cab7 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 @@ -22,5 +22,17 @@ error: passing `Foo` by reference LL | fn with_ref(&self) {} | ^^^^^ help: try passing by value: `Foo` -error: aborting due to 3 previous errors +error: passing `WithParameters` by reference + --> $DIR/rustc_pass_by_value_self.rs:47:17 + | +LL | fn with_ref(&self) {} + | ^^^^^ help: try passing by value: `WithParameters` + +error: passing `WithParameters` by reference + --> $DIR/rustc_pass_by_value_self.rs:51:17 + | +LL | fn with_ref(&self) {} + | ^^^^^ help: try passing by value: `WithParameters` + +error: aborting due to 5 previous errors