fn try_visit_primitive(
        &mut self,
        value: OpTy<'tcx, M::PointerTag>,
    ) -> InterpResult<'tcx, bool> {
        // Go over all the primitive types
        let ty = value.layout.ty;
        match ty.kind {
            ty::Bool => {
                let value = self.ecx.read_scalar(value)?;
                try_validation!(value.to_bool(), value, self.path, "a boolean");
                Ok(true)
            }
            ty::Char => {
                let value = self.ecx.read_scalar(value)?;
                try_validation!(value.to_char(), value, self.path, "a valid unicode codepoint");
                Ok(true)
            }
            ty::Float(_) | ty::Int(_) | ty::Uint(_) => {
                let value = self.ecx.read_scalar(value)?;
                // NOTE: Keep this in sync with the array optimization for int/float
                // types below!
                if self.ref_tracking_for_consts.is_some() {
                    // Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
                    let is_bits = value.not_undef().map_or(false, |v| v.is_bits());
                    if !is_bits {
                        throw_validation_failure!(
                            value,
                            self.path,
                            "initialized plain (non-pointer) bytes"
                        )
                    }
                } else {
                    // At run-time, for now, we accept *anything* for these types, including
                    // undef. We should fix that, but let's start low.
                }
                Ok(true)
            }
            ty::RawPtr(..) => {
                // We are conservative with undef for integers, but try to
                // actually enforce our current rules for raw pointers.
                let place = try_validation!(
                    self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?),
                    "undefined pointer",
                    self.path
                );
                if place.layout.is_unsized() {
                    self.check_wide_ptr_meta(place.meta, place.layout)?;
                }
                Ok(true)
            }
            ty::Ref(..) => {
                self.check_safe_pointer(value, "reference")?;
                Ok(true)
            }
            ty::Adt(def, ..) if def.is_box() => {
                self.check_safe_pointer(value, "box")?;
                Ok(true)
            }
            ty::FnPtr(_sig) => {
                let value = self.ecx.read_scalar(value)?;
                let _fn = try_validation!(
                    value.not_undef().and_then(|ptr| self.ecx.memory.get_fn(ptr)),
                    value,
                    self.path,
                    "a function pointer"
                );
                // FIXME: Check if the signature matches
                Ok(true)
            }
            ty::Never => throw_validation_failure!("a value of the never type `!`", self.path),
            ty::Foreign(..) | ty::FnDef(..) => {
                // Nothing to check.
                Ok(true)
            }
            // The above should be all the (inhabited) primitive types. The rest is compound, we
            // check them by visiting their fields/variants.
            // (`Str` UTF-8 check happens in `visit_aggregate`, too.)
            ty::Adt(..)
            | ty::Tuple(..)
            | ty::Array(..)
            | ty::Slice(..)
            | ty::Str
            | ty::Dynamic(..)
            | ty::Closure(..)
            | ty::Generator(..) => Ok(false),
            // Some types only occur during typechecking, they have no layout.
            // We should not see them here and we could not check them anyway.
            ty::Error
            | ty::Infer(..)
            | ty::Placeholder(..)
            | ty::Bound(..)
            | ty::Param(..)
            | ty::Opaque(..)
            | ty::UnnormalizedProjection(..)
            | ty::Projection(..)
            | ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
        }
    }
/// Check if this is a value of primitive type, and if yes check the validity of the value
/// at that type.  Return `true` if the type is indeed primitive.
Check if this is a value of primitive type, and if yes check the validity of the value
at that type.  Return `true` if the type is indeed primitive.
Check if this is a value of primitive type and if yes check the validity of the value at that type . Return ` true ` if the type is indeed primitive .
fn try_visit_primitive(
        &mut self,
        value: OpTy<'tcx, M::PointerTag>,
    ) -> InterpResult<'tcx, bool> {
        // Go over all the primitive types
        let ty = value.layout.ty;
        match ty.kind {
            ty::Bool => {
                let value = self.ecx.read_scalar(value)?;
                try_validation!(value.to_bool(), value, self.path, "a boolean");
                Ok(true)
            }
            ty::Char => {
                let value = self.ecx.read_scalar(value)?;
                try_validation!(value.to_char(), value, self.path, "a valid unicode codepoint");
                Ok(true)
            }
            ty::Float(_) | ty::Int(_) | ty::Uint(_) => {
                let value = self.ecx.read_scalar(value)?;
                // NOTE: Keep this in sync with the array optimization for int/float
                // types below!
                if self.ref_tracking_for_consts.is_some() {
                    // Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
                    let is_bits = value.not_undef().map_or(false, |v| v.is_bits());
                    if !is_bits {
                        throw_validation_failure!(
                            value,
                            self.path,
                            "initialized plain (non-pointer) bytes"
                        )
                    }
                } else {
                    // At run-time, for now, we accept *anything* for these types, including
                    // undef. We should fix that, but let's start low.
                }
                Ok(true)
            }
            ty::RawPtr(..) => {
                // We are conservative with undef for integers, but try to
                // actually enforce our current rules for raw pointers.
                let place = try_validation!(
                    self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?),
                    "undefined pointer",
                    self.path
                );
                if place.layout.is_unsized() {
                    self.check_wide_ptr_meta(place.meta, place.layout)?;
                }
                Ok(true)
            }
            ty::Ref(..) => {
                self.check_safe_pointer(value, "reference")?;
                Ok(true)
            }
            ty::Adt(def, ..) if def.is_box() => {
                self.check_safe_pointer(value, "box")?;
                Ok(true)
            }
            ty::FnPtr(_sig) => {
                let value = self.ecx.read_scalar(value)?;
                let _fn = try_validation!(
                    value.not_undef().and_then(|ptr| self.ecx.memory.get_fn(ptr)),
                    value,
                    self.path,
                    "a function pointer"
                );
                // FIXME: Check if the signature matches
                Ok(true)
            }
            ty::Never => throw_validation_failure!("a value of the never type `!`", self.path),
            ty::Foreign(..) | ty::FnDef(..) => {
                // Nothing to check.
                Ok(true)
            }
            // The above should be all the (inhabited) primitive types. The rest is compound, we
            // check them by visiting their fields/variants.
            // (`Str` UTF-8 check happens in `visit_aggregate`, too.)
            ty::Adt(..)
            | ty::Tuple(..)
            | ty::Array(..)
            | ty::Slice(..)
            | ty::Str
            | ty::Dynamic(..)
            | ty::Closure(..)
            | ty::Generator(..) => Ok(false),
            // Some types only occur during typechecking, they have no layout.
            // We should not see them here and we could not check them anyway.
            ty::Error
            | ty::Infer(..)
            | ty::Placeholder(..)
            | ty::Bound(..)
            | ty::Param(..)
            | ty::Opaque(..)
            | ty::UnnormalizedProjection(..)
            | ty::Projection(..)
            | ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
        }
    }
fn try_visit_primitive ( & mut self , value : OpTy < ' tcx , M :: PointerTag > , ) -> InterpResult < ' tcx , bool > { // Go over all the primitive types let ty = value . layout . ty ; match ty . kind { ty :: Bool => { let value = self . ecx . read_scalar ( value ) ? ; try_validation ! ( value to_bool ( ) value self path " " ) ; Ok ( true ) } ty :: Char => { let value = self . ecx . read_scalar ( value ) ? ; try_validation ! ( value to_char ( ) value self path " " ) ; Ok ( true ) } ty :: Float ( _ ) | ty :: Int ( _ ) | ty :: Uint ( _ ) => { let value = self . ecx . read_scalar ( value ) ? ; // NOTE: Keep this in sync with the array optimization for int/float // types below! if self . ref_tracking_for_consts . is_some ( ) { // Integers/floats in CTFE: Must be scalar bits, pointers are dangerous let is_bits = value . not_undef ( ) . map_or ( false , | v | v . is_bits ( ) ) ; if ! is_bits { throw_validation_failure ! ( value self path " " ) } } else { // At run-time, for now, we accept *anything* for these types, including // undef. We should fix that, but let's start low. } Ok ( true ) } ty :: RawPtr ( .. ) => { // We are conservative with undef for integers, but try to // actually enforce our current rules for raw pointers. let place = try_validation ! ( self ecx ref_to_mplace ( self ecx read_immediate ( value ) ) " " self path ) ; if place . layout . is_unsized ( ) { self . check_wide_ptr_meta ( place . meta , place . layout ) ? ; } Ok ( true ) } ty :: Ref ( .. ) => { self . check_safe_pointer ( value , " " ) ? ; Ok ( true ) } ty :: Adt ( def , .. ) if def . is_box ( ) => { self . check_safe_pointer ( value , " " ) ? ; Ok ( true ) } ty :: FnPtr ( _sig ) => { let value = self . ecx . read_scalar ( value ) ? ; let _fn = try_validation ! ( value not_undef ( ) and_then ( ptr self ecx memory get_fn ( ptr ) ) value self path " " ) ; // FIXME: Check if the signature matches Ok ( true ) } ty :: Never => throw_validation_failure ! ( " " self path ) , ty :: Foreign ( .. ) | ty :: FnDef ( .. ) => { // Nothing to check. Ok ( true ) } // The above should be all the (inhabited) primitive types. The rest is compound, we // check them by visiting their fields/variants. // (`Str` UTF-8 check happens in `visit_aggregate`, too.) ty :: Adt ( .. ) | ty :: Tuple ( .. ) | ty :: Array ( .. ) | ty :: Slice ( .. ) | ty :: Str | ty :: Dynamic ( .. ) | ty :: Closure ( .. ) | ty :: Generator ( .. ) => Ok ( false ) , // Some types only occur during typechecking, they have no layout. // We should not see them here and we could not check them anyway. ty :: Error | ty :: Infer ( .. ) | ty :: Placeholder ( .. ) | ty :: Bound ( .. ) | ty :: Param ( .. ) | ty :: Opaque ( .. ) | ty :: UnnormalizedProjection ( .. ) | ty :: Projection ( .. ) | ty :: GeneratorWitness ( .. ) => bug ! ( " " ty ) , } }
Check if this is a value of primitive type, and if yes check the validity of the value
at that type.
Check if this is a value of primitive type and if yes check the validity of the value at that type .
&mut self
value
OpTy<'tcx, M::PointerTag>