fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
        if let layout::Abi::Scalar(ref scalar) = self.abi {
            // Use a different cache for scalars because pointers to DSTs
            // can be either fat or thin (data pointers of fat pointers).
            if let Some(&llty) = cx.scalar_lltypes.borrow().get(&self.ty) {
                return llty;
            }
            let llty = match self.ty.sty {
                ty::TyRef(_, ty, _) |
                ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
                    cx.layout_of(ty).llvm_type(cx).ptr_to()
                }
                ty::TyAdt(def, _) if def.is_box() => {
                    cx.layout_of(self.ty.boxed_ty()).llvm_type(cx).ptr_to()
                }
                ty::TyFnPtr(sig) => {
                    let sig = cx.tcx.normalize_erasing_late_bound_regions(
                        ty::ParamEnv::reveal_all(),
                        &sig,
                    );
                    FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to()
                }
                _ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO)
            };
            cx.scalar_lltypes.borrow_mut().insert(self.ty, llty);
            return llty;
        }


        // Check the cache.
        let variant_index = match self.variants {
            layout::Variants::Single { index } => Some(index),
            _ => None
        };
        if let Some(&llty) = cx.lltypes.borrow().get(&(self.ty, variant_index)) {
            return llty;
        }

        debug!("llvm_type({:#?})", self);

        assert!(!self.ty.has_escaping_regions(), "{:?} has escaping regions", self.ty);

        // Make sure lifetimes are erased, to avoid generating distinct LLVM
        // types for Rust types that only differ in the choice of lifetimes.
        let normal_ty = cx.tcx.erase_regions(&self.ty);

        let mut defer = None;
        let llty = if self.ty != normal_ty {
            let mut layout = cx.layout_of(normal_ty);
            if let Some(v) = variant_index {
                layout = layout.for_variant(cx, v);
            }
            layout.llvm_type(cx)
        } else {
            uncached_llvm_type(cx, *self, &mut defer)
        };
        debug!("--> mapped {:#?} to llty={:?}", self, llty);

        cx.lltypes.borrow_mut().insert((self.ty, variant_index), llty);

        if let Some((llty, layout)) = defer {
            let (llfields, packed) = struct_llfields(cx, layout);
            llty.set_struct_body(&llfields, packed)
        }

        llty
    }
/// Get the LLVM type corresponding to a Rust type, i.e. `rustc::ty::Ty`.
/// The pointee type of the pointer in `PlaceRef` is always this type.
/// For sized types, it is also the right LLVM type for an `alloca`
/// containing a value of that type, and most immediates (except `bool`).
/// Unsized types, however, are represented by a "minimal unit", e.g.
/// `[T]` becomes `T`, while `str` and `Trait` turn into `i8` - this
/// is useful for indexing slices, as `&[T]`'s data pointer is `T*`.
/// If the type is an unsized struct, the regular layout is generated,
/// with the inner-most trailing unsized field using the "minimal unit"
/// of that field's type - this is useful for taking the address of
/// that field and ensuring the struct has the right alignment.
Get the LLVM type corresponding to a Rust type, i.e.
Get the LLVM type corresponding to a Rust type i . e .
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
        if let layout::Abi::Scalar(ref scalar) = self.abi {
            // Use a different cache for scalars because pointers to DSTs
            // can be either fat or thin (data pointers of fat pointers).
            if let Some(&llty) = cx.scalar_lltypes.borrow().get(&self.ty) {
                return llty;
            }
            let llty = match self.ty.sty {
                ty::TyRef(_, ty, _) |
                ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
                    cx.layout_of(ty).llvm_type(cx).ptr_to()
                }
                ty::TyAdt(def, _) if def.is_box() => {
                    cx.layout_of(self.ty.boxed_ty()).llvm_type(cx).ptr_to()
                }
                ty::TyFnPtr(sig) => {
                    let sig = cx.tcx.normalize_erasing_late_bound_regions(
                        ty::ParamEnv::reveal_all(),
                        &sig,
                    );
                    FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to()
                }
                _ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO)
            };
            cx.scalar_lltypes.borrow_mut().insert(self.ty, llty);
            return llty;
        }
        // Check the cache.
        let variant_index = match self.variants {
            layout::Variants::Single { index } => Some(index),
            _ => None
        };
        if let Some(&llty) = cx.lltypes.borrow().get(&(self.ty, variant_index)) {
            return llty;
        }
        debug!("llvm_type({:#?})", self);
        assert!(!self.ty.has_escaping_regions(), "{:?} has escaping regions", self.ty);
        // Make sure lifetimes are erased, to avoid generating distinct LLVM
        // types for Rust types that only differ in the choice of lifetimes.
        let normal_ty = cx.tcx.erase_regions(&self.ty);
        let mut defer = None;
        let llty = if self.ty != normal_ty {
            let mut layout = cx.layout_of(normal_ty);
            if let Some(v) = variant_index {
                layout = layout.for_variant(cx, v);
            }
            layout.llvm_type(cx)
        } else {
            uncached_llvm_type(cx, *self, &mut defer)
        };
        debug!("--> mapped {:#?} to llty={:?}", self, llty);
        cx.lltypes.borrow_mut().insert((self.ty, variant_index), llty);
        if let Some((llty, layout)) = defer {
            let (llfields, packed) = struct_llfields(cx, layout);
            llty.set_struct_body(&llfields, packed)
        }
        llty
    }
fn llvm_type < ' a > ( & self , cx : & CodegenCx < ' a , ' tcx > ) -> & ' a Type { if let layout :: Abi :: Scalar ( ref scalar ) = self . abi { // Use a different cache for scalars because pointers to DSTs // can be either fat or thin (data pointers of fat pointers). if let Some ( & llty ) = cx . scalar_lltypes . borrow ( ) . get ( & self . ty ) { return llty ; } let llty = match self . ty . sty { ty :: TyRef ( _ , ty , _ ) | ty :: TyRawPtr ( ty :: TypeAndMut { ty , .. } ) => { cx . layout_of ( ty ) . llvm_type ( cx ) . ptr_to ( ) } ty :: TyAdt ( def , _ ) if def . is_box ( ) => { cx . layout_of ( self . ty . boxed_ty ( ) ) . llvm_type ( cx ) . ptr_to ( ) } ty :: TyFnPtr ( sig ) => { let sig = cx . tcx . normalize_erasing_late_bound_regions ( ty :: ParamEnv :: reveal_all ( ) , & sig , ) ; FnType :: new ( cx , sig , & [ ] ) . llvm_type ( cx ) . ptr_to ( ) } _ => self . scalar_llvm_type_at ( cx , scalar , Size :: ZERO ) } ; cx . scalar_lltypes . borrow_mut ( ) . insert ( self . ty , llty ) ; return llty ; } // Check the cache. let variant_index = match self . variants { layout :: Variants :: Single { index } => Some ( index ) , _ => None } ; if let Some ( & llty ) = cx . lltypes . borrow ( ) . get ( & ( self . ty , variant_index ) ) { return llty ; } debug ! ( " " self ) ; assert ! ( self ty has_escaping_regions ( ) " " self ty ) ; // Make sure lifetimes are erased, to avoid generating distinct LLVM // types for Rust types that only differ in the choice of lifetimes. let normal_ty = cx . tcx . erase_regions ( & self . ty ) ; let mut defer = None ; let llty = if self . ty != normal_ty { let mut layout = cx . layout_of ( normal_ty ) ; if let Some ( v ) = variant_index { layout = layout . for_variant ( cx , v ) ; } layout . llvm_type ( cx ) } else { uncached_llvm_type ( cx , * self , & mut defer ) } ; debug ! ( " " self llty ) ; cx . lltypes . borrow_mut ( ) . insert ( ( self . ty , variant_index ) , llty ) ; if let Some ( ( llty , layout ) ) = defer { let ( llfields , packed ) = struct_llfields ( cx , layout ) ; llty . set_struct_body ( & llfields , packed ) } llty }
Get the LLVM type corresponding to a Rust type, i.e.
Get the LLVM type corresponding to a Rust type i . e .
&self
cx
&CodegenCx<'a, 'tcx>
&self
cx
&CodegenCx<'a, 'tcx>