Skip to content

Commit 383eb01

Browse files
Remove promotion_candidates from Checker
Also removes any code used only to populate `promotion_candidates` during const checking.
1 parent 328a898 commit 383eb01

File tree

1 file changed

+12
-131
lines changed

1 file changed

+12
-131
lines changed

src/librustc_mir/transform/qualify_consts.rs

Lines changed: 12 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
77
use rustc_index::bit_set::BitSet;
88
use rustc_index::vec::IndexVec;
9-
use rustc_data_structures::fx::FxHashSet;
109
use rustc_target::spec::abi::Abi;
1110
use rustc::hir;
1211
use rustc::hir::def_id::DefId;
@@ -20,7 +19,6 @@ use rustc::mir::traversal::ReversePostorder;
2019
use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
2120
use rustc::middle::lang_items;
2221
use rustc::session::config::nightly_options;
23-
use syntax::ast::LitKind;
2422
use syntax::feature_gate::{emit_feature_err, GateIssue};
2523
use syntax::symbol::sym;
2624
use syntax_pos::{Span, DUMMY_SP};
@@ -678,7 +676,6 @@ struct Checker<'a, 'tcx> {
678676
rpo: ReversePostorder<'a, 'tcx>,
679677

680678
temp_promotion_state: IndexVec<Local, TempState>,
681-
promotion_candidates: Vec<Candidate>,
682679
unchecked_promotion_candidates: Vec<Candidate>,
683680

684681
/// If `true`, do not emit errors to the user, merely collect them in `errors`.
@@ -748,7 +745,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
748745
def_id,
749746
rpo,
750747
temp_promotion_state: temps,
751-
promotion_candidates: vec![],
752748
unchecked_promotion_candidates,
753749
errors: vec![],
754750
suppress_errors: false,
@@ -794,7 +790,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
794790
let mut qualifs = self.qualifs_in_value(source);
795791

796792
match source {
797-
ValueSource::Rvalue(&Rvalue::Ref(_, kind, ref place)) => {
793+
ValueSource::Rvalue(&Rvalue::Ref(_, kind, _)) => {
798794
// Getting `true` from `HasMutInterior::in_rvalue` means
799795
// the borrowed place is disallowed from being borrowed,
800796
// due to either a mutable borrow (with some exceptions),
@@ -833,57 +829,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
833829
}
834830
}
835831
}
836-
} else if let BorrowKind::Mut { .. } | BorrowKind::Shared = kind {
837-
// Don't promote BorrowKind::Shallow borrows, as they don't
838-
// reach codegen.
839-
// FIXME(eddyb) the two other kinds of borrow (`Shallow` and `Unique`)
840-
// aren't promoted here but *could* be promoted as part of a larger
841-
// value because `IsNotPromotable` isn't being set for them,
842-
// need to figure out what is the intended behavior.
843-
844-
// We might have a candidate for promotion.
845-
let candidate = Candidate::Ref(location);
846-
// Start by traversing to the "base", with non-deref projections removed.
847-
let deref_proj =
848-
place.projection.iter().rev().find(|&elem| *elem == ProjectionElem::Deref);
849-
850-
debug!(
851-
"qualify_consts: promotion candidate: place={:?} {:?}",
852-
place.base, deref_proj
853-
);
854-
// We can only promote interior borrows of promotable temps (non-temps
855-
// don't get promoted anyway).
856-
// (If we bailed out of the loop due to a `Deref` above, we will definitely
857-
// not enter the conditional here.)
858-
if let (PlaceBase::Local(local), None) = (&place.base, deref_proj) {
859-
if self.body.local_kind(*local) == LocalKind::Temp {
860-
debug!("qualify_consts: promotion candidate: local={:?}", local);
861-
// The borrowed place doesn't have `HasMutInterior`
862-
// (from `in_rvalue`), so we can safely ignore
863-
// `HasMutInterior` from the local's qualifications.
864-
// This allows borrowing fields which don't have
865-
// `HasMutInterior`, from a type that does, e.g.:
866-
// `let _: &'static _ = &(Cell::new(1), 2).1;`
867-
let mut local_qualifs = self.qualifs_in_local(*local);
868-
// Any qualifications, except HasMutInterior (see above), disqualify
869-
// from promotion.
870-
// This is, in particular, the "implicit promotion" version of
871-
// the check making sure that we don't run drop glue during const-eval.
872-
local_qualifs[HasMutInterior] = false;
873-
if !local_qualifs.0.iter().any(|&qualif| qualif) {
874-
debug!("qualify_consts: promotion candidate: {:?}", candidate);
875-
self.promotion_candidates.push(candidate);
876-
}
877-
}
878-
}
879-
}
880-
},
881-
ValueSource::Rvalue(&Rvalue::Repeat(ref operand, _)) => {
882-
debug!("assign: self.cx.mode={:?} self.def_id={:?} location={:?} operand={:?}",
883-
self.cx.mode, self.def_id, location, operand);
884-
if self.should_promote_repeat_expression(operand) &&
885-
self.tcx.features().const_in_array_repeat_expressions {
886-
self.promotion_candidates.push(Candidate::Repeat(location));
887832
}
888833
},
889834
_ => {},
@@ -1047,22 +992,17 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
1047992
// Collect all the temps we need to promote.
1048993
let mut promoted_temps = BitSet::new_empty(self.temp_promotion_state.len());
1049994

1050-
// HACK(eddyb) don't try to validate promotion candidates if any
1051-
// parts of the control-flow graph were skipped due to an error.
1052-
let promotion_candidates = if has_controlflow_error {
1053-
let unleash_miri = self
1054-
.tcx
1055-
.sess
1056-
.opts
1057-
.debugging_opts
1058-
.unleash_the_miri_inside_of_you;
1059-
if !unleash_miri {
1060-
self.tcx.sess.delay_span_bug(
1061-
body.span,
1062-
"check_const: expected control-flow error(s)",
1063-
);
1064-
}
1065-
self.promotion_candidates.clone()
995+
// HACK: if parts of the control-flow graph were skipped due to an error, don't try to
996+
// promote anything, since that can cause errors in a `const` if e.g. rvalue static
997+
// promotion is attempted within a loop body.
998+
let unleash_miri = self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you;
999+
let promotion_candidates = if has_controlflow_error && !unleash_miri {
1000+
self.tcx.sess.delay_span_bug(
1001+
body.span,
1002+
"check_const: expected control-flow error(s)",
1003+
);
1004+
1005+
vec![]
10661006
} else {
10671007
promote_consts::validate_candidates(
10681008
self.tcx,
@@ -1111,15 +1051,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
11111051

11121052
(qualifs.encode_to_bits(), self.tcx.arena.alloc(promoted_temps))
11131053
}
1114-
1115-
/// Returns `true` if the operand of a repeat expression is promotable.
1116-
fn should_promote_repeat_expression(&self, operand: &Operand<'tcx>) -> bool {
1117-
let not_promotable = IsNotImplicitlyPromotable::in_operand(self, operand) ||
1118-
IsNotPromotable::in_operand(self, operand);
1119-
debug!("should_promote_repeat_expression: operand={:?} not_promotable={:?}",
1120-
operand, not_promotable);
1121-
!not_promotable
1122-
}
11231054
}
11241055

11251056
impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
@@ -1431,11 +1362,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
14311362
}
14321363

14331364
let fn_ty = func.ty(self.body, self.tcx);
1434-
let mut callee_def_id = None;
1435-
let mut is_shuffle = false;
14361365
match fn_ty.kind {
14371366
ty::FnDef(def_id, _) => {
1438-
callee_def_id = Some(def_id);
14391367
match self.tcx.fn_sig(def_id).abi() {
14401368
Abi::RustIntrinsic |
14411369
Abi::PlatformIntrinsic => {
@@ -1459,10 +1387,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
14591387
}
14601388
}
14611389

1462-
name if name.starts_with("simd_shuffle") => {
1463-
is_shuffle = true;
1464-
}
1465-
14661390
// no need to check feature gates, intrinsics are only callable
14671391
// from the libstd or with forever unstable feature gates
14681392
_ => {}
@@ -1550,36 +1474,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
15501474
}
15511475
}
15521476

1553-
// No need to do anything in constants and statics, as everything is "constant" anyway
1554-
// so promotion would be useless.
1555-
if self.mode != Mode::Static && self.mode != Mode::Const {
1556-
let constant_args = callee_def_id.and_then(|id| {
1557-
args_required_const(self.tcx, id)
1558-
}).unwrap_or_default();
1559-
for (i, arg) in args.iter().enumerate() {
1560-
if !(is_shuffle && i == 2 || constant_args.contains(&i)) {
1561-
continue;
1562-
}
1563-
1564-
let candidate = Candidate::Argument { bb: location.block, index: i };
1565-
// Since the argument is required to be constant,
1566-
// we care about constness, not promotability.
1567-
// If we checked for promotability, we'd miss out on
1568-
// the results of function calls (which are never promoted
1569-
// in runtime code).
1570-
// This is not a problem, because the argument explicitly
1571-
// requests constness, in contrast to regular promotion
1572-
// which happens even without the user requesting it.
1573-
//
1574-
// `promote_consts` is responsible for emitting the error if
1575-
// the argument is not promotable.
1576-
if !IsNotPromotable::in_operand(self, arg) {
1577-
debug!("visit_terminator_kind: candidate={:?}", candidate);
1578-
self.promotion_candidates.push(candidate);
1579-
}
1580-
}
1581-
}
1582-
15831477
// Check callee and argument operands.
15841478
self.visit_operand(func, location);
15851479
for arg in args {
@@ -1887,19 +1781,6 @@ fn check_static_is_sync(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, hir_id: HirId)
18871781
});
18881782
}
18891783

1890-
fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<FxHashSet<usize>> {
1891-
let attrs = tcx.get_attrs(def_id);
1892-
let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;
1893-
let mut ret = FxHashSet::default();
1894-
for meta in attr.meta_item_list()? {
1895-
match meta.literal()?.kind {
1896-
LitKind::Int(a, _) => { ret.insert(a as usize); }
1897-
_ => return None,
1898-
}
1899-
}
1900-
Some(ret)
1901-
}
1902-
19031784
fn validator_mismatch(
19041785
tcx: TyCtxt<'tcx>,
19051786
body: &Body<'tcx>,

0 commit comments

Comments
 (0)