diff options
| author | b-naber <bn263@gmx.de> | 2022-06-03 20:42:35 +0200 |
|---|---|---|
| committer | b-naber <bn263@gmx.de> | 2022-06-14 16:11:27 +0200 |
| commit | 773d8b2e15024b2687b2d29972921a3b17816a13 (patch) | |
| tree | da7c1cd2ba5441aeda00ab7a43350c749f94f375 /compiler | |
| parent | 0a6815a924448b6e4b93adb8645d6903cbbc47eb (diff) | |
| download | rust-773d8b2e15024b2687b2d29972921a3b17816a13.tar.gz rust-773d8b2e15024b2687b2d29972921a3b17816a13.zip | |
address review
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/queries.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/value.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/mod.rs | 59 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/constant.rs | 72 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/src/v0.rs | 5 |
7 files changed, 70 insertions, 107 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 9284d240037..5f32f0d5e89 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -11,9 +11,6 @@ impl<'tcx> TyCtxt<'tcx> { /// Evaluates a constant without providing any substitutions. This is useful to evaluate consts /// that can't take any generic arguments like statics, const items or enum discriminants. If a /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned. - /// - /// Note: Returns a `ConstValue`, which isn't supposed to be used in the type system. In order to - /// evaluate to a type-system level constant value use `const_eval_poly_for_typeck`. #[instrument(skip(self), level = "debug")] pub fn const_eval_poly(self, def_id: DefId) -> EvalToConstValueResult<'tcx> { // In some situations def_id will have substitutions within scope, but they aren't allowed @@ -26,23 +23,6 @@ impl<'tcx> TyCtxt<'tcx> { let param_env = self.param_env(def_id).with_reveal_all_normalized(self); self.const_eval_global_id(param_env, cid, None) } - - /// Evaluates a constant without providing any substitutions. This is useful to evaluate consts - /// that can't take any generic arguments like statics, const items or enum discriminants. If a - /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned. - #[instrument(skip(self), level = "debug")] - pub fn const_eval_poly_for_typeck(self, def_id: DefId) -> EvalToValTreeResult<'tcx> { - // In some situations def_id will have substitutions within scope, but they aren't allowed - // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions - // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are - // encountered. - let substs = InternalSubsts::identity_for_item(self, def_id); - let instance = ty::Instance::new(def_id, substs); - let cid = GlobalId { instance, promoted: None }; - let param_env = self.param_env(def_id).with_reveal_all_normalized(self); - self.const_eval_global_id_for_typeck(param_env, cid, None) - } - /// Resolves and evaluates a constant. /// /// The constant can be located on a trait like `<A as B>::C`, in which case the given diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 146ae45e468..e80918d5e5d 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -111,6 +111,10 @@ impl<'tcx> ConstValue<'tcx> { pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self { ConstValue::Scalar(Scalar::from_machine_usize(i, cx)) } + + pub fn zst() -> Self { + Self::Scalar(Scalar::ZST) + } } /// A `Scalar` represents an immediate, primitive value existing outside of a diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 512615ccbab..b3cf8cdde0e 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2405,7 +2405,7 @@ impl<'tcx> Operand<'tcx> { Operand::Constant(Box::new(Constant { span, user_ty: None, - literal: ConstantKind::Ty(ty::Const::zero_sized(tcx, ty)), + literal: ConstantKind::Val(ConstValue::zst(), ty), })) } @@ -2981,16 +2981,6 @@ impl<'tcx> ConstantKind<'tcx> { } } - pub fn try_val(&self, tcx: TyCtxt<'tcx>) -> Option<ConstValue<'tcx>> { - match self { - ConstantKind::Ty(c) => match c.kind() { - ty::ConstKind::Value(v) => Some(tcx.valtree_to_const_val((c.ty(), v))), - _ => None, - }, - ConstantKind::Val(v, _) => Some(*v), - } - } - #[inline] pub fn try_to_value(self, tcx: TyCtxt<'tcx>) -> Option<interpret::ConstValue<'tcx>> { match self { @@ -3548,6 +3538,7 @@ fn comma_sep<'tcx>(fmt: &mut Formatter<'_>, elems: Vec<ConstantKind<'tcx>>) -> f Ok(()) } +// FIXME: Move that into `mir/pretty.rs`. fn pretty_print_const_value<'tcx>( ct: ConstValue<'tcx>, ty: Ty<'tcx>, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3028a57e11c..129d2051c19 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1530,7 +1530,9 @@ pub trait PrettyPrinter<'tcx>: } // fallback - if valtree != ty::ValTree::zst() { + if valtree == ty::ValTree::zst() { + p!(write("<ZST>")); + } else { p!(write("{:?}", valtree)); } if print_ty { diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 0376b53ecc5..8d14a37676d 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -2,9 +2,9 @@ use crate::build; pub(crate) use crate::build::expr::as_constant::lit_to_mir_constant; use crate::build::expr::as_place::PlaceBuilder; use crate::build::scope::DropKind; -use crate::thir::constant::parse_float_into_scalar; use crate::thir::pattern::pat_from_hir; use rustc_data_structures::fx::FxHashMap; +use rustc_apfloat::ieee::{Double, Single}; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -15,6 +15,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::middle::region; use rustc_middle::mir::interpret::ConstValue; +use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::*; use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, PatKind, Thir}; use rustc_middle::ty::subst::Subst; @@ -1093,6 +1094,62 @@ fn parse_float_into_constval<'tcx>( parse_float_into_scalar(num, float_ty, neg).map(ConstValue::Scalar) } +pub(crate) fn parse_float_into_scalar( + num: Symbol, + float_ty: ty::FloatTy, + neg: bool, +) -> Option<Scalar> { + let num = num.as_str(); + match float_ty { + ty::FloatTy::F32 => { + let Ok(rust_f) = num.parse::<f32>() else { return None }; + let mut f = num.parse::<Single>().unwrap_or_else(|e| { + panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e) + }); + + assert!( + u128::from(rust_f.to_bits()) == f.to_bits(), + "apfloat::ieee::Single gave different result for `{}`: \ + {}({:#x}) vs Rust's {}({:#x})", + rust_f, + f, + f.to_bits(), + Single::from_bits(rust_f.to_bits().into()), + rust_f.to_bits() + ); + + if neg { + f = -f; + } + + Some(Scalar::from_f32(f)) + } + ty::FloatTy::F64 => { + let Ok(rust_f) = num.parse::<f64>() else { return None }; + let mut f = num.parse::<Double>().unwrap_or_else(|e| { + panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e) + }); + + assert!( + u128::from(rust_f.to_bits()) == f.to_bits(), + "apfloat::ieee::Double gave different result for `{}`: \ + {}({:#x}) vs Rust's {}({:#x})", + rust_f, + f, + f.to_bits(), + Double::from_bits(rust_f.to_bits().into()), + rust_f.to_bits() + ); + + if neg { + f = -f; + } + + Some(Scalar::from_f64(f)) + } + } +} + /////////////////////////////////////////////////////////////////////////// // Builder methods are broken up into modules, depending on what kind // of thing is being lowered. Note that they use the `unpack` macro diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index cfb09ecedd6..a7e4403a242 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,9 +1,6 @@ -use rustc_apfloat::ieee::{Double, Single}; -use rustc_apfloat::Float; use rustc_ast as ast; -use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput, Scalar}; +use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt}; -use rustc_span::symbol::Symbol; pub(crate) fn lit_to_const<'tcx>( tcx: TyCtxt<'tcx>, @@ -45,9 +42,6 @@ pub(crate) fn lit_to_const<'tcx>( trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })?; ty::ValTree::from_scalar_int(scalar_int) } - (ast::LitKind::Float(n, _), ty::Float(fty)) => { - parse_float_into_valtree(*n, *fty, neg).ok_or(LitToConstError::Reported)? - } (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()), (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), (ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported), @@ -56,67 +50,3 @@ pub(crate) fn lit_to_const<'tcx>( Ok(ty::Const::from_value(tcx, valtree, ty)) } - -pub(crate) fn parse_float_into_scalar( - num: Symbol, - float_ty: ty::FloatTy, - neg: bool, -) -> Option<Scalar> { - let num = num.as_str(); - match float_ty { - ty::FloatTy::F32 => { - let Ok(rust_f) = num.parse::<f32>() else { return None }; - let mut f = num.parse::<Single>().unwrap_or_else(|e| { - panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e) - }); - - assert!( - u128::from(rust_f.to_bits()) == f.to_bits(), - "apfloat::ieee::Single gave different result for `{}`: \ - {}({:#x}) vs Rust's {}({:#x})", - rust_f, - f, - f.to_bits(), - Single::from_bits(rust_f.to_bits().into()), - rust_f.to_bits() - ); - - if neg { - f = -f; - } - - Some(Scalar::from_f32(f)) - } - ty::FloatTy::F64 => { - let Ok(rust_f) = num.parse::<f64>() else { return None }; - let mut f = num.parse::<Double>().unwrap_or_else(|e| { - panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e) - }); - - assert!( - u128::from(rust_f.to_bits()) == f.to_bits(), - "apfloat::ieee::Double gave different result for `{}`: \ - {}({:#x}) vs Rust's {}({:#x})", - rust_f, - f, - f.to_bits(), - Double::from_bits(rust_f.to_bits().into()), - rust_f.to_bits() - ); - - if neg { - f = -f; - } - - Some(Scalar::from_f64(f)) - } - } -} - -fn parse_float_into_valtree<'tcx>( - num: Symbol, - float_ty: ty::FloatTy, - neg: bool, -) -> Option<ty::ValTree<'tcx>> { - parse_float_into_scalar(num, float_ty, neg).map(|s| ty::ValTree::Leaf(s.try_to_int().unwrap())) -} diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index ff070636797..3cd52183330 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -626,9 +626,8 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { let _ = write!(self.out, "{:x}_", bits); } - // HACK(eddyb) because `ty::Const` only supports sized values (for now), - // we can't use dereference the const + supporting `str`, we have to specially - // handle `&str` and include both `&` ("R") and `str` ("e") prefixes. + // FIXME(valtrees): Remove the special case for `str` + // here and fully support unsized constants. ty::Ref(_, inner_ty, mutbl) => { self.push(match mutbl { hir::Mutability::Not => "R", |
