Stop returning promotables from mir_const_qualif
This commit is contained in:
parent
9e346646e9
commit
3783ef6dbe
@ -93,7 +93,7 @@ rustc_queries! {
|
|||||||
/// Maps DefId's that have an associated `mir::Body` to the result
|
/// Maps DefId's that have an associated `mir::Body` to the result
|
||||||
/// of the MIR qualify_consts pass. The actual meaning of
|
/// of the MIR qualify_consts pass. The actual meaning of
|
||||||
/// the value isn't known except to the pass itself.
|
/// the value isn't known except to the pass itself.
|
||||||
query mir_const_qualif(key: DefId) -> (u8, &'tcx BitSet<mir::Local>) {
|
query mir_const_qualif(key: DefId) -> u8 {
|
||||||
desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ use crate::util::common::ErrorReported;
|
|||||||
use crate::util::profiling::ProfileCategory::*;
|
use crate::util::profiling::ProfileCategory::*;
|
||||||
|
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
use rustc_index::bit_set::BitSet;
|
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_data_structures::fx::{FxIndexMap, FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxIndexMap, FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::stable_hasher::StableVec;
|
use rustc_data_structures::stable_hasher::StableVec;
|
||||||
|
@ -32,7 +32,6 @@ use syntax::parse::parser::emit_unclosed_delims;
|
|||||||
use syntax::source_map::Spanned;
|
use syntax::source_map::Spanned;
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
use syntax_pos::{Span, FileName};
|
use syntax_pos::{Span, FileName};
|
||||||
use rustc_index::bit_set::BitSet;
|
|
||||||
|
|
||||||
macro_rules! provide {
|
macro_rules! provide {
|
||||||
(<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
|
(<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
|
||||||
@ -122,9 +121,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||||||
}
|
}
|
||||||
optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
|
optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
|
||||||
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
|
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
|
||||||
mir_const_qualif => {
|
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
|
||||||
(cdata.mir_const_qualif(def_id.index), tcx.arena.alloc(BitSet::new_empty(0)))
|
|
||||||
}
|
|
||||||
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
|
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
|
||||||
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
|
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
|
||||||
is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) }
|
is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) }
|
||||||
|
@ -955,7 +955,7 @@ impl EncodeContext<'tcx> {
|
|||||||
record!(self.per_def.kind[def_id] <- match impl_item.kind {
|
record!(self.per_def.kind[def_id] <- match impl_item.kind {
|
||||||
ty::AssocKind::Const => {
|
ty::AssocKind::Const => {
|
||||||
if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
|
if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
|
||||||
let mir = self.tcx.at(ast_item.span).mir_const_qualif(def_id).0;
|
let mir = self.tcx.at(ast_item.span).mir_const_qualif(def_id);
|
||||||
|
|
||||||
EntryKind::AssocConst(container,
|
EntryKind::AssocConst(container,
|
||||||
ConstQualif { mir },
|
ConstQualif { mir },
|
||||||
@ -1089,7 +1089,7 @@ impl EncodeContext<'tcx> {
|
|||||||
hir::ItemKind::Static(_, hir::MutMutable, _) => EntryKind::MutStatic,
|
hir::ItemKind::Static(_, hir::MutMutable, _) => EntryKind::MutStatic,
|
||||||
hir::ItemKind::Static(_, hir::MutImmutable, _) => EntryKind::ImmStatic,
|
hir::ItemKind::Static(_, hir::MutImmutable, _) => EntryKind::ImmStatic,
|
||||||
hir::ItemKind::Const(_, body_id) => {
|
hir::ItemKind::Const(_, body_id) => {
|
||||||
let mir = self.tcx.at(item.span).mir_const_qualif(def_id).0;
|
let mir = self.tcx.at(item.span).mir_const_qualif(def_id);
|
||||||
EntryKind::Const(
|
EntryKind::Const(
|
||||||
ConstQualif { mir },
|
ConstQualif { mir },
|
||||||
self.encode_rendered_const_for_body(body_id)
|
self.encode_rendered_const_for_body(body_id)
|
||||||
@ -1368,7 +1368,7 @@ impl EncodeContext<'tcx> {
|
|||||||
let id = self.tcx.hir().as_local_hir_id(def_id).unwrap();
|
let id = self.tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||||
let body_id = self.tcx.hir().body_owned_by(id);
|
let body_id = self.tcx.hir().body_owned_by(id);
|
||||||
let const_data = self.encode_rendered_const_for_body(body_id);
|
let const_data = self.encode_rendered_const_for_body(body_id);
|
||||||
let mir = self.tcx.mir_const_qualif(def_id).0;
|
let mir = self.tcx.mir_const_qualif(def_id);
|
||||||
|
|
||||||
record!(self.per_def.kind[def_id] <- EntryKind::Const(ConstQualif { mir }, const_data));
|
record!(self.per_def.kind[def_id] <- EntryKind::Const(ConstQualif { mir }, const_data));
|
||||||
record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
|
record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
|
||||||
|
@ -123,7 +123,7 @@ pub trait Qualif {
|
|||||||
if cx.tcx.trait_of_item(def_id).is_some() {
|
if cx.tcx.trait_of_item(def_id).is_some() {
|
||||||
Self::in_any_value_of_ty(cx, constant.literal.ty)
|
Self::in_any_value_of_ty(cx, constant.literal.ty)
|
||||||
} else {
|
} else {
|
||||||
let (bits, _) = cx.tcx.at(constant.span).mir_const_qualif(def_id);
|
let bits = cx.tcx.at(constant.span).mir_const_qualif(def_id);
|
||||||
|
|
||||||
let qualif = QualifSet(bits).contains::<Self>();
|
let qualif = QualifSet(bits).contains::<Self>();
|
||||||
|
|
||||||
|
@ -538,7 +538,7 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||||||
// is gone - we can always promote constants even if they
|
// is gone - we can always promote constants even if they
|
||||||
// fail to pass const-checking, as compilation would've
|
// fail to pass const-checking, as compilation would've
|
||||||
// errored independently and promotion can't change that.
|
// errored independently and promotion can't change that.
|
||||||
let (bits, _) = self.tcx.at(constant.span).mir_const_qualif(def_id);
|
let bits = self.tcx.at(constant.span).mir_const_qualif(def_id);
|
||||||
if bits == super::qualify_consts::QUALIF_ERROR_BIT {
|
if bits == super::qualify_consts::QUALIF_ERROR_BIT {
|
||||||
self.tcx.sess.delay_span_bug(
|
self.tcx.sess.delay_span_bug(
|
||||||
constant.span,
|
constant.span,
|
||||||
|
@ -258,7 +258,7 @@ trait Qualif {
|
|||||||
if cx.tcx.trait_of_item(def_id).is_some() {
|
if cx.tcx.trait_of_item(def_id).is_some() {
|
||||||
Self::in_any_value_of_ty(cx, constant.literal.ty).unwrap_or(false)
|
Self::in_any_value_of_ty(cx, constant.literal.ty).unwrap_or(false)
|
||||||
} else {
|
} else {
|
||||||
let (bits, _) = cx.tcx.at(constant.span).mir_const_qualif(def_id);
|
let bits = cx.tcx.at(constant.span).mir_const_qualif(def_id);
|
||||||
|
|
||||||
let qualif = PerQualif::decode_from_bits(bits).0[Self::IDX];
|
let qualif = PerQualif::decode_from_bits(bits).0[Self::IDX];
|
||||||
|
|
||||||
@ -682,7 +682,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check a whole const, static initializer or const fn.
|
/// Check a whole const, static initializer or const fn.
|
||||||
fn check_const(&mut self) -> (u8, &'tcx BitSet<Local>) {
|
fn check_const(&mut self) -> u8 {
|
||||||
use crate::transform::check_consts as new_checker;
|
use crate::transform::check_consts as new_checker;
|
||||||
|
|
||||||
debug!("const-checking {} {:?}", self.mode, self.def_id);
|
debug!("const-checking {} {:?}", self.mode, self.def_id);
|
||||||
@ -704,7 +704,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||||||
|
|
||||||
let mut seen_blocks = BitSet::new_empty(body.basic_blocks().len());
|
let mut seen_blocks = BitSet::new_empty(body.basic_blocks().len());
|
||||||
let mut bb = START_BLOCK;
|
let mut bb = START_BLOCK;
|
||||||
let mut has_controlflow_error = false;
|
|
||||||
loop {
|
loop {
|
||||||
seen_blocks.insert(bb.index());
|
seen_blocks.insert(bb.index());
|
||||||
|
|
||||||
@ -745,7 +744,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||||||
bb = target;
|
bb = target;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
has_controlflow_error = true;
|
|
||||||
self.not_const(ops::Loop);
|
self.not_const(ops::Loop);
|
||||||
validator.check_op(ops::Loop);
|
validator.check_op(ops::Loop);
|
||||||
break;
|
break;
|
||||||
@ -772,51 +770,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect all the temps we need to promote.
|
self.qualifs_in_local(RETURN_PLACE).encode_to_bits()
|
||||||
let mut promoted_temps = BitSet::new_empty(self.temp_promotion_state.len());
|
|
||||||
|
|
||||||
// HACK: if parts of the control-flow graph were skipped due to an error, don't try to
|
|
||||||
// promote anything, since that can cause errors in a `const` if e.g. rvalue static
|
|
||||||
// promotion is attempted within a loop body.
|
|
||||||
let unleash_miri = self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you;
|
|
||||||
let promotion_candidates = if has_controlflow_error && !unleash_miri {
|
|
||||||
self.tcx.sess.delay_span_bug(
|
|
||||||
body.span,
|
|
||||||
"check_const: expected control-flow error(s)",
|
|
||||||
);
|
|
||||||
|
|
||||||
vec![]
|
|
||||||
} else {
|
|
||||||
promote_consts::validate_candidates(
|
|
||||||
self.tcx,
|
|
||||||
self.body,
|
|
||||||
self.def_id,
|
|
||||||
&self.temp_promotion_state,
|
|
||||||
&self.unchecked_promotion_candidates,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!("qualify_const: promotion_candidates={:?}", promotion_candidates);
|
|
||||||
for candidate in promotion_candidates {
|
|
||||||
match candidate {
|
|
||||||
Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
|
|
||||||
if let StatementKind::Assign(box( _, Rvalue::Ref(_, _, place)))
|
|
||||||
= &self.body[bb].statements[stmt_idx].kind
|
|
||||||
{
|
|
||||||
if let PlaceBase::Local(local) = place.base {
|
|
||||||
promoted_temps.insert(local);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only rvalue-static promotion requires extending the lifetime of the promoted
|
|
||||||
// local.
|
|
||||||
Candidate::Argument { .. } | Candidate::Repeat(_) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let qualifs = self.qualifs_in_local(RETURN_PLACE);
|
|
||||||
(qualifs.encode_to_bits(), self.tcx.arena.alloc(promoted_temps))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1346,7 +1300,7 @@ pub fn provide(providers: &mut Providers<'_>) {
|
|||||||
// in `promote_consts`, see the comment in `validate_operand`.
|
// in `promote_consts`, see the comment in `validate_operand`.
|
||||||
pub(super) const QUALIF_ERROR_BIT: u8 = 1 << 2;
|
pub(super) const QUALIF_ERROR_BIT: u8 = 1 << 2;
|
||||||
|
|
||||||
fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
|
fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> u8 {
|
||||||
// N.B., this `borrow()` is guaranteed to be valid (i.e., the value
|
// N.B., this `borrow()` is guaranteed to be valid (i.e., the value
|
||||||
// cannot yet be stolen), because `mir_validated()`, which steals
|
// cannot yet be stolen), because `mir_validated()`, which steals
|
||||||
// from `mir_const(), forces this query to execute before
|
// from `mir_const(), forces this query to execute before
|
||||||
@ -1355,7 +1309,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
|
|||||||
|
|
||||||
if body.return_ty().references_error() {
|
if body.return_ty().references_error() {
|
||||||
tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors");
|
tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors");
|
||||||
return (QUALIF_ERROR_BIT, tcx.arena.alloc(BitSet::new_empty(0)));
|
return QUALIF_ERROR_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Checker::new(tcx, def_id, body, Mode::Const).check_const()
|
Checker::new(tcx, def_id, body, Mode::Const).check_const()
|
||||||
@ -1436,11 +1390,11 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
check_short_circuiting_in_const_local(tcx, body, mode);
|
check_short_circuiting_in_const_local(tcx, body, mode);
|
||||||
|
|
||||||
let promoted_temps = match mode {
|
match mode {
|
||||||
Mode::Const => tcx.mir_const_qualif(def_id).1,
|
Mode::Const => tcx.mir_const_qualif(def_id),
|
||||||
_ => Checker::new(tcx, def_id, body, mode).check_const().1,
|
_ => Checker::new(tcx, def_id, body, mode).check_const(),
|
||||||
};
|
};
|
||||||
remove_drop_and_storage_dead_on_promoted_locals(body, promoted_temps);
|
remove_drop_and_storage_dead_on_promoted_locals(body, unimplemented!());
|
||||||
}
|
}
|
||||||
|
|
||||||
if mode == Mode::Static && !tcx.has_attr(def_id, sym::thread_local) {
|
if mode == Mode::Static && !tcx.has_attr(def_id, sym::thread_local) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user