Skip to content

Commit

Permalink
rebase and remove dead code
Browse files Browse the repository at this point in the history
  • Loading branch information
b-naber committed Apr 2, 2022
1 parent 9b28d3b commit 14e3d03
Show file tree
Hide file tree
Showing 7 changed files with 4 additions and 234 deletions.
70 changes: 0 additions & 70 deletions compiler/rustc_const_eval/src/const_eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,40 +172,6 @@ pub(crate) fn try_destructure_const<'tcx>(
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>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
Expand Down Expand Up @@ -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 })
}

#[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)
}
8 changes: 0 additions & 8 deletions compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ pub fn provide(providers: &mut Providers) {
let (param_env, value) = param_env_and_value.into_parts();
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| {
let (param_env, raw) = param_env_and_value.into_parts();
const_eval::const_to_valtree(tcx, param_env, raw)
Expand All @@ -57,8 +53,4 @@ pub fn provide(providers: &mut Providers) {
let (param_env, value) = param_env_and_value.into_parts();
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)
}
}
108 changes: 1 addition & 107 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
#[inline]
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)
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
Expand Down Expand Up @@ -2793,112 +2793,6 @@ impl<'tcx> ConstantKind<'tcx> {
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
/// converted to a constant, everything else becomes `Unevaluated`.
pub fn from_anon_const(
Expand Down
9 changes: 1 addition & 8 deletions compiler/rustc_middle/src/mir/query.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! 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 rustc_data_structures::stable_map::FxHashMap;
use rustc_data_structures::vec_map::VecMap;
Expand Down Expand Up @@ -421,13 +421,6 @@ pub struct DestructuredConst<'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
/// compiler option `-Cinstrument-coverage`). This information is generated by the
/// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query.
Expand Down
16 changes: 0 additions & 16 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -940,13 +940,6 @@ rustc_queries! {
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
/// again.
query deref_const(
Expand All @@ -956,15 +949,6 @@ rustc_queries! {
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> {
desc { "get a &core::panic::Location referring to a span" }
}
Expand Down
23 changes: 1 addition & 22 deletions compiler/rustc_mir_build/src/thir/cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@
use crate::thir::pattern::pat_from_hir;
use crate::thir::util::UserAnnotatedTyHelpers;

use rustc_ast::ast;
use rustc_data_structures::steal::Steal;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::HirId;
use rustc_hir::Node;
use rustc_middle::middle::region;
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
use rustc_middle::mir::ConstantKind;
use rustc_middle::thir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::Span;

crate fn thir_body<'tcx>(
Expand Down Expand Up @@ -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> {
let p = match self.tcx.hir().get(p.hir_id) {
Node::Pat(p) | Node::Binding(p) => p,
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
crate fn compare_const_vals<'tcx>(
tcx: TyCtxt<'tcx>,
Expand All @@ -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
// are just integer addresses).
// FIXME This might be wrong
if a == b {
if a.val() == b.val() {
return from_bool(true);
}

Expand Down

0 comments on commit 14e3d03

Please sign in to comment.