Skip to content

Commit f9216b7

Browse files
committed
Auto merge of rust-lang#108325 - matthiaskrgr:rollup-73qihie, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#104239 (Better debug logs for borrowck constraint graph) - rust-lang#108202 (Make sure `test_type_match` doesn't ICE with late-bound types) - rust-lang#108295 (Use DefKind to give more item kind information during BindingObligation note ) - rust-lang#108306 (compiletest: up deps) - rust-lang#108313 (Fix compiletest possible crash in option only-modified) - rust-lang#108322 (Clean ConstProp) - rust-lang#108323 (hir-analysis: make one diagnostic translatable) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 375d5ac + d39fc21 commit f9216b7

File tree

95 files changed

+818
-440
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+818
-440
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -891,11 +891,11 @@ dependencies = [
891891
"diff",
892892
"getopts",
893893
"glob",
894-
"lazy_static",
895894
"lazycell",
896895
"libc",
897-
"miow 0.3.7",
896+
"miow 0.5.0",
898897
"miropt-test-tools",
898+
"once_cell",
899899
"regex",
900900
"rustfix",
901901
"serde",

compiler/rustc_borrowck/src/constraints/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub(crate) mod graph;
1717
/// constraints of the form `R1: R2`. Each constraint is identified by
1818
/// a unique `OutlivesConstraintIndex` and you can index into the set
1919
/// (`constraint_set[i]`) to access the constraint details.
20-
#[derive(Clone, Default)]
20+
#[derive(Clone, Debug, Default)]
2121
pub(crate) struct OutlivesConstraintSet<'tcx> {
2222
outlives: IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>>,
2323
}

compiler/rustc_borrowck/src/lib.rs

+89-9
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ use rustc_hir as hir;
2525
use rustc_hir::def_id::LocalDefId;
2626
use rustc_index::bit_set::ChunkedBitSet;
2727
use rustc_index::vec::IndexVec;
28-
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
28+
use rustc_infer::infer::{
29+
DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt,
30+
};
2931
use rustc_middle::mir::{
3032
traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand,
3133
Place, PlaceElem, PlaceRef, VarDebugInfoContents,
@@ -43,6 +45,7 @@ use smallvec::SmallVec;
4345
use std::cell::OnceCell;
4446
use std::cell::RefCell;
4547
use std::collections::BTreeMap;
48+
use std::ops::Deref;
4649
use std::rc::Rc;
4750

4851
use rustc_mir_dataflow::impls::{
@@ -94,6 +97,7 @@ use nll::{PoloniusOutput, ToRegionVid};
9497
use place_ext::PlaceExt;
9598
use places_conflict::{places_conflict, PlaceConflictBias};
9699
use region_infer::RegionInferenceContext;
100+
use renumber::RegionCtxt;
97101

98102
// FIXME(eddyb) perhaps move this somewhere more centrally.
99103
#[derive(Debug)]
@@ -167,10 +171,10 @@ fn do_mir_borrowck<'tcx>(
167171
return_body_with_facts: bool,
168172
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
169173
let def = input_body.source.with_opt_param().as_local().unwrap();
170-
171174
debug!(?def);
172175

173176
let tcx = infcx.tcx;
177+
let infcx = BorrowckInferCtxt::new(infcx);
174178
let param_env = tcx.param_env(def.did);
175179

176180
let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
@@ -218,7 +222,7 @@ fn do_mir_borrowck<'tcx>(
218222
let mut body_owned = input_body.clone();
219223
let mut promoted = input_promoted.clone();
220224
let free_regions =
221-
nll::replace_regions_in_mir(infcx, param_env, &mut body_owned, &mut promoted);
225+
nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted);
222226
let body = &body_owned; // no further changes
223227

224228
let location_table_owned = LocationTable::new(body);
@@ -256,7 +260,7 @@ fn do_mir_borrowck<'tcx>(
256260
opt_closure_req,
257261
nll_errors,
258262
} = nll::compute_regions(
259-
infcx,
263+
&infcx,
260264
free_regions,
261265
body,
262266
&promoted,
@@ -271,12 +275,12 @@ fn do_mir_borrowck<'tcx>(
271275

272276
// Dump MIR results into a file, if that is enabled. This let us
273277
// write unit-tests, as well as helping with debugging.
274-
nll::dump_mir_results(infcx, &body, &regioncx, &opt_closure_req);
278+
nll::dump_mir_results(&infcx, &body, &regioncx, &opt_closure_req);
275279

276280
// We also have a `#[rustc_regions]` annotation that causes us to dump
277281
// information.
278282
nll::dump_annotation(
279-
infcx,
283+
&infcx,
280284
&body,
281285
&regioncx,
282286
&opt_closure_req,
@@ -320,7 +324,7 @@ fn do_mir_borrowck<'tcx>(
320324

321325
if let Err((move_data, move_errors)) = move_data_results {
322326
let mut promoted_mbcx = MirBorrowckCtxt {
323-
infcx,
327+
infcx: &infcx,
324328
param_env,
325329
body: promoted_body,
326330
move_data: &move_data,
@@ -349,7 +353,7 @@ fn do_mir_borrowck<'tcx>(
349353
}
350354

351355
let mut mbcx = MirBorrowckCtxt {
352-
infcx,
356+
infcx: &infcx,
353357
param_env,
354358
body,
355359
move_data: &mdpe.move_data,
@@ -481,8 +485,84 @@ pub struct BodyWithBorrowckFacts<'tcx> {
481485
pub location_table: LocationTable,
482486
}
483487

488+
pub struct BorrowckInferCtxt<'cx, 'tcx> {
489+
pub(crate) infcx: &'cx InferCtxt<'tcx>,
490+
pub(crate) reg_var_to_origin: RefCell<FxHashMap<ty::RegionVid, RegionCtxt>>,
491+
}
492+
493+
impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
494+
pub(crate) fn new(infcx: &'cx InferCtxt<'tcx>) -> Self {
495+
BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()) }
496+
}
497+
498+
pub(crate) fn next_region_var<F>(
499+
&self,
500+
origin: RegionVariableOrigin,
501+
get_ctxt_fn: F,
502+
) -> ty::Region<'tcx>
503+
where
504+
F: Fn() -> RegionCtxt,
505+
{
506+
let next_region = self.infcx.next_region_var(origin);
507+
let vid = next_region
508+
.as_var()
509+
.unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
510+
511+
if cfg!(debug_assertions) {
512+
debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
513+
let ctxt = get_ctxt_fn();
514+
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
515+
let prev = var_to_origin.insert(vid, ctxt);
516+
517+
// This only makes sense if not called in a canonicalization context. If this
518+
// ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
519+
// or modify how we track nll region vars for that map.
520+
assert!(matches!(prev, None));
521+
}
522+
523+
next_region
524+
}
525+
526+
#[instrument(skip(self, get_ctxt_fn), level = "debug")]
527+
pub(crate) fn next_nll_region_var<F>(
528+
&self,
529+
origin: NllRegionVariableOrigin,
530+
get_ctxt_fn: F,
531+
) -> ty::Region<'tcx>
532+
where
533+
F: Fn() -> RegionCtxt,
534+
{
535+
let next_region = self.infcx.next_nll_region_var(origin.clone());
536+
let vid = next_region
537+
.as_var()
538+
.unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
539+
540+
if cfg!(debug_assertions) {
541+
debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
542+
let ctxt = get_ctxt_fn();
543+
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
544+
let prev = var_to_origin.insert(vid, ctxt);
545+
546+
// This only makes sense if not called in a canonicalization context. If this
547+
// ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
548+
// or modify how we track nll region vars for that map.
549+
assert!(matches!(prev, None));
550+
}
551+
552+
next_region
553+
}
554+
}
555+
556+
impl<'cx, 'tcx> Deref for BorrowckInferCtxt<'cx, 'tcx> {
557+
type Target = InferCtxt<'tcx>;
558+
559+
fn deref(&self) -> &'cx Self::Target {
560+
self.infcx
561+
}
562+
}
563+
484564
struct MirBorrowckCtxt<'cx, 'tcx> {
485-
infcx: &'cx InferCtxt<'tcx>,
565+
infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>,
486566
param_env: ParamEnv<'tcx>,
487567
body: &'cx Body<'tcx>,
488568
move_data: &'cx MoveData<'tcx>,

compiler/rustc_borrowck/src/nll.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use rustc_data_structures::vec_map::VecMap;
66
use rustc_hir::def_id::LocalDefId;
77
use rustc_index::vec::IndexVec;
8-
use rustc_infer::infer::InferCtxt;
98
use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere};
109
use rustc_middle::mir::{
1110
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
@@ -37,7 +36,7 @@ use crate::{
3736
renumber,
3837
type_check::{self, MirTypeckRegionConstraints, MirTypeckResults},
3938
universal_regions::UniversalRegions,
40-
Upvar,
39+
BorrowckInferCtxt, Upvar,
4140
};
4241

4342
pub type PoloniusOutput = Output<RustcFacts>;
@@ -58,7 +57,7 @@ pub(crate) struct NllOutput<'tcx> {
5857
/// `compute_regions`.
5958
#[instrument(skip(infcx, param_env, body, promoted), level = "debug")]
6059
pub(crate) fn replace_regions_in_mir<'tcx>(
61-
infcx: &InferCtxt<'tcx>,
60+
infcx: &BorrowckInferCtxt<'_, 'tcx>,
6261
param_env: ty::ParamEnv<'tcx>,
6362
body: &mut Body<'tcx>,
6463
promoted: &mut IndexVec<Promoted, Body<'tcx>>,
@@ -157,7 +156,7 @@ fn populate_polonius_move_facts(
157156
///
158157
/// This may result in errors being reported.
159158
pub(crate) fn compute_regions<'cx, 'tcx>(
160-
infcx: &InferCtxt<'tcx>,
159+
infcx: &BorrowckInferCtxt<'_, 'tcx>,
161160
universal_regions: UniversalRegions<'tcx>,
162161
body: &Body<'tcx>,
163162
promoted: &IndexVec<Promoted, Body<'tcx>>,
@@ -259,6 +258,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
259258
);
260259

261260
let mut regioncx = RegionInferenceContext::new(
261+
infcx,
262262
var_origins,
263263
universal_regions,
264264
placeholder_indices,
@@ -322,7 +322,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
322322
}
323323

324324
pub(super) fn dump_mir_results<'tcx>(
325-
infcx: &InferCtxt<'tcx>,
325+
infcx: &BorrowckInferCtxt<'_, 'tcx>,
326326
body: &Body<'tcx>,
327327
regioncx: &RegionInferenceContext<'tcx>,
328328
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
@@ -372,7 +372,7 @@ pub(super) fn dump_mir_results<'tcx>(
372372
#[allow(rustc::diagnostic_outside_of_impl)]
373373
#[allow(rustc::untranslatable_diagnostic)]
374374
pub(super) fn dump_annotation<'tcx>(
375-
infcx: &InferCtxt<'tcx>,
375+
infcx: &BorrowckInferCtxt<'_, 'tcx>,
376376
body: &Body<'tcx>,
377377
regioncx: &RegionInferenceContext<'tcx>,
378378
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,

compiler/rustc_borrowck/src/region_infer/mod.rs

+76-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use crate::{
3434
},
3535
type_check::{free_region_relations::UniversalRegionRelations, Locations},
3636
universal_regions::UniversalRegions,
37+
BorrowckInferCtxt,
3738
};
3839

3940
mod dump_mir;
@@ -243,6 +244,70 @@ pub enum ExtraConstraintInfo {
243244
PlaceholderFromPredicate(Span),
244245
}
245246

247+
#[instrument(skip(infcx, sccs), level = "debug")]
248+
fn sccs_info<'cx, 'tcx>(
249+
infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>,
250+
sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
251+
) {
252+
use crate::renumber::RegionCtxt;
253+
254+
let var_to_origin = infcx.reg_var_to_origin.borrow();
255+
256+
let mut var_to_origin_sorted = var_to_origin.clone().into_iter().collect::<Vec<_>>();
257+
var_to_origin_sorted.sort_by(|a, b| a.0.cmp(&b.0));
258+
let mut debug_str = "region variables to origins:\n".to_string();
259+
for (reg_var, origin) in var_to_origin_sorted.into_iter() {
260+
debug_str.push_str(&format!("{:?}: {:?}\n", reg_var, origin));
261+
}
262+
debug!(debug_str);
263+
264+
let num_components = sccs.scc_data().ranges().len();
265+
let mut components = vec![FxHashSet::default(); num_components];
266+
267+
for (reg_var_idx, scc_idx) in sccs.scc_indices().iter().enumerate() {
268+
let reg_var = ty::RegionVid::from_usize(reg_var_idx);
269+
let origin = var_to_origin.get(&reg_var).unwrap_or_else(|| &RegionCtxt::Unknown);
270+
components[scc_idx.as_usize()].insert((reg_var, *origin));
271+
}
272+
273+
let mut components_str = "strongly connected components:".to_string();
274+
for (scc_idx, reg_vars_origins) in components.iter().enumerate() {
275+
let regions_info = reg_vars_origins.clone().into_iter().collect::<Vec<_>>();
276+
components_str.push_str(&format!(
277+
"{:?}: {:?})",
278+
ConstraintSccIndex::from_usize(scc_idx),
279+
regions_info,
280+
))
281+
}
282+
debug!(components_str);
283+
284+
// calculate the best representative for each component
285+
let components_representatives = components
286+
.into_iter()
287+
.enumerate()
288+
.map(|(scc_idx, region_ctxts)| {
289+
let repr = region_ctxts
290+
.into_iter()
291+
.map(|reg_var_origin| reg_var_origin.1)
292+
.max_by(|x, y| x.preference_value().cmp(&y.preference_value()))
293+
.unwrap();
294+
295+
(ConstraintSccIndex::from_usize(scc_idx), repr)
296+
})
297+
.collect::<FxHashMap<_, _>>();
298+
299+
let mut scc_node_to_edges = FxHashMap::default();
300+
for (scc_idx, repr) in components_representatives.iter() {
301+
let edges_range = sccs.scc_data().ranges()[*scc_idx].clone();
302+
let edges = &sccs.scc_data().all_successors()[edges_range];
303+
let edge_representatives =
304+
edges.iter().map(|scc_idx| components_representatives[scc_idx]).collect::<Vec<_>>();
305+
scc_node_to_edges.insert((scc_idx, repr), edge_representatives);
306+
}
307+
308+
debug!("SCC edges {:#?}", scc_node_to_edges);
309+
}
310+
246311
impl<'tcx> RegionInferenceContext<'tcx> {
247312
/// Creates a new region inference context with a total of
248313
/// `num_region_variables` valid inference variables; the first N
@@ -251,7 +316,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
251316
///
252317
/// The `outlives_constraints` and `type_tests` are an initial set
253318
/// of constraints produced by the MIR type check.
254-
pub(crate) fn new(
319+
pub(crate) fn new<'cx>(
320+
_infcx: &BorrowckInferCtxt<'cx, 'tcx>,
255321
var_infos: VarInfos,
256322
universal_regions: Rc<UniversalRegions<'tcx>>,
257323
placeholder_indices: Rc<PlaceholderIndices>,
@@ -263,6 +329,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
263329
liveness_constraints: LivenessValues<RegionVid>,
264330
elements: &Rc<RegionValueElements>,
265331
) -> Self {
332+
debug!("universal_regions: {:#?}", universal_regions);
333+
debug!("outlives constraints: {:#?}", outlives_constraints);
334+
debug!("placeholder_indices: {:#?}", placeholder_indices);
335+
debug!("type tests: {:#?}", type_tests);
336+
266337
// Create a RegionDefinition for each inference variable.
267338
let definitions: IndexVec<_, _> = var_infos
268339
.iter()
@@ -274,6 +345,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
274345
let fr_static = universal_regions.fr_static;
275346
let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static));
276347

348+
if cfg!(debug_assertions) {
349+
sccs_info(_infcx, constraint_sccs.clone());
350+
}
351+
277352
let mut scc_values =
278353
RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
279354

compiler/rustc_borrowck/src/region_infer/values.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl<N: Idx> LivenessValues<N> {
181181
/// Maps from `ty::PlaceholderRegion` values that are used in the rest of
182182
/// rustc to the internal `PlaceholderIndex` values that are used in
183183
/// NLL.
184-
#[derive(Default)]
184+
#[derive(Debug, Default)]
185185
pub(crate) struct PlaceholderIndices {
186186
indices: FxIndexSet<ty::PlaceholderRegion>,
187187
}

0 commit comments

Comments
 (0)