rust-clippy/tests/ui/use_self.rs

365 lines
6.5 KiB
Rust
Raw Normal View History

2019-01-22 14:16:54 +00:00
// run-rustfix
2019-11-07 03:59:13 +00:00
// compile-flags: --edition 2018
2019-01-22 14:16:54 +00:00
2018-07-28 15:34:52 +00:00
#![warn(clippy::use_self)]
#![allow(dead_code)]
2018-07-28 15:34:52 +00:00
#![allow(clippy::should_implement_trait)]
fn main() {}
mod use_self {
struct Foo {}
impl Foo {
fn new() -> Foo {
Foo {}
}
fn test() -> Foo {
Foo::new()
}
}
impl Default for Foo {
fn default() -> Foo {
Foo::new()
}
}
}
mod better {
struct Foo {}
impl Foo {
fn new() -> Self {
Self {}
}
fn test() -> Self {
Self::new()
}
}
impl Default for Foo {
fn default() -> Self {
Self::new()
}
}
}
2017-08-21 22:18:37 +00:00
mod lifetimes {
2018-12-09 22:26:16 +00:00
struct Foo<'a> {
foo_str: &'a str,
}
2017-08-21 22:18:37 +00:00
impl<'a> Foo<'a> {
2018-12-09 22:26:16 +00:00
// Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) ->
// Foo<'b>`
2017-08-21 22:18:37 +00:00
fn foo(s: &str) -> Foo {
Foo { foo_str: s }
}
// cannot replace with `Self`, because that's `Foo<'a>`
fn bar() -> Foo<'static> {
2018-12-09 22:26:16 +00:00
Foo { foo_str: "foo" }
2017-08-21 22:18:37 +00:00
}
// FIXME: the lint does not handle lifetimed struct
2018-12-27 08:54:19 +00:00
// `Self` should be applicable here
2017-08-21 22:18:37 +00:00
fn clone(&self) -> Foo<'a> {
2018-12-09 22:26:16 +00:00
Foo { foo_str: self.foo_str }
2017-08-21 22:18:37 +00:00
}
}
}
2018-07-14 10:18:50 +00:00
2018-07-28 15:34:52 +00:00
#[allow(clippy::boxed_local)]
2018-07-14 10:18:50 +00:00
mod traits {
2018-07-17 06:20:49 +00:00
use std::ops::Mul;
2018-07-14 10:18:50 +00:00
trait SelfTrait {
fn refs(p1: &Self) -> &Self;
fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self;
fn mut_refs(p1: &mut Self) -> &mut Self;
fn nested(p1: Box<Self>, p2: (&u8, &Self));
fn vals(r: Self) -> Self;
}
#[derive(Default)]
struct Bad;
impl SelfTrait for Bad {
fn refs(p1: &Bad) -> &Bad {
p1
}
fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {
p1
}
fn mut_refs(p1: &mut Bad) -> &mut Bad {
p1
}
2018-12-09 22:26:16 +00:00
fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}
2018-07-14 10:18:50 +00:00
fn vals(_: Bad) -> Bad {
Bad::default()
}
}
2018-07-17 06:20:49 +00:00
impl Mul for Bad {
type Output = Bad;
fn mul(self, rhs: Bad) -> Bad {
rhs
}
}
impl Clone for Bad {
fn clone(&self) -> Self {
Bad
}
}
2018-07-14 10:18:50 +00:00
#[derive(Default)]
struct Good;
impl SelfTrait for Good {
fn refs(p1: &Self) -> &Self {
p1
}
fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
p1
}
fn mut_refs(p1: &mut Self) -> &mut Self {
p1
}
2018-12-09 22:26:16 +00:00
fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}
2018-07-14 10:18:50 +00:00
fn vals(_: Self) -> Self {
Self::default()
}
}
2018-07-17 06:20:49 +00:00
impl Mul for Good {
type Output = Self;
fn mul(self, rhs: Self) -> Self {
rhs
}
}
2018-07-14 10:18:50 +00:00
trait NameTrait {
fn refs(p1: &u8) -> &u8;
fn ref_refs<'a>(p1: &'a &'a u8) -> &'a &'a u8;
fn mut_refs(p1: &mut u8) -> &mut u8;
fn nested(p1: Box<u8>, p2: (&u8, &u8));
fn vals(p1: u8) -> u8;
}
// Using `Self` instead of the type name is OK
impl NameTrait for u8 {
fn refs(p1: &Self) -> &Self {
p1
}
fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
p1
}
fn mut_refs(p1: &mut Self) -> &mut Self {
p1
}
2018-12-09 22:26:16 +00:00
fn nested(_p1: Box<Self>, _p2: (&Self, &Self)) {}
2018-07-14 10:18:50 +00:00
fn vals(_: Self) -> Self {
Self::default()
}
}
}
mod issue2894 {
trait IntoBytes {
fn into_bytes(&self) -> Vec<u8>;
}
// This should not be linted
impl IntoBytes for u8 {
fn into_bytes(&self) -> Vec<u8> {
vec![*self]
}
}
}
2018-10-25 03:28:54 +00:00
mod existential {
struct Foo;
impl Foo {
2018-12-09 22:26:16 +00:00
fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
2018-10-25 03:28:54 +00:00
foos.iter()
}
2018-12-09 22:26:16 +00:00
fn good(foos: &[Self]) -> impl Iterator<Item = &Self> {
2018-10-25 03:28:54 +00:00
foos.iter()
}
}
}
2018-12-27 16:27:42 +00:00
mod tuple_structs {
pub struct TS(i32);
impl TS {
pub fn ts() -> Self {
TS(0)
}
}
}
mod macros {
macro_rules! use_self_expand {
() => {
fn new() -> Foo {
Foo {}
}
};
}
struct Foo {}
impl Foo {
use_self_expand!(); // Should lint in local macros
}
}
2019-01-06 14:05:04 +00:00
mod nesting {
struct Foo {}
impl Foo {
fn foo() {
#[allow(unused_imports)]
2019-01-06 14:05:04 +00:00
use self::Foo; // Can't use Self here
struct Bar {
foo: Foo, // Foo != Self
}
2019-01-07 13:11:53 +00:00
impl Bar {
fn bar() -> Bar {
2019-01-07 13:38:01 +00:00
Bar { foo: Foo {} }
2019-01-07 13:11:53 +00:00
}
}
// Can't use Self here
fn baz() -> Foo {
Foo {}
}
}
// Should lint here
fn baz() -> Foo {
Foo {}
2019-01-06 14:05:04 +00:00
}
}
enum Enum {
A,
B(u64),
2019-08-01 05:09:57 +00:00
C { field: bool },
2019-01-06 14:05:04 +00:00
}
impl Enum {
fn method() {
2019-01-22 14:16:54 +00:00
#[allow(unused_imports)]
2019-01-07 13:11:53 +00:00
use self::Enum::*; // Issue 3425
2019-01-06 14:05:04 +00:00
static STATIC: Enum = Enum::A; // Can't use Self as type
}
fn method2() {
let _ = Enum::B(42);
let _ = Enum::C { field: true };
let _ = Enum::A;
}
2019-01-06 14:05:04 +00:00
}
}
mod issue3410 {
struct A;
struct B;
trait Trait<T> {
fn a(v: T);
}
impl Trait<Vec<A>> for Vec<B> {
fn a(_: Vec<A>) {}
}
}
2019-01-22 14:16:54 +00:00
#[allow(clippy::no_effect, path_statements)]
mod rustfix {
mod nested {
pub struct A {}
}
impl nested::A {
const A: bool = true;
fn fun_1() {}
fn fun_2() {
nested::A::fun_1();
nested::A::A;
nested::A {};
}
}
}
mod issue3567 {
struct TestStruct {}
impl TestStruct {
fn from_something() -> Self {
Self {}
}
}
trait Test {
fn test() -> TestStruct;
}
impl Test for TestStruct {
fn test() -> TestStruct {
TestStruct::from_something()
}
}
}
2019-11-07 03:59:13 +00:00
mod paths_created_by_lowering {
use std::ops::Range;
struct S {}
impl S {
const A: usize = 0;
const B: usize = 1;
2019-11-07 03:59:13 +00:00
async fn g() -> S {
S {}
}
fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
&p[S::A..S::B]
}
}
2019-11-07 03:59:13 +00:00
trait T {
fn f<'a>(&self, p: &'a [u8]) -> &'a [u8];
}
impl T for Range<u8> {
fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
&p[0..1]
}
}
}