use GlobalId in eval_to_valtree query and introduce query for valtree_to_const_val
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use super::{AllocId, ConstAlloc, Pointer, Scalar};
|
||||
|
||||
use crate::mir::interpret::ConstValue;
|
||||
use crate::ty::{layout, query::TyCtxtAt, tls, FnSig, Ty};
|
||||
use crate::ty::{layout, query::TyCtxtAt, tls, FnSig, Ty, ValTree};
|
||||
|
||||
use rustc_data_structures::sync::Lock;
|
||||
use rustc_errors::{pluralize, struct_span_err, DiagnosticBuilder, ErrorGuaranteed};
|
||||
@@ -35,6 +35,7 @@ TrivialTypeFoldableAndLiftImpls! {
|
||||
|
||||
pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
|
||||
pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
|
||||
pub type EvalToValTreeResult<'tcx> = Result<Option<ValTree<'tcx>>, ErrorHandled>;
|
||||
|
||||
pub fn struct_error<'tcx>(
|
||||
tcx: TyCtxtAt<'tcx>,
|
||||
|
||||
@@ -119,9 +119,9 @@ use crate::ty::{self, Instance, Ty, TyCtxt};
|
||||
|
||||
pub use self::error::{
|
||||
struct_error, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult,
|
||||
InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, MachineStopType,
|
||||
ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo, UninitBytesAccess,
|
||||
UnsupportedOpInfo,
|
||||
EvalToValTreeResult, InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo,
|
||||
MachineStopType, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo,
|
||||
UninitBytesAccess, UnsupportedOpInfo,
|
||||
};
|
||||
|
||||
pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar, ScalarMaybeUninit};
|
||||
|
||||
@@ -110,11 +110,22 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
|
||||
}
|
||||
|
||||
/// Destructure a constant ADT or array into its variant index and its field values.
|
||||
/// Destructure a type-level constant ADT or array into its variant index and its field values.
|
||||
/// Panics if the destructuring fails, use `try_destructure_const` for fallible version.
|
||||
pub fn destructure_const(
|
||||
self,
|
||||
param_env_and_val: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>,
|
||||
) -> mir::DestructuredConst<'tcx> {
|
||||
self.try_destructure_const(param_env_and_val).unwrap()
|
||||
}
|
||||
|
||||
/// Destructure a mir constant ADT or array into its variant index and its field values.
|
||||
/// Panics if the destructuring fails, use `try_destructure_const` for fallible version.
|
||||
pub fn destructure_mir_constant(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
constant: mir::ConstantKind<'tcx>,
|
||||
) -> mir::DestructuredMirConstant<'tcx> {
|
||||
self.try_destructure_mir_constant(param_env.and(constant)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
|
||||
|
||||
use crate::mir::coverage::{CodeRegion, CoverageKind};
|
||||
use crate::mir::interpret::{ConstAllocation, ConstValue, GlobalAlloc, Scalar};
|
||||
use crate::mir::interpret::{ConstAllocation, ConstValue, GlobalAlloc, LitToConstInput, Scalar};
|
||||
use crate::mir::visit::MirVisitable;
|
||||
use crate::ty::adjustment::PointerCast;
|
||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||
@@ -3078,6 +3078,58 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id), param_env)
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
let body_id = match tcx.hir().get(hir_id) {
|
||||
hir::Node::AnonConst(ac) => ac.body,
|
||||
_ => span_bug!(
|
||||
tcx.def_span(def_id.to_def_id()),
|
||||
"from_inline_const can only process anonymous constants"
|
||||
),
|
||||
};
|
||||
let expr = &tcx.hir().body(body_id).value;
|
||||
let ty = tcx.typeck(def_id).node_type(hir_id);
|
||||
|
||||
let lit_input = match expr.kind {
|
||||
hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
|
||||
hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
|
||||
hir::ExprKind::Lit(ref lit) => {
|
||||
Some(LitToConstInput { lit: &lit.node, ty, neg: true })
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
if let Some(lit_input) = lit_input {
|
||||
// If an error occurred, ignore that it's a literal and leave reporting the error up to
|
||||
// mir.
|
||||
match tcx.at(expr.span).lit_to_mir_constant(lit_input) {
|
||||
Ok(c) => return c,
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
|
||||
let parent_substs =
|
||||
tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
|
||||
let substs =
|
||||
ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
|
||||
.substs;
|
||||
let uneval_const = tcx.mk_const(ty::ConstS {
|
||||
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
||||
def: ty::WithOptConstParam::unknown(def_id).to_global(),
|
||||
substs,
|
||||
promoted: None,
|
||||
}),
|
||||
ty,
|
||||
});
|
||||
debug!(?uneval_const);
|
||||
debug_assert!(!uneval_const.has_free_regions());
|
||||
|
||||
Self::Ty(uneval_const)
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
fn from_opt_const_arg_anon_const(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Values computed by queries that use MIR.
|
||||
|
||||
use crate::mir::{Body, Promoted};
|
||||
use crate::mir::{self, Body, Promoted};
|
||||
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
|
||||
use rustc_data_structures::stable_map::FxHashMap;
|
||||
use rustc_data_structures::vec_map::VecMap;
|
||||
@@ -413,13 +413,20 @@ pub enum ClosureOutlivesSubject<'tcx> {
|
||||
Region(ty::RegionVid),
|
||||
}
|
||||
|
||||
/// The constituent parts of an ADT or array.
|
||||
/// The constituent parts of a type level constant of kind ADT or array.
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub struct DestructuredConst<'tcx> {
|
||||
pub variant: Option<VariantIdx>,
|
||||
pub fields: &'tcx [ty::Const<'tcx>],
|
||||
}
|
||||
|
||||
/// The constituent parts of a mir constant of kind ADT or array.
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub struct DestructuredMirConstant<'tcx> {
|
||||
pub variant: Option<VariantIdx>,
|
||||
pub fields: &'tcx [mir::ConstantKind<'tcx>],
|
||||
}
|
||||
|
||||
/// Coverage information summarized from a MIR if instrumented for source code coverage (see
|
||||
/// compiler option `-Cinstrument-coverage`). This information is generated by the
|
||||
/// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query.
|
||||
|
||||
Reference in New Issue
Block a user