Skip to content

Commit eb2535c

Browse files
Use in_*_initially methods to initialize qualifs
1 parent 72e3f72 commit eb2535c

File tree

1 file changed

+66
-11
lines changed

1 file changed

+66
-11
lines changed

src/librustc_mir/transform/qualify_consts.rs

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,27 @@ trait Qualif: QualifIdx {
174174
Self::in_any_value_of_ty(cx, ty).unwrap_or(true)
175175
}
176176

177+
fn in_arg_initially(cx: &ConstCx<'_, 'tcx>, local: Local) -> bool {
178+
Self::in_any_value_of_ty(cx, cx.body.local_decls[local].ty)
179+
.expect("`in_arg_initially` is overridden if `in_any_value_of_ty` is `None`")
180+
}
181+
182+
fn in_temp_initially(
183+
_cx: &ConstCx<'_, 'tcx>,
184+
_local: Local,
185+
_promotion_state: &IndexVec<Local, TempState>,
186+
) -> bool {
187+
false
188+
}
189+
190+
fn in_user_variable_initially(_cx: &ConstCx<'_, 'tcx>, _local: Local) -> bool {
191+
false
192+
}
193+
194+
fn in_return_place_initially(_cx: &ConstCx<'_, 'tcx>, _local: Local) -> bool {
195+
false
196+
}
197+
177198
fn in_local(cx: &ConstCx<'_, '_>, local: Local) -> bool {
178199
cx.per_local.0[Self::IDX].contains(local)
179200
}
@@ -428,6 +449,22 @@ impl Qualif for NeedsDrop {
428449
struct IsNotPromotable;
429450

430451
impl Qualif for IsNotPromotable {
452+
fn in_arg_initially(_cx: &ConstCx<'_, 'tcx>, _local: Local) -> bool {
453+
true
454+
}
455+
456+
fn in_temp_initially(
457+
_cx: &ConstCx<'_, 'tcx>,
458+
local: Local,
459+
promotion_state: &IndexVec<Local, TempState>,
460+
) -> bool {
461+
!promotion_state[local].is_promotable()
462+
}
463+
464+
fn in_user_variable_initially(_cx: &ConstCx<'_, 'tcx>, _local: Local) -> bool {
465+
true
466+
}
467+
431468
fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool {
432469
match static_.kind {
433470
StaticKind::Promoted(_, _) => unreachable!(),
@@ -578,6 +615,12 @@ impl Qualif for IsNotPromotable {
578615
struct IsNotImplicitlyPromotable;
579616

580617
impl Qualif for IsNotImplicitlyPromotable {
618+
/// Function parameters will still never be promoted because this same function returns `true`
619+
/// for `IsNotPromotable`, and both are checked before promoting a `Local`.
620+
fn in_arg_initially(_cx: &ConstCx<'_, 'tcx>, _local: Local) -> bool {
621+
false
622+
}
623+
581624
fn in_call(
582625
cx: &ConstCx<'_, 'tcx>,
583626
callee: &Operand<'tcx>,
@@ -729,18 +772,30 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
729772
per_local: PerQualif::new(BitSet::new_empty(body.local_decls.len())),
730773
};
731774

732-
for (local, decl) in body.local_decls.iter_enumerated() {
733-
if let LocalKind::Arg = body.local_kind(local) {
734-
let qualifs = cx.qualifs_in_any_value_of_ty(decl.ty);
735-
for (per_local, qualif) in &mut cx.per_local.as_mut().zip(qualifs).0 {
736-
if *qualif {
737-
per_local.insert(local);
775+
for (local, _) in body.local_decls.iter_enumerated() {
776+
match cx.body.local_kind(local) {
777+
LocalKind::Arg => for_each_qualif!(|q: Q| {
778+
if Q::in_arg_initially(&cx, local) {
779+
cx.per_local[q].insert(local);
738780
}
739-
}
740-
}
741-
if !temps[local].is_promotable() {
742-
cx.per_local[IsNotPromotable].insert(local);
743-
}
781+
}),
782+
LocalKind::Temp => for_each_qualif!(|q: Q| {
783+
if Q::in_temp_initially(&cx, local, &temps) {
784+
cx.per_local[q].insert(local);
785+
}
786+
}),
787+
LocalKind::Var => for_each_qualif!(|q: Q| {
788+
if Q::in_user_variable_initially(&cx, local) {
789+
cx.per_local[q].insert(local);
790+
}
791+
}),
792+
LocalKind::ReturnPointer => for_each_qualif!(|q: Q| {
793+
if Q::in_return_place_initially(&cx, local) {
794+
cx.per_local[q].insert(local);
795+
}
796+
}),
797+
};
798+
744799
if let LocalKind::Var = body.local_kind(local) {
745800
// Sanity check to prevent implicit and explicit promotion of
746801
// named locals

0 commit comments

Comments
 (0)