//@ check-pass //@ edition:2021 //@ aux-build:non_local_macro.rs //@ rustc-env:CARGO_CRATE_NAME=non_local_def #![feature(inline_const)] extern crate non_local_macro; use std::fmt::{Debug, Display}; struct Test; impl Debug for Test { fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { todo!() } } mod do_not_lint_mod { pub trait Tait {} impl super::Test { fn hugo() {} } impl Tait for super::Test {} } trait Uto {} const Z: () = { trait Uto1 {} impl Uto1 for Test {} // the trait is local, don't lint impl Uto for &Test {} //~^ WARN non-local `impl` definition }; trait Ano {} const _: () = { impl Ano for &Test {} // ignored since the parent is an anon-const }; type A = [u32; { impl Uto for *mut Test {} //~^ WARN non-local `impl` definition 1 }]; enum Enum { Discr = { impl Uto for Test {} //~^ WARN non-local `impl` definition 1 } } trait Uto2 {} static A: u32 = { impl Uto2 for Test {} //~^ WARN non-local `impl` definition 1 }; trait Uto3 {} const B: u32 = { impl Uto3 for Test {} //~^ WARN non-local `impl` definition #[macro_export] macro_rules! m0 { () => { } }; //~^ WARN non-local `macro_rules!` definition trait Uto4 {} impl Uto4 for Test {} 1 }; trait Uto5 {} fn main() { #[macro_export] macro_rules! m { () => { } }; //~^ WARN non-local `macro_rules!` definition impl Test { //~^ WARN non-local `impl` definition fn foo() {} } let _array = [0i32; { impl Test { //~^ WARN non-local `impl` definition fn bar() {} } 1 }]; const { impl Test { //~^ WARN non-local `impl` definition fn hoo() {} } 1 }; const _: u32 = { impl Test { //~^ WARN non-local `impl` definition fn foo2() {} } 1 }; impl Display for Test { //~^ WARN non-local `impl` definition fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { todo!() } } impl dyn Uto5 {} //~^ WARN non-local `impl` definition impl Uto5 for Vec { } //~^ WARN non-local `impl` definition impl Uto5 for &dyn Uto5 {} //~^ WARN non-local `impl` definition impl Uto5 for *mut Test {} //~^ WARN non-local `impl` definition impl Uto5 for *mut [Test] {} //~^ WARN non-local `impl` definition impl Uto5 for [Test; 8] {} //~^ WARN non-local `impl` definition impl Uto5 for (Test,) {} //~^ WARN non-local `impl` definition impl Uto5 for fn(Test) -> () {} //~^ WARN non-local `impl` definition impl Uto5 for fn() -> Test {} //~^ WARN non-local `impl` definition let _a = || { impl Uto5 for Test {} //~^ WARN non-local `impl` definition 1 }; type A = [u32; { impl Uto5 for &Test {} //~^ WARN non-local `impl` definition 1 }]; fn a(_: [u32; { impl Uto5 for &(Test,) {} //~^ WARN non-local `impl` definition 1 }]) {} fn b() -> [u32; { impl Uto5 for &(Test,Test) {} //~^ WARN non-local `impl` definition 1 }] { todo!() } struct InsideMain; impl Uto5 for *mut InsideMain {} //~^ WARN non-local `impl` definition impl Uto5 for *mut [InsideMain] {} //~^ WARN non-local `impl` definition impl Uto5 for [InsideMain; 8] {} //~^ WARN non-local `impl` definition impl Uto5 for (InsideMain,) {} //~^ WARN non-local `impl` definition impl Uto5 for fn(InsideMain) -> () {} //~^ WARN non-local `impl` definition impl Uto5 for fn() -> InsideMain {} //~^ WARN non-local `impl` definition impl Debug for InsideMain { fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { todo!() } } impl InsideMain { fn foo() {} } fn inside_inside() { impl Display for InsideMain { //~^ WARN non-local `impl` definition fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { todo!() } } impl InsideMain { //~^ WARN non-local `impl` definition fn bar() { #[macro_export] macro_rules! m2 { () => { } }; //~^ WARN non-local `macro_rules!` definition } } } trait Uto6 {} impl dyn Uto6 {} impl Uto5 for dyn Uto6 {} impl Uto3 for Vec { } //~^ WARN non-local `impl` definition } trait Uto7 {} trait Uto8 {} fn bad() { struct Local; impl Uto7 for Test where Local: std::any::Any {} //~^ WARN non-local `impl` definition impl Uto8 for T {} //~^ WARN non-local `impl` definition } trait Uto9 {} trait Uto10 {} const _: u32 = { let _a = || { impl Uto9 for Test {} //~^ WARN non-local `impl` definition 1 }; type A = [u32; { impl Uto10 for Test {} //~^ WARN non-local `impl` definition 1 }]; 1 }; struct UwU(T); fn fun() { #[derive(Debug)] struct OwO; impl Default for UwU { //~^ WARN non-local `impl` definition fn default() -> Self { UwU(OwO) } } } struct Cat; fn meow() { impl From for () { fn from(_: Cat) -> () { todo!() } } #[derive(Debug)] struct Cat; impl AsRef for () { //~^ WARN non-local `impl` definition fn as_ref(&self) -> &Cat { &Cat } } } struct G; fn fun2() { #[derive(Debug, Default)] struct B; impl PartialEq for G { //~^ WARN non-local `impl` definition fn eq(&self, _: &B) -> bool { true } } } fn side_effects() { dbg!(().as_ref()); // prints `Cat` dbg!(UwU::default().0); let _ = G::eq(&G, dbg!(&<_>::default())); } struct Dog; fn woof() { impl PartialEq for &Dog { //~^ WARN non-local `impl` definition fn eq(&self, _: &Dog) -> bool { todo!() } } impl PartialEq<()> for Dog { //~^ WARN non-local `impl` definition fn eq(&self, _: &()) -> bool { todo!() } } impl PartialEq<()> for &Dog { //~^ WARN non-local `impl` definition fn eq(&self, _: &()) -> bool { todo!() } } impl PartialEq for () { //~^ WARN non-local `impl` definition fn eq(&self, _: &Dog) -> bool { todo!() } } struct Test; impl PartialEq for Test { fn eq(&self, _: &Dog) -> bool { todo!() } } } struct Wrap(T); impl Wrap>> {} fn rawr() { struct Lion; impl From>> for () { //~^ WARN non-local `impl` definition fn from(_: Wrap>) -> Self { todo!() } } impl From<()> for Wrap { //~^ WARN non-local `impl` definition fn from(_: ()) -> Self { todo!() } } #[derive(Debug)] struct Elephant; impl From>> for () { //~^ WARN non-local `impl` definition fn from(_: Wrap>) -> Self { todo!() } } } pub trait StillNonLocal {} impl StillNonLocal for &str {} fn only_global() { struct Foo; impl StillNonLocal for &Foo {} //~^ WARN non-local `impl` definition } struct GlobalSameFunction; fn same_function() { struct Local1(GlobalSameFunction); impl From for GlobalSameFunction { //~^ WARN non-local `impl` definition fn from(x: Local1) -> GlobalSameFunction { x.0 } } struct Local2(GlobalSameFunction); impl From for GlobalSameFunction { //~^ WARN non-local `impl` definition fn from(x: Local2) -> GlobalSameFunction { x.0 } } } struct GlobalDifferentFunction; fn diff_foo() { struct Local(GlobalDifferentFunction); impl From for GlobalDifferentFunction { // FIXME(Urgau): Should warn but doesn't since we currently consider // the other impl to be "global", but that's not the case for the type-system fn from(x: Local) -> GlobalDifferentFunction { x.0 } } } fn diff_bar() { struct Local(GlobalDifferentFunction); impl From for GlobalDifferentFunction { // FIXME(Urgau): Should warn but doesn't since we currently consider // the other impl to be "global", but that's not the case for the type-system fn from(x: Local) -> GlobalDifferentFunction { x.0 } } } macro_rules! m { () => { trait MacroTrait {} struct OutsideStruct; fn my_func() { impl MacroTrait for OutsideStruct {} //~^ WARN non-local `impl` definition } } } m!(); struct CargoUpdate; non_local_macro::non_local_impl!(CargoUpdate); //~^ WARN non-local `impl` definition non_local_macro::non_local_macro_rules!(my_macro); //~^ WARN non-local `macro_rules!` definition fn bitflags() { struct Flags; const _: () = { impl Flags {} }; } // https://github.com/rust-lang/rust/issues/121621#issuecomment-1976826895 fn commonly_reported() { struct Local(u8); impl From for u8 { fn from(x: Local) -> u8 { x.0 } } } // https://github.com/rust-lang/rust/issues/121621#issue-2153187542 pub trait Serde {} impl Serde for &[u8] {} impl Serde for &str {} fn serde() { struct Thing; impl Serde for &Thing {} }