2018-07-28 10:34:52 -05:00
|
|
|
#![deny(clippy::useless_asref)]
|
2023-06-15 10:24:39 -05:00
|
|
|
#![allow(
|
|
|
|
clippy::explicit_auto_deref,
|
|
|
|
clippy::uninlined_format_args,
|
2024-01-06 12:33:09 -06:00
|
|
|
clippy::map_clone,
|
|
|
|
clippy::needless_pass_by_ref_mut,
|
|
|
|
clippy::redundant_closure
|
2023-06-15 10:24:39 -05:00
|
|
|
)]
|
2019-03-15 01:29:12 -05:00
|
|
|
|
2017-10-21 12:42:35 -05:00
|
|
|
use std::fmt::Debug;
|
|
|
|
|
2017-10-20 10:39:20 -05:00
|
|
|
struct FakeAsRef;
|
|
|
|
|
2018-07-28 10:34:52 -05:00
|
|
|
#[allow(clippy::should_implement_trait)]
|
2017-10-20 10:39:20 -05:00
|
|
|
impl FakeAsRef {
|
2018-12-09 16:26:16 -06:00
|
|
|
fn as_ref(&self) -> &Self {
|
|
|
|
self
|
|
|
|
}
|
2017-10-20 10:39:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
struct MoreRef;
|
|
|
|
|
|
|
|
impl<'a, 'b, 'c> AsRef<&'a &'b &'c MoreRef> for MoreRef {
|
|
|
|
fn as_ref(&self) -> &&'a &'b &'c MoreRef {
|
|
|
|
&&&&MoreRef
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-09 16:26:16 -06:00
|
|
|
fn foo_rstr(x: &str) {
|
|
|
|
println!("{:?}", x);
|
|
|
|
}
|
|
|
|
fn foo_rslice(x: &[i32]) {
|
|
|
|
println!("{:?}", x);
|
|
|
|
}
|
|
|
|
fn foo_mrslice(x: &mut [i32]) {
|
|
|
|
println!("{:?}", x);
|
|
|
|
}
|
|
|
|
fn foo_rrrrmr(_: &&&&MoreRef) {
|
|
|
|
println!("so many refs");
|
|
|
|
}
|
2017-10-20 10:39:20 -05:00
|
|
|
|
|
|
|
fn not_ok() {
|
|
|
|
let rstr: &str = "hello";
|
2018-12-09 16:26:16 -06:00
|
|
|
let mut mrslice: &mut [i32] = &mut [1, 2, 3];
|
2017-10-20 10:39:20 -05:00
|
|
|
|
|
|
|
{
|
|
|
|
let rslice: &[i32] = &*mrslice;
|
|
|
|
foo_rstr(rstr.as_ref());
|
|
|
|
foo_rstr(rstr);
|
|
|
|
foo_rslice(rslice.as_ref());
|
|
|
|
foo_rslice(rslice);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
foo_mrslice(mrslice.as_mut());
|
|
|
|
foo_mrslice(mrslice);
|
|
|
|
foo_rslice(mrslice.as_ref());
|
|
|
|
foo_rslice(mrslice);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let rrrrrstr = &&&&rstr;
|
|
|
|
let rrrrrslice = &&&&&*mrslice;
|
|
|
|
foo_rslice(rrrrrslice.as_ref());
|
|
|
|
foo_rslice(rrrrrslice);
|
|
|
|
foo_rstr(rrrrrstr.as_ref());
|
|
|
|
foo_rstr(rrrrrstr);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let mrrrrrslice = &mut &mut &mut &mut mrslice;
|
|
|
|
foo_mrslice(mrrrrrslice.as_mut());
|
|
|
|
foo_mrslice(mrrrrrslice);
|
|
|
|
foo_rslice(mrrrrrslice.as_ref());
|
|
|
|
foo_rslice(mrrrrrslice);
|
|
|
|
}
|
2022-01-11 13:31:35 -06:00
|
|
|
#[allow(unused_parens, clippy::double_parens, clippy::needless_borrow)]
|
2017-10-20 10:39:20 -05:00
|
|
|
foo_rrrrmr((&&&&MoreRef).as_ref());
|
2017-10-21 12:42:35 -05:00
|
|
|
|
|
|
|
generic_not_ok(mrslice);
|
|
|
|
generic_ok(mrslice);
|
2017-10-20 10:39:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fn ok() {
|
|
|
|
let string = "hello".to_owned();
|
2018-12-09 16:26:16 -06:00
|
|
|
let mut arr = [1, 2, 3];
|
|
|
|
let mut vec = vec![1, 2, 3];
|
2017-10-20 10:39:20 -05:00
|
|
|
|
|
|
|
{
|
|
|
|
foo_rstr(string.as_ref());
|
|
|
|
foo_rslice(arr.as_ref());
|
|
|
|
foo_rslice(vec.as_ref());
|
|
|
|
}
|
|
|
|
{
|
|
|
|
foo_mrslice(arr.as_mut());
|
|
|
|
foo_mrslice(vec.as_mut());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let rrrrstring = &&&&string;
|
|
|
|
let rrrrarr = &&&&arr;
|
|
|
|
let rrrrvec = &&&&vec;
|
|
|
|
foo_rstr(rrrrstring.as_ref());
|
|
|
|
foo_rslice(rrrrarr.as_ref());
|
|
|
|
foo_rslice(rrrrvec.as_ref());
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let mrrrrarr = &mut &mut &mut &mut arr;
|
|
|
|
let mrrrrvec = &mut &mut &mut &mut vec;
|
|
|
|
foo_mrslice(mrrrrarr.as_mut());
|
|
|
|
foo_mrslice(mrrrrvec.as_mut());
|
|
|
|
}
|
|
|
|
FakeAsRef.as_ref();
|
|
|
|
foo_rrrrmr(MoreRef.as_ref());
|
2017-10-21 12:42:35 -05:00
|
|
|
|
|
|
|
generic_not_ok(arr.as_mut());
|
|
|
|
generic_ok(&mut arr);
|
2017-10-20 10:39:20 -05:00
|
|
|
}
|
2017-10-21 12:42:35 -05:00
|
|
|
|
2018-12-09 16:26:16 -06:00
|
|
|
fn foo_mrt<T: Debug + ?Sized>(t: &mut T) {
|
|
|
|
println!("{:?}", t);
|
|
|
|
}
|
|
|
|
fn foo_rt<T: Debug + ?Sized>(t: &T) {
|
|
|
|
println!("{:?}", t);
|
|
|
|
}
|
2017-10-21 12:42:35 -05:00
|
|
|
|
|
|
|
fn generic_not_ok<T: AsMut<T> + AsRef<T> + Debug + ?Sized>(mrt: &mut T) {
|
|
|
|
foo_mrt(mrt.as_mut());
|
|
|
|
foo_mrt(mrt);
|
|
|
|
foo_rt(mrt.as_ref());
|
|
|
|
foo_rt(mrt);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn generic_ok<U: AsMut<T> + AsRef<T> + ?Sized, T: Debug + ?Sized>(mru: &mut U) {
|
|
|
|
foo_mrt(mru.as_mut());
|
|
|
|
foo_rt(mru.as_ref());
|
|
|
|
}
|
|
|
|
|
2024-01-06 09:56:38 -06:00
|
|
|
fn foo() {
|
|
|
|
let x = Some(String::new());
|
2024-01-06 12:33:09 -06:00
|
|
|
let z = x.as_ref().map(String::clone);
|
|
|
|
//~^ ERROR: this call to `as_ref.map(...)` does nothing
|
|
|
|
let z = x.as_ref().map(|z| z.clone());
|
|
|
|
//~^ ERROR: this call to `as_ref.map(...)` does nothing
|
|
|
|
let z = x.as_ref().map(|z| String::clone(z));
|
|
|
|
//~^ ERROR: this call to `as_ref.map(...)` does nothing
|
2024-01-06 09:56:38 -06:00
|
|
|
}
|
|
|
|
|
2024-01-12 06:39:42 -06:00
|
|
|
mod issue12135 {
|
|
|
|
pub struct Struct {
|
|
|
|
field: Option<InnerStruct>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Foo;
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
struct InnerStruct {
|
|
|
|
x: Foo,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl InnerStruct {
|
|
|
|
fn method(&self) -> &Foo {
|
|
|
|
&self.x
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn f(x: &Struct) -> Option<Foo> {
|
|
|
|
x.field.as_ref().map(|v| v.clone());
|
|
|
|
//~^ ERROR: this call to `as_ref.map(...)` does nothing
|
|
|
|
x.field.as_ref().map(Clone::clone);
|
|
|
|
//~^ ERROR: this call to `as_ref.map(...)` does nothing
|
|
|
|
x.field.as_ref().map(|v| Clone::clone(v));
|
|
|
|
//~^ ERROR: this call to `as_ref.map(...)` does nothing
|
|
|
|
|
2024-01-13 10:46:46 -06:00
|
|
|
// https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223
|
|
|
|
#[allow(clippy::clone_on_copy)]
|
|
|
|
Some(1).as_ref().map(|&x| x.clone());
|
|
|
|
//~^ ERROR: this call to `as_ref.map(...)` does nothing
|
|
|
|
|
2024-01-12 06:39:42 -06:00
|
|
|
x.field.as_ref().map(|v| v.method().clone())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-20 10:39:20 -05:00
|
|
|
fn main() {
|
|
|
|
not_ok();
|
|
|
|
ok();
|
|
|
|
}
|