1
- use rustc_data_structures:: vec_linked_list as vll;
2
1
use rustc_index:: IndexVec ;
3
2
use rustc_middle:: mir:: visit:: { PlaceContext , Visitor } ;
4
3
use rustc_middle:: mir:: { Body , Local , Location } ;
@@ -37,9 +36,12 @@ pub(crate) struct LocalUseMap {
37
36
/// we add for each local variable.
38
37
first_drop_at : IndexVec < Local , Option < AppearanceIndex > > ,
39
38
40
- appearances : IndexVec < AppearanceIndex , Appearance > ,
39
+ appearances : Appearances ,
41
40
}
42
41
42
+ // The `Appearance::next` field effectively embeds a linked list within `Appearances`.
43
+ type Appearances = IndexVec < AppearanceIndex , Appearance > ;
44
+
43
45
struct Appearance {
44
46
point_index : PointIndex ,
45
47
next : Option < AppearanceIndex > ,
@@ -49,14 +51,34 @@ rustc_index::newtype_index! {
49
51
pub struct AppearanceIndex { }
50
52
}
51
53
52
- impl vll:: LinkElem for Appearance {
53
- type LinkIndex = AppearanceIndex ;
54
+ fn appearances_iter (
55
+ first : Option < AppearanceIndex > ,
56
+ appearances : & Appearances ,
57
+ ) -> impl Iterator < Item = AppearanceIndex > + ' _ {
58
+ AppearancesIter { appearances, current : first }
59
+ }
60
+
61
+ // Iterates over `Appearances` by following `next` fields.
62
+ struct AppearancesIter < ' a > {
63
+ appearances : & ' a Appearances ,
64
+ current : Option < AppearanceIndex > ,
65
+ }
54
66
55
- fn next ( elem : & Self ) -> Option < AppearanceIndex > {
56
- elem. next
67
+ impl < ' a > Iterator for AppearancesIter < ' a > {
68
+ type Item = AppearanceIndex ;
69
+
70
+ fn next ( & mut self ) -> Option < AppearanceIndex > {
71
+ if let Some ( c) = self . current {
72
+ self . current = self . appearances [ c] . next ;
73
+ Some ( c)
74
+ } else {
75
+ None
76
+ }
57
77
}
58
78
}
59
79
80
+ //-----------------------------------------------------------------------------
81
+
60
82
impl LocalUseMap {
61
83
pub ( crate ) fn build (
62
84
live_locals : & [ Local ] ,
@@ -86,17 +108,17 @@ impl LocalUseMap {
86
108
}
87
109
88
110
pub ( crate ) fn defs ( & self , local : Local ) -> impl Iterator < Item = PointIndex > + ' _ {
89
- vll :: iter ( self . first_def_at [ local] , & self . appearances )
111
+ appearances_iter ( self . first_def_at [ local] , & self . appearances )
90
112
. map ( move |aa| self . appearances [ aa] . point_index )
91
113
}
92
114
93
115
pub ( crate ) fn uses ( & self , local : Local ) -> impl Iterator < Item = PointIndex > + ' _ {
94
- vll :: iter ( self . first_use_at [ local] , & self . appearances )
116
+ appearances_iter ( self . first_use_at [ local] , & self . appearances )
95
117
. map ( move |aa| self . appearances [ aa] . point_index )
96
118
}
97
119
98
120
pub ( crate ) fn drops ( & self , local : Local ) -> impl Iterator < Item = PointIndex > + ' _ {
99
- vll :: iter ( self . first_drop_at [ local] , & self . appearances )
121
+ appearances_iter ( self . first_drop_at [ local] , & self . appearances )
100
122
. map ( move |aa| self . appearances [ aa] . point_index )
101
123
}
102
124
}
@@ -146,7 +168,7 @@ impl LocalUseMapBuild<'_> {
146
168
fn insert (
147
169
elements : & DenseLocationMap ,
148
170
first_appearance : & mut Option < AppearanceIndex > ,
149
- appearances : & mut IndexVec < AppearanceIndex , Appearance > ,
171
+ appearances : & mut Appearances ,
150
172
location : Location ,
151
173
) {
152
174
let point_index = elements. point_from_location ( location) ;
0 commit comments