@@ -228,24 +228,24 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
228228 let st = mk_struct ( cx, cases[ discr] . tys [ ] ,
229229 false , t) ;
230230 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 => {
232232 return RawNullablePointer {
233233 nndiscr : discr as Disr ,
234234 nnty : st. fields [ 0 ] ,
235235 nullfields : cases[ 1 - discr] . tys . clone ( )
236236 } ;
237237 }
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 ( ) ;
241241 return StructWrappedNullablePointer {
242242 nndiscr : discr as Disr ,
243243 nonnull : st,
244244 discrfield : discrfield,
245245 nullfields : cases[ 1 - discr] . tys . clone ( )
246246 } ;
247247 }
248- None => { }
248+ None => { }
249249 }
250250 }
251251 discr += 1 ;
@@ -338,33 +338,38 @@ struct Case<'tcx> {
338338/// This represents the (GEP) indices to follow to get to the discriminant field
339339pub type DiscrField = Vec < uint > ;
340340
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 > {
342344 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)
352349 } ,
353350
351+ // Regular thin pointer: &T/&mut T/Box<T>
352+ ty:: ty_rptr( ..) | ty:: ty_uniq( ..) => Some ( path) ,
353+
354354 // Functions are just pointers
355- ty:: ty_bare_fn( ..) => Some ( vec ! [ ] ) ,
355+ ty:: ty_bare_fn( ..) => Some ( path ) ,
356356
357357 // 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+ } ,
359362
360363 // Is this the NonZero lang item wrapping a pointer or integer type?
361364 ty:: ty_struct( did, ref substs) if Some ( did) == tcx. lang_items . non_zero ( ) => {
362365 let nonzero_fields = ty:: lookup_struct_fields ( tcx, did) ;
363366 assert_eq ! ( nonzero_fields. len( ) , 1 ) ;
364367 let nonzero_field = ty:: lookup_field_type ( tcx, did, nonzero_fields[ 0 ] . id , substs) ;
365368 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+ } ,
368373 _ => None
369374 }
370375 } ,
@@ -375,13 +380,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
375380 let fields = ty:: lookup_struct_fields ( tcx, def_id) ;
376381 for ( j, field) in fields. iter ( ) . enumerate ( ) {
377382 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) ;
385386 }
386387 }
387388 None
@@ -390,13 +391,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
390391 // Can we use one of the fields in this tuple?
391392 ty:: ty_tup( ref tys) => {
392393 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) ;
400397 }
401398 }
402399 None
@@ -405,13 +402,11 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
405402 // Is this a fixed-size array of something non-zero
406403 // with at least one element?
407404 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
415410 }
416411 } ,
417412
@@ -427,13 +422,9 @@ impl<'tcx> Case<'tcx> {
427422
428423 fn find_ptr < ' a > ( & self , cx : & CrateContext < ' a , ' tcx > ) -> Option < DiscrField > {
429424 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) ;
437428 }
438429 }
439430 None
0 commit comments