87 lines
2.6 KiB
Rust
87 lines
2.6 KiB
Rust
#![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<T>(x: T) -> impl Deref<Target = T> {
|
|
Box::new(x)
|
|
}
|
|
|
|
// Deref implied by DerefMut
|
|
fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> {
|
|
Box::new(x)
|
|
}
|
|
|
|
trait GenericTrait<T> {}
|
|
trait GenericTrait2<V> {}
|
|
// 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<T, U, V>: GenericTrait<U> + GenericTrait2<V> {}
|
|
|
|
impl GenericTrait<i32> for () {}
|
|
impl GenericTrait<i64> for () {}
|
|
impl<V> GenericTrait2<V> for () {}
|
|
impl<V> GenericSubtrait<(), i32, V> for () {}
|
|
impl<V> GenericSubtrait<(), i64, V> for () {}
|
|
|
|
fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U>
|
|
where
|
|
(): GenericSubtrait<U, W, U>,
|
|
{
|
|
}
|
|
|
|
fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}
|
|
|
|
fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>
|
|
where
|
|
(): GenericSubtrait<(), T, V> + GenericTrait<T>,
|
|
{
|
|
}
|
|
|
|
// i32 != i64, GenericSubtrait<_, i64, _> does not imply GenericTrait<i32>, don't lint
|
|
fn generics_different() -> impl GenericTrait<i32> + GenericSubtrait<(), i64, ()> {}
|
|
|
|
// i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait<i32>, lint
|
|
fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {}
|
|
|
|
trait SomeTrait {
|
|
// Check that it works in trait declarations.
|
|
fn f() -> impl Deref + DerefMut<Target = u8>;
|
|
}
|
|
struct SomeStruct;
|
|
impl SomeStruct {
|
|
// Check that it works in inherent impl blocks.
|
|
fn f() -> impl Deref + DerefMut<Target = u8> {
|
|
Box::new(123)
|
|
}
|
|
}
|
|
impl SomeTrait for SomeStruct {
|
|
// Check that it works in trait impls.
|
|
fn f() -> impl Deref + DerefMut<Target = u8> {
|
|
Box::new(42)
|
|
}
|
|
}
|
|
|
|
mod issue11422 {
|
|
use core::fmt::Debug;
|
|
// Some additional tests that would cause ICEs:
|
|
|
|
// `PartialOrd` has a default generic parameter and does not need to be explicitly specified.
|
|
// This needs special handling.
|
|
fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {}
|
|
fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {}
|
|
|
|
// Referring to `Self` in the supertrait clause needs special handling.
|
|
trait Trait1<X: ?Sized> {}
|
|
trait Trait2: Trait1<Self> {}
|
|
impl Trait1<()> for () {}
|
|
impl Trait2 for () {}
|
|
|
|
fn f() -> impl Trait1<()> + Trait2 {}
|
|
}
|
|
|
|
fn main() {}
|