Skip to content

Commit 96042bc

Browse files
committed
merge NLL "constraint generation" into liveness
1 parent 626289a commit 96042bc

File tree

4 files changed

+82
-81
lines changed

4 files changed

+82
-81
lines changed

compiler/rustc_borrowck/src/constraint_generation.rs

-74
This file was deleted.

compiler/rustc_borrowck/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ use self::path_utils::*;
6464

6565
pub mod borrow_set;
6666
mod borrowck_errors;
67-
mod constraint_generation;
6867
mod constraints;
6968
mod dataflow;
7069
mod def_use;

compiler/rustc_borrowck/src/nll.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use std::str::FromStr;
2222

2323
use crate::{
2424
borrow_set::BorrowSet,
25-
constraint_generation,
2625
consumers::ConsumerOptions,
2726
diagnostics::RegionErrors,
2827
facts::{AllFacts, AllFactsExt, RustcFacts},
@@ -141,15 +140,14 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
141140
let MirTypeckRegionConstraints {
142141
placeholder_indices,
143142
placeholder_index_to_region: _,
144-
mut liveness_constraints,
143+
liveness_constraints,
145144
outlives_constraints,
146145
member_constraints,
147146
universe_causes,
148147
type_tests,
149148
} = constraints;
150149
let placeholder_indices = Rc::new(placeholder_indices);
151150

152-
constraint_generation::generate_constraints(infcx.tcx, &mut liveness_constraints, body);
153151
polonius::emit_cfg_and_loan_kills_facts(
154152
infcx.tcx,
155153
&mut all_facts,

compiler/rustc_borrowck/src/type_check/liveness/mod.rs

+81-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use itertools::{Either, Itertools};
22
use rustc_data_structures::fx::FxHashSet;
3-
use rustc_middle::mir::{Body, Local};
4-
use rustc_middle::ty::{RegionVid, TyCtxt};
3+
use rustc_middle::mir::visit::{TyContext, Visitor};
4+
use rustc_middle::mir::{Body, Local, Location, SourceInfo};
5+
use rustc_middle::ty::visit::TypeVisitable;
6+
use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt};
57
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
68
use rustc_mir_dataflow::move_paths::MoveData;
79
use rustc_mir_dataflow::ResultsCursor;
@@ -11,7 +13,7 @@ use crate::{
1113
constraints::OutlivesConstraintSet,
1214
facts::{AllFacts, AllFactsExt},
1315
location::LocationTable,
14-
region_infer::values::RegionValueElements,
16+
region_infer::values::{LivenessValues, RegionValueElements},
1517
universal_regions::UniversalRegions,
1618
};
1719

@@ -65,6 +67,14 @@ pub(super) fn generate<'mir, 'tcx>(
6567
boring_locals,
6668
polonius_drop_used,
6769
);
70+
71+
// Mark regions that should be live where they appear within rvalues or within a call: like
72+
// args, regions, and types.
73+
record_regular_live_regions(
74+
typeck.tcx(),
75+
&mut typeck.borrowck_context.constraints.liveness_constraints,
76+
body,
77+
);
6878
}
6979

7080
// The purpose of `compute_relevant_live_locals` is to define the subset of `Local`
@@ -132,3 +142,71 @@ fn regions_that_outlive_free_regions<'tcx>(
132142
// Return the final set of things we visited.
133143
outlives_free_region
134144
}
145+
146+
/// Some variables are "regular live" at `location` -- i.e., they may be used later. This means that
147+
/// all regions appearing in their type must be live at `location`.
148+
fn record_regular_live_regions<'tcx>(
149+
tcx: TyCtxt<'tcx>,
150+
liveness_constraints: &mut LivenessValues,
151+
body: &Body<'tcx>,
152+
) {
153+
let mut visitor = LiveVariablesVisitor { tcx, liveness_constraints };
154+
for (bb, data) in body.basic_blocks.iter_enumerated() {
155+
visitor.visit_basic_block_data(bb, data);
156+
}
157+
}
158+
159+
/// Visitor looking for regions that should be live within rvalues or calls.
160+
struct LiveVariablesVisitor<'cx, 'tcx> {
161+
tcx: TyCtxt<'tcx>,
162+
liveness_constraints: &'cx mut LivenessValues,
163+
}
164+
165+
impl<'cx, 'tcx> Visitor<'tcx> for LiveVariablesVisitor<'cx, 'tcx> {
166+
/// We sometimes have `args` within an rvalue, or within a
167+
/// call. Make them live at the location where they appear.
168+
fn visit_args(&mut self, args: &GenericArgsRef<'tcx>, location: Location) {
169+
self.record_regions_live_at(*args, location);
170+
self.super_args(args);
171+
}
172+
173+
/// We sometimes have `region`s within an rvalue, or within a
174+
/// call. Make them live at the location where they appear.
175+
fn visit_region(&mut self, region: Region<'tcx>, location: Location) {
176+
self.record_regions_live_at(region, location);
177+
self.super_region(region);
178+
}
179+
180+
/// We sometimes have `ty`s within an rvalue, or within a
181+
/// call. Make them live at the location where they appear.
182+
fn visit_ty(&mut self, ty: Ty<'tcx>, ty_context: TyContext) {
183+
match ty_context {
184+
TyContext::ReturnTy(SourceInfo { span, .. })
185+
| TyContext::YieldTy(SourceInfo { span, .. })
186+
| TyContext::UserTy(span)
187+
| TyContext::LocalDecl { source_info: SourceInfo { span, .. }, .. } => {
188+
span_bug!(span, "should not be visiting outside of the CFG: {:?}", ty_context);
189+
}
190+
TyContext::Location(location) => {
191+
self.record_regions_live_at(ty, location);
192+
}
193+
}
194+
195+
self.super_ty(ty);
196+
}
197+
}
198+
199+
impl<'cx, 'tcx> LiveVariablesVisitor<'cx, 'tcx> {
200+
/// Some variable is "regular live" at `location` -- i.e., it may be used later. This means that
201+
/// all regions appearing in the type of `value` must be live at `location`.
202+
fn record_regions_live_at<T>(&mut self, value: T, location: Location)
203+
where
204+
T: TypeVisitable<TyCtxt<'tcx>>,
205+
{
206+
debug!("record_regions_live_at(value={:?}, location={:?})", value, location);
207+
self.tcx.for_each_free_region(&value, |live_region| {
208+
let live_region_vid = live_region.as_var();
209+
self.liveness_constraints.add_location(live_region_vid, location);
210+
});
211+
}
212+
}

0 commit comments

Comments
 (0)