@@ -10,9 +10,9 @@ use rustc_session::config::OptLevel;
1010use rustc_span:: { DUMMY_SP , Span } ;
1111use tracing:: { debug, instrument} ;
1212
13- use super :: FunctionCx ;
1413use super :: operand:: { OperandRef , OperandValue } ;
1514use super :: place:: PlaceRef ;
15+ use super :: { FunctionCx , LocalRef } ;
1616use crate :: common:: IntPredicate ;
1717use crate :: traits:: * ;
1818use crate :: { MemFlags , base} ;
@@ -607,6 +607,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
607607 self . codegen_place_to_pointer ( bx, place, mk_ptr)
608608 }
609609
610+ mir:: Rvalue :: Len ( place) => {
611+ let size = self . evaluate_array_len ( bx, place) ;
612+ OperandRef {
613+ val : OperandValue :: Immediate ( size) ,
614+ layout : bx. cx ( ) . layout_of ( bx. tcx ( ) . types . usize ) ,
615+ }
616+ }
617+
610618 mir:: Rvalue :: BinaryOp ( op_with_overflow, box ( ref lhs, ref rhs) )
611619 if let Some ( op) = op_with_overflow. overflowing_to_wrapping ( ) =>
612620 {
@@ -806,6 +814,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
806814 }
807815 }
808816
817+ fn evaluate_array_len ( & mut self , bx : & mut Bx , place : mir:: Place < ' tcx > ) -> Bx :: Value {
818+ // ZST are passed as operands and require special handling
819+ // because codegen_place() panics if Local is operand.
820+ if let Some ( index) = place. as_local ( ) {
821+ if let LocalRef :: Operand ( op) = self . locals [ index] {
822+ if let ty:: Array ( _, n) = op. layout . ty . kind ( ) {
823+ let n = n
824+ . try_to_target_usize ( bx. tcx ( ) )
825+ . expect ( "expected monomorphic const in codegen" ) ;
826+ return bx. cx ( ) . const_usize ( n) ;
827+ }
828+ }
829+ }
830+ // use common size calculation for non zero-sized types
831+ let cg_value = self . codegen_place ( bx, place. as_ref ( ) ) ;
832+ cg_value. len ( bx. cx ( ) )
833+ }
834+
809835 /// Codegen an `Rvalue::RawPtr` or `Rvalue::Ref`
810836 fn codegen_place_to_pointer (
811837 & mut self ,
@@ -1077,6 +1103,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10771103 mir:: Rvalue :: Ref ( ..) |
10781104 mir:: Rvalue :: CopyForDeref ( ..) |
10791105 mir:: Rvalue :: RawPtr ( ..) |
1106+ mir:: Rvalue :: Len ( ..) |
10801107 mir:: Rvalue :: Cast ( ..) | // (*)
10811108 mir:: Rvalue :: ShallowInitBox ( ..) | // (*)
10821109 mir:: Rvalue :: BinaryOp ( ..) |
0 commit comments