Skip to content

Commit 91feb76

Browse files
committed
Skip unused_allocation lint when method takes &Box<Self>
1 parent ef2657c commit 91feb76

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

compiler/rustc_lint/src/unused.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1782,7 +1782,7 @@ declare_lint! {
17821782
declare_lint_pass!(UnusedAllocation => [UNUSED_ALLOCATION]);
17831783

17841784
impl<'tcx> LateLintPass<'tcx> for UnusedAllocation {
1785-
fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) {
1785+
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &hir::Expr<'_>) {
17861786
match e.kind {
17871787
hir::ExprKind::Call(path_expr, [_])
17881788
if let hir::ExprKind::Path(qpath) = &path_expr.kind
@@ -1793,6 +1793,12 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation {
17931793

17941794
for adj in cx.typeck_results().expr_adjustments(e) {
17951795
if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(m)) = adj.kind {
1796+
if let ty::Ref(_, inner_ty, _) = adj.target.kind()
1797+
&& inner_ty.is_box()
1798+
{
1799+
// If the target type is `&Box<T>` or `&mut Box<T>`, the allocation is necessary
1800+
continue;
1801+
}
17961802
match m {
17971803
adjustment::AutoBorrowMutability::Not => {
17981804
cx.emit_span_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationDiag);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//@ check-pass
2+
// Test for issue #151846: unused_allocation warning should ignore
3+
// allocations to pass Box to things taking self: &Box
4+
5+
#![deny(unused_allocation)]
6+
7+
struct MyStruct;
8+
9+
trait TraitTakesBoxRef {
10+
fn trait_takes_box_ref(&self);
11+
}
12+
13+
impl TraitTakesBoxRef for Box<MyStruct> {
14+
fn trait_takes_box_ref(&self) {}
15+
}
16+
17+
impl MyStruct {
18+
fn inherent_takes_box_ref(self: &Box<Self>) {}
19+
}
20+
21+
fn takes_box_ref(_: &Box<MyStruct>) {}
22+
23+
trait TraitTakesBoxVal {
24+
fn trait_takes_box_val(self);
25+
}
26+
27+
impl TraitTakesBoxVal for Box<MyStruct> {
28+
fn trait_takes_box_val(self) {}
29+
}
30+
31+
impl MyStruct {
32+
fn inherent_takes_box_val(self: Box<Self>) {}
33+
}
34+
35+
fn takes_box_val(_: Box<MyStruct>) {}
36+
37+
pub fn foo() {
38+
// These should NOT warn - the allocation is necessary because
39+
// the method takes &Box<Self>
40+
Box::new(MyStruct).trait_takes_box_ref();
41+
Box::new(MyStruct).inherent_takes_box_ref();
42+
takes_box_ref(&Box::new(MyStruct));
43+
44+
// These already don't warn - the allocation is necessary
45+
Box::new(MyStruct).trait_takes_box_val();
46+
Box::new(MyStruct).inherent_takes_box_val();
47+
takes_box_val(Box::new(MyStruct));
48+
49+
// Fully-qualified syntax also does not warn:
50+
<Box<MyStruct> as TraitTakesBoxRef>::trait_takes_box_ref(&Box::new(MyStruct));
51+
MyStruct::inherent_takes_box_ref(&Box::new(MyStruct));
52+
}
53+
54+
fn main() {}

0 commit comments

Comments
 (0)