@@ -358,19 +358,33 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
358358        let  field = self . layout . field ( bx. cx ( ) ,  i) ; 
359359        let  offset = self . layout . fields . offset ( i) ; 
360360
361-         let  val = if  field. is_zst ( )  { 
362-             OperandValue :: ZeroSized 
363-         }  else  if  field. size  == self . layout . size  { 
364-             assert_eq ! ( offset. bytes( ) ,  0 ) ; 
365-             if  let  Some ( field_val)  = fx. codegen_transmute_operand ( bx,  * self ,  field)  { 
366-                 field_val
367-             }  else  { 
368-                 // we have to go through memory for things like 
361+         if  !bx. is_backend_ref ( self . layout )  && bx. is_backend_ref ( field)  { 
362+             if  let  BackendRepr :: Vector  {  count,  .. }  = self . layout . backend_repr 
363+                 && let  BackendRepr :: Memory  {  sized :  true  }  = field. backend_repr 
364+                 && count. is_power_of_two ( ) 
365+             { 
366+                 assert_eq ! ( field. size,  self . layout. size) ; 
367+                 // This is being deprecated, but for now stdarch still needs it for 
369368                // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]); 
370369                let  place = PlaceRef :: alloca ( bx,  field) ; 
371370                self . val . store ( bx,  place. val . with_type ( self . layout ) ) ; 
372-                 bx. load_operand ( place) . val 
371+                 return  bx. load_operand ( place) ; 
372+             }  else  { 
373+                 // Part of https://github.com/rust-lang/compiler-team/issues/838 
374+                 bug ! ( "Non-ref type {self:?} cannot project to ref field type {field:?}" ) ; 
373375            } 
376+         } 
377+ 
378+         let  val = if  field. is_zst ( )  { 
379+             OperandValue :: ZeroSized 
380+         }  else  if  field. size  == self . layout . size  { 
381+             assert_eq ! ( offset. bytes( ) ,  0 ) ; 
382+             fx. codegen_transmute_operand ( bx,  * self ,  field) . unwrap_or_else ( || { 
383+                 bug ! ( 
384+                     "Expected `codegen_transmute_operand` to handle equal-size \  
385+ 
386+                 ) 
387+             } ) 
374388        }  else  { 
375389            let  ( in_scalar,  imm)  = match  ( self . val ,  self . layout . backend_repr )  { 
376390                // Extract a scalar component from a pair. 
@@ -385,11 +399,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
385399                    } 
386400                } 
387401
388-                 // `#[repr(simd)]` types are also immediate. 
389-                 ( OperandValue :: Immediate ( llval) ,  BackendRepr :: Vector  {  .. } )  => { 
390-                     ( None ,  bx. extract_element ( llval,  bx. cx ( ) . const_usize ( i as  u64 ) ) ) 
391-                 } 
392- 
393402                _ => { 
394403                    span_bug ! ( fx. mir. span,  "OperandRef::extract_field({:?}): not applicable" ,  self ) 
395404                } 
@@ -415,14 +424,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
415424                        imm
416425                    } 
417426                } 
418-                 BackendRepr :: Memory  {  sized :  true  }  => { 
419-                     span_bug ! ( 
420-                         fx. mir. span, 
421-                         "Projecting into a simd type with padding doesn't work; \  
422- , 
423-                     ) ; 
424-                 } 
425-                 BackendRepr :: ScalarPair ( _,  _)  | BackendRepr :: Memory  {  sized :  false  }  => bug ! ( ) , 
427+                 BackendRepr :: ScalarPair ( _,  _)  | BackendRepr :: Memory  {  .. }  => bug ! ( ) , 
426428            } ) 
427429        } ; 
428430
0 commit comments