]> git.proxmox.com Git - rustc.git/blame - src/test/ui/hrtb/issue-30786.rs
New upstream version 1.45.0+dfsg1
[rustc.git] / src / test / ui / hrtb / issue-30786.rs
CommitLineData
416331ca
XL
1// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
2// should act as assertion that item does not borrow from its stream;
3// but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
4// have such an item.
5//
6// This tests double-checks that we do not allow such behavior to leak
7// through again.
8
9// revisions: migrate nll
10
11// Since we are testing nll (and migration) explicitly as a separate
12// revisions, don't worry about the --compare-mode=nll on this test.
13
14// ignore-compare-mode-nll
15// ignore-compare-mode-polonius
16
17//[nll]compile-flags: -Z borrowck=mir
18
e1599b0c 19pub trait Stream { //[migrate]~ NOTE trait `Stream` defined here
416331ca
XL
20 type Item;
21 fn next(self) -> Option<Self::Item>;
22}
23
24// Example stream
25pub struct Repeat(u64);
26
27impl<'a> Stream for &'a mut Repeat {
28 type Item = &'a u64;
29 fn next(self) -> Option<Self::Item> {
30 Some(&self.0)
31 }
32}
33
34pub struct Map<S, F> {
35 stream: S,
36 func: F,
37}
38
39impl<'a, A, F, T> Stream for &'a mut Map<A, F>
40where &'a mut A: Stream,
41 F: FnMut(<&'a mut A as Stream>::Item) -> T,
42{
43 type Item = T;
44 fn next(self) -> Option<T> {
45 match self.stream.next() {
46 Some(item) => Some((self.func)(item)),
47 None => None,
48 }
49 }
50}
51
52pub struct Filter<S, F> {
53 stream: S,
54 func: F,
55}
56
57impl<'a, A, F, T> Stream for &'a mut Filter<A, F>
58where for<'b> &'b mut A: Stream<Item=T>, // <---- BAD
59 F: FnMut(&T) -> bool,
60{
61 type Item = <&'a mut A as Stream>::Item;
62 fn next(self) -> Option<Self::Item> {
63 while let Some(item) = self.stream.next() {
64 if (self.func)(&item) {
65 return Some(item);
66 }
67 }
68 None
69 }
70}
71
72pub trait StreamExt where for<'b> &'b mut Self: Stream {
73 fn map<F>(self, func: F) -> Map<Self, F>
74 where Self: Sized,
75 for<'a> &'a mut Map<Self, F>: Stream,
76 {
77 Map {
78 func: func,
79 stream: self,
80 }
81 }
82
83 fn filter<F>(self, func: F) -> Filter<Self, F>
84 where Self: Sized,
85 for<'a> &'a mut Filter<Self, F>: Stream,
86 {
87 Filter {
88 func: func,
89 stream: self,
90 }
91 }
92
93 fn count(mut self) -> usize
94 where Self: Sized,
95 {
96 let mut count = 0;
97 while let Some(_) = self.next() {
98 count += 1;
99 }
100 count
101 }
102}
103
104impl<T> StreamExt for T where for<'a> &'a mut T: Stream { }
105
106fn main() {
107 let source = Repeat(10);
108 let map = source.map(|x: &_| x);
e74abb32
XL
109 //[nll]~^ ERROR higher-ranked subtype error
110 //[migrate]~^^ ERROR implementation of `Stream` is not general enough
416331ca
XL
111 //[migrate]~| NOTE `Stream` would have to be implemented for the type `&'0 mut Map
112 //[migrate]~| NOTE but `Stream` is actually implemented for the type `&'1
e1599b0c 113 //[migrate]~| NOTE implementation of `Stream` is not general enough
416331ca
XL
114 let filter = map.filter(|x: &_| true);
115 //[nll]~^ ERROR higher-ranked subtype error
dfeec247
XL
116 //[nll]~| ERROR higher-ranked subtype error
117 //[nll]~| ERROR higher-ranked subtype error
118 //[nll]~| ERROR higher-ranked subtype error
416331ca
XL
119 let count = filter.count(); // Assert that we still have a valid stream.
120 //[nll]~^ ERROR higher-ranked subtype error
dfeec247
XL
121 //[nll]~| ERROR higher-ranked subtype error
122 //[nll]~| ERROR higher-ranked subtype error
123 //[nll]~| ERROR higher-ranked subtype error
416331ca 124}