mirror of https://github.com/rust-lang/rust.git
tag_for_variant follow-ups
This commit is contained in:
parent
c3b05c6e5b
commit
928bd3b4e0
|
@ -3,7 +3,7 @@ use either::{Left, Right};
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo};
|
||||
use rustc_middle::mir::{self, ConstAlloc, ConstValue};
|
||||
use rustc_middle::query::{Key, TyCtxtAt};
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::traits::Reveal;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
|
@ -243,24 +243,6 @@ pub(crate) fn turn_into_const_value<'tcx>(
|
|||
op_to_const(&ecx, &mplace.into(), /* for diagnostics */ false)
|
||||
}
|
||||
|
||||
/// Computes the tag (if any) for a given type and variant.
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
pub fn tag_for_variant_provider<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(ty, variant_index): (Ty<'tcx>, abi::VariantIdx),
|
||||
) -> Option<ty::ScalarInt> {
|
||||
assert!(ty.is_enum());
|
||||
|
||||
let ecx = InterpCx::new(
|
||||
tcx,
|
||||
ty.default_span(tcx),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
crate::const_eval::DummyMachine,
|
||||
);
|
||||
|
||||
ecx.tag_for_variant(ty, variant_index).unwrap().map(|(tag, _tag_field)| tag)
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
pub fn eval_to_const_value_raw_provider<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::InterpErrorInfo;
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_middle::query::{Key, TyCtxtAt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
|
||||
use crate::interpret::format_interp_error;
|
||||
use crate::interpret::{format_interp_error, InterpCx};
|
||||
|
||||
mod dummy_machine;
|
||||
mod error;
|
||||
|
@ -77,3 +78,21 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
|
|||
|
||||
Some(mir::DestructuredConstant { variant, fields })
|
||||
}
|
||||
|
||||
/// Computes the tag (if any) for a given type and variant.
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
pub fn tag_for_variant_provider<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(ty, variant_index): (Ty<'tcx>, VariantIdx),
|
||||
) -> Option<ty::ScalarInt> {
|
||||
assert!(ty.is_enum());
|
||||
|
||||
let ecx = InterpCx::new(
|
||||
tcx,
|
||||
ty.default_span(tcx),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
crate::const_eval::DummyMachine,
|
||||
);
|
||||
|
||||
ecx.tag_for_variant(ty, variant_index).unwrap().map(|(tag, _tag_field)| tag)
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
None => {
|
||||
// No need to write the tag here, because an untagged variant is
|
||||
// implicitly encoded. For `Niche`-optimized enums, it's by
|
||||
// implicitly encoded. For `Niche`-optimized enums, this works by
|
||||
// simply by having a value that is outside the niche variants.
|
||||
// But what if the data stored here does not actually encode
|
||||
// this variant? That would be bad! So let's double-check...
|
||||
|
@ -227,8 +227,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
Ok(ImmTy::from_scalar(discr_value, discr_layout))
|
||||
}
|
||||
|
||||
/// Computes the tag value and its field number (if any) of a given variant
|
||||
/// of type `ty`.
|
||||
/// Computes how to write the tag of a given variant of enum `ty`:
|
||||
/// - `None` means that nothing needs to be done as the variant is encoded implicitly
|
||||
/// - `Some((val, field_idx))` means that the given integer value needs to be stored at the
|
||||
/// given field index.
|
||||
pub(crate) fn tag_for_variant(
|
||||
&self,
|
||||
ty: Ty<'tcx>,
|
||||
|
|
Loading…
Reference in New Issue