2018-10-06 11:18:06 -05:00
|
|
|
// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2018-07-28 10:34:52 -05:00
|
|
|
#![warn(clippy::needless_pass_by_value)]
|
2018-12-09 16:26:16 -06:00
|
|
|
#![allow(
|
|
|
|
dead_code,
|
|
|
|
clippy::single_match,
|
|
|
|
clippy::redundant_pattern_matching,
|
|
|
|
clippy::many_single_char_names,
|
|
|
|
clippy::option_option
|
|
|
|
)]
|
2017-02-18 02:00:36 -06:00
|
|
|
|
2017-10-07 20:23:41 -05:00
|
|
|
use std::borrow::Borrow;
|
|
|
|
use std::convert::AsRef;
|
|
|
|
|
2017-02-20 01:45:37 -06:00
|
|
|
// `v` should be warned
|
2017-02-18 02:00:36 -06:00
|
|
|
// `w`, `x` and `y` are allowed (moved or mutated)
|
|
|
|
fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
|
|
|
|
assert_eq!(v.len(), 42);
|
|
|
|
|
|
|
|
consume(w);
|
|
|
|
|
|
|
|
x.push(T::default());
|
|
|
|
|
|
|
|
y
|
|
|
|
}
|
|
|
|
|
|
|
|
fn consume<T>(_: T) {}
|
|
|
|
|
2017-02-19 21:50:31 -06:00
|
|
|
struct Wrapper(String);
|
|
|
|
|
|
|
|
fn bar(x: String, y: Wrapper) {
|
|
|
|
assert_eq!(x.len(), 42);
|
|
|
|
assert_eq!(y.0.len(), 42);
|
|
|
|
}
|
|
|
|
|
2017-10-07 20:23:41 -05:00
|
|
|
// V implements `Borrow<V>`, but should be warned correctly
|
|
|
|
fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
|
2017-02-19 21:50:31 -06:00
|
|
|
println!("{}", t.borrow());
|
2017-10-07 20:23:41 -05:00
|
|
|
println!("{}", u.as_ref());
|
|
|
|
consume(&v);
|
2017-02-19 21:50:31 -06:00
|
|
|
}
|
|
|
|
|
2017-02-18 02:00:36 -06:00
|
|
|
// ok
|
|
|
|
fn test_fn<F: Fn(i32) -> i32>(f: F) {
|
|
|
|
f(1);
|
|
|
|
}
|
|
|
|
|
2017-02-20 01:45:37 -06:00
|
|
|
// x should be warned, but y is ok
|
|
|
|
fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
|
|
|
|
match x {
|
|
|
|
Some(Some(_)) => 1, // not moved
|
|
|
|
_ => 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
match y {
|
|
|
|
Some(Some(s)) => consume(s), // moved
|
|
|
|
_ => (),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-02-20 03:18:31 -06:00
|
|
|
// x and y should be warned, but z is ok
|
|
|
|
fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
|
|
|
let Wrapper(s) = z; // moved
|
|
|
|
let Wrapper(ref t) = y; // not moved
|
2017-02-21 03:44:31 -06:00
|
|
|
let Wrapper(_) = y; // still not moved
|
|
|
|
|
2017-02-20 01:45:37 -06:00
|
|
|
assert_eq!(x.0.len(), s.len());
|
2017-02-20 03:18:31 -06:00
|
|
|
println!("{}", t);
|
2017-02-20 01:45:37 -06:00
|
|
|
}
|
|
|
|
|
2017-10-07 20:23:41 -05:00
|
|
|
trait Foo {}
|
|
|
|
|
2017-11-03 03:24:10 -05:00
|
|
|
// `S: Serialize` is allowed to be passed by value, since a caller can pass `&S` instead
|
2017-10-07 20:23:41 -05:00
|
|
|
trait Serialize {}
|
|
|
|
impl<'a, T> Serialize for &'a T where T: Serialize {}
|
|
|
|
impl Serialize for i32 {}
|
|
|
|
|
|
|
|
fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
|
|
|
|
|
2017-10-08 03:51:44 -05:00
|
|
|
fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
|
|
|
|
s.capacity();
|
|
|
|
let _ = t.clone();
|
|
|
|
u.capacity();
|
|
|
|
let _ = v.clone();
|
|
|
|
}
|
|
|
|
|
2017-11-03 03:24:10 -05:00
|
|
|
struct S<T, U>(T, U);
|
|
|
|
|
|
|
|
impl<T: Serialize, U> S<T, U> {
|
|
|
|
fn foo(
|
2018-12-09 16:26:16 -06:00
|
|
|
self,
|
|
|
|
// taking `self` by value is always allowed
|
2017-11-03 03:24:10 -05:00
|
|
|
s: String,
|
|
|
|
t: String,
|
|
|
|
) -> usize {
|
|
|
|
s.len() + t.capacity()
|
|
|
|
}
|
|
|
|
|
2018-12-09 16:26:16 -06:00
|
|
|
fn bar(_t: T // Ok, since `&T: Serialize` too
|
2017-11-03 03:24:10 -05:00
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
2018-12-09 16:26:16 -06:00
|
|
|
fn baz(&self, _u: U, _s: Self) {}
|
2017-11-03 03:24:10 -05:00
|
|
|
}
|
|
|
|
|
2017-11-06 15:33:25 -06:00
|
|
|
trait FalsePositive {
|
|
|
|
fn visit_str(s: &str);
|
|
|
|
fn visit_string(s: String) {
|
|
|
|
Self::visit_str(&s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-18 02:30:52 -06:00
|
|
|
// shouldn't warn on extern funcs
|
2018-12-09 16:26:16 -06:00
|
|
|
extern "C" fn ext(x: String) -> usize {
|
|
|
|
x.len()
|
|
|
|
}
|
2018-01-18 02:30:52 -06:00
|
|
|
|
2018-01-18 02:49:19 -06:00
|
|
|
// whitelist RangeArgument
|
2018-05-29 03:56:58 -05:00
|
|
|
fn range<T: ::std::ops::RangeBounds<usize>>(range: T) {
|
|
|
|
let _ = range.start_bound();
|
2018-01-18 02:49:19 -06:00
|
|
|
}
|
|
|
|
|
2018-01-18 07:27:47 -06:00
|
|
|
struct CopyWrapper(u32);
|
|
|
|
|
|
|
|
fn bar_copy(x: u32, y: CopyWrapper) {
|
|
|
|
assert_eq!(x, 42);
|
|
|
|
assert_eq!(y.0, 42);
|
|
|
|
}
|
|
|
|
|
|
|
|
// x and y should be warned, but z is ok
|
|
|
|
fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
|
|
|
|
let CopyWrapper(s) = z; // moved
|
|
|
|
let CopyWrapper(ref t) = y; // not moved
|
|
|
|
let CopyWrapper(_) = y; // still not moved
|
|
|
|
|
|
|
|
assert_eq!(x.0, s);
|
|
|
|
println!("{}", t);
|
|
|
|
}
|
|
|
|
|
2018-10-01 15:33:20 -05:00
|
|
|
// The following 3 lines should not cause an ICE. See #2831
|
|
|
|
trait Bar<'a, A> {}
|
|
|
|
impl<'b, T> Bar<'b, T> for T {}
|
|
|
|
fn some_fun<'b, S: Bar<'b, ()>>(_item: S) {}
|
|
|
|
|
|
|
|
// Also this should not cause an ICE. See #2831
|
|
|
|
trait Club<'a, A> {}
|
|
|
|
impl<T> Club<'static, T> for T {}
|
|
|
|
fn more_fun(_item: impl Club<'static, i32>) {}
|
|
|
|
|
2017-02-18 02:00:36 -06:00
|
|
|
fn main() {}
|