@@ -164,6 +164,23 @@ fn enter_rec(&@crate_ctxt ccx, &match m, uint col, &ast::ident[] fields,
164
164
ret result;
165
165
}
166
166
167
+ fn enter_box( & @crate_ctxt ccx, & match m, uint col, ValueRef val) -> match {
168
+ auto result = ~[ ] ;
169
+ auto dummy = @rec( id=0 , node=ast:: pat_wild, span=rec( lo=0 u, hi=0 u) ) ;
170
+ for ( match_branch br in m) {
171
+ auto pats = ivec:: slice( br. pats, 0 u, col) ;
172
+ alt ( br. pats. ( col) . node) {
173
+ ast:: pat_box( ?sub) { pats += ~[ sub] ; }
174
+ _ { pats += ~[ dummy] ; }
175
+ }
176
+ pats += ivec:: slice( br. pats, col + 1 u, ivec:: len( br. pats) ) ;
177
+ auto new_br = @rec( pats=pats with * br) ;
178
+ result += ~[ new_br] ;
179
+ bind_for_pat( br. pats. ( col) , new_br, val) ;
180
+ }
181
+ ret result;
182
+ }
183
+
167
184
fn get_options( & @crate_ctxt ccx, & match m, uint col) -> opt[ ] {
168
185
fn add_to_set( & mutable opt[ ] set, & opt val) {
169
186
for ( opt l in set) {
@@ -211,6 +228,33 @@ fn extract_variant_args(@block_ctxt bcx, ast::node_id pat_id,
211
228
ret tup ( args, bcx) ;
212
229
}
213
230
231
+ fn collect_record_fields( & match m, uint col) -> ast:: ident[ ] {
232
+ auto fields = ~[ ] ;
233
+ for ( match_branch br in m) {
234
+ alt ( br. pats . ( col) . node ) {
235
+ ast:: pat_rec ( ?fs, _) {
236
+ for ( ast:: field_pat f in fs) {
237
+ if ( !ivec:: any ( bind str:: eq ( f. ident , _) , fields) ) {
238
+ fields += ~[ f. ident ] ;
239
+ }
240
+ }
241
+ }
242
+ _ { }
243
+ }
244
+ }
245
+ ret fields;
246
+ }
247
+
248
+ fn any_box_pat( & match m, uint col) -> bool {
249
+ for ( match_branch br in m) {
250
+ alt ( br. pats . ( col) . node ) {
251
+ ast:: pat_box( _) { ret true; }
252
+ _ { }
253
+ }
254
+ }
255
+ ret false;
256
+ }
257
+
214
258
type exit_node = rec ( bind_map bound,
215
259
BasicBlockRef from,
216
260
BasicBlockRef to) ;
@@ -236,24 +280,13 @@ fn compile_submatch(@block_ctxt bcx, &match m, ValueRef[] vals, &mk_fail f,
236
280
auto vals_left = ivec:: slice ( vals, 1 u, ivec:: len ( vals) ) ;
237
281
auto ccx = bcx. fcx . lcx . ccx ;
238
282
auto pat_id = 0 ;
239
-
240
- auto rec_fields = ~[ ] ;
241
283
for ( match_branch br in m) {
242
284
// Find a real id (we're adding placeholder wildcard patterns, but
243
285
// each column is guaranteed to have at least one real pattern)
244
286
if ( pat_id == 0 ) { pat_id = br. pats . ( col) . id ; }
245
- // Gather field names
246
- alt ( br. pats . ( col) . node ) {
247
- ast:: pat_rec ( ?fs, _) {
248
- for ( ast:: field_pat f in fs) {
249
- if ( !ivec:: any ( bind str:: eq ( f. ident , _) , rec_fields) ) {
250
- rec_fields += ~[ f. ident ] ;
251
- }
252
- }
253
- }
254
- _ { }
255
- }
256
287
}
288
+
289
+ auto rec_fields = collect_record_fields ( m, col) ;
257
290
// Separate path for extracting and binding record fields
258
291
if ( ivec:: len ( rec_fields) > 0 u) {
259
292
auto rec_ty = ty:: node_id_to_monotype ( ccx. tcx , pat_id) ;
@@ -273,6 +306,16 @@ fn compile_submatch(@block_ctxt bcx, &match m, ValueRef[] vals, &mk_fail f,
273
306
ret;
274
307
}
275
308
309
+ // Unbox in case of a box field
310
+ if ( any_box_pat ( m, col) ) {
311
+ auto box = bcx. build . Load ( val) ;
312
+ auto unboxed = bcx. build . InBoundsGEP
313
+ ( box, ~[ C_int ( 0 ) , C_int ( back:: abi:: box_rc_field_body) ] ) ;
314
+ compile_submatch ( bcx, enter_box ( ccx, m, col, val) ,
315
+ ~[ unboxed] + vals_left, f, exits) ;
316
+ ret;
317
+ }
318
+
276
319
// Decide what kind of branch we need
277
320
auto opts = get_options ( ccx, m, col) ;
278
321
tag branch_kind { no_branch; single; switch; compare; }
0 commit comments