/// Find the path leading to a non-zero leaf field, starting from
/// the given type and recursing through aggregates.
// FIXME(eddyb) track value ranges and traverse already optimized enums.
Find the path leading to a non-zero leaf field, starting from
the given type and recursing through aggregates.
FIXME(eddyb) track value ranges and traverse already optimized enums.
Find the path leading to a non - zero leaf field starting from the given type and recursing through aggregates . FIXME ( eddyb ) track value ranges and traverse already optimized enums .
pub fn non_zero_field_in_type(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
                                  ty: Ty<'gcx>)
                                  -> Result<Option<FieldPath>, LayoutError<'gcx>> {
        let tcx = infcx.tcx.global_tcx();
        match (ty.layout(infcx)?, &ty.sty) {
            (&Scalar { non_zero: true, .. }, _) => Ok(Some(vec![])),
            (&FatPointer { non_zero: true, .. }, _) => {
                Ok(Some(vec![FAT_PTR_ADDR as u32]))
            }
            // Is this the NonZero lang item wrapping a pointer or integer type?
            (&Univariant { non_zero: true, .. }, &ty::TyStruct(def, substs)) => {
                let fields = &def.struct_variant().fields;
                assert_eq!(fields.len(), 1);
                let ty = normalize_associated_type(infcx, fields[0].ty(tcx, substs));
                match *ty.layout(infcx)? {
                    // FIXME(eddyb) also allow floating-point types here.
                    Scalar { value: Int(_), non_zero: false } |
                    Scalar { value: Pointer, non_zero: false } => {
                        Ok(Some(vec![0]))
                    }
                    FatPointer { non_zero: false, .. } => {
                        Ok(Some(vec![FAT_PTR_ADDR as u32, 0]))
                    }
                    _ => Ok(None)
                }
            }
            // Perhaps one of the fields of this struct is non-zero
            // let's recurse and find out
            (_, &ty::TyStruct(def, substs)) => {
                Struct::non_zero_field_path(infcx, def.struct_variant().fields
                                                      .iter().map(|field| {
                    normalize_associated_type(infcx, field.ty(tcx, substs))
                }))
            }
            // Perhaps one of the upvars of this closure is non-zero
            // Let's recurse and find out!
            (_, &ty::TyClosure(_, ty::ClosureSubsts { upvar_tys: tys, .. })) |
            // Can we use one of the fields in this tuple?
            (_, &ty::TyTuple(tys)) => {
                Struct::non_zero_field_path(infcx, tys.iter().cloned())
            }
            // Is this a fixed-size array of something non-zero
            // with at least one element?
            (_, &ty::TyArray(ety, d)) if d > 0 => {
                Struct::non_zero_field_path(infcx, Some(ety).into_iter())
            }
            // Anything else is not a non-zero type.
            _ => Ok(None)
        }
    }
pub fn non_zero_field_in_type ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > , ty : Ty < ' gcx > ) -> Result < Option < FieldPath > , LayoutError < ' gcx > > { let tcx = infcx . tcx . global_tcx ( ) ; match ( ty . layout ( infcx ) ? , & ty . sty ) { ( & Scalar { non_zero : true , .. } , _ ) => Ok ( Some ( vec ! [ ] ) ) , ( & FatPointer { non_zero : true , .. } , _ ) => { Ok ( Some ( vec ! [ FAT_PTR_ADDR as u32 ] ) ) } // Is this the NonZero lang item wrapping a pointer or integer type? ( & Univariant { non_zero : true , .. } , & ty :: TyStruct ( def , substs ) ) => { let fields = & def . struct_variant ( ) . fields ; assert_eq ! ( fields len ( ) 1 ) ; let ty = normalize_associated_type ( infcx , fields [ 0 ] . ty ( tcx , substs ) ) ; match * ty . layout ( infcx ) ? { // FIXME(eddyb) also allow floating-point types here. Scalar { value : Int ( _ ) , non_zero : false } | Scalar { value : Pointer , non_zero : false } => { Ok ( Some ( vec ! [ 0 ] ) ) } FatPointer { non_zero : false , .. } => { Ok ( Some ( vec ! [ FAT_PTR_ADDR as u32 0 ] ) ) } _ => Ok ( None ) } } // Perhaps one of the fields of this struct is non-zero // let's recurse and find out ( _ , & ty :: TyStruct ( def , substs ) ) => { Struct :: non_zero_field_path ( infcx , def . struct_variant ( ) . fields . iter ( ) . map ( | field | { normalize_associated_type ( infcx , field . ty ( tcx , substs ) ) } ) ) } // Perhaps one of the upvars of this closure is non-zero // Let's recurse and find out! ( _ , & ty :: TyClosure ( _ , ty :: ClosureSubsts { upvar_tys : tys , .. } ) ) | // Can we use one of the fields in this tuple? ( _ , & ty :: TyTuple ( tys ) ) => { Struct :: non_zero_field_path ( infcx , tys . iter ( ) . cloned ( ) ) } // Is this a fixed-size array of something non-zero // with at least one element? ( _ , & ty :: TyArray ( ety , d ) ) if d > 0 => { Struct :: non_zero_field_path ( infcx , Some ( ety ) . into_iter ( ) ) } // Anything else is not a non-zero type. _ => Ok ( None ) } }
Find the path leading to a non-zero leaf field, starting from
the given type and recursing through aggregates.
Find the path leading to a non - zero leaf field starting from the given type and recursing through aggregates .
infcx
&InferCtxt<'a, 'gcx, 'tcx>
ty
Ty<'gcx>