Skip to content

Commit 0414594

Browse files
committed
Auto merge of #39409 - pnkfelix:mir-borrowck2, r=nikomatsakis
MIR EndRegion Statements (was MIR dataflow for Borrows) This PR adds an `EndRegion` statement to MIR (where the `EndRegion` statement is what terminates a borrow). An earlier version of the PR implemented a dataflow analysis on borrow expressions, but I am now factoring that into a follow-up PR so that reviewing this one is easier. (And also because there are some revisions I want to make to that dataflow code, but I want this PR to get out of WIP status...) This is a baby step towards MIR borrowck. I just want to get the review process going while I independently work on the remaining steps.
2 parents 5ce5126 + 11f4968 commit 0414594

Some content is hidden

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

45 files changed

+1047
-73
lines changed

src/librustc/ich/impls_mir.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ for mir::StatementKind<'tcx> {
226226
mir::StatementKind::StorageDead(ref lvalue) => {
227227
lvalue.hash_stable(hcx, hasher);
228228
}
229+
mir::StatementKind::EndRegion(ref extents) => {
230+
extents.hash_stable(hcx, hasher);
231+
}
229232
mir::StatementKind::Nop => {}
230233
mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
231234
asm.hash_stable(hcx, hasher);

src/librustc/mir/mod.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1313
use graphviz::IntoCow;
1414
use middle::const_val::ConstVal;
15+
use middle::region::CodeExtent;
1516
use rustc_const_math::{ConstUsize, ConstInt, ConstMathErr};
1617
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
1718
use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
@@ -804,6 +805,10 @@ pub enum StatementKind<'tcx> {
804805
inputs: Vec<Operand<'tcx>>
805806
},
806807

808+
/// Mark one terminating point of an extent (i.e. static region).
809+
/// (The starting point(s) arise implicitly from borrows.)
810+
EndRegion(CodeExtent),
811+
807812
/// No-op. Useful for deleting instructions without affecting statement indices.
808813
Nop,
809814
}
@@ -813,6 +818,8 @@ impl<'tcx> Debug for Statement<'tcx> {
813818
use self::StatementKind::*;
814819
match self.kind {
815820
Assign(ref lv, ref rv) => write!(fmt, "{:?} = {:?}", lv, rv),
821+
// (reuse lifetime rendering policy from ppaux.)
822+
EndRegion(ref ce) => write!(fmt, "EndRegion({})", ty::ReScope(*ce)),
816823
StorageLive(ref lv) => write!(fmt, "StorageLive({:?})", lv),
817824
StorageDead(ref lv) => write!(fmt, "StorageDead({:?})", lv),
818825
SetDiscriminant{lvalue: ref lv, variant_index: index} => {
@@ -1176,12 +1183,22 @@ impl<'tcx> Debug for Rvalue<'tcx> {
11761183
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
11771184
Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval),
11781185
NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
1179-
Ref(_, borrow_kind, ref lv) => {
1186+
Ref(region, borrow_kind, ref lv) => {
11801187
let kind_str = match borrow_kind {
11811188
BorrowKind::Shared => "",
11821189
BorrowKind::Mut | BorrowKind::Unique => "mut ",
11831190
};
1184-
write!(fmt, "&{}{:?}", kind_str, lv)
1191+
1192+
// When identifying regions, add trailing space if
1193+
// necessary.
1194+
let region = if ppaux::identify_regions() {
1195+
let mut region = format!("{}", region);
1196+
if region.len() > 0 { region.push(' '); }
1197+
region
1198+
} else {
1199+
"".to_owned()
1200+
};
1201+
write!(fmt, "&{}{}{:?}", region, kind_str, lv)
11851202
}
11861203

11871204
Aggregate(ref kind, ref lvs) => {
@@ -1224,7 +1241,11 @@ impl<'tcx> Debug for Rvalue<'tcx> {
12241241

12251242
AggregateKind::Closure(def_id, _) => ty::tls::with(|tcx| {
12261243
if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
1227-
let name = format!("[closure@{:?}]", tcx.hir.span(node_id));
1244+
let name = if tcx.sess.opts.debugging_opts.span_free_formats {
1245+
format!("[closure@{:?}]", node_id)
1246+
} else {
1247+
format!("[closure@{:?}]", tcx.hir.span(node_id))
1248+
};
12281249
let mut struct_fmt = fmt.debug_struct(&name);
12291250

12301251
tcx.with_freevars(node_id, |freevars| {
@@ -1458,6 +1479,13 @@ impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
14581479
outputs: outputs.fold_with(folder),
14591480
inputs: inputs.fold_with(folder)
14601481
},
1482+
1483+
// Note for future: If we want to expose the extents
1484+
// during the fold, we need to either generalize EndRegion
1485+
// to carry `[ty::Region]`, or extend the `TypeFolder`
1486+
// trait with a `fn fold_extent`.
1487+
EndRegion(ref extent) => EndRegion(extent.clone()),
1488+
14611489
Nop => Nop,
14621490
};
14631491
Statement {
@@ -1476,6 +1504,13 @@ impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
14761504
StorageDead(ref lvalue) => lvalue.visit_with(visitor),
14771505
InlineAsm { ref outputs, ref inputs, .. } =>
14781506
outputs.visit_with(visitor) || inputs.visit_with(visitor),
1507+
1508+
// Note for future: If we want to expose the extents
1509+
// during the visit, we need to either generalize EndRegion
1510+
// to carry `[ty::Region]`, or extend the `TypeVisitor`
1511+
// trait with a `fn visit_extent`.
1512+
EndRegion(ref _extent) => false,
1513+
14791514
Nop => false,
14801515
}
14811516
}

src/librustc/mir/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ macro_rules! make_mir_visitor {
325325
ref $($mutability)* rvalue) => {
326326
self.visit_assign(block, lvalue, rvalue, location);
327327
}
328+
StatementKind::EndRegion(_) => {}
328329
StatementKind::SetDiscriminant{ ref $($mutability)* lvalue, .. } => {
329330
self.visit_lvalue(lvalue, LvalueContext::Store, location);
330331
}

src/librustc/session/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
893893
DB_OPTIONS, db_type_desc, dbsetters,
894894
verbose: bool = (false, parse_bool, [UNTRACKED],
895895
"in general, enable more debug printouts"),
896+
span_free_formats: bool = (false, parse_bool, [UNTRACKED],
897+
"when debug-printing compiler state, do not include spans"), // o/w tests have closure@path
898+
identify_regions: bool = (false, parse_bool, [UNTRACKED],
899+
"make unnamed regions display as '# (where # is some non-ident unique id)"),
896900
time_passes: bool = (false, parse_bool, [UNTRACKED],
897901
"measure time of each rustc pass"),
898902
count_llvm_insns: bool = (false, parse_bool,

src/librustc/util/ppaux.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use hir::BodyId;
1112
use hir::def_id::DefId;
1213
use hir::map::definitions::DefPathData;
14+
use middle::region::{CodeExtent, BlockRemainder};
1315
use ty::subst::{self, Subst};
1416
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
1517
use ty::{TyBool, TyChar, TyAdt};
@@ -32,6 +34,10 @@ pub fn verbose() -> bool {
3234
ty::tls::with(|tcx| tcx.sess.verbose())
3335
}
3436

37+
pub fn identify_regions() -> bool {
38+
ty::tls::with(|tcx| tcx.sess.opts.debugging_opts.identify_regions)
39+
}
40+
3541
fn fn_sig(f: &mut fmt::Formatter,
3642
inputs: &[Ty],
3743
variadic: bool,
@@ -519,6 +525,23 @@ impl fmt::Display for ty::RegionKind {
519525
ty::ReSkolemized(_, br) => {
520526
write!(f, "{}", br)
521527
}
528+
ty::ReScope(code_extent) if identify_regions() => {
529+
match code_extent {
530+
CodeExtent::Misc(node_id) =>
531+
write!(f, "'{}mce", node_id.as_u32()),
532+
CodeExtent::CallSiteScope(BodyId { node_id }) =>
533+
write!(f, "'{}cce", node_id.as_u32()),
534+
CodeExtent::ParameterScope(BodyId { node_id }) =>
535+
write!(f, "'{}pce", node_id.as_u32()),
536+
CodeExtent::DestructionScope(node_id) =>
537+
write!(f, "'{}dce", node_id.as_u32()),
538+
CodeExtent::Remainder(BlockRemainder { block, first_statement_index }) =>
539+
write!(f, "'{}_{}rce", block, first_statement_index),
540+
}
541+
}
542+
ty::ReVar(region_vid) if identify_regions() => {
543+
write!(f, "'{}rv", region_vid.index)
544+
}
522545
ty::ReScope(_) |
523546
ty::ReVar(_) |
524547
ty::ReErased => Ok(()),
@@ -789,7 +812,11 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
789812
write!(f, "[closure")?;
790813

791814
if let Some(node_id) = tcx.hir.as_local_node_id(did) {
792-
write!(f, "@{:?}", tcx.hir.span(node_id))?;
815+
if tcx.sess.opts.debugging_opts.span_free_formats {
816+
write!(f, "@{:?}", node_id)?;
817+
} else {
818+
write!(f, "@{:?}", tcx.hir.span(node_id))?;
819+
}
793820
let mut sep = " ";
794821
tcx.with_freevars(node_id, |freevars| {
795822
for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {

src/librustc_borrowck/borrowck/mir/dataflow/impls.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
474474
mir::StatementKind::StorageLive(_) |
475475
mir::StatementKind::StorageDead(_) |
476476
mir::StatementKind::InlineAsm { .. } |
477+
mir::StatementKind::EndRegion(_) |
477478
mir::StatementKind::Nop => {}
478479
}
479480
}

src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
105105
mir::StatementKind::StorageLive(_) |
106106
mir::StatementKind::StorageDead(_) |
107107
mir::StatementKind::InlineAsm { .. } |
108+
mir::StatementKind::EndRegion(_) |
108109
mir::StatementKind::Nop => continue,
109110
mir::StatementKind::SetDiscriminant{ .. } =>
110111
span_bug!(stmt.source_info.span,

src/librustc_borrowck/borrowck/mir/elaborate_drops.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,11 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
594594
assert!(self.patch.is_patched(bb));
595595
allow_initializations = false;
596596
}
597+
TerminatorKind::Resume => {
598+
// It is possible for `Resume` to be patched
599+
// (in particular it can be patched to be replaced with
600+
// a Goto; see `MirPatch::new`).
601+
}
597602
_ => {
598603
assert!(!self.patch.is_patched(bb));
599604
}

src/librustc_borrowck/borrowck/mir/gather_moves.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
413413
"SetDiscriminant should not exist during borrowck");
414414
}
415415
StatementKind::InlineAsm { .. } |
416+
StatementKind::EndRegion(_) |
416417
StatementKind::Nop => {}
417418
}
418419
}

src/librustc_borrowck/borrowck/mir/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
394394
mir::StatementKind::StorageLive(_) |
395395
mir::StatementKind::StorageDead(_) |
396396
mir::StatementKind::InlineAsm { .. } |
397+
mir::StatementKind::EndRegion(_) |
397398
mir::StatementKind::Nop => {}
398399
},
399400
None => {

0 commit comments

Comments
 (0)