summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed
blob: fa117aaddcd60abc025e86986ee205c819ca49b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#![warn(clippy::implied_bounds_in_impls)]
#![allow(dead_code)]

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 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 GenericSubtrait<U, W, U>
where
    (): GenericSubtrait<U, W, U>,
{
}

fn generics_implied_multi<V>() -> impl GenericSubtrait<(), i32, V> {}

fn generics_implied_multi2<T, V>() -> impl 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 GenericSubtrait<(), i32, ()> {}

trait SomeTrait {
    // Check that it works in trait declarations.
    fn f() -> impl DerefMut<Target = u8>;
}
struct SomeStruct;
impl SomeStruct {
    // Check that it works in inherent impl blocks.
    fn f() -> impl DerefMut<Target = u8> {
        Box::new(123)
    }
}
impl SomeTrait for SomeStruct {
    // Check that it works in trait impls.
    fn f() -> impl 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 PartialOrd + Debug {}
    fn default_generic_param2() -> impl PartialOrd + 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 {}
}

mod issue11435 {
    // Associated type needs to be included on DoubleEndedIterator in the suggestion
    fn my_iter() -> impl DoubleEndedIterator<Item = u32> {
        0..5
    }

    // Removing the `Clone` bound should include the `+` behind it in its remove suggestion
    fn f() -> impl Copy {
        1
    }

    trait Trait1<T> {
        type U;
    }
    impl Trait1<i32> for () {
        type U = i64;
    }
    trait Trait2<T>: Trait1<T> {}
    impl Trait2<i32> for () {}

    // When the other trait has generics, it shouldn't add another pair of `<>`
    fn f2() -> impl Trait2<i32, U = i64> {}

    trait Trait3<T, U, V> {
        type X;
        type Y;
    }
    trait Trait4<T>: Trait3<T, i16, i64> {}
    impl Trait3<i8, i16, i64> for () {
        type X = i32;
        type Y = i128;
    }
    impl Trait4<i8> for () {}

    // Associated type `X` is specified, but `Y` is not, so only that associated type should be moved
    // over
    fn f3() -> impl Trait4<i8, X = i32, Y = i128> {}
}

fn main() {}