2018-05-11 06:20:39 -05:00
|
|
|
#![feature(box_syntax)]
|
2019-09-16 10:50:36 -05:00
|
|
|
#![allow(
|
|
|
|
clippy::borrowed_box,
|
|
|
|
clippy::needless_pass_by_value,
|
|
|
|
clippy::unused_unit,
|
2020-01-19 04:07:13 -06:00
|
|
|
clippy::redundant_clone,
|
2020-01-26 10:03:39 -06:00
|
|
|
clippy::match_single_binding
|
2019-09-16 10:50:36 -05:00
|
|
|
)]
|
2018-10-15 13:20:50 -05:00
|
|
|
#![warn(clippy::boxed_local)]
|
2015-12-04 04:12:53 -06:00
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
struct A;
|
|
|
|
|
|
|
|
impl A {
|
2018-12-09 16:26:16 -06:00
|
|
|
fn foo(&self) {}
|
2015-12-04 04:12:53 -06:00
|
|
|
}
|
|
|
|
|
2016-02-01 13:37:07 -06:00
|
|
|
trait Z {
|
|
|
|
fn bar(&self);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Z for A {
|
|
|
|
fn bar(&self) {
|
|
|
|
//nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-09 16:26:16 -06:00
|
|
|
fn main() {}
|
2015-12-04 04:12:53 -06:00
|
|
|
|
2019-05-30 01:23:47 -05:00
|
|
|
fn ok_box_trait(boxed_trait: &Box<dyn Z>) {
|
2016-02-01 13:37:07 -06:00
|
|
|
let boxed_local = boxed_trait;
|
|
|
|
// done
|
|
|
|
}
|
|
|
|
|
2015-12-04 04:12:53 -06:00
|
|
|
fn warn_call() {
|
2017-02-08 07:58:07 -06:00
|
|
|
let x = box A;
|
2016-09-09 13:24:00 -05:00
|
|
|
x.foo();
|
2015-12-04 04:12:53 -06:00
|
|
|
}
|
|
|
|
|
2017-02-08 07:58:07 -06:00
|
|
|
fn warn_arg(x: Box<A>) {
|
2015-12-28 08:12:57 -06:00
|
|
|
x.foo();
|
|
|
|
}
|
|
|
|
|
2016-02-01 05:35:01 -06:00
|
|
|
fn nowarn_closure_arg() {
|
|
|
|
let x = Some(box A);
|
|
|
|
x.map_or((), |x| take_ref(&x));
|
|
|
|
}
|
|
|
|
|
2015-12-04 04:12:53 -06:00
|
|
|
fn warn_rename_call() {
|
|
|
|
let x = box A;
|
|
|
|
|
2017-02-08 07:58:07 -06:00
|
|
|
let y = x;
|
2015-12-04 04:12:53 -06:00
|
|
|
y.foo(); // via autoderef
|
|
|
|
}
|
|
|
|
|
|
|
|
fn warn_notuse() {
|
2017-02-08 07:58:07 -06:00
|
|
|
let bz = box A;
|
2015-12-04 04:12:53 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn warn_pass() {
|
2017-02-08 07:58:07 -06:00
|
|
|
let bz = box A;
|
2015-12-04 04:12:53 -06:00
|
|
|
take_ref(&bz); // via deref coercion
|
|
|
|
}
|
|
|
|
|
|
|
|
fn nowarn_return() -> Box<A> {
|
2018-10-15 13:20:50 -05:00
|
|
|
box A // moved out, "escapes"
|
2015-12-04 04:12:53 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn nowarn_move() {
|
|
|
|
let bx = box A;
|
|
|
|
drop(bx) // moved in, "escapes"
|
|
|
|
}
|
|
|
|
fn nowarn_call() {
|
|
|
|
let bx = box A;
|
|
|
|
bx.clone(); // method only available to Box, not via autoderef
|
|
|
|
}
|
|
|
|
|
|
|
|
fn nowarn_pass() {
|
|
|
|
let bx = box A;
|
|
|
|
take_box(&bx); // fn needs &Box
|
|
|
|
}
|
|
|
|
|
|
|
|
fn take_box(x: &Box<A>) {}
|
|
|
|
fn take_ref(x: &A) {}
|
|
|
|
|
|
|
|
fn nowarn_ref_take() {
|
|
|
|
// false positive, should actually warn
|
2017-02-08 07:58:07 -06:00
|
|
|
let x = box A;
|
2015-12-04 04:12:53 -06:00
|
|
|
let y = &x;
|
|
|
|
take_box(y);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn nowarn_match() {
|
|
|
|
let x = box A; // moved into a match
|
|
|
|
match x {
|
2018-12-09 16:26:16 -06:00
|
|
|
y => drop(y),
|
2015-12-04 04:12:53 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn warn_match() {
|
2017-02-08 07:58:07 -06:00
|
|
|
let x = box A;
|
2018-12-09 16:26:16 -06:00
|
|
|
match &x {
|
|
|
|
// not moved
|
|
|
|
ref y => (),
|
2015-12-04 04:12:53 -06:00
|
|
|
}
|
2015-12-28 08:12:57 -06:00
|
|
|
}
|
2016-07-10 08:23:50 -05:00
|
|
|
|
|
|
|
fn nowarn_large_array() {
|
|
|
|
// should not warn, is large array
|
|
|
|
// and should not be on stack
|
|
|
|
let x = box [1; 10000];
|
2018-12-09 16:26:16 -06:00
|
|
|
match &x {
|
|
|
|
// not moved
|
|
|
|
ref y => (),
|
2016-07-10 08:23:50 -05:00
|
|
|
}
|
|
|
|
}
|
2016-12-22 07:16:07 -06:00
|
|
|
|
|
|
|
/// ICE regression test
|
|
|
|
pub trait Foo {
|
|
|
|
type Item;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Foo for &'a () {
|
|
|
|
type Item = ();
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct PeekableSeekable<I: Foo> {
|
|
|
|
_peeked: I::Item,
|
|
|
|
}
|
|
|
|
|
2018-12-09 16:26:16 -06:00
|
|
|
pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}
|
2018-10-15 13:20:50 -05:00
|
|
|
|
|
|
|
/// 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) {}
|
|
|
|
}
|
2019-02-20 22:59:10 -06:00
|
|
|
|
|
|
|
// Issue #3739 - capture in closures
|
|
|
|
mod issue_3739 {
|
|
|
|
use super::A;
|
|
|
|
|
|
|
|
fn consume<T>(_: T) {}
|
|
|
|
fn borrow<T>(_: &T) {}
|
|
|
|
|
|
|
|
fn closure_consume(x: Box<A>) {
|
|
|
|
let _ = move || {
|
|
|
|
consume(x);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
fn closure_borrow(x: Box<A>) {
|
|
|
|
let _ = || {
|
|
|
|
borrow(&x);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2020-10-07 20:49:50 -05:00
|
|
|
|
|
|
|
/// Issue #5542
|
|
|
|
///
|
2020-10-08 07:07:24 -05:00
|
|
|
/// This shouldn't warn for `boxed_local` as it is intended to called from non-Rust code.
|
2020-10-08 07:06:19 -05:00
|
|
|
pub extern "C" fn do_not_warn_me(_c_pointer: Box<String>) -> () {}
|
2020-10-08 16:50:52 -05:00
|
|
|
|
|
|
|
#[rustfmt::skip] // Forces rustfmt to not add ABI
|
|
|
|
pub extern fn do_not_warn_me_no_abi(_c_pointer: Box<String>) -> () {}
|