| #![warn(clippy::new_without_default)] | |
| #![expect(clippy::extra_unused_lifetimes, clippy::missing_safety_doc)] | |
| pub struct Foo; | |
| impl Foo { | |
| pub fn new() -> Foo { | |
| //~^ new_without_default | |
| Foo | |
| } | |
| } | |
| pub struct Bar; | |
| impl Bar { | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| Bar | |
| } | |
| } | |
| pub struct Ok; | |
| impl Ok { | |
| pub fn new() -> Self { | |
| Ok | |
| } | |
| } | |
| impl Default for Ok { | |
| fn default() -> Self { | |
| Ok | |
| } | |
| } | |
| pub struct Params; | |
| impl Params { | |
| pub fn new(_: u32) -> Self { | |
| Params | |
| } | |
| } | |
| pub struct GenericsOk<T> { | |
| bar: T, | |
| } | |
| impl<U> Default for GenericsOk<U> { | |
| fn default() -> Self { | |
| unimplemented!(); | |
| } | |
| } | |
| impl<'c, V> GenericsOk<V> { | |
| pub fn new() -> GenericsOk<V> { | |
| unimplemented!() | |
| } | |
| } | |
| pub struct LtOk<'a> { | |
| foo: &'a bool, | |
| } | |
| impl<'b> Default for LtOk<'b> { | |
| fn default() -> Self { | |
| unimplemented!(); | |
| } | |
| } | |
| impl<'c> LtOk<'c> { | |
| pub fn new() -> LtOk<'c> { | |
| unimplemented!() | |
| } | |
| } | |
| pub struct LtKo<'a> { | |
| foo: &'a bool, | |
| } | |
| impl<'c> LtKo<'c> { | |
| pub fn new() -> LtKo<'c> { | |
| //~^ new_without_default | |
| unimplemented!() | |
| } | |
| } | |
| struct Private; | |
| impl Private { | |
| fn new() -> Private { | |
| unimplemented!() | |
| } // We don't lint private items | |
| } | |
| struct PrivateStruct; | |
| impl PrivateStruct { | |
| pub fn new() -> PrivateStruct { | |
| unimplemented!() | |
| } // We don't lint public items on private structs | |
| } | |
| pub struct PrivateItem; | |
| impl PrivateItem { | |
| fn new() -> PrivateItem { | |
| unimplemented!() | |
| } // We don't lint private items on public structs | |
| } | |
| pub struct Const; | |
| impl Const { | |
| pub const fn new() -> Const { | |
| //~^ new_without_default | |
| Const | |
| } // While Default is not const, it can still call const functions, so we should lint this | |
| } | |
| pub struct IgnoreGenericNew; | |
| impl IgnoreGenericNew { | |
| pub fn new<T>() -> Self { | |
| IgnoreGenericNew | |
| } // the derived Default does not make sense here as the result depends on T | |
| } | |
| pub trait TraitWithNew: Sized { | |
| fn new() -> Self { | |
| panic!() | |
| } | |
| } | |
| pub struct IgnoreUnsafeNew; | |
| impl IgnoreUnsafeNew { | |
| pub unsafe fn new() -> Self { | |
| IgnoreUnsafeNew | |
| } | |
| } | |
| #[derive(Default)] | |
| pub struct OptionRefWrapper<'a, T>(Option<&'a T>); | |
| impl<'a, T> OptionRefWrapper<'a, T> { | |
| pub fn new() -> Self { | |
| OptionRefWrapper(None) | |
| } | |
| } | |
| pub struct Allow(Foo); | |
| impl Allow { | |
| #[allow(clippy::new_without_default)] | |
| pub fn new() -> Self { | |
| unimplemented!() | |
| } | |
| } | |
| pub struct AllowDerive; | |
| impl AllowDerive { | |
| #[allow(clippy::new_without_default)] | |
| pub fn new() -> Self { | |
| unimplemented!() | |
| } | |
| } | |
| pub struct NewNotEqualToDerive { | |
| foo: i32, | |
| } | |
| impl NewNotEqualToDerive { | |
| // This `new` implementation is not equal to a derived `Default`, so do not suggest deriving. | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| NewNotEqualToDerive { foo: 1 } | |
| } | |
| } | |
| // see #6933 | |
| pub struct FooGenerics<T>(std::marker::PhantomData<T>); | |
| impl<T> FooGenerics<T> { | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| Self(Default::default()) | |
| } | |
| } | |
| pub struct BarGenerics<T>(std::marker::PhantomData<T>); | |
| impl<T: Copy> BarGenerics<T> { | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| Self(Default::default()) | |
| } | |
| } | |
| pub mod issue7220 { | |
| pub struct Foo<T> { | |
| _bar: *mut T, | |
| } | |
| impl<T> Foo<T> { | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| todo!() | |
| } | |
| } | |
| } | |
| // see issue #8152 | |
| // This should not create any lints | |
| pub struct DocHidden; | |
| impl DocHidden { | |
| #[doc(hidden)] | |
| pub fn new() -> Self { | |
| DocHidden | |
| } | |
| } | |
| fn main() {} | |
| pub struct IgnoreConstGenericNew(usize); | |
| impl IgnoreConstGenericNew { | |
| pub fn new<const N: usize>() -> Self { | |
| Self(N) | |
| } | |
| } | |
| pub struct IgnoreLifetimeNew; | |
| impl IgnoreLifetimeNew { | |
| pub fn new<'a>() -> Self { | |
| Self | |
| } | |
| } | |
| // From issue #11267 | |
| pub struct MyStruct<K, V> | |
| where | |
| K: std::hash::Hash + Eq + PartialEq, | |
| { | |
| _kv: Option<(K, V)>, | |
| } | |
| impl<K, V> MyStruct<K, V> | |
| where | |
| K: std::hash::Hash + Eq + PartialEq, | |
| { | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| Self { _kv: None } | |
| } | |
| } | |
| // From issue #14552, but with `#[cfg]`s that are actually `true` in the uitest context | |
| pub struct NewWithCfg; | |
| impl NewWithCfg { | |
| #[cfg(not(test))] | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| unimplemented!() | |
| } | |
| } | |
| pub struct NewWith2Cfgs; | |
| impl NewWith2Cfgs { | |
| #[cfg(not(test))] | |
| #[cfg(panic = "unwind")] | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| unimplemented!() | |
| } | |
| } | |
| pub struct NewWithExtraneous; | |
| impl NewWithExtraneous { | |
| #[inline] | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| unimplemented!() | |
| } | |
| } | |
| pub struct NewWithCfgAndExtraneous; | |
| impl NewWithCfgAndExtraneous { | |
| #[cfg(not(test))] | |
| #[inline] | |
| pub fn new() -> Self { | |
| //~^ new_without_default | |
| unimplemented!() | |
| } | |
| } | |
| mod issue15778 { | |
| pub struct Foo(Vec<i32>); | |
| impl Foo { | |
| pub fn new() -> Self { | |
| Self(Vec::new()) | |
| } | |
| } | |
| impl<'a> IntoIterator for &'a Foo { | |
| type Item = &'a i32; | |
| type IntoIter = std::slice::Iter<'a, i32>; | |
| fn into_iter(self) -> Self::IntoIter { | |
| self.0.as_slice().iter() | |
| } | |
| } | |
| } | |
| pub mod issue16255 { | |
| use std::fmt::Display; | |
| use std::marker::PhantomData; | |
| pub struct Foo<T> { | |
| marker: PhantomData<T>, | |
| } | |
| impl<T> Foo<T> | |
| where | |
| T: Display, | |
| { | |
| pub fn new() -> Self | |
| //~^ new_without_default | |
| where | |
| T: Clone, | |
| { | |
| Self { marker: PhantomData } | |
| } | |
| } | |
| pub struct Bar<T> { | |
| marker: PhantomData<T>, | |
| } | |
| impl<T> Bar<T> { | |
| pub fn new() -> Self | |
| //~^ new_without_default | |
| where | |
| T: Clone, | |
| { | |
| Self { marker: PhantomData } | |
| } | |
| } | |
| } | |
| pub mod issue17361 { | |
| //! This test ensures that attributes applied to the impl block | |
| //! containing `fn new()` do not get mistakenly applied to the | |
| //! newly generated `Default` trait impl. This has been the | |
| //! case because the `Default` trait impl was inserted right | |
| //! before the existing impl block, but after the attributes. | |
| #![deny(clippy::unwrap_used, reason = "check that expect below stays put")] | |
| pub struct S; | |
| #[expect(clippy::unwrap_used, reason = "without it, new() fails to compile")] | |
| impl S { | |
| pub fn new() -> S { | |
| //~^ new_without_default | |
| std::hint::black_box(Some(S)).unwrap() | |
| } | |
| } | |
| } |