@@ -228,24 +228,24 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
228
228
let st = mk_struct ( cx, cases[ discr] . tys [ ] ,
229
229
false , t) ;
230
230
match cases[ discr] . find_ptr ( cx) {
231
- Some ( ref pf ) if pf . len ( ) == 1 && st. fields . len ( ) == 1 => {
231
+ Some ( ref df ) if df . len ( ) == 1 && st. fields . len ( ) == 1 => {
232
232
return RawNullablePointer {
233
233
nndiscr : discr as Disr ,
234
234
nnty : st. fields [ 0 ] ,
235
235
nullfields : cases[ 1 - discr] . tys . clone ( )
236
236
} ;
237
237
}
238
- Some ( pf ) => {
239
- let mut discrfield = vec ! [ 0 ] ;
240
- discrfield. extend ( pf . into_iter ( ) ) ;
238
+ Some ( mut discrfield ) => {
239
+ discrfield. push ( 0 ) ;
240
+ discrfield. reverse ( ) ;
241
241
return StructWrappedNullablePointer {
242
242
nndiscr : discr as Disr ,
243
243
nonnull : st,
244
244
discrfield : discrfield,
245
245
nullfields : cases[ 1 - discr] . tys . clone ( )
246
246
} ;
247
247
}
248
- None => { }
248
+ None => { }
249
249
}
250
250
}
251
251
discr += 1 ;
@@ -338,33 +338,38 @@ struct Case<'tcx> {
338
338
/// This represents the (GEP) indices to follow to get to the discriminant field
339
339
pub type DiscrField = Vec < uint > ;
340
340
341
- fn find_discr_field_candidate < ' tcx > ( tcx : & ty:: ctxt < ' tcx > , ty : Ty < ' tcx > ) -> Option < DiscrField > {
341
+ fn find_discr_field_candidate < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
342
+ ty : Ty < ' tcx > ,
343
+ mut path : DiscrField ) -> Option < DiscrField > {
342
344
match ty. sty {
343
- // &T/&mut T/Box<T> could either be a thin or fat pointer depending on T
344
- ty:: ty_rptr( _, ty:: mt { ty, .. } ) | ty:: ty_uniq( ty) => match ty. sty {
345
- // &[T] and &str are a pointer and length pair
346
- ty:: ty_vec( _, None ) | ty:: ty_str => Some ( vec ! [ FAT_PTR_ADDR ] ) ,
347
-
348
- ty:: ty_struct( ..) if !ty:: type_is_sized ( tcx, ty) => Some ( vec ! [ FAT_PTR_ADDR ] ) ,
349
-
350
- // Any other &T is just a pointer
351
- _ => Some ( vec ! [ ] )
345
+ // Fat &T/&mut T/Box<T> i.e. T is [T], str, or Trait
346
+ ty:: ty_rptr( _, ty:: mt { ty, .. } ) | ty:: ty_uniq( ty) if !ty:: type_is_sized ( tcx, ty) => {
347
+ path. push ( FAT_PTR_ADDR ) ;
348
+ Some ( path)
352
349
} ,
353
350
351
+ // Regular thin pointer: &T/&mut T/Box<T>
352
+ ty:: ty_rptr( ..) | ty:: ty_uniq( ..) => Some ( path) ,
353
+
354
354
// Functions are just pointers
355
- ty:: ty_bare_fn( ..) => Some ( vec ! [ ] ) ,
355
+ ty:: ty_bare_fn( ..) => Some ( path ) ,
356
356
357
357
// Closures are a pair of pointers: the code and environment
358
- ty:: ty_closure( ..) => Some ( vec ! [ FAT_PTR_ADDR ] ) ,
358
+ ty:: ty_closure( ..) => {
359
+ path. push ( FAT_PTR_ADDR ) ;
360
+ Some ( path)
361
+ } ,
359
362
360
363
// Is this the NonZero lang item wrapping a pointer or integer type?
361
364
ty:: ty_struct( did, ref substs) if Some ( did) == tcx. lang_items . non_zero ( ) => {
362
365
let nonzero_fields = ty:: lookup_struct_fields ( tcx, did) ;
363
366
assert_eq ! ( nonzero_fields. len( ) , 1 ) ;
364
367
let nonzero_field = ty:: lookup_field_type ( tcx, did, nonzero_fields[ 0 ] . id , substs) ;
365
368
match nonzero_field. sty {
366
- ty:: ty_ptr( ..) | ty:: ty_int( ..) |
367
- ty:: ty_uint( ..) => Some ( vec ! [ 0 ] ) ,
369
+ ty:: ty_ptr( ..) | ty:: ty_int( ..) | ty:: ty_uint( ..) => {
370
+ path. push ( 0 ) ;
371
+ Some ( path)
372
+ } ,
368
373
_ => None
369
374
}
370
375
} ,
@@ -375,13 +380,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
375
380
let fields = ty:: lookup_struct_fields ( tcx, def_id) ;
376
381
for ( j, field) in fields. iter ( ) . enumerate ( ) {
377
382
let field_ty = ty:: lookup_field_type ( tcx, def_id, field. id , substs) ;
378
- match find_discr_field_candidate ( tcx, field_ty) {
379
- Some ( v) => {
380
- let mut discrfield = vec ! [ j] ;
381
- discrfield. extend ( v. into_iter ( ) ) ;
382
- return Some ( discrfield) ;
383
- }
384
- None => continue
383
+ if let Some ( mut fpath) = find_discr_field_candidate ( tcx, field_ty, path. clone ( ) ) {
384
+ fpath. push ( j) ;
385
+ return Some ( fpath) ;
385
386
}
386
387
}
387
388
None
@@ -390,13 +391,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
390
391
// Can we use one of the fields in this tuple?
391
392
ty:: ty_tup( ref tys) => {
392
393
for ( j, & ty) in tys. iter ( ) . enumerate ( ) {
393
- match find_discr_field_candidate ( tcx, ty) {
394
- Some ( v) => {
395
- let mut discrfield = vec ! [ j] ;
396
- discrfield. extend ( v. into_iter ( ) ) ;
397
- return Some ( discrfield) ;
398
- }
399
- None => continue
394
+ if let Some ( mut fpath) = find_discr_field_candidate ( tcx, ty, path. clone ( ) ) {
395
+ fpath. push ( j) ;
396
+ return Some ( fpath) ;
400
397
}
401
398
}
402
399
None
@@ -405,13 +402,11 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
405
402
// Is this a fixed-size array of something non-zero
406
403
// with at least one element?
407
404
ty:: ty_vec( ety, Some ( d) ) if d > 0 => {
408
- match find_discr_field_candidate ( tcx, ety) {
409
- Some ( v) => {
410
- let mut discrfield = vec ! [ 0 ] ;
411
- discrfield. extend ( v. into_iter ( ) ) ;
412
- return Some ( discrfield) ;
413
- }
414
- None => None
405
+ if let Some ( mut vpath) = find_discr_field_candidate ( tcx, ety, path) {
406
+ vpath. push ( 0 ) ;
407
+ Some ( vpath)
408
+ } else {
409
+ None
415
410
}
416
411
} ,
417
412
@@ -427,13 +422,9 @@ impl<'tcx> Case<'tcx> {
427
422
428
423
fn find_ptr < ' a > ( & self , cx : & CrateContext < ' a , ' tcx > ) -> Option < DiscrField > {
429
424
for ( i, & ty) in self . tys . iter ( ) . enumerate ( ) {
430
- match find_discr_field_candidate ( cx. tcx ( ) , ty) {
431
- Some ( v) => {
432
- let mut discrfield = vec ! [ i] ;
433
- discrfield. extend ( v. into_iter ( ) ) ;
434
- return Some ( discrfield) ;
435
- }
436
- None => continue
425
+ if let Some ( mut path) = find_discr_field_candidate ( cx. tcx ( ) , ty, vec ! [ ] ) {
426
+ path. push ( i) ;
427
+ return Some ( path) ;
437
428
}
438
429
}
439
430
None
0 commit comments