summaryrefslogtreecommitdiffstats
path: root/tests/ui/overloaded/overloaded-autoderef-order.rs
blob: f48bae55f5f1e820063df9c290b47ef4ce53b5c6 (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
// run-pass

#![allow(dead_code)]

use std::rc::Rc;
use std::ops::Deref;

#[derive(Copy, Clone)]
struct DerefWrapper<X, Y> {
    x: X,
    y: Y
}

impl<X, Y> DerefWrapper<X, Y> {
    fn get_x(self) -> X {
        self.x
    }
}

impl<X, Y> Deref for DerefWrapper<X, Y> {
    type Target = Y;

    fn deref(&self) -> &Y {
        &self.y
    }
}

mod priv_test {
    use std::ops::Deref;

    #[derive(Copy, Clone)]
    pub struct DerefWrapperHideX<X, Y> {
        x: X,
        pub y: Y
    }

    impl<X, Y> DerefWrapperHideX<X, Y> {
        pub fn new(x: X, y: Y) -> DerefWrapperHideX<X, Y> {
            DerefWrapperHideX {
                x: x,
                y: y
            }
        }
    }

    impl<X, Y> Deref for DerefWrapperHideX<X, Y> {
        type Target = Y;

        fn deref(&self) -> &Y {
            &self.y
        }
    }
}

pub fn main() {
    let nested = DerefWrapper {x: true, y: DerefWrapper {x: 0, y: 1}};

    // Use the first field that you can find.
    assert_eq!(nested.x, true);
    assert_eq!((*nested).x, 0);

    // Same for methods, even though there are multiple
    // candidates (at different nesting levels).
    assert_eq!(nested.get_x(), true);
    assert_eq!((*nested).get_x(), 0);

    // Also go through multiple levels of indirection.
    assert_eq!(Rc::new(nested).x, true);

    let nested_priv = priv_test::DerefWrapperHideX::new(true, DerefWrapper {x: 0, y: 1});
    assert_eq!(nested_priv.x, 0);
    assert_eq!((*nested_priv).x, 0);
}