Repository: rust-lang/rust
File: compiler/rustc_middle/src/ty/consts/valtree.rs (Rust)

Code before:
        self.try_to_leaf().map(|s| s.to_target_usize(tcx))
    }

    /// Get the values inside the ValTree as a slice of bytes. This only works for
    /// constants with types &str, &[u8], or [u8; _].
    pub fn try_to_raw_bytes(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx [u8]> {
        match self.ty.kind() {
            ty::Ref(_, inner_ty, _) => match inner_ty.kind() {
                // `&str` can be interpreted as raw bytes
                ty::Str => {}
                // `&[u8]` can be interpreted as raw bytes
                ty::Slice(slice_ty) if *slice_ty == tcx.types.u8 => {}
                // other `&_` can't be interpreted as raw bytes
                _ => return None,
            },
            // `[u8; N]` can be interpreted as raw bytes
            ty::Array(array_ty, _) if *array_ty == tcx.types.u8 => {}
            // Otherwise, type cannot be interpreted as raw bytes
            _ => return None,
        }

        // We create an iterator that yields `Option<u8>`
        let iterator = self
            .to_branch()
            .into_iter()
            .map(|ct| ct.try_to_leaf()?.try_to_bits(Size::from_bytes(1)).ok().map(|b| b as u8));
        // If there is `None` in the iterator, then the array is not a valid array of u8s and we return `None`
        let bytes: Vec<u8> = iterator.collect::<Option<Vec<u8>>>()?;

        Some(tcx.arena.alloc_from_iter(bytes))
    }

    /// Converts to a `ValTreeKind::Leaf` value, `panic`'ing
    /// if this constant is some other kind.
    #[inline]
    pub fn to_leaf(self) -> ScalarInt {
        match &**self.valtree {
            ValTreeKind::Leaf(s) => *s,
            ValTreeKind::Branch(..) => bug!("expected leaf, got {:?}", self),
        }
    }

    /// Converts to a `ValTreeKind::Branch` value, `panic`'ing
    /// if this constant is some other kind.
    #[inline]
    pub fn to_branch(self) -> &'tcx [ty::Const<'tcx>] {
        match &**self.valtree {
            ValTreeKind::Branch(branch) => &**branch,
            ValTreeKind::Leaf(..) => bug!("expected branch, got {:?}", self),
        }
    }

Review comment (suggestion):
can you instead check that the type of the of the element `ty::Value` is `u8` then call `to_u8`? I expect we don't want to let this function succeed for an array of 1-byte sized ADTs wrapping a `u8` 

Code after:
        self.try_to_leaf().map(|s| s.to_target_usize(tcx))
    }

    /// Get the values inside the ValTree as a slice of bytes. This only works for
    /// constants with types &str, &[u8], or [u8; _].
    pub fn try_to_raw_bytes(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx [u8]> {
        match self.ty.kind() {
            ty::Ref(_, inner_ty, _) => match inner_ty.kind() {
                // `&str` can be interpreted as raw bytes
                ty::Str => {}
                // `&[T]` can be interpreted as raw bytes if elements are `u8`
                ty::Slice(_) => {}
                // other `&_` can't be interpreted as raw bytes
                _ => return None,
            },
            // `[T; N]` can be interpreted as raw bytes if elements are `u8`
            ty::Array(_, _) => {}
            // Otherwise, type cannot be interpreted as raw bytes
            _ => return None,
        }

        // We create an iterator that yields `Option<u8>`
        let iterator = self.to_branch().into_iter().map(|ct| {
            (*ct)
                .try_to_value()
                .and_then(|value| (value.ty == tcx.types.u8).then_some(value))
                .and_then(|value| value.try_to_leaf().map(|leaf| leaf.to_u8()))
        });
        // If there is `None` in the iterator, then the array is not a valid array of u8s and we return `None`
        let bytes: Vec<u8> = iterator.collect::<Option<Vec<u8>>>()?;

        Some(tcx.arena.alloc_from_iter(bytes))
    }

    /// Converts to a `ValTreeKind::Leaf` value, `panic`'ing
    /// if this constant is some other kind.
    #[inline]
    pub fn to_leaf(self) -> ScalarInt {
        match &**self.valtree {
            ValTreeKind::Leaf(s) => *s,
            ValTreeKind::Branch(..) => bug!("expected leaf, got {:?}", self),
        }
    }

    /// Converts to a `ValTreeKind::Branch` value, `panic`'ing
    /// if this constant is some other kind.
    #[inline]
    pub fn to_branch(self) -> &'tcx [ty::Const<'tcx>] {
        match &**self.valtree {
            ValTreeKind::Branch(branch) => &**branch,
            ValTreeKind::Leaf(..) => bug!("expected branch, got {:?}", self),