@@ -60,8 +60,6 @@ pub enum constness {
60
60
non_const
61
61
}
62
62
63
- type constness_cache = HashMap < ast:: DefId , constness > ;
64
-
65
63
pub fn join ( a : constness , b : constness ) -> constness {
66
64
match ( a, b) {
67
65
( integral_const, integral_const) => integral_const,
@@ -76,12 +74,102 @@ pub fn join_all<It: Iterator<constness>>(mut cs: It) -> constness {
76
74
cs. fold ( integral_const, |a, b| join ( a, b) )
77
75
}
78
76
77
+ pub fn classify ( e : & Expr ,
78
+ tcx : ty:: ctxt )
79
+ -> constness {
80
+ let did = ast_util:: local_def ( e. id ) ;
81
+ match tcx. ccache . find ( & did) {
82
+ Some ( & x) => x,
83
+ None => {
84
+ let cn =
85
+ match e. node {
86
+ ast:: ExprLit ( lit) => {
87
+ match lit. node {
88
+ ast:: lit_str( * ) |
89
+ ast:: lit_float( * ) => general_const,
90
+ _ => integral_const
91
+ }
92
+ }
93
+
94
+ ast:: ExprUnary ( _, _, inner) |
95
+ ast:: ExprParen ( inner) => {
96
+ classify ( inner, tcx)
97
+ }
98
+
99
+ ast:: ExprBinary ( _, _, a, b) => {
100
+ join ( classify ( a, tcx) ,
101
+ classify ( b, tcx) )
102
+ }
103
+
104
+ ast:: ExprTup ( ref es) |
105
+ ast:: ExprVec ( ref es, ast:: MutImmutable ) => {
106
+ join_all ( es. iter ( ) . map ( |e| classify ( * e, tcx) ) )
107
+ }
108
+
109
+ ast:: ExprVstore ( e, vstore) => {
110
+ match vstore {
111
+ ast:: ExprVstoreSlice => classify ( e, tcx) ,
112
+ ast:: ExprVstoreUniq |
113
+ ast:: ExprVstoreBox |
114
+ ast:: ExprVstoreMutBox |
115
+ ast:: ExprVstoreMutSlice => non_const
116
+ }
117
+ }
118
+
119
+ ast:: ExprStruct ( _, ref fs, None ) => {
120
+ let cs = do fs. iter ( ) . map |f| {
121
+ classify ( f. expr , tcx)
122
+ } ;
123
+ join_all ( cs)
124
+ }
125
+
126
+ ast:: ExprCast ( base, _) => {
127
+ let ty = ty:: expr_ty ( tcx, e) ;
128
+ let base = classify ( base, tcx) ;
129
+ if ty:: type_is_integral ( ty) {
130
+ join ( integral_const, base)
131
+ } else if ty:: type_is_fp ( ty) {
132
+ join ( general_const, base)
133
+ } else {
134
+ non_const
135
+ }
136
+ }
137
+
138
+ ast:: ExprField ( base, _, _) => {
139
+ classify ( base, tcx)
140
+ }
141
+
142
+ ast:: ExprIndex ( _, base, idx) => {
143
+ join ( classify ( base, tcx) ,
144
+ classify ( idx, tcx) )
145
+ }
146
+
147
+ ast:: ExprAddrOf ( ast:: MutImmutable , base) => {
148
+ classify ( base, tcx)
149
+ }
150
+
151
+ // FIXME: (#3728) we can probably do something CCI-ish
152
+ // surrounding nonlocal constants. But we don't yet.
153
+ ast:: ExprPath ( _) => {
154
+ lookup_constness ( tcx, e)
155
+ }
156
+
157
+ ast:: ExprRepeat ( * ) => general_const,
158
+
159
+ _ => non_const
160
+ } ;
161
+ tcx. ccache . insert ( did, cn) ;
162
+ cn
163
+ }
164
+ }
165
+ }
166
+
79
167
pub fn lookup_const ( tcx : ty:: ctxt , e : & Expr ) -> Option < @Expr > {
80
168
match tcx. def_map . find ( & e. id ) {
81
- Some ( & ast:: DefStatic ( def_id, false ) ) =>
82
- lookup_const_by_id ( tcx, def_id ) ,
83
- Some ( & ast :: DefVariant ( enum_def , variant_def , _ ) ) =>
84
- lookup_variant_by_id ( tcx , enum_def , variant_def) ,
169
+ Some ( & ast:: DefStatic ( def_id, false ) ) => lookup_const_by_id ( tcx , def_id ) ,
170
+ Some ( & ast :: DefVariant ( enum_def , variant_def , _ ) ) => lookup_variant_by_id ( tcx,
171
+ enum_def ,
172
+ variant_def) ,
85
173
_ => None
86
174
}
87
175
}
@@ -111,18 +199,14 @@ pub fn lookup_variant_by_id(tcx: ty::ctxt,
111
199
Some ( _) => None
112
200
}
113
201
} else {
114
- match tcx. extern_const_variants . find ( & variant_def) {
115
- Some ( & e) => return e,
116
- None => { }
117
- }
118
202
let maps = astencode:: Maps {
119
203
root_map : @mut HashMap :: new ( ) ,
120
204
method_map : @mut HashMap :: new ( ) ,
121
205
vtable_map : @mut HashMap :: new ( ) ,
122
206
write_guard_map : @mut HashSet :: new ( ) ,
123
207
capture_map : @mut HashMap :: new ( )
124
208
} ;
125
- let e = match csearch:: maybe_get_item_ast ( tcx, enum_def,
209
+ match csearch:: maybe_get_item_ast ( tcx, enum_def,
126
210
|a, b, c, d| astencode:: decode_inlined_item ( a,
127
211
b,
128
212
maps,
@@ -135,9 +219,7 @@ pub fn lookup_variant_by_id(tcx: ty::ctxt,
135
219
_ => None
136
220
} ,
137
221
_ => None
138
- } ;
139
- tcx. extern_const_variants . insert ( variant_def, e) ;
140
- return e;
222
+ }
141
223
}
142
224
}
143
225
@@ -154,136 +236,49 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
154
236
Some ( _) => None
155
237
}
156
238
} else {
157
- match tcx. extern_const_statics . find ( & def_id) {
158
- Some ( & e) => return e,
159
- None => { }
160
- }
161
239
let maps = astencode:: Maps {
162
240
root_map : @mut HashMap :: new ( ) ,
163
241
method_map : @mut HashMap :: new ( ) ,
164
242
vtable_map : @mut HashMap :: new ( ) ,
165
243
write_guard_map : @mut HashSet :: new ( ) ,
166
244
capture_map : @mut HashMap :: new ( )
167
245
} ;
168
- let e = match csearch:: maybe_get_item_ast ( tcx, def_id,
246
+ match csearch:: maybe_get_item_ast ( tcx, def_id,
169
247
|a, b, c, d| astencode:: decode_inlined_item ( a, b, maps, c, d) ) {
170
248
csearch:: found( ast:: ii_item( item) ) => match item. node {
171
249
item_static( _, ast:: MutImmutable , const_expr) => Some ( const_expr) ,
172
250
_ => None
173
251
} ,
174
252
_ => None
175
- } ;
176
- tcx. extern_const_statics . insert ( def_id, e) ;
177
- return e;
178
- }
179
- }
180
-
181
- struct ConstEvalVisitor {
182
- tcx : ty:: ctxt ,
183
- ccache : constness_cache ,
184
- }
185
-
186
- impl ConstEvalVisitor {
187
- fn classify ( & mut self , e : & Expr ) -> constness {
188
- let did = ast_util:: local_def ( e. id ) ;
189
- match self . ccache . find ( & did) {
190
- Some ( & x) => return x,
191
- None => { }
192
253
}
193
- let cn = match e. node {
194
- ast:: ExprLit ( lit) => {
195
- match lit. node {
196
- ast:: lit_str( * ) | ast:: lit_float( * ) => general_const,
197
- _ => integral_const
198
- }
199
- }
200
-
201
- ast:: ExprUnary ( _, _, inner) | ast:: ExprParen ( inner) =>
202
- self . classify ( inner) ,
203
-
204
- ast:: ExprBinary ( _, _, a, b) =>
205
- join ( self . classify ( a) , self . classify ( b) ) ,
206
-
207
- ast:: ExprTup ( ref es) |
208
- ast:: ExprVec ( ref es, ast:: MutImmutable ) =>
209
- join_all ( es. iter ( ) . map ( |e| self . classify ( * e) ) ) ,
210
-
211
- ast:: ExprVstore ( e, vstore) => {
212
- match vstore {
213
- ast:: ExprVstoreSlice => self . classify ( e) ,
214
- ast:: ExprVstoreUniq |
215
- ast:: ExprVstoreBox |
216
- ast:: ExprVstoreMutBox |
217
- ast:: ExprVstoreMutSlice => non_const
218
- }
219
- }
220
-
221
- ast:: ExprStruct ( _, ref fs, None ) => {
222
- let cs = do fs. iter ( ) . map |f| {
223
- self . classify ( f. expr )
224
- } ;
225
- join_all ( cs)
226
- }
227
-
228
- ast:: ExprCast ( base, _) => {
229
- let ty = ty:: expr_ty ( self . tcx , e) ;
230
- let base = self . classify ( base) ;
231
- if ty:: type_is_integral ( ty) {
232
- join ( integral_const, base)
233
- } else if ty:: type_is_fp ( ty) {
234
- join ( general_const, base)
235
- } else {
236
- non_const
237
- }
238
- }
239
-
240
- ast:: ExprField ( base, _, _) => self . classify ( base) ,
241
-
242
- ast:: ExprIndex ( _, base, idx) =>
243
- join ( self . classify ( base) , self . classify ( idx) ) ,
244
-
245
- ast:: ExprAddrOf ( ast:: MutImmutable , base) => self . classify ( base) ,
246
-
247
- // FIXME: (#3728) we can probably do something CCI-ish
248
- // surrounding nonlocal constants. But we don't yet.
249
- ast:: ExprPath ( _) => self . lookup_constness ( e) ,
250
-
251
- ast:: ExprRepeat ( * ) => general_const,
252
-
253
- _ => non_const
254
- } ;
255
- self . ccache . insert ( did, cn) ;
256
- cn
257
254
}
255
+ }
258
256
259
- fn lookup_constness ( & self , e : & Expr ) -> constness {
260
- match lookup_const ( self . tcx , e) {
261
- Some ( rhs) => {
262
- let ty = ty:: expr_ty ( self . tcx , rhs) ;
263
- if ty:: type_is_integral ( ty) {
264
- integral_const
265
- } else {
266
- general_const
267
- }
257
+ pub fn lookup_constness ( tcx : ty:: ctxt , e : & Expr ) -> constness {
258
+ match lookup_const ( tcx, e) {
259
+ Some ( rhs) => {
260
+ let ty = ty:: expr_ty ( tcx, rhs) ;
261
+ if ty:: type_is_integral ( ty) {
262
+ integral_const
263
+ } else {
264
+ general_const
268
265
}
269
- None => non_const
270
266
}
267
+ None => non_const
271
268
}
272
-
273
269
}
274
270
271
+ struct ConstEvalVisitor { tcx : ty:: ctxt }
272
+
275
273
impl Visitor < ( ) > for ConstEvalVisitor {
276
274
fn visit_expr_post ( & mut self , e : @Expr , _: ( ) ) {
277
- self . classify ( e) ;
275
+ classify ( e, self . tcx ) ;
278
276
}
279
277
}
280
278
281
279
pub fn process_crate ( crate : & ast:: Crate ,
282
280
tcx : ty:: ctxt ) {
283
- let mut v = ConstEvalVisitor {
284
- tcx : tcx,
285
- ccache : HashMap :: new ( ) ,
286
- } ;
281
+ let mut v = ConstEvalVisitor { tcx : tcx } ;
287
282
visit:: walk_crate ( & mut v, crate , ( ) ) ;
288
283
tcx. sess . abort_if_errors ( ) ;
289
284
}
0 commit comments