diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 595ef2aad49d9..367e0e710c834 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -6,12 +6,10 @@ use syntax_pos::DUMMY_SP; use super::{ConstKind, Item as ConstCx}; -#[derive(Clone, Copy)] -pub struct QualifSet(u8); - -impl QualifSet { - fn contains(self) -> bool { - self.0 & (1 << Q::IDX) != 0 +pub fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> QualifSet { + QualifSet { + has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty), + needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty), } } @@ -22,14 +20,14 @@ impl QualifSet { /// /// The default implementations proceed structurally. pub trait Qualif { - const IDX: usize; - /// The name of the file used to debug the dataflow analysis that computes this qualif. const ANALYSIS_NAME: &'static str; /// Whether this `Qualif` is cleared when a local is moved from. const IS_CLEARED_ON_MOVE: bool = false; + fn in_qualif_set(set: &QualifSet) -> bool; + /// Return the qualification that is (conservatively) correct for any value /// of the type. fn in_any_value_of_ty(_cx: &ConstCx<'_, 'tcx>, _ty: Ty<'tcx>) -> bool; @@ -122,9 +120,8 @@ pub trait Qualif { if cx.tcx.trait_of_item(def_id).is_some() { Self::in_any_value_of_ty(cx, constant.literal.ty) } else { - let bits = cx.tcx.at(constant.span).mir_const_qualif(def_id); - - let qualif = QualifSet(bits).contains::(); + let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def_id); + let qualif = Self::in_qualif_set(&qualifs); // Just in case the type is more specific than // the definition, e.g., impl associated const @@ -210,9 +207,12 @@ pub trait Qualif { pub struct HasMutInterior; impl Qualif for HasMutInterior { - const IDX: usize = 0; const ANALYSIS_NAME: &'static str = "flow_has_mut_interior"; + fn in_qualif_set(set: &QualifSet) -> bool { + set.has_mut_interior + } + fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool { !ty.is_freeze(cx.tcx, cx.param_env, DUMMY_SP) } @@ -275,10 +275,13 @@ impl Qualif for HasMutInterior { pub struct NeedsDrop; impl Qualif for NeedsDrop { - const IDX: usize = 1; const ANALYSIS_NAME: &'static str = "flow_needs_drop"; const IS_CLEARED_ON_MOVE: bool = true; + fn in_qualif_set(set: &QualifSet) -> bool { + set.needs_drop + } + fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool { ty.needs_drop(cx.tcx, cx.param_env) } diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 022f2bcd88144..2f2c65b8469a3 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -19,9 +19,9 @@ use std::ops::Deref; use crate::dataflow::{self as old_dataflow, generic as dataflow}; use self::old_dataflow::IndirectlyMutableLocals; use super::ops::{self, NonConstOp}; -use super::qualifs::{HasMutInterior, NeedsDrop}; +use super::qualifs::{self, HasMutInterior, NeedsDrop}; use super::resolver::FlowSensitiveAnalysis; -use super::{ConstKind, Item, Qualif, QualifSet, is_lang_panic_fn}; +use super::{ConstKind, Item, Qualif, is_lang_panic_fn}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum CheckOpResult { @@ -130,18 +130,16 @@ impl Qualifs<'a, 'mir, 'tcx> { .map(|(bb, _)| bb); let return_block = match return_block { - None => return QualifSet::in_any_value_of_ty(item, item.body.return_ty()), + None => return qualifs::in_any_value_of_ty(item, item.body.return_ty()), Some(bb) => bb, }; let return_loc = item.body.terminator_loc(return_block); - let mut qualifs = QualifSet::default(); - - qualifs.set::(self.needs_drop_lazy_seek(RETURN_PLACE, return_loc)); - qualifs.set::(self.has_mut_interior_lazy_seek(RETURN_PLACE, return_loc)); - - qualifs + QualifSet { + needs_drop: self.needs_drop_lazy_seek(RETURN_PLACE, return_loc), + has_mut_interior: self.has_mut_interior_lazy_seek(RETURN_PLACE, return_loc), + } } }