Skip to content

Commit 2fbd7be

Browse files
authored
Rollup merge of rust-lang#59796 - oli-obk:const_arg_ice, r=eddyb
Retire `IsNotConst` naming This naming scheme caused a lot of confusion lately (including ICEs) due to misrefactored code. Also clean up the initialization code for said flag. r? @eddyb previous discussions: rust-lang#58784 (comment) rust-lang#58403 (comment)
2 parents 8ac023f + f10394a commit 2fbd7be

File tree

2 files changed

+51
-45
lines changed

2 files changed

+51
-45
lines changed

src/librustc_mir/transform/promote_consts.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ pub enum TempState {
4444
impl TempState {
4545
pub fn is_promotable(&self) -> bool {
4646
debug!("is_promotable: self={:?}", self);
47-
if let TempState::Defined { uses, .. } = *self {
48-
uses > 0
47+
if let TempState::Defined { .. } = *self {
48+
true
4949
} else {
5050
false
5151
}
@@ -80,9 +80,14 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
8080
context: PlaceContext<'tcx>,
8181
location: Location) {
8282
debug!("visit_local: index={:?} context={:?} location={:?}", index, context, location);
83-
// We're only interested in temporaries
84-
if self.mir.local_kind(index) != LocalKind::Temp {
85-
return;
83+
// We're only interested in temporaries and the return place
84+
match self.mir.local_kind(index) {
85+
| LocalKind::Temp
86+
| LocalKind::ReturnPointer
87+
=> {},
88+
| LocalKind::Arg
89+
| LocalKind::Var
90+
=> return,
8691
}
8792

8893
// Ignore drops, if the temp gets promoted,
@@ -101,7 +106,6 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
101106
if *temp == TempState::Undefined {
102107
match context {
103108
PlaceContext::MutatingUse(MutatingUseContext::Store) |
104-
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) |
105109
PlaceContext::MutatingUse(MutatingUseContext::Call) => {
106110
*temp = TempState::Defined {
107111
location,

src/librustc_mir/transform/qualify_consts.rs

+41-39
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,11 @@ impl Qualif for NeedsDrop {
365365
}
366366
}
367367

368-
// Not constant at all - non-`const fn` calls, asm!,
368+
// Not promotable at all - non-`const fn` calls, asm!,
369369
// pointer comparisons, ptr-to-int casts, etc.
370-
struct IsNotConst;
370+
struct IsNotPromotable;
371371

372-
impl Qualif for IsNotConst {
372+
impl Qualif for IsNotPromotable {
373373
const IDX: usize = 2;
374374

375375
fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool {
@@ -508,13 +508,17 @@ impl Qualif for IsNotConst {
508508
}
509509
}
510510

511-
// Refers to temporaries which cannot be promoted as
512-
// promote_consts decided they weren't simple enough.
513-
// FIXME(oli-obk,eddyb): Remove this flag entirely and
514-
// solely process this information via `IsNotConst`.
515-
struct IsNotPromotable;
516-
517-
impl Qualif for IsNotPromotable {
511+
/// Refers to temporaries which cannot be promoted *implicitly*.
512+
/// Explicit promotion happens e.g. for constant arguments declared via `rustc_args_required_const`.
513+
/// Inside a const context all constness rules
514+
/// apply, so implicit promotion simply has to follow the regular constant rules (modulo interior
515+
/// mutability or `Drop` rules which are handled `HasMutInterior` and `NeedsDrop` respectively).
516+
/// Implicit promotion inside regular functions does not happen if `const fn` calls are involved,
517+
/// as the call may be perfectly alright at runtime, but fail at compile time e.g. due to addresses
518+
/// being compared inside the function.
519+
struct IsNotImplicitlyPromotable;
520+
521+
impl Qualif for IsNotImplicitlyPromotable {
518522
const IDX: usize = 3;
519523

520524
fn in_call(
@@ -550,33 +554,36 @@ macro_rules! static_assert_seq_qualifs {
550554
static_assert!(SEQ_QUALIFS: QUALIF_COUNT == $i);
551555
};
552556
}
553-
static_assert_seq_qualifs!(0 => HasMutInterior, NeedsDrop, IsNotConst, IsNotPromotable);
557+
static_assert_seq_qualifs!(
558+
0 => HasMutInterior, NeedsDrop, IsNotPromotable, IsNotImplicitlyPromotable
559+
);
554560

555561
impl ConstCx<'_, 'tcx> {
556562
fn qualifs_in_any_value_of_ty(&self, ty: Ty<'tcx>) -> PerQualif<bool> {
557563
let mut qualifs = PerQualif::default();
558564
qualifs[HasMutInterior] = HasMutInterior::in_any_value_of_ty(self, ty).unwrap_or(false);
559565
qualifs[NeedsDrop] = NeedsDrop::in_any_value_of_ty(self, ty).unwrap_or(false);
560-
qualifs[IsNotConst] = IsNotConst::in_any_value_of_ty(self, ty).unwrap_or(false);
561566
qualifs[IsNotPromotable] = IsNotPromotable::in_any_value_of_ty(self, ty).unwrap_or(false);
567+
qualifs[IsNotImplicitlyPromotable] =
568+
IsNotImplicitlyPromotable::in_any_value_of_ty(self, ty).unwrap_or(false);
562569
qualifs
563570
}
564571

565572
fn qualifs_in_local(&self, local: Local) -> PerQualif<bool> {
566573
let mut qualifs = PerQualif::default();
567574
qualifs[HasMutInterior] = HasMutInterior::in_local(self, local);
568575
qualifs[NeedsDrop] = NeedsDrop::in_local(self, local);
569-
qualifs[IsNotConst] = IsNotConst::in_local(self, local);
570576
qualifs[IsNotPromotable] = IsNotPromotable::in_local(self, local);
577+
qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_local(self, local);
571578
qualifs
572579
}
573580

574581
fn qualifs_in_value(&self, source: ValueSource<'_, 'tcx>) -> PerQualif<bool> {
575582
let mut qualifs = PerQualif::default();
576583
qualifs[HasMutInterior] = HasMutInterior::in_value(self, source);
577584
qualifs[NeedsDrop] = NeedsDrop::in_value(self, source);
578-
qualifs[IsNotConst] = IsNotConst::in_value(self, source);
579585
qualifs[IsNotPromotable] = IsNotPromotable::in_value(self, source);
586+
qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_value(self, source);
580587
qualifs
581588
}
582589
}
@@ -631,26 +638,21 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
631638
};
632639

633640
for (local, decl) in mir.local_decls.iter_enumerated() {
634-
match mir.local_kind(local) {
635-
LocalKind::Arg => {
636-
let qualifs = cx.qualifs_in_any_value_of_ty(decl.ty);
637-
for (per_local, qualif) in &mut cx.per_local.as_mut().zip(qualifs).0 {
638-
if *qualif {
639-
per_local.insert(local);
640-
}
641+
if let LocalKind::Arg = mir.local_kind(local) {
642+
let qualifs = cx.qualifs_in_any_value_of_ty(decl.ty);
643+
for (per_local, qualif) in &mut cx.per_local.as_mut().zip(qualifs).0 {
644+
if *qualif {
645+
per_local.insert(local);
641646
}
642-
cx.per_local[IsNotConst].insert(local);
643647
}
644-
645-
LocalKind::Var if mode == Mode::Fn => {
646-
cx.per_local[IsNotConst].insert(local);
647-
}
648-
649-
LocalKind::Temp if !temps[local].is_promotable() => {
650-
cx.per_local[IsNotConst].insert(local);
651-
}
652-
653-
_ => {}
648+
}
649+
if !temps[local].is_promotable() {
650+
cx.per_local[IsNotPromotable].insert(local);
651+
}
652+
if let LocalKind::Var = mir.local_kind(local) {
653+
// Sanity check to prevent implicit and explicit promotion of
654+
// named locals
655+
assert!(cx.per_local[IsNotPromotable].contains(local));
654656
}
655657
}
656658

@@ -698,11 +700,11 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
698700
// the borrowed place is disallowed from being borrowed,
699701
// due to either a mutable borrow (with some exceptions),
700702
// or an shared borrow of a value with interior mutability.
701-
// Then `HasMutInterior` is replaced with `IsNotConst`,
703+
// Then `HasMutInterior` is replaced with `IsNotPromotable`,
702704
// to avoid duplicate errors (e.g. from reborrowing).
703705
if qualifs[HasMutInterior] {
704706
qualifs[HasMutInterior] = false;
705-
qualifs[IsNotConst] = true;
707+
qualifs[IsNotPromotable] = true;
706708

707709
if self.mode != Mode::Fn {
708710
if let BorrowKind::Mut { .. } = kind {
@@ -817,15 +819,15 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
817819
}
818820
}
819821

820-
// Ensure the `IsNotConst` qualification is preserved.
822+
// Ensure the `IsNotPromotable` qualification is preserved.
821823
// NOTE(eddyb) this is actually unnecessary right now, as
822824
// we never replace the local's qualif, but we might in
823825
// the future, and so it serves to catch changes that unset
824826
// important bits (in which case, asserting `contains` could
825827
// be replaced with calling `insert` to re-set the bit).
826828
if kind == LocalKind::Temp {
827829
if !self.temp_promotion_state[index].is_promotable() {
828-
assert!(self.cx.per_local[IsNotConst].contains(index));
830+
assert!(self.cx.per_local[IsNotPromotable].contains(index));
829831
}
830832
}
831833
}
@@ -911,7 +913,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
911913

912914
// Account for errors in consts by using the
913915
// conservative type qualification instead.
914-
if qualifs[IsNotConst] {
916+
if qualifs[IsNotPromotable] {
915917
qualifs = self.qualifs_in_any_value_of_ty(mir.return_ty());
916918
}
917919

@@ -1326,7 +1328,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
13261328
// which happens even without the user requesting it.
13271329
// We can error out with a hard error if the argument is not
13281330
// constant here.
1329-
if !IsNotConst::in_operand(self, arg) {
1331+
if !IsNotPromotable::in_operand(self, arg) {
13301332
debug!("visit_terminator_kind: candidate={:?}", candidate);
13311333
self.promotion_candidates.push(candidate);
13321334
} else {
@@ -1444,7 +1446,7 @@ fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
14441446

14451447
if mir.return_ty().references_error() {
14461448
tcx.sess.delay_span_bug(mir.span, "mir_const_qualif: Mir had errors");
1447-
return (1 << IsNotConst::IDX, Lrc::new(BitSet::new_empty(0)));
1449+
return (1 << IsNotPromotable::IDX, Lrc::new(BitSet::new_empty(0)));
14481450
}
14491451

14501452
Checker::new(tcx, def_id, mir, Mode::Const).check_const()

0 commit comments

Comments
 (0)