X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Ftools%2Fclippy%2Fclippy_utils%2Fsrc%2Fconsts.rs;h=c31c560f427f25ef3ec33c05078ffa7b1158e182;hb=705d818bd52a6324d5e7693cc4306457395eebc8;hp=d487868cafe50e42b682aa56969453d4db69979d;hpb=52ee2a2738c957ca6fd54e97b4e090a266ba96ba;p=rust.git diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index d487868cafe..c31c560f427 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -7,7 +7,6 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp}; use rustc_lint::LateContext; -use rustc_middle::mir::interpret::Scalar; use rustc_middle::ty::subst::{Subst, SubstsRef}; use rustc_middle::ty::{self, EarlyBinder, FloatTy, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; @@ -423,14 +422,14 @@ fn fetch_path(&mut self, qpath: &QPath<'_>, id: HirId, ty: Ty<'tcx>) -> Option, right: &Expr<'_>) -> Option) -> Option { - use rustc_middle::mir::interpret::ConstValue; - match result.val() { - ty::ConstKind::Value(ConstValue::Scalar(Scalar::Int(int))) => { - match result.ty().kind() { - ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)), - ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))), - ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits( +pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: ty::Const<'tcx>) -> Option { + match result.kind() { + ty::ConstKind::Value(valtree) => { + match (valtree, result.ty().kind()) { + (ty::ValTree::Leaf(int), ty::Bool) => Some(Constant::Bool(int == ScalarInt::TRUE)), + (ty::ValTree::Leaf(int), ty::Uint(_) | ty::Int(_)) => Some(Constant::Int(int.assert_bits(int.size()))), + (ty::ValTree::Leaf(int), ty::Float(FloatTy::F32)) => Some(Constant::F32(f32::from_bits( int.try_into().expect("invalid f32 bit representation"), ))), - ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits( + (ty::ValTree::Leaf(int), ty::Float(FloatTy::F64)) => Some(Constant::F64(f64::from_bits( int.try_into().expect("invalid f64 bit representation"), ))), - ty::RawPtr(type_and_mut) => { + (ty::ValTree::Leaf(int), ty::RawPtr(type_and_mut)) => { if let ty::Uint(_) = type_and_mut.ty.kind() { return Some(Constant::RawPtr(int.assert_bits(int.size()))); } None }, - // FIXME: implement other conversions. - _ => None, - } - }, - ty::ConstKind::Value(ConstValue::Slice { data, start, end }) => match result.ty().kind() { - ty::Ref(_, tam, _) => match tam.kind() { - ty::Str => String::from_utf8( - data.inner() - .inspect_with_uninit_and_ptr_outside_interpreter(start..end) - .to_owned(), - ) - .ok() - .map(Constant::Str), - _ => None, - }, - _ => None, - }, - ty::ConstKind::Value(ConstValue::ByRef { alloc, offset: _ }) => match result.ty().kind() { - ty::Array(sub_type, len) => match sub_type.kind() { - ty::Float(FloatTy::F32) => match miri_to_const(*len) { - Some(Constant::Int(len)) => alloc - .inner() - .inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * len as usize)) - .to_owned() - .chunks(4) - .map(|chunk| { - Some(Constant::F32(f32::from_le_bytes( - chunk.try_into().expect("this shouldn't happen"), - ))) - }) - .collect::>>() - .map(Constant::Vec), - _ => None, - }, - ty::Float(FloatTy::F64) => match miri_to_const(*len) { - Some(Constant::Int(len)) => alloc - .inner() - .inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * len as usize)) - .to_owned() - .chunks(8) - .map(|chunk| { - Some(Constant::F64(f64::from_le_bytes( - chunk.try_into().expect("this shouldn't happen"), - ))) - }) - .collect::>>() - .map(Constant::Vec), + (ty::ValTree::Branch(_), ty::Ref(_, inner_ty, _)) if *inner_ty == tcx.types.str_ => valtree + .try_to_raw_bytes(tcx, result.ty()) + .and_then(|bytes| String::from_utf8(bytes.to_owned()).ok().map(Constant::Str)), + (ty::ValTree::Branch(_), ty::Array(arr_ty, len)) => match arr_ty.kind() { + ty::Float(float_ty) => { + let chunk_size = match float_ty { + FloatTy::F32 => 4, + FloatTy::F64 => 8, + }; + + match miri_to_const(tcx, *len) { + Some(Constant::Int(_)) => valtree.try_to_raw_bytes(tcx, result.ty()).and_then(|bytes| { + bytes + .to_owned() + .chunks(chunk_size) + .map(|chunk| match float_ty { + FloatTy::F32 => { + let float = f32::from_le_bytes( + chunk + .try_into() + .expect(&format!("expected to construct f32 from {:?}", chunk)), + ); + Some(Constant::F32(float)) + }, + FloatTy::F64 => { + let float = f64::from_le_bytes( + chunk + .try_into() + .expect(&format!("expected to construct f64 from {:?}", chunk)), + ); + Some(Constant::F64(float)) + }, + }) + .collect::>>() + .map(Constant::Vec) + }), + _ => None, + } + }, _ => None, }, - // FIXME: implement other array type conversions. + // FIXME: implement other conversions. _ => None, - }, - _ => None, + } }, - // FIXME: implement other conversions. _ => None, } }