Skip to content

Commit

Permalink
Merge pull request rust-lang#3321 from 0ndorio/fix/1123_false_positiv…
Browse files Browse the repository at this point in the history
…e_on_boxed_local

Avoid linting `boxed_local` on trait implementations.
  • Loading branch information
oli-obk authored Oct 16, 2018
2 parents eb683e6 + 2d8b4f3 commit 6ae89c4
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 7 deletions.
13 changes: 12 additions & 1 deletion clippy_lints/src/escape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ impl LintPass for Pass {
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {

fn check_fn(
&mut self,
cx: &LateContext<'a, 'tcx>,
Expand All @@ -74,13 +75,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
_: Span,
node_id: NodeId,
) {
let fn_def_id = cx.tcx.hir.local_def_id(node_id);
// If the method is an impl for a trait, don't warn
let parent_id = cx.tcx.hir.get_parent(node_id);
let parent_node = cx.tcx.hir.find(parent_id);

if let Some(Node::Item(item)) = parent_node {
if let ItemKind::Impl(_, _, _, _, Some(..), _, _) = item.node {
return;
}
}

let mut v = EscapeDelegate {
cx,
set: NodeSet(),
too_large_for_stack: self.too_large_for_stack,
};

let fn_def_id = cx.tcx.hir.local_def_id(node_id);
let region_scope_tree = &cx.tcx.region_scope_tree(fn_def_id);
ExprUseVisitor::new(&mut v, cx.tcx, cx.param_env, region_scope_tree, cx.tables, None).consume_body(body);

Expand Down
34 changes: 28 additions & 6 deletions tests/ui/escape_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.


#![feature(box_syntax)]

#![allow(warnings, clippy)]

#![warn(boxed_local)]
#![allow(clippy::borrowed_box, clippy::needless_pass_by_value, clippy::unused_unit)]
#![warn(clippy::boxed_local)]

#[derive(Clone)]
struct A;
Expand Down Expand Up @@ -70,8 +68,7 @@ fn warn_pass() {
}

fn nowarn_return() -> Box<A> {
let fx = box A;
fx // moved out, "escapes"
box A // moved out, "escapes"
}

fn nowarn_move() {
Expand Down Expand Up @@ -139,3 +136,28 @@ pub struct PeekableSeekable<I: Foo> {

pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {
}

/// Regression for #916, #1123
///
/// This shouldn't warn for `boxed_local`as the implementation of a trait
/// can't change much about the trait definition.
trait BoxedAction {
fn do_sth(self: Box<Self>);
}

impl BoxedAction for u64 {
fn do_sth(self: Box<Self>) {
println!("{}", *self)
}
}

/// Regression for #1478
///
/// This shouldn't warn for `boxed_local`as self itself is a box type.
trait MyTrait {
fn do_sth(self);
}

impl<T> MyTrait for Box<T> {
fn do_sth(self) {}
}
16 changes: 16 additions & 0 deletions tests/ui/escape_analysis.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error: local variable doesn't need to be boxed here
--> $DIR/escape_analysis.rs:45:13
|
45 | fn warn_arg(x: Box<A>) {
| ^
|
= note: `-D clippy::boxed-local` implied by `-D warnings`

error: local variable doesn't need to be boxed here
--> $DIR/escape_analysis.rs:137:12
|
137 | pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {
| ^^^^^^^^^^^

error: aborting due to 2 previous errors

0 comments on commit 6ae89c4

Please sign in to comment.