rebase and remove dead code
This commit is contained in:
parent
9b28d3b494
commit
14e3d038c0
7 changed files with 4 additions and 234 deletions
|
@ -172,40 +172,6 @@ pub(crate) fn try_destructure_const<'tcx>(
|
||||||
Ok(mir::DestructuredConst { variant, fields })
|
Ok(mir::DestructuredConst { variant, fields })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn destructure_mir_constant<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
val: mir::ConstantKind<'tcx>,
|
|
||||||
) -> mir::DestructuredMirConstant<'tcx> {
|
|
||||||
trace!("destructure_const: {:?}", val);
|
|
||||||
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
|
|
||||||
let op = ecx.mir_const_to_op(&val, None).unwrap();
|
|
||||||
|
|
||||||
// We go to `usize` as we cannot allocate anything bigger anyway.
|
|
||||||
let (field_count, variant, down) = match val.ty().kind() {
|
|
||||||
ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op),
|
|
||||||
ty::Adt(def, _) if def.variants().is_empty() => {
|
|
||||||
return mir::DestructuredMirConstant { variant: None, fields: &[] };
|
|
||||||
}
|
|
||||||
ty::Adt(def, _) => {
|
|
||||||
let variant = ecx.read_discriminant(&op).unwrap().1;
|
|
||||||
let down = ecx.operand_downcast(&op, variant).unwrap();
|
|
||||||
(def.variants()[variant].fields.len(), Some(variant), down)
|
|
||||||
}
|
|
||||||
ty::Tuple(substs) => (substs.len(), None, op),
|
|
||||||
_ => bug!("cannot destructure constant {:?}", val),
|
|
||||||
};
|
|
||||||
|
|
||||||
let fields_iter = (0..field_count).map(|i| {
|
|
||||||
let field_op = ecx.operand_field(&down, i).unwrap();
|
|
||||||
let val = op_to_const(&ecx, &field_op);
|
|
||||||
mir::ConstantKind::Val(val, field_op.layout.ty)
|
|
||||||
});
|
|
||||||
let fields = tcx.arena.alloc_from_iter(fields_iter);
|
|
||||||
|
|
||||||
mir::DestructuredMirConstant { variant, fields }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn deref_const<'tcx>(
|
pub(crate) fn deref_const<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
@ -241,39 +207,3 @@ pub(crate) fn deref_const<'tcx>(
|
||||||
|
|
||||||
tcx.mk_const(ty::ConstS { val: ty::ConstKind::Value(op_to_const(&ecx, &mplace.into())), ty })
|
tcx.mk_const(ty::ConstS { val: ty::ConstKind::Value(op_to_const(&ecx, &mplace.into())), ty })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(tcx), level = "debug")]
|
|
||||||
pub(crate) fn deref_mir_constant<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
val: mir::ConstantKind<'tcx>,
|
|
||||||
) -> mir::ConstantKind<'tcx> {
|
|
||||||
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
|
|
||||||
let op = ecx.mir_const_to_op(&val, None).unwrap();
|
|
||||||
let mplace = ecx.deref_operand(&op).unwrap();
|
|
||||||
if let Some(alloc_id) = mplace.ptr.provenance {
|
|
||||||
assert_eq!(
|
|
||||||
tcx.get_global_alloc(alloc_id).unwrap().unwrap_memory().0.0.mutability,
|
|
||||||
Mutability::Not,
|
|
||||||
"deref_const cannot be used with mutable allocations as \
|
|
||||||
that could allow pattern matching to observe mutable statics",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let ty = match mplace.meta {
|
|
||||||
MemPlaceMeta::None => mplace.layout.ty,
|
|
||||||
MemPlaceMeta::Poison => bug!("poison metadata in `deref_const`: {:#?}", mplace),
|
|
||||||
// In case of unsized types, figure out the real type behind.
|
|
||||||
MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() {
|
|
||||||
ty::Str => bug!("there's no sized equivalent of a `str`"),
|
|
||||||
ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_machine_usize(&tcx).unwrap()),
|
|
||||||
_ => bug!(
|
|
||||||
"type {} should not have metadata, but had {:?}",
|
|
||||||
mplace.layout.ty,
|
|
||||||
mplace.meta
|
|
||||||
),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
mir::ConstantKind::Val(op_to_const(&ecx, &mplace.into()), ty)
|
|
||||||
}
|
|
||||||
|
|
|
@ -45,10 +45,6 @@ pub fn provide(providers: &mut Providers) {
|
||||||
let (param_env, value) = param_env_and_value.into_parts();
|
let (param_env, value) = param_env_and_value.into_parts();
|
||||||
const_eval::try_destructure_const(tcx, param_env, value).ok()
|
const_eval::try_destructure_const(tcx, param_env, value).ok()
|
||||||
};
|
};
|
||||||
providers.destructure_mir_constant = |tcx, param_env_and_value| {
|
|
||||||
let (param_env, value) = param_env_and_value.into_parts();
|
|
||||||
const_eval::destructure_mir_constant(tcx, param_env, value)
|
|
||||||
};
|
|
||||||
providers.const_to_valtree = |tcx, param_env_and_value| {
|
providers.const_to_valtree = |tcx, param_env_and_value| {
|
||||||
let (param_env, raw) = param_env_and_value.into_parts();
|
let (param_env, raw) = param_env_and_value.into_parts();
|
||||||
const_eval::const_to_valtree(tcx, param_env, raw)
|
const_eval::const_to_valtree(tcx, param_env, raw)
|
||||||
|
@ -57,8 +53,4 @@ pub fn provide(providers: &mut Providers) {
|
||||||
let (param_env, value) = param_env_and_value.into_parts();
|
let (param_env, value) = param_env_and_value.into_parts();
|
||||||
const_eval::deref_const(tcx, param_env, value)
|
const_eval::deref_const(tcx, param_env, value)
|
||||||
};
|
};
|
||||||
providers.deref_mir_constant = |tcx, param_env_and_value| {
|
|
||||||
let (param_env, value) = param_env_and_value.into_parts();
|
|
||||||
const_eval::deref_mir_constant(tcx, param_env, value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2721,8 +2721,8 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
|
/// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
|
||||||
|
#[inline]
|
||||||
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
|
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
|
||||||
self.try_eval_bits(tcx, param_env, ty)
|
self.try_eval_bits(tcx, param_env, ty)
|
||||||
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
|
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
|
||||||
|
@ -2793,112 +2793,6 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||||
Self::from_bits(tcx, n as u128, ty::ParamEnv::empty().and(ty))
|
Self::from_bits(tcx, n as u128, ty::ParamEnv::empty().and(ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(tcx), level = "debug")]
|
|
||||||
pub fn try_eval_lit_or_param(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
ty: Ty<'tcx>,
|
|
||||||
expr: &'tcx hir::Expr<'tcx>,
|
|
||||||
) -> Option<Self> {
|
|
||||||
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
|
|
||||||
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
|
|
||||||
let expr = match &expr.kind {
|
|
||||||
hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
|
|
||||||
block.expr.as_ref().unwrap()
|
|
||||||
}
|
|
||||||
_ => expr,
|
|
||||||
};
|
|
||||||
|
|
||||||
let lit_input = match expr.kind {
|
|
||||||
hir::ExprKind::Lit(ref lit) => {
|
|
||||||
Some(interpret::LitToConstInput { lit: &lit.node, ty, neg: false })
|
|
||||||
}
|
|
||||||
hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
|
|
||||||
hir::ExprKind::Lit(ref lit) => {
|
|
||||||
Some(interpret::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 Some(c),
|
|
||||||
Err(e) => {
|
|
||||||
tcx.sess.delay_span_bug(
|
|
||||||
expr.span,
|
|
||||||
&format!("Const::from_anon_const: couldn't lit_to_const {:?}", e),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
|
|
||||||
match expr.kind {
|
|
||||||
ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {
|
|
||||||
// Find the name and index of the const parameter by indexing the generics of
|
|
||||||
// the parent item and construct a `ParamConst`.
|
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
|
||||||
let item_id = tcx.hir().get_parent_node(hir_id);
|
|
||||||
let item_def_id = tcx.hir().local_def_id(item_id);
|
|
||||||
let generics = tcx.generics_of(item_def_id.to_def_id());
|
|
||||||
let index = generics.param_def_id_to_index[&def_id];
|
|
||||||
let name = tcx.hir().name(hir_id);
|
|
||||||
let ty_const = tcx.mk_const(ty::ConstS {
|
|
||||||
val: ty::ConstKind::Param(ty::ParamConst::new(index, name)),
|
|
||||||
ty,
|
|
||||||
});
|
|
||||||
|
|
||||||
Some(Self::Ty(ty_const))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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 ret = match Self::try_eval_lit_or_param(tcx, ty, expr) {
|
|
||||||
Some(v) => v,
|
|
||||||
None => {
|
|
||||||
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 ty_const = tcx.mk_const(ty::ConstS {
|
|
||||||
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
|
||||||
def: ty::WithOptConstParam::unknown(def_id).to_global(),
|
|
||||||
substs,
|
|
||||||
promoted: None,
|
|
||||||
}),
|
|
||||||
ty,
|
|
||||||
});
|
|
||||||
|
|
||||||
Self::Ty(ty_const)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
debug_assert!(!ret.has_free_regions());
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly
|
/// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly
|
||||||
/// converted to a constant, everything else becomes `Unevaluated`.
|
/// converted to a constant, everything else becomes `Unevaluated`.
|
||||||
pub fn from_anon_const(
|
pub fn from_anon_const(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Values computed by queries that use MIR.
|
//! Values computed by queries that use MIR.
|
||||||
|
|
||||||
use crate::mir::{self, Body, Promoted};
|
use crate::mir::{Body, Promoted};
|
||||||
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
|
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
|
||||||
use rustc_data_structures::stable_map::FxHashMap;
|
use rustc_data_structures::stable_map::FxHashMap;
|
||||||
use rustc_data_structures::vec_map::VecMap;
|
use rustc_data_structures::vec_map::VecMap;
|
||||||
|
@ -421,13 +421,6 @@ pub struct DestructuredConst<'tcx> {
|
||||||
pub fields: &'tcx [ty::Const<'tcx>],
|
pub fields: &'tcx [ty::Const<'tcx>],
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The constituent parts of an 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
|
/// Coverage information summarized from a MIR if instrumented for source code coverage (see
|
||||||
/// compiler option `-Cinstrument-coverage`). This information is generated by the
|
/// compiler option `-Cinstrument-coverage`). This information is generated by the
|
||||||
/// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query.
|
/// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query.
|
||||||
|
|
|
@ -940,13 +940,6 @@ rustc_queries! {
|
||||||
remap_env_constness
|
remap_env_constness
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructure an `mir::ConstantKind` ADT or array into its variant index
|
|
||||||
/// and its field values.
|
|
||||||
query destructure_mir_constant(key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>) -> mir::DestructuredMirConstant<'tcx> {
|
|
||||||
desc { "destructure mir constant"}
|
|
||||||
remap_env_constness
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dereference a constant reference or raw pointer and turn the result into a constant
|
/// Dereference a constant reference or raw pointer and turn the result into a constant
|
||||||
/// again.
|
/// again.
|
||||||
query deref_const(
|
query deref_const(
|
||||||
|
@ -956,15 +949,6 @@ rustc_queries! {
|
||||||
remap_env_constness
|
remap_env_constness
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dereference a constant reference or raw pointer and turn the result into a constant
|
|
||||||
/// again.
|
|
||||||
query deref_mir_constant(
|
|
||||||
key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
|
|
||||||
) -> mir::ConstantKind<'tcx> {
|
|
||||||
desc { "deref constant" }
|
|
||||||
remap_env_constness
|
|
||||||
}
|
|
||||||
|
|
||||||
query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
|
query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
|
||||||
desc { "get a &core::panic::Location referring to a span" }
|
desc { "get a &core::panic::Location referring to a span" }
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
use crate::thir::pattern::pat_from_hir;
|
use crate::thir::pattern::pat_from_hir;
|
||||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
use crate::thir::util::UserAnnotatedTyHelpers;
|
||||||
|
|
||||||
use rustc_ast::ast;
|
|
||||||
use rustc_data_structures::steal::Steal;
|
use rustc_data_structures::steal::Steal;
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -13,10 +12,8 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::HirId;
|
use rustc_hir::HirId;
|
||||||
use rustc_hir::Node;
|
use rustc_hir::Node;
|
||||||
use rustc_middle::middle::region;
|
use rustc_middle::middle::region;
|
||||||
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
|
|
||||||
use rustc_middle::mir::ConstantKind;
|
|
||||||
use rustc_middle::thir::*;
|
use rustc_middle::thir::*;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
crate fn thir_body<'tcx>(
|
crate fn thir_body<'tcx>(
|
||||||
|
@ -78,24 +75,6 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
|
||||||
crate fn const_eval_literal(
|
|
||||||
&mut self,
|
|
||||||
lit: &'tcx ast::LitKind,
|
|
||||||
ty: Ty<'tcx>,
|
|
||||||
sp: Span,
|
|
||||||
neg: bool,
|
|
||||||
) -> ConstantKind<'tcx> {
|
|
||||||
match self.tcx.at(sp).lit_to_mir_constant(LitToConstInput { lit, ty, neg }) {
|
|
||||||
Ok(c) => c,
|
|
||||||
Err(LitToConstError::Reported) => {
|
|
||||||
// create a dummy value and continue compiling
|
|
||||||
ConstantKind::Ty(self.tcx.const_error(ty))
|
|
||||||
}
|
|
||||||
Err(LitToConstError::TypeError) => bug!("const_eval_literal: had type error"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> {
|
crate fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> {
|
||||||
let p = match self.tcx.hir().get(p.hir_id) {
|
let p = match self.tcx.hir().get(p.hir_id) {
|
||||||
Node::Pat(p) | Node::Binding(p) => p,
|
Node::Pat(p) | Node::Binding(p) => p,
|
||||||
|
|
|
@ -739,7 +739,6 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Get rid of this function once valtrees land
|
|
||||||
#[instrument(skip(tcx), level = "debug")]
|
#[instrument(skip(tcx), level = "debug")]
|
||||||
crate fn compare_const_vals<'tcx>(
|
crate fn compare_const_vals<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
@ -759,8 +758,7 @@ crate fn compare_const_vals<'tcx>(
|
||||||
|
|
||||||
// Early return for equal constants (so e.g. references to ZSTs can be compared, even if they
|
// Early return for equal constants (so e.g. references to ZSTs can be compared, even if they
|
||||||
// are just integer addresses).
|
// are just integer addresses).
|
||||||
// FIXME This might be wrong
|
if a.val() == b.val() {
|
||||||
if a == b {
|
|
||||||
return from_bool(true);
|
return from_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue