1 //! Miscellaneous builder routines that are not specific to building any particular 2 //! kind of thing. 3 4 use crate::build::Builder; 5 6 use rustc_middle::mir::*; 7 use rustc_middle::ty::{self, Ty}; 8 use rustc_span::Span; 9 use rustc_trait_selection::infer::InferCtxtExt; 10 11 impl<'a, 'tcx> Builder<'a, 'tcx> { 12 /// Adds a new temporary value of type `ty` storing the result of 13 /// evaluating `expr`. 14 /// 15 /// N.B., **No cleanup is scheduled for this temporary.** You should 16 /// call `schedule_drop` once the temporary is initialized. temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx>17 pub(crate) fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> { 18 // Mark this local as internal to avoid temporaries with types not present in the 19 // user's code resulting in ICEs from the generator transform. 20 let temp = self.local_decls.push(LocalDecl::new(ty, span).internal()); 21 let place = Place::from(temp); 22 debug!("temp: created temp {:?} with type {:?}", place, self.local_decls[temp].ty); 23 place 24 } 25 26 /// Convenience function for creating a literal operand, one 27 /// without any user type annotation. literal_operand( &mut self, span: Span, literal: ConstantKind<'tcx>, ) -> Operand<'tcx>28 pub(crate) fn literal_operand( 29 &mut self, 30 span: Span, 31 literal: ConstantKind<'tcx>, 32 ) -> Operand<'tcx> { 33 let constant = Box::new(Constant { span, user_ty: None, literal }); 34 Operand::Constant(constant) 35 } 36 37 /// Returns a zero literal operand for the appropriate type, works for 38 /// bool, char and integers. zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx>39 pub(crate) fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { 40 let literal = ConstantKind::from_bits(self.tcx, 0, ty::ParamEnv::empty().and(ty)); 41 42 self.literal_operand(span, literal) 43 } 44 push_usize( &mut self, block: BasicBlock, source_info: SourceInfo, value: u64, ) -> Place<'tcx>45 pub(crate) fn push_usize( 46 &mut self, 47 block: BasicBlock, 48 source_info: SourceInfo, 49 value: u64, 50 ) -> Place<'tcx> { 51 let usize_ty = self.tcx.types.usize; 52 let temp = self.temp(usize_ty, source_info.span); 53 self.cfg.push_assign_constant( 54 block, 55 source_info, 56 temp, 57 Constant { 58 span: source_info.span, 59 user_ty: None, 60 literal: ConstantKind::from_usize(self.tcx, value), 61 }, 62 ); 63 temp 64 } 65 consume_by_copy_or_move(&self, place: Place<'tcx>) -> Operand<'tcx>66 pub(crate) fn consume_by_copy_or_move(&self, place: Place<'tcx>) -> Operand<'tcx> { 67 let tcx = self.tcx; 68 let ty = place.ty(&self.local_decls, tcx).ty; 69 if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty) { 70 Operand::Move(place) 71 } else { 72 Operand::Copy(place) 73 } 74 } 75 } 76