]> git.lizzy.rs Git - rust.git/blob - src/test/ui/overloaded/overloaded-deref-count.rs
Auto merge of #95454 - randomicon00:fix95444, r=wesleywiser
[rust.git] / src / test / ui / overloaded / overloaded-deref-count.rs
1 // run-pass
2
3 use std::cell::Cell;
4 use std::ops::{Deref, DerefMut};
5 use std::vec::Vec;
6
7 struct DerefCounter<T> {
8     count_imm: Cell<usize>,
9     count_mut: usize,
10     value: T
11 }
12
13 impl<T> DerefCounter<T> {
14     fn new(value: T) -> DerefCounter<T> {
15         DerefCounter {
16             count_imm: Cell::new(0),
17             count_mut: 0,
18             value: value
19         }
20     }
21
22     fn counts(&self) -> (usize, usize) {
23         (self.count_imm.get(), self.count_mut)
24     }
25 }
26
27 impl<T> Deref for DerefCounter<T> {
28     type Target = T;
29
30     fn deref(&self) -> &T {
31         self.count_imm.set(self.count_imm.get() + 1);
32         &self.value
33     }
34 }
35
36 impl<T> DerefMut for DerefCounter<T> {
37     fn deref_mut(&mut self) -> &mut T {
38         self.count_mut += 1;
39         &mut self.value
40     }
41 }
42
43 pub fn main() {
44     let mut n = DerefCounter::new(0);
45     let mut v = DerefCounter::new(Vec::new());
46
47     let _ = *n; // Immutable deref + copy a POD.
48     assert_eq!(n.counts(), (1, 0));
49
50     let _ = (&*n, &*v); // Immutable deref + borrow.
51     assert_eq!(n.counts(), (2, 0)); assert_eq!(v.counts(), (1, 0));
52
53     let _ = (&mut *n, &mut *v); // Mutable deref + mutable borrow.
54     assert_eq!(n.counts(), (2, 1)); assert_eq!(v.counts(), (1, 1));
55
56     let mut v2 = Vec::new();
57     v2.push(1);
58
59     *n = 5; *v = v2; // Mutable deref + assignment.
60     assert_eq!(n.counts(), (2, 2)); assert_eq!(v.counts(), (1, 2));
61
62     *n -= 3; // Mutable deref + assignment with binary operation.
63     assert_eq!(n.counts(), (2, 3));
64
65     // Immutable deref used for calling a method taking &self. (The
66     // typechecker is smarter now about doing this.)
67     (*n).to_string();
68     assert_eq!(n.counts(), (3, 3));
69
70     // Mutable deref used for calling a method taking &mut self.
71     (*v).push(2);
72     assert_eq!(v.counts(), (1, 3));
73
74     // Check the final states.
75     assert_eq!(*n, 2);
76     let expected: &[_] = &[1, 2];
77     assert_eq!((*v), expected);
78 }