#![warn(clippy::implied_bounds_in_impls)] #![allow(dead_code)] #![feature(return_position_impl_trait_in_trait)] use std::ops::{Deref, DerefMut}; // Only one bound, nothing to lint. fn normal_deref(x: T) -> impl Deref { Box::new(x) } // Deref implied by DerefMut fn deref_derefmut(x: T) -> impl DerefMut { Box::new(x) } trait GenericTrait {} trait GenericTrait2 {} // U is intentionally at a different "index" in GenericSubtrait than `T` is in GenericTrait, // so this can be a good test to make sure that the calculations are right (no off-by-one errors, // ...) trait GenericSubtrait: GenericTrait + GenericTrait2 {} impl GenericTrait for () {} impl GenericTrait for () {} impl GenericTrait2 for () {} impl GenericSubtrait<(), i32, V> for () {} impl GenericSubtrait<(), i64, V> for () {} fn generics_implied() -> impl GenericSubtrait where (): GenericSubtrait, { } fn generics_implied_multi() -> impl GenericSubtrait<(), i32, V> {} fn generics_implied_multi2() -> impl GenericSubtrait<(), T, V> where (): GenericSubtrait<(), T, V> + GenericTrait, { } // i32 != i64, GenericSubtrait<_, i64, _> does not imply GenericTrait, don't lint fn generics_different() -> impl GenericTrait + GenericSubtrait<(), i64, ()> {} // i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait, lint fn generics_same() -> impl GenericSubtrait<(), i32, ()> {} trait SomeTrait { // Check that it works in trait declarations. fn f() -> impl DerefMut; } struct SomeStruct; impl SomeStruct { // Check that it works in inherent impl blocks. fn f() -> impl DerefMut { Box::new(123) } } impl SomeTrait for SomeStruct { // Check that it works in trait impls. fn f() -> impl DerefMut { Box::new(42) } } fn main() {}