File: hrtb-doesnt-borrow-self-2.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg3-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid, trixie
  • size: 893,396 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; perl: 29; lisp: 29; ruby: 19; sql: 11
file content (116 lines) | stat: -rw-r--r-- 2,578 bytes parent folder | download | duplicates (4)
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
//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"

// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
// should act as assertion that item does not borrow from its stream;
// but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
// have such an item.
//
// This tests double-checks that we do not allow such behavior to leak
// through again.

pub trait Stream {
    type Item;
    fn next(self) -> Option<Self::Item>;
}

// Example stream
pub struct Repeat(u64);

impl<'a> Stream for &'a mut Repeat {
    type Item = &'a u64;
    fn next(self) -> Option<Self::Item> {
        Some(&self.0)
    }
}

pub struct Map<S, F> {
    stream: S,
    func: F,
}

impl<'a, A, F, T> Stream for &'a mut Map<A, F>
where
    &'a mut A: Stream,
    F: FnMut(<&'a mut A as Stream>::Item) -> T,
{
    type Item = T;
    fn next(self) -> Option<T> {
        match self.stream.next() {
            Some(item) => Some((self.func)(item)),
            None => None,
        }
    }
}

pub struct Filter<S, F> {
    stream: S,
    func: F,
}

impl<'a, A, F, T> Stream for &'a mut Filter<A, F>
where
    for<'b> &'b mut A: Stream<Item = T>, // <---- BAD
    F: FnMut(&T) -> bool,
{
    type Item = <&'a mut A as Stream>::Item;
    fn next(self) -> Option<Self::Item> {
        while let Some(item) = self.stream.next() {
            if (self.func)(&item) {
                return Some(item);
            }
        }
        None
    }
}

pub trait StreamExt
where
    for<'b> &'b mut Self: Stream,
{
    fn mapx<F>(self, func: F) -> Map<Self, F>
    where
        Self: Sized,
        for<'a> &'a mut Map<Self, F>: Stream,
    {
        Map { func: func, stream: self }
    }

    fn filterx<F>(self, func: F) -> Filter<Self, F>
    where
        Self: Sized,
        for<'a> &'a mut Filter<Self, F>: Stream,
    {
        Filter { func: func, stream: self }
    }

    fn countx(mut self) -> usize
    where
        Self: Sized,
    {
        let mut count = 0;
        while let Some(_) = self.next() {
            count += 1;
        }
        count
    }
}

impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}

fn identity<T>(x: &T) -> &T {
    x
}

fn variant2() {
    let source = Repeat(10);

    // Here, we use a function, which is not subject to the vagaries
    // of closure signature inference. In this case, we get the error
    // on `countx` as, I think, the test originally expected.
    let map = source.mapx(identity);
    let filter = map.filterx(|x: &_| true);
    let count = filter.countx();
    //~^ ERROR the method
}

fn main() {}