Skip to content

Commit fe89698

Browse files
authored
Rollup merge of #161378 - nnethercote:FlowSensitiveAnalysis-cleanups, r=jackh726
`FlowSensitiveAnalysis` cleanups Details in individual commits. r? @cjgillot
2 parents bfff871 + 6229d6d commit fe89698

3 files changed

Lines changed: 38 additions & 77 deletions

File tree

‎compiler/rustc_const_eval/src/check_consts/check.rs‎

Lines changed: 32 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -49,91 +49,33 @@ pub(crate) struct Qualifs<'mir, 'tcx> {
4949
}
5050

5151
impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
52-
/// Returns `true` if `local` is `NeedsDrop` at the given `Location`.
53-
///
54-
/// Only updates the cursor if absolutely necessary
55-
pub(crate) fn needs_drop(
56-
&mut self,
57-
ccx: &'mir ConstCx<'mir, 'tcx>,
58-
local: Local,
59-
location: Location,
60-
) -> bool {
61-
let ty = ccx.body.local_decls[local].ty;
62-
// Peeking into opaque types causes cycles if the current function declares said opaque
63-
// type. Thus we avoid short circuiting on the type and instead run the more expensive
64-
// analysis that looks at the actual usage within this function
65-
if !ty.has_opaque_types() && !NeedsDrop::in_any_value_of_ty(ccx, ty) {
66-
return false;
67-
}
68-
69-
let needs_drop = self.needs_drop.get_or_insert_with(|| {
70-
let ConstCx { tcx, body, .. } = *ccx;
71-
72-
FlowSensitiveAnalysis::new(NeedsDrop, ccx)
73-
.iterate_to_fixpoint(tcx, body, None)
74-
.into_results_cursor(body)
75-
});
76-
77-
needs_drop.seek_before_primary_effect(location);
78-
needs_drop.get().contains(local)
79-
}
80-
81-
/// Returns `true` if `local` is `NeedsNonConstDrop` at the given `Location`.
82-
///
83-
/// Only updates the cursor if absolutely necessary
84-
pub(crate) fn needs_non_const_drop(
85-
&mut self,
86-
ccx: &'mir ConstCx<'mir, 'tcx>,
87-
local: Local,
88-
location: Location,
89-
) -> bool {
90-
let ty = ccx.body.local_decls[local].ty;
91-
// Peeking into opaque types causes cycles if the current function declares said opaque
92-
// type. Thus we avoid short circuiting on the type and instead run the more expensive
93-
// analysis that looks at the actual usage within this function
94-
if !ty.has_opaque_types() && !NeedsNonConstDrop::in_any_value_of_ty(ccx, ty) {
95-
return false;
96-
}
97-
98-
let needs_non_const_drop = self.needs_non_const_drop.get_or_insert_with(|| {
99-
let ConstCx { tcx, body, .. } = *ccx;
100-
101-
FlowSensitiveAnalysis::new(NeedsNonConstDrop, ccx)
102-
.iterate_to_fixpoint(tcx, body, None)
103-
.into_results_cursor(body)
104-
});
105-
106-
needs_non_const_drop.seek_before_primary_effect(location);
107-
needs_non_const_drop.get().contains(local)
108-
}
109-
110-
/// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
52+
/// Does `Q` hold for the `local` at the given `Location`?
11153
///
11254
/// Only updates the cursor if absolutely necessary.
113-
fn has_mut_interior(
114-
&mut self,
55+
fn in_local<Q: Qualif>(
56+
qualif_results: &mut Option<QualifResults<'mir, 'tcx, Q>>,
11557
ccx: &'mir ConstCx<'mir, 'tcx>,
11658
local: Local,
11759
location: Location,
11860
) -> bool {
11961
let ty = ccx.body.local_decls[local].ty;
12062
// Peeking into opaque types causes cycles if the current function declares said opaque
12163
// type. Thus we avoid short circuiting on the type and instead run the more expensive
122-
// analysis that looks at the actual usage within this function
123-
if !ty.has_opaque_types() && !HasMutInterior::in_any_value_of_ty(ccx, ty) {
64+
// analysis that looks at the actual usage within this function.
65+
if !ty.has_opaque_types() && !Q::in_any_value_of_ty(ccx, ty) {
12466
return false;
12567
}
12668

127-
let has_mut_interior = self.has_mut_interior.get_or_insert_with(|| {
69+
let qualif_results = qualif_results.get_or_insert_with(|| {
12870
let ConstCx { tcx, body, .. } = *ccx;
12971

130-
FlowSensitiveAnalysis::new(HasMutInterior, ccx)
72+
FlowSensitiveAnalysis::new(ccx)
13173
.iterate_to_fixpoint(tcx, body, None)
13274
.into_results_cursor(body)
13375
});
13476

135-
has_mut_interior.seek_before_primary_effect(location);
136-
has_mut_interior.get().contains(local)
77+
qualif_results.seek_before_primary_effect(location);
78+
qualif_results.get().contains(local)
13779
}
13880

13981
fn in_return_place(
@@ -161,9 +103,19 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
161103
let return_loc = ccx.body.terminator_loc(return_block);
162104

163105
ConstQualifs {
164-
needs_drop: self.needs_drop(ccx, RETURN_PLACE, return_loc),
165-
needs_non_const_drop: self.needs_non_const_drop(ccx, RETURN_PLACE, return_loc),
166-
has_mut_interior: self.has_mut_interior(ccx, RETURN_PLACE, return_loc),
106+
needs_drop: Self::in_local(&mut self.needs_drop, ccx, RETURN_PLACE, return_loc),
107+
needs_non_const_drop: Self::in_local(
108+
&mut self.needs_non_const_drop,
109+
ccx,
110+
RETURN_PLACE,
111+
return_loc,
112+
),
113+
has_mut_interior: Self::in_local(
114+
&mut self.has_mut_interior,
115+
ccx,
116+
RETURN_PLACE,
117+
return_loc,
118+
),
167119
tainted_by_errors,
168120
}
169121
}
@@ -435,7 +387,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
435387
let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty;
436388

437389
let needs_drop = if let Some(local) = dropped_place.as_local() {
438-
self.qualifs.needs_drop(self.ccx, local, location)
390+
Qualifs::in_local(&mut self.qualifs.needs_drop, self.ccx, local, location)
439391
} else {
440392
qualifs::NeedsDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place)
441393
};
@@ -448,7 +400,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
448400
let needs_non_const_drop = if let Some(local) = dropped_place.as_local() {
449401
// Use the span where the local was declared as the span of the drop error.
450402
err_span = self.body.local_decls[local].source_info.span;
451-
self.qualifs.needs_non_const_drop(self.ccx, local, location)
403+
Qualifs::in_local(&mut self.qualifs.needs_non_const_drop, self.ccx, local, location)
452404
} else {
453405
qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place)
454406
};
@@ -602,7 +554,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
602554
| Rvalue::RawPtr(RawPtrKind::Const, place) => {
603555
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
604556
self.ccx,
605-
&mut |local| self.qualifs.has_mut_interior(self.ccx, local, location),
557+
&mut |local| {
558+
Qualifs::in_local(
559+
&mut self.qualifs.has_mut_interior,
560+
self.ccx,
561+
local,
562+
location,
563+
)
564+
},
606565
place.as_ref(),
607566
);
608567

‎compiler/rustc_const_eval/src/check_consts/qualifs.rs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ pub trait Qualif {
4545
const ANALYSIS_NAME: &'static str;
4646

4747
/// Whether this `Qualif` is cleared when a local is moved from.
48-
const IS_CLEARED_ON_MOVE: bool = false;
48+
const IS_CLEARED_ON_MOVE: bool;
4949

5050
/// Whether this `Qualif` might be evaluated after the promotion and can encounter a promoted.
51-
const ALLOW_PROMOTED: bool = false;
51+
const ALLOW_PROMOTED: bool;
5252

5353
/// Extracts the field of `ConstQualifs` that corresponds to this `Qualif`.
5454
fn in_qualifs(qualifs: &ConstQualifs) -> bool;
@@ -79,6 +79,8 @@ pub struct HasMutInterior;
7979

8080
impl Qualif for HasMutInterior {
8181
const ANALYSIS_NAME: &'static str = "flow_has_mut_interior";
82+
const IS_CLEARED_ON_MOVE: bool = false;
83+
const ALLOW_PROMOTED: bool = false;
8284

8385
fn in_qualifs(qualifs: &ConstQualifs) -> bool {
8486
qualifs.has_mut_interior

‎compiler/rustc_const_eval/src/check_consts/resolver.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ impl<'mir, 'tcx, Q> FlowSensitiveAnalysis<'mir, 'tcx, Q>
247247
where
248248
Q: Qualif,
249249
{
250-
pub(super) fn new(_: Q, ccx: &'mir ConstCx<'mir, 'tcx>) -> Self {
250+
pub(super) fn new(ccx: &'mir ConstCx<'mir, 'tcx>) -> Self {
251251
FlowSensitiveAnalysis { ccx, _qualif: PhantomData }
252252
}
253253

@@ -309,7 +309,7 @@ impl<C> DebugWithContext<C> for State {
309309

310310
if self.borrow != old.borrow {
311311
f.write_str("borrow: ")?;
312-
self.qualif.fmt_diff_with(&old.borrow, ctxt, f)?;
312+
self.borrow.fmt_diff_with(&old.borrow, ctxt, f)?;
313313
f.write_str("\n")?;
314314
}
315315

0 commit comments

Comments
 (0)