Skip to content

Commit 970470a

Browse files
committed
Merge branch 'master' of github.com:rust-lang/rust
2 parents f9441ad + 3ff17e7 commit 970470a

19 files changed

+660
-47
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -2577,9 +2577,9 @@ checksum = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
25772577

25782578
[[package]]
25792579
name = "polonius-engine"
2580-
version = "0.10.0"
2580+
version = "0.11.0"
25812581
source = "registry+https://github.com/rust-lang/crates.io-index"
2582-
checksum = "50fa9dbfd0d3d60594da338cfe6f94028433eecae4b11b7e83fd99759227bbfe"
2582+
checksum = "1e478d7c38eb785c6416cbe58df12aa55d7aefa3759b6d3e044b2ed03f423cec"
25832583
dependencies = [
25842584
"datafrog",
25852585
"log",

src/librustc/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ scoped-tls = "1.0"
2020
log = { version = "0.4", features = ["release_max_level_info", "std"] }
2121
rustc-rayon = "0.3.0"
2222
rustc-rayon-core = "0.3.0"
23-
polonius-engine = "0.10.0"
23+
polonius-engine = "0.11.0"
2424
rustc_apfloat = { path = "../librustc_apfloat" }
2525
rustc_feature = { path = "../librustc_feature" }
2626
rustc_target = { path = "../librustc_target" }

src/librustc_data_structures/transitive_relation.rs

+8
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,14 @@ impl<T: Clone + Debug + Eq + Hash> TransitiveRelation<T> {
373373
}
374374
matrix
375375
}
376+
377+
/// Lists all the base edges in the graph: the initial _non-transitive_ set of element
378+
/// relations, which will be later used as the basis for the transitive closure computation.
379+
pub fn base_edges(&self) -> impl Iterator<Item=(&T, &T)> {
380+
self.edges
381+
.iter()
382+
.map(move |edge| (&self.elements[edge.source.0], &self.elements[edge.target.0]))
383+
}
376384
}
377385

378386
/// Pare down is used as a step in the LUB computation. It edits the

src/librustc_mir/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ dot = { path = "../libgraphviz", package = "graphviz" }
1616
itertools = "0.8"
1717
log = "0.4"
1818
log_settings = "0.1.1"
19-
polonius-engine = "0.10.0"
19+
polonius-engine = "0.11.0"
2020
rustc = { path = "../librustc" }
2121
rustc_target = { path = "../librustc_target" }
2222
rustc_data_structures = { path = "../librustc_data_structures" }

src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -240,15 +240,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
240240
let tcx = self.infcx.tcx;
241241
let generics = tcx.generics_of(self.mir_def_id);
242242
let param = generics.type_param(&param_ty, tcx);
243-
let generics = tcx.hir().get_generics(self.mir_def_id).unwrap();
244-
suggest_constraining_type_param(
245-
generics,
246-
&mut err,
247-
&param.name.as_str(),
248-
"Copy",
249-
tcx.sess.source_map(),
250-
span,
251-
);
243+
if let Some(generics) = tcx.hir().get_generics(self.mir_def_id) {
244+
suggest_constraining_type_param(
245+
generics,
246+
&mut err,
247+
&param.name.as_str(),
248+
"Copy",
249+
tcx.sess.source_map(),
250+
span,
251+
);
252+
}
252253
}
253254
let span = if let Some(local) = place.as_local() {
254255
let decl = &self.body.local_decls[local];

src/librustc_mir/borrow_check/flows.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
//! FIXME: this might be better as a "generic" fixed-point combinator,
44
//! but is not as ugly as it is right now.
55
6-
use rustc::mir::{BasicBlock, Local, Location};
7-
use rustc::ty::RegionVid;
6+
use rustc::mir::{BasicBlock, Location};
87
use rustc_index::bit_set::BitIter;
98

109
use crate::borrow_check::location::LocationIndex;
1110

12-
use polonius_engine::Output;
11+
use crate::borrow_check::nll::PoloniusOutput;
1312

1413
use crate::dataflow::indexes::BorrowIndex;
15-
use crate::dataflow::move_paths::{HasMoveData, MovePathIndex};
14+
use crate::dataflow::move_paths::HasMoveData;
1615
use crate::dataflow::Borrows;
1716
use crate::dataflow::EverInitializedPlaces;
1817
use crate::dataflow::MaybeUninitializedPlaces;
@@ -21,8 +20,6 @@ use either::Either;
2120
use std::fmt;
2221
use std::rc::Rc;
2322

24-
crate type PoloniusOutput = Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
25-
2623
crate struct Flows<'b, 'tcx> {
2724
borrows: FlowAtLocation<'tcx, Borrows<'b, 'tcx>>,
2825
pub uninits: FlowAtLocation<'tcx, MaybeUninitializedPlaces<'b, 'tcx>>,

src/librustc_mir/borrow_check/nll/facts.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::borrow_check::location::{LocationIndex, LocationTable};
22
use crate::dataflow::indexes::{BorrowIndex, MovePathIndex};
3-
use polonius_engine::AllFacts as PoloniusAllFacts;
3+
use polonius_engine::AllFacts as PoloniusFacts;
44
use polonius_engine::Atom;
55
use rustc::mir::Local;
66
use rustc::ty::{RegionVid, TyCtxt};
@@ -11,7 +11,18 @@ use std::fs::{self, File};
1111
use std::io::Write;
1212
use std::path::Path;
1313

14-
crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
14+
#[derive(Copy, Clone, Debug)]
15+
crate struct RustcFacts;
16+
17+
impl polonius_engine::FactTypes for RustcFacts {
18+
type Origin = RegionVid;
19+
type Loan = BorrowIndex;
20+
type Point = LocationIndex;
21+
type Variable = Local;
22+
type Path = MovePathIndex;
23+
}
24+
25+
crate type AllFacts = PoloniusFacts<RustcFacts>;
1526

1627
crate trait AllFactsExt {
1728
/// Returns `true` if there is a need to gather `AllFacts` given the
@@ -55,6 +66,7 @@ impl AllFactsExt for AllFacts {
5566
wr.write_facts_to_path(self.[
5667
borrow_region,
5768
universal_region,
69+
placeholder,
5870
cfg_edge,
5971
killed,
6072
outlives,
@@ -69,6 +81,7 @@ impl AllFactsExt for AllFacts {
6981
initialized_at,
7082
moved_out_at,
7183
path_accessed_at,
84+
known_subset,
7285
])
7386
}
7487
Ok(())

src/librustc_mir/borrow_check/nll/mod.rs

+49-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use crate::borrow_check::borrow_set::BorrowSet;
2-
use crate::borrow_check::location::{LocationIndex, LocationTable};
2+
use crate::borrow_check::location::LocationTable;
33
use crate::borrow_check::nll::facts::AllFactsExt;
44
use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
55
use crate::borrow_check::nll::region_infer::values::RegionValueElements;
6-
use crate::dataflow::indexes::BorrowIndex;
7-
use crate::dataflow::move_paths::{InitLocation, MoveData, MovePathIndex, InitKind};
6+
use crate::dataflow::move_paths::{InitLocation, MoveData, InitKind};
87
use crate::dataflow::FlowAtLocation;
98
use crate::dataflow::MaybeInitializedPlaces;
109
use crate::transform::MirSource;
@@ -43,10 +42,12 @@ crate mod universal_regions;
4342
crate mod type_check;
4443
crate mod region_infer;
4544

46-
use self::facts::AllFacts;
45+
use self::facts::{AllFacts, RustcFacts};
4746
use self::region_infer::RegionInferenceContext;
4847
use self::universal_regions::UniversalRegions;
4948

49+
crate type PoloniusOutput = Output<RustcFacts>;
50+
5051
/// Rewrites the regions in the MIR to use NLL variables, also
5152
/// scraping out the set of universal regions (e.g., region parameters)
5253
/// declared on the function. That set will need to be given to
@@ -170,7 +171,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
170171
errors_buffer: &mut Vec<Diagnostic>,
171172
) -> (
172173
RegionInferenceContext<'tcx>,
173-
Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>>>,
174+
Option<Rc<PoloniusOutput>>,
174175
Option<ClosureRegionRequirements<'tcx>>,
175176
) {
176177
let mut all_facts = AllFacts::enabled(infcx.tcx).then_some(AllFacts::default());
@@ -204,6 +205,39 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
204205
.universal_region
205206
.extend(universal_regions.universal_regions());
206207
populate_polonius_move_facts(all_facts, move_data, location_table, &body);
208+
209+
// Emit universal regions facts, and their relations, for Polonius.
210+
//
211+
// 1: universal regions are modeled in Polonius as a pair:
212+
// - the universal region vid itself.
213+
// - a "placeholder loan" associated to this universal region. Since they don't exist in
214+
// the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index
215+
// added to the existing number of loans, as if they succeeded them in the set.
216+
//
217+
let borrow_count = borrow_set.borrows.len();
218+
debug!(
219+
"compute_regions: polonius placeholders, num_universals={}, borrow_count={}",
220+
universal_regions.len(),
221+
borrow_count
222+
);
223+
224+
for universal_region in universal_regions.universal_regions() {
225+
let universal_region_idx = universal_region.index();
226+
let placeholder_loan_idx = borrow_count + universal_region_idx;
227+
all_facts.placeholder.push((universal_region, placeholder_loan_idx.into()));
228+
}
229+
230+
// 2: the universal region relations `outlives` constraints are emitted as
231+
// `known_subset` facts.
232+
for (fr1, fr2) in universal_region_relations.known_outlives() {
233+
if fr1 != fr2 {
234+
debug!(
235+
"compute_regions: emitting polonius `known_subset` fr1={:?}, fr2={:?}",
236+
fr1, fr2
237+
);
238+
all_facts.known_subset.push((*fr1, *fr2));
239+
}
240+
}
207241
}
208242

209243
// Create the region inference context, taking ownership of the
@@ -265,7 +299,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
265299

266300
if infcx.tcx.sess.opts.debugging_opts.polonius {
267301
let algorithm = env::var("POLONIUS_ALGORITHM")
268-
.unwrap_or_else(|_| String::from("Hybrid"));
302+
.unwrap_or_else(|_| String::from("Naive"));
269303
let algorithm = Algorithm::from_str(&algorithm).unwrap();
270304
debug!("compute_regions: using polonius algorithm {:?}", algorithm);
271305
Some(Rc::new(Output::compute(
@@ -279,8 +313,15 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
279313
});
280314

281315
// Solve the region constraints.
282-
let closure_region_requirements =
283-
regioncx.solve(infcx, &body, local_names, upvars, def_id, errors_buffer);
316+
let closure_region_requirements = regioncx.solve(
317+
infcx,
318+
&body,
319+
local_names,
320+
upvars,
321+
def_id,
322+
errors_buffer,
323+
polonius_output.clone(),
324+
);
284325

285326
// Dump MIR results into a file, if that is enabled. This let us
286327
// write unit-tests, as well as helping with debugging.

0 commit comments

Comments
 (0)