Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 71b3fbd

Browse files
authoredJul 7, 2022
Rollup merge of #98930 - tmiasko:pub-basic-blocks, r=oli-obk
Make MIR basic blocks field public This makes it possible to mutably borrow different fields of the MIR body without resorting to methods like `basic_blocks_local_decls_mut_and_var_debug_info`. To preserve validity of control flow graph caches in the presence of modifications, a new struct `BasicBlocks` wraps together basic blocks and control flow graph caches. The `BasicBlocks` dereferences to `IndexVec<BasicBlock, BasicBlockData>`. On the other hand a mutable access requires explicit `as_mut()` call.
2 parents ade6d2c + 17adfeb commit 71b3fbd

File tree

32 files changed

+229
-230
lines changed

32 files changed

+229
-230
lines changed
 

‎compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1628,7 +1628,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
16281628
location: Location,
16291629
) -> impl Iterator<Item = Location> + Captures<'tcx> + 'a {
16301630
if location.statement_index == 0 {
1631-
let predecessors = body.predecessors()[location.block].to_vec();
1631+
let predecessors = body.basic_blocks.predecessors()[location.block].to_vec();
16321632
Either::Left(predecessors.into_iter().map(move |bb| body.terminator_loc(bb)))
16331633
} else {
16341634
Either::Right(std::iter::once(Location {

‎compiler/rustc_borrowck/src/invalidation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub(super) fn generate_invalidates<'tcx>(
2626

2727
if let Some(all_facts) = all_facts {
2828
let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
29-
let dominators = body.dominators();
29+
let dominators = body.basic_blocks.dominators();
3030
let mut ig = InvalidationGenerator {
3131
all_facts,
3232
borrow_set,

‎compiler/rustc_borrowck/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ fn do_mir_borrowck<'a, 'tcx>(
334334
};
335335
}
336336

337-
let dominators = body.dominators();
337+
let dominators = body.basic_blocks.dominators();
338338

339339
let mut mbcx = MirBorrowckCtxt {
340340
infcx,

‎compiler/rustc_borrowck/src/type_check/liveness/trace.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
258258

259259
let block = self.cx.elements.to_location(block_start).block;
260260
self.stack.extend(
261-
self.cx.body.predecessors()[block]
261+
self.cx.body.basic_blocks.predecessors()[block]
262262
.iter()
263263
.map(|&pred_bb| self.cx.body.terminator_loc(pred_bb))
264264
.map(|pred_loc| self.cx.elements.point_from_location(pred_loc)),
@@ -354,7 +354,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
354354
}
355355

356356
let body = self.cx.body;
357-
for &pred_block in body.predecessors()[block].iter() {
357+
for &pred_block in body.basic_blocks.predecessors()[block].iter() {
358358
debug!("compute_drop_live_points_for_block: pred_block = {:?}", pred_block,);
359359

360360
// Check whether the variable is (at least partially)

‎compiler/rustc_codegen_ssa/src/mir/analyze.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
1515
fx: &FunctionCx<'a, 'tcx, Bx>,
1616
) -> BitSet<mir::Local> {
1717
let mir = fx.mir;
18-
let dominators = mir.dominators();
18+
let dominators = mir.basic_blocks.dominators();
1919
let locals = mir
2020
.local_decls
2121
.iter()

‎compiler/rustc_const_eval/src/transform/promote_consts.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
856856
literal: ConstantKind::from_const(_const, tcx),
857857
}))
858858
};
859-
let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
859+
let blocks = self.source.basic_blocks.as_mut();
860+
let local_decls = &mut self.source.local_decls;
860861
let loc = candidate.location;
861862
let statement = &mut blocks[loc.block].statements[loc.statement_index];
862863
match statement.kind {
@@ -865,7 +866,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
865866
Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
866867
)) => {
867868
// Use the underlying local for this (necessarily interior) borrow.
868-
let ty = local_decls.local_decls()[place.local].ty;
869+
let ty = local_decls[place.local].ty;
869870
let span = statement.source_info.span;
870871

871872
let ref_ty = tcx.mk_ref(
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
use crate::mir::graph_cyclic_cache::GraphIsCyclicCache;
2+
use crate::mir::predecessors::{PredecessorCache, Predecessors};
3+
use crate::mir::switch_sources::{SwitchSourceCache, SwitchSources};
4+
use crate::mir::traversal::PostorderCache;
5+
use crate::mir::{BasicBlock, BasicBlockData, Successors, START_BLOCK};
6+
7+
use rustc_data_structures::graph;
8+
use rustc_data_structures::graph::dominators::{dominators, Dominators};
9+
use rustc_index::vec::IndexVec;
10+
11+
#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)]
12+
pub struct BasicBlocks<'tcx> {
13+
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
14+
predecessor_cache: PredecessorCache,
15+
switch_source_cache: SwitchSourceCache,
16+
is_cyclic: GraphIsCyclicCache,
17+
postorder_cache: PostorderCache,
18+
}
19+
20+
impl<'tcx> BasicBlocks<'tcx> {
21+
#[inline]
22+
pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
23+
BasicBlocks {
24+
basic_blocks,
25+
predecessor_cache: PredecessorCache::new(),
26+
switch_source_cache: SwitchSourceCache::new(),
27+
is_cyclic: GraphIsCyclicCache::new(),
28+
postorder_cache: PostorderCache::new(),
29+
}
30+
}
31+
32+
/// Returns true if control-flow graph contains a cycle reachable from the `START_BLOCK`.
33+
#[inline]
34+
pub fn is_cfg_cyclic(&self) -> bool {
35+
self.is_cyclic.is_cyclic(self)
36+
}
37+
38+
#[inline]
39+
pub fn dominators(&self) -> Dominators<BasicBlock> {
40+
dominators(&self)
41+
}
42+
43+
/// Returns predecessors for each basic block.
44+
#[inline]
45+
pub fn predecessors(&self) -> &Predecessors {
46+
self.predecessor_cache.compute(&self.basic_blocks)
47+
}
48+
49+
/// Returns basic blocks in a postorder.
50+
#[inline]
51+
pub fn postorder(&self) -> &[BasicBlock] {
52+
self.postorder_cache.compute(&self.basic_blocks)
53+
}
54+
55+
/// `switch_sources()[&(target, switch)]` returns a list of switch
56+
/// values that lead to a `target` block from a `switch` block.
57+
#[inline]
58+
pub fn switch_sources(&self) -> &SwitchSources {
59+
self.switch_source_cache.compute(&self.basic_blocks)
60+
}
61+
62+
/// Returns mutable reference to basic blocks. Invalidates CFG cache.
63+
#[inline]
64+
pub fn as_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
65+
self.invalidate_cfg_cache();
66+
&mut self.basic_blocks
67+
}
68+
69+
/// Get mutable access to basic blocks without invalidating the CFG cache.
70+
///
71+
/// By calling this method instead of e.g. [`BasicBlocks::as_mut`] you promise not to change
72+
/// the CFG. This means that
73+
///
74+
/// 1) The number of basic blocks remains unchanged
75+
/// 2) The set of successors of each terminator remains unchanged.
76+
/// 3) For each `TerminatorKind::SwitchInt`, the `targets` remains the same and the terminator
77+
/// kind is not changed.
78+
///
79+
/// If any of these conditions cannot be upheld, you should call [`BasicBlocks::invalidate_cfg_cache`].
80+
#[inline]
81+
pub fn as_mut_preserves_cfg(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
82+
&mut self.basic_blocks
83+
}
84+
85+
/// Invalidates cached information about the CFG.
86+
///
87+
/// You will only ever need this if you have also called [`BasicBlocks::as_mut_preserves_cfg`].
88+
/// All other methods that allow you to mutate the basic blocks also call this method
89+
/// themselves, thereby avoiding any risk of accidentaly cache invalidation.
90+
pub fn invalidate_cfg_cache(&mut self) {
91+
self.predecessor_cache.invalidate();
92+
self.switch_source_cache.invalidate();
93+
self.is_cyclic.invalidate();
94+
self.postorder_cache.invalidate();
95+
}
96+
}
97+
98+
impl<'tcx> std::ops::Deref for BasicBlocks<'tcx> {
99+
type Target = IndexVec<BasicBlock, BasicBlockData<'tcx>>;
100+
101+
#[inline]
102+
fn deref(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
103+
&self.basic_blocks
104+
}
105+
}
106+
107+
impl<'tcx> graph::DirectedGraph for BasicBlocks<'tcx> {
108+
type Node = BasicBlock;
109+
}
110+
111+
impl<'tcx> graph::WithNumNodes for BasicBlocks<'tcx> {
112+
#[inline]
113+
fn num_nodes(&self) -> usize {
114+
self.basic_blocks.len()
115+
}
116+
}
117+
118+
impl<'tcx> graph::WithStartNode for BasicBlocks<'tcx> {
119+
#[inline]
120+
fn start_node(&self) -> Self::Node {
121+
START_BLOCK
122+
}
123+
}
124+
125+
impl<'tcx> graph::WithSuccessors for BasicBlocks<'tcx> {
126+
#[inline]
127+
fn successors(&self, node: Self::Node) -> <Self as graph::GraphSuccessors<'_>>::Iter {
128+
self.basic_blocks[node].terminator().successors()
129+
}
130+
}
131+
132+
impl<'a, 'b> graph::GraphSuccessors<'b> for BasicBlocks<'a> {
133+
type Item = BasicBlock;
134+
type Iter = Successors<'b>;
135+
}
136+
137+
impl<'tcx, 'graph> graph::GraphPredecessors<'graph> for BasicBlocks<'tcx> {
138+
type Item = BasicBlock;
139+
type Iter = std::iter::Copied<std::slice::Iter<'graph, BasicBlock>>;
140+
}
141+
142+
impl<'tcx> graph::WithPredecessors for BasicBlocks<'tcx> {
143+
#[inline]
144+
fn predecessors(&self, node: Self::Node) -> <Self as graph::GraphPredecessors<'_>>::Iter {
145+
self.predecessors()[node].iter().copied()
146+
}
147+
}

‎compiler/rustc_middle/src/mir/mod.rs

Lines changed: 9 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use crate::mir::interpret::{
66
AllocRange, ConstAllocation, ConstValue, GlobalAlloc, LitToConstInput, Scalar,
77
};
8-
use crate::mir::traversal::PostorderCache;
98
use crate::mir::visit::MirVisitable;
109
use crate::ty::codec::{TyDecoder, TyEncoder};
1110
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
@@ -27,8 +26,7 @@ use rustc_target::abi::{Size, VariantIdx};
2726
use polonius_engine::Atom;
2827
pub use rustc_ast::Mutability;
2928
use rustc_data_structures::fx::FxHashSet;
30-
use rustc_data_structures::graph::dominators::{dominators, Dominators};
31-
use rustc_data_structures::graph::{self, GraphSuccessors};
29+
use rustc_data_structures::graph::dominators::Dominators;
3230
use rustc_index::bit_set::BitMatrix;
3331
use rustc_index::vec::{Idx, IndexVec};
3432
use rustc_serialize::{Decodable, Encodable};
@@ -43,11 +41,10 @@ use std::fmt::{self, Debug, Display, Formatter, Write};
4341
use std::ops::{ControlFlow, Index, IndexMut};
4442
use std::{iter, mem};
4543

46-
use self::graph_cyclic_cache::GraphIsCyclicCache;
47-
use self::predecessors::{PredecessorCache, Predecessors};
4844
pub use self::query::*;
49-
use self::switch_sources::{SwitchSourceCache, SwitchSources};
45+
pub use basic_blocks::BasicBlocks;
5046

47+
mod basic_blocks;
5148
pub mod coverage;
5249
mod generic_graph;
5350
pub mod generic_graphviz;
@@ -189,7 +186,7 @@ pub struct GeneratorInfo<'tcx> {
189186
pub struct Body<'tcx> {
190187
/// A list of basic blocks. References to basic block use a newtyped index type [`BasicBlock`]
191188
/// that indexes into this vector.
192-
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
189+
pub basic_blocks: BasicBlocks<'tcx>,
193190

194191
/// Records how far through the "desugaring and optimization" process this particular
195192
/// MIR has traversed. This is particularly useful when inlining, since in that context
@@ -257,11 +254,6 @@ pub struct Body<'tcx> {
257254
/// potentially allow things like `[u8; std::mem::size_of::<T>() * 0]` due to this.
258255
pub is_polymorphic: bool,
259256

260-
predecessor_cache: PredecessorCache,
261-
switch_source_cache: SwitchSourceCache,
262-
is_cyclic: GraphIsCyclicCache,
263-
postorder_cache: PostorderCache,
264-
265257
pub tainted_by_errors: Option<ErrorGuaranteed>,
266258
}
267259

@@ -289,7 +281,7 @@ impl<'tcx> Body<'tcx> {
289281
let mut body = Body {
290282
phase: MirPhase::Built,
291283
source,
292-
basic_blocks,
284+
basic_blocks: BasicBlocks::new(basic_blocks),
293285
source_scopes,
294286
generator: generator_kind.map(|generator_kind| {
295287
Box::new(GeneratorInfo {
@@ -307,10 +299,6 @@ impl<'tcx> Body<'tcx> {
307299
span,
308300
required_consts: Vec::new(),
309301
is_polymorphic: false,
310-
predecessor_cache: PredecessorCache::new(),
311-
switch_source_cache: SwitchSourceCache::new(),
312-
is_cyclic: GraphIsCyclicCache::new(),
313-
postorder_cache: PostorderCache::new(),
314302
tainted_by_errors,
315303
};
316304
body.is_polymorphic = body.has_param_types_or_consts();
@@ -326,7 +314,7 @@ impl<'tcx> Body<'tcx> {
326314
let mut body = Body {
327315
phase: MirPhase::Built,
328316
source: MirSource::item(CRATE_DEF_ID.to_def_id()),
329-
basic_blocks,
317+
basic_blocks: BasicBlocks::new(basic_blocks),
330318
source_scopes: IndexVec::new(),
331319
generator: None,
332320
local_decls: IndexVec::new(),
@@ -337,10 +325,6 @@ impl<'tcx> Body<'tcx> {
337325
required_consts: Vec::new(),
338326
var_debug_info: Vec::new(),
339327
is_polymorphic: false,
340-
predecessor_cache: PredecessorCache::new(),
341-
switch_source_cache: SwitchSourceCache::new(),
342-
is_cyclic: GraphIsCyclicCache::new(),
343-
postorder_cache: PostorderCache::new(),
344328
tainted_by_errors: None,
345329
};
346330
body.is_polymorphic = body.has_param_types_or_consts();
@@ -354,74 +338,7 @@ impl<'tcx> Body<'tcx> {
354338

355339
#[inline]
356340
pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
357-
// Because the user could mutate basic block terminators via this reference, we need to
358-
// invalidate the caches.
359-
//
360-
// FIXME: Use a finer-grained API for this, so only transformations that alter terminators
361-
// invalidate the caches.
362-
self.invalidate_cfg_cache();
363-
&mut self.basic_blocks
364-
}
365-
366-
#[inline]
367-
pub fn basic_blocks_and_local_decls_mut(
368-
&mut self,
369-
) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) {
370-
self.invalidate_cfg_cache();
371-
(&mut self.basic_blocks, &mut self.local_decls)
372-
}
373-
374-
#[inline]
375-
pub fn basic_blocks_local_decls_mut_and_var_debug_info(
376-
&mut self,
377-
) -> (
378-
&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>,
379-
&mut LocalDecls<'tcx>,
380-
&mut Vec<VarDebugInfo<'tcx>>,
381-
) {
382-
self.invalidate_cfg_cache();
383-
(&mut self.basic_blocks, &mut self.local_decls, &mut self.var_debug_info)
384-
}
385-
386-
/// Get mutable access to parts of the Body without invalidating the CFG cache.
387-
///
388-
/// By calling this method instead of eg [`Body::basic_blocks_mut`], you promise not to change
389-
/// the CFG. This means that
390-
///
391-
/// 1) The number of basic blocks remains unchanged
392-
/// 2) The set of successors of each terminator remains unchanged.
393-
/// 3) For each `TerminatorKind::SwitchInt`, the `targets` remains the same and the terminator
394-
/// kind is not changed.
395-
///
396-
/// If any of these conditions cannot be upheld, you should call [`Body::invalidate_cfg_cache`].
397-
#[inline]
398-
pub fn basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate(
399-
&mut self,
400-
) -> (
401-
&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>,
402-
&mut LocalDecls<'tcx>,
403-
&mut Vec<VarDebugInfo<'tcx>>,
404-
) {
405-
(&mut self.basic_blocks, &mut self.local_decls, &mut self.var_debug_info)
406-
}
407-
408-
/// Invalidates cached information about the CFG.
409-
///
410-
/// You will only ever need this if you have also called
411-
/// [`Body::basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate`]. All other methods
412-
/// that allow you to mutate the body also call this method themselves, thereby avoiding any
413-
/// risk of accidentaly cache invalidation.
414-
pub fn invalidate_cfg_cache(&mut self) {
415-
self.predecessor_cache.invalidate();
416-
self.switch_source_cache.invalidate();
417-
self.is_cyclic.invalidate();
418-
self.postorder_cache.invalidate();
419-
}
420-
421-
/// Returns `true` if a cycle exists in the control-flow graph that is reachable from the
422-
/// `START_BLOCK`.
423-
pub fn is_cfg_cyclic(&self) -> bool {
424-
self.is_cyclic.is_cyclic(self)
341+
self.basic_blocks.as_mut()
425342
}
426343

427344
#[inline]
@@ -495,14 +412,6 @@ impl<'tcx> Body<'tcx> {
495412
self.local_decls.drain(self.arg_count + 1..)
496413
}
497414

498-
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
499-
/// invalidating statement indices in `Location`s.
500-
pub fn make_statement_nop(&mut self, location: Location) {
501-
let block = &mut self.basic_blocks[location.block];
502-
debug_assert!(location.statement_index < block.statements.len());
503-
block.statements[location.statement_index].make_nop()
504-
}
505-
506415
/// Returns the source info associated with `location`.
507416
pub fn source_info(&self, location: Location) -> &SourceInfo {
508417
let block = &self[location.block];
@@ -538,23 +447,6 @@ impl<'tcx> Body<'tcx> {
538447
.unwrap_or_else(|| Either::Right(block_data.terminator()))
539448
}
540449

541-
#[inline]
542-
pub fn predecessors(&self) -> &Predecessors {
543-
self.predecessor_cache.compute(&self.basic_blocks)
544-
}
545-
546-
/// `body.switch_sources()[&(target, switch)]` returns a list of switch
547-
/// values that lead to a `target` block from a `switch` block.
548-
#[inline]
549-
pub fn switch_sources(&self) -> &SwitchSources {
550-
self.switch_source_cache.compute(&self.basic_blocks)
551-
}
552-
553-
#[inline]
554-
pub fn dominators(&self) -> Dominators<BasicBlock> {
555-
dominators(self)
556-
}
557-
558450
#[inline]
559451
pub fn yield_ty(&self) -> Option<Ty<'tcx>> {
560452
self.generator.as_ref().and_then(|generator| generator.yield_ty)
@@ -599,7 +491,7 @@ impl<'tcx> Index<BasicBlock> for Body<'tcx> {
599491
impl<'tcx> IndexMut<BasicBlock> for Body<'tcx> {
600492
#[inline]
601493
fn index_mut(&mut self, index: BasicBlock) -> &mut BasicBlockData<'tcx> {
602-
&mut self.basic_blocks_mut()[index]
494+
&mut self.basic_blocks.as_mut()[index]
603495
}
604496
}
605497

@@ -2890,48 +2782,6 @@ fn pretty_print_const_value<'tcx>(
28902782
})
28912783
}
28922784

2893-
impl<'tcx> graph::DirectedGraph for Body<'tcx> {
2894-
type Node = BasicBlock;
2895-
}
2896-
2897-
impl<'tcx> graph::WithNumNodes for Body<'tcx> {
2898-
#[inline]
2899-
fn num_nodes(&self) -> usize {
2900-
self.basic_blocks.len()
2901-
}
2902-
}
2903-
2904-
impl<'tcx> graph::WithStartNode for Body<'tcx> {
2905-
#[inline]
2906-
fn start_node(&self) -> Self::Node {
2907-
START_BLOCK
2908-
}
2909-
}
2910-
2911-
impl<'tcx> graph::WithSuccessors for Body<'tcx> {
2912-
#[inline]
2913-
fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
2914-
self.basic_blocks[node].terminator().successors()
2915-
}
2916-
}
2917-
2918-
impl<'a, 'b> graph::GraphSuccessors<'b> for Body<'a> {
2919-
type Item = BasicBlock;
2920-
type Iter = Successors<'b>;
2921-
}
2922-
2923-
impl<'tcx, 'graph> graph::GraphPredecessors<'graph> for Body<'tcx> {
2924-
type Item = BasicBlock;
2925-
type Iter = std::iter::Copied<std::slice::Iter<'graph, BasicBlock>>;
2926-
}
2927-
2928-
impl<'tcx> graph::WithPredecessors for Body<'tcx> {
2929-
#[inline]
2930-
fn predecessors(&self, node: Self::Node) -> <Self as graph::GraphPredecessors<'_>>::Iter {
2931-
self.predecessors()[node].iter().copied()
2932-
}
2933-
}
2934-
29352785
/// `Location` represents the position of the start of the statement; or, if
29362786
/// `statement_index` equals the number of statements, then the start of the
29372787
/// terminator.
@@ -2968,7 +2818,7 @@ impl Location {
29682818
return true;
29692819
}
29702820

2971-
let predecessors = body.predecessors();
2821+
let predecessors = body.basic_blocks.predecessors();
29722822

29732823
// If we're in another block, then we want to check that block is a predecessor of `other`.
29742824
let mut queue: Vec<BasicBlock> = predecessors[other.block].to_vec();

‎compiler/rustc_middle/src/mir/traversal.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,25 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
104104
///
105105
/// A Postorder traversal of this graph is `D B C A` or `D C B A`
106106
pub struct Postorder<'a, 'tcx> {
107-
body: &'a Body<'tcx>,
107+
basic_blocks: &'a IndexVec<BasicBlock, BasicBlockData<'tcx>>,
108108
visited: BitSet<BasicBlock>,
109109
visit_stack: Vec<(BasicBlock, Successors<'a>)>,
110110
root_is_start_block: bool,
111111
}
112112

113113
impl<'a, 'tcx> Postorder<'a, 'tcx> {
114-
pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
114+
pub fn new(
115+
basic_blocks: &'a IndexVec<BasicBlock, BasicBlockData<'tcx>>,
116+
root: BasicBlock,
117+
) -> Postorder<'a, 'tcx> {
115118
let mut po = Postorder {
116-
body,
117-
visited: BitSet::new_empty(body.basic_blocks().len()),
119+
basic_blocks,
120+
visited: BitSet::new_empty(basic_blocks.len()),
118121
visit_stack: Vec::new(),
119122
root_is_start_block: root == START_BLOCK,
120123
};
121124

122-
let data = &po.body[root];
125+
let data = &po.basic_blocks[root];
123126

124127
if let Some(ref term) = data.terminator {
125128
po.visited.insert(root);
@@ -190,7 +193,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
190193
};
191194

192195
if self.visited.insert(bb) {
193-
if let Some(term) = &self.body[bb].terminator {
196+
if let Some(term) = &self.basic_blocks[bb].terminator {
194197
self.visit_stack.push((bb, term.successors()));
195198
}
196199
}
@@ -199,7 +202,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
199202
}
200203

201204
pub fn postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Postorder<'a, 'tcx> {
202-
Postorder::new(body, START_BLOCK)
205+
Postorder::new(&body.basic_blocks, START_BLOCK)
203206
}
204207

205208
impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
@@ -211,12 +214,12 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
211214
self.traverse_successor();
212215
}
213216

214-
next.map(|(bb, _)| (bb, &self.body[bb]))
217+
next.map(|(bb, _)| (bb, &self.basic_blocks[bb]))
215218
}
216219

217220
fn size_hint(&self) -> (usize, Option<usize>) {
218221
// All the blocks, minus the number of blocks we've visited.
219-
let upper = self.body.basic_blocks().len() - self.visited.count();
222+
let upper = self.basic_blocks.len() - self.visited.count();
220223

221224
let lower = if self.root_is_start_block {
222225
// We will visit all remaining blocks exactly once.
@@ -263,10 +266,8 @@ pub struct ReversePostorder<'a, 'tcx> {
263266

264267
impl<'a, 'tcx> ReversePostorder<'a, 'tcx> {
265268
pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> {
266-
let blocks: Vec<_> = Postorder::new(body, root).map(|(bb, _)| bb).collect();
267-
269+
let blocks: Vec<_> = Postorder::new(&body.basic_blocks, root).map(|(bb, _)| bb).collect();
268270
let len = blocks.len();
269-
270271
ReversePostorder { body, blocks, idx: len }
271272
}
272273
}
@@ -334,10 +335,8 @@ impl<'a, 'tcx> Iterator for ReversePostorderIter<'a, 'tcx> {
334335
impl<'a, 'tcx> ExactSizeIterator for ReversePostorderIter<'a, 'tcx> {}
335336

336337
pub fn reverse_postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> ReversePostorderIter<'a, 'tcx> {
337-
let blocks = body.postorder_cache.compute(body);
338-
338+
let blocks = body.basic_blocks.postorder();
339339
let len = blocks.len();
340-
341340
ReversePostorderIter { body, blocks, idx: len }
342341
}
343342

@@ -360,7 +359,7 @@ impl PostorderCache {
360359

361360
/// Returns the `&[BasicBlocks]` represents the postorder graph for this MIR.
362361
#[inline]
363-
pub(super) fn compute(&self, body: &Body<'_>) -> &[BasicBlock] {
362+
pub(super) fn compute(&self, body: &IndexVec<BasicBlock, BasicBlockData<'_>>) -> &[BasicBlock] {
364363
self.cache.get_or_init(|| Postorder::new(body, START_BLOCK).map(|(bb, _)| bb).collect())
365364
}
366365
}

‎compiler/rustc_mir_build/src/lints.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_data_structures::graph::iterate::{
22
NodeStatus, TriColorDepthFirstSearch, TriColorVisitor,
33
};
44
use rustc_hir::intravisit::FnKind;
5-
use rustc_middle::mir::{BasicBlock, Body, Operand, TerminatorKind};
5+
use rustc_middle::mir::{BasicBlock, BasicBlocks, Body, Operand, TerminatorKind};
66
use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
77
use rustc_middle::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
88
use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION;
@@ -30,7 +30,9 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
3030
};
3131

3232
let mut vis = Search { tcx, body, reachable_recursive_calls: vec![], trait_substs };
33-
if let Some(NonRecursive) = TriColorDepthFirstSearch::new(&body).run_from_start(&mut vis) {
33+
if let Some(NonRecursive) =
34+
TriColorDepthFirstSearch::new(&body.basic_blocks).run_from_start(&mut vis)
35+
{
3436
return;
3537
}
3638
if vis.reachable_recursive_calls.is_empty() {
@@ -101,7 +103,7 @@ impl<'mir, 'tcx> Search<'mir, 'tcx> {
101103
}
102104
}
103105

104-
impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> {
106+
impl<'mir, 'tcx> TriColorVisitor<BasicBlocks<'tcx>> for Search<'mir, 'tcx> {
105107
type BreakVal = NonRecursive;
106108

107109
fn node_examined(

‎compiler/rustc_mir_dataflow/src/framework/direction.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ impl Direction for Backward {
228228
) where
229229
A: Analysis<'tcx>,
230230
{
231-
for pred in body.predecessors()[bb].iter().copied() {
231+
for pred in body.basic_blocks.predecessors()[bb].iter().copied() {
232232
match body[pred].terminator().kind {
233233
// Apply terminator-specific edge effects.
234234
//
@@ -316,7 +316,7 @@ where
316316
fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) {
317317
assert!(!self.effects_applied);
318318

319-
let values = &self.body.switch_sources()[&(self.bb, self.pred)];
319+
let values = &self.body.basic_blocks.switch_sources()[&(self.bb, self.pred)];
320320
let targets = values.iter().map(|&value| SwitchIntTarget { value, target: self.bb });
321321

322322
let mut tmp = None;

‎compiler/rustc_mir_dataflow/src/framework/engine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ where
101101
// transfer function for each block exactly once (assuming that we process blocks in RPO).
102102
//
103103
// In this case, there's no need to compute the block transfer functions ahead of time.
104-
if !body.is_cfg_cyclic() {
104+
if !body.basic_blocks.is_cfg_cyclic() {
105105
return Self::new(tcx, body, analysis, None);
106106
}
107107

‎compiler/rustc_mir_transform/src/add_call_guards.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl<'tcx> MirPass<'tcx> for AddCallGuards {
3939
impl AddCallGuards {
4040
pub fn add_call_guards(&self, body: &mut Body<'_>) {
4141
let mut pred_count: IndexVec<_, _> =
42-
body.predecessors().iter().map(|ps| ps.len()).collect();
42+
body.basic_blocks.predecessors().iter().map(|ps| ps.len()).collect();
4343
pred_count[START_BLOCK] += 1;
4444

4545
// We need a place to store the new blocks generated

‎compiler/rustc_mir_transform/src/add_retag.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
9191
super::add_call_guards::AllCallEdges.run_pass(tcx, body);
9292

9393
let (span, arg_count) = (body.span, body.arg_count);
94-
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
94+
let basic_blocks = body.basic_blocks.as_mut();
95+
let local_decls = &body.local_decls;
9596
let needs_retag = |place: &Place<'tcx>| {
9697
// FIXME: Instead of giving up for unstable places, we should introduce
9798
// a temporary and retag on that.

‎compiler/rustc_mir_transform/src/coverage/graph.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl CoverageGraph {
8080
IndexVec<BasicCoverageBlock, BasicCoverageBlockData>,
8181
IndexVec<BasicBlock, Option<BasicCoverageBlock>>,
8282
) {
83-
let num_basic_blocks = mir_body.num_nodes();
83+
let num_basic_blocks = mir_body.basic_blocks.len();
8484
let mut bcbs = IndexVec::with_capacity(num_basic_blocks);
8585
let mut bb_to_bcb = IndexVec::from_elem_n(None, num_basic_blocks);
8686

@@ -95,7 +95,7 @@ impl CoverageGraph {
9595
let mut basic_blocks = Vec::new();
9696
for (bb, data) in mir_cfg_without_unwind {
9797
if let Some(last) = basic_blocks.last() {
98-
let predecessors = &mir_body.predecessors()[bb];
98+
let predecessors = &mir_body.basic_blocks.predecessors()[bb];
9999
if predecessors.len() > 1 || !predecessors.contains(last) {
100100
// The `bb` has more than one _incoming_ edge, and should start its own
101101
// `BasicCoverageBlockData`. (Note, the `basic_blocks` vector does not yet

‎compiler/rustc_mir_transform/src/coverage/spans.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,8 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
321321
}
322322

323323
fn mir_to_initial_sorted_coverage_spans(&self) -> Vec<CoverageSpan> {
324-
let mut initial_spans = Vec::<CoverageSpan>::with_capacity(self.mir_body.num_nodes() * 2);
324+
let mut initial_spans =
325+
Vec::<CoverageSpan>::with_capacity(self.mir_body.basic_blocks.len() * 2);
325326
for (bcb, bcb_data) in self.basic_coverage_blocks.iter_enumerated() {
326327
initial_spans.extend(self.bcb_to_initial_coverage_spans(bcb, bcb_data));
327328
}

‎compiler/rustc_mir_transform/src/coverage/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ fn print_mir_graphviz(name: &str, mir_body: &Body<'_>) {
222222
bb,
223223
debug::term_type(&data.terminator().kind),
224224
mir_body
225+
.basic_blocks
225226
.successors(bb)
226227
.map(|successor| { format!(" {:?} -> {:?};", bb, successor) })
227228
.join("\n")

‎compiler/rustc_mir_transform/src/dead_store_elimination.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
6666
return;
6767
}
6868

69-
let bbs = body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate().0;
69+
let bbs = body.basic_blocks.as_mut_preserves_cfg();
7070
for Location { block, statement_index } in patch {
7171
bbs[block].statements[statement_index].make_nop();
7272
}

‎compiler/rustc_mir_transform/src/deaggregator.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
1111
}
1212

1313
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
14-
let (basic_blocks, local_decls, _) =
15-
body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate();
16-
let local_decls = &*local_decls;
14+
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
1715
for bb in basic_blocks {
1816
bb.expand_statements(|stmt| {
1917
// FIXME(eddyb) don't match twice on `stmt.kind` (post-NLL).
@@ -38,7 +36,7 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
3836
Some(expand_aggregate(
3937
lhs,
4038
operands.into_iter().map(|op| {
41-
let ty = op.ty(local_decls, tcx);
39+
let ty = op.ty(&body.local_decls, tcx);
4240
(op, ty)
4341
}),
4442
*kind,

‎compiler/rustc_mir_transform/src/elaborate_box_derefs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,13 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
110110

111111
let patch = MirPatch::new(body);
112112

113-
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
113+
let local_decls = &mut body.local_decls;
114114

115115
let mut visitor =
116116
ElaborateBoxDerefVisitor { tcx, unique_did, nonnull_did, local_decls, patch };
117117

118118
for (block, BasicBlockData { statements, terminator, .. }) in
119-
basic_blocks.iter_enumerated_mut()
119+
body.basic_blocks.as_mut().iter_enumerated_mut()
120120
{
121121
let mut index = 0;
122122
for statement in statements {

‎compiler/rustc_mir_transform/src/instcombine.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
1616
}
1717

1818
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
19-
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
20-
let ctx = InstCombineContext { tcx, local_decls };
21-
for block in basic_blocks.iter_mut() {
19+
let ctx = InstCombineContext { tcx, local_decls: &body.local_decls };
20+
for block in body.basic_blocks.as_mut() {
2221
for statement in block.statements.iter_mut() {
2322
match statement.kind {
2423
StatementKind::Assign(box (_place, ref mut rvalue)) => {

‎compiler/rustc_mir_transform/src/lower_intrinsics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ pub struct LowerIntrinsics;
1111

1212
impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
1313
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
14-
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
15-
for block in basic_blocks {
14+
let local_decls = &body.local_decls;
15+
for block in body.basic_blocks.as_mut() {
1616
let terminator = block.terminator.as_mut().unwrap();
1717
if let TerminatorKind::Call { func, args, destination, target, .. } =
1818
&mut terminator.kind

‎compiler/rustc_mir_transform/src/lower_slice_len.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@ pub fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
2727
};
2828

2929
// The one successor remains unchanged, so no need to invalidate
30-
let (basic_blocks, local_decls, _) =
31-
body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate();
32-
30+
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
3331
for block in basic_blocks {
3432
// lower `<[_]>::len` calls
35-
lower_slice_len_call(tcx, block, &*local_decls, slice_len_fn_item_def_id);
33+
lower_slice_len_call(tcx, block, &body.local_decls, slice_len_fn_item_def_id);
3634
}
3735
}
3836

‎compiler/rustc_mir_transform/src/match_branches.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
4848
let def_id = body.source.def_id();
4949
let param_env = tcx.param_env(def_id);
5050

51-
let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut();
51+
let bbs = body.basic_blocks.as_mut();
5252
let mut should_cleanup = false;
5353
'outer: for bb_idx in bbs.indices() {
5454
if !tcx.consider_optimizing(|| format!("MatchBranchSimplification {:?} ", def_id)) {
@@ -108,7 +108,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
108108

109109
// Introduce a temporary for the discriminant value.
110110
let source_info = bbs[bb_idx].terminator().source_info;
111-
let discr_local = local_decls.push(LocalDecl::new(switch_ty, source_info.span));
111+
let discr_local = body.local_decls.push(LocalDecl::new(switch_ty, source_info.span));
112112

113113
// We already checked that first and second are different blocks,
114114
// and bb_idx has a different terminator from both of them.

‎compiler/rustc_mir_transform/src/normalize_array_len.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ impl<'tcx> MirPass<'tcx> for NormalizeArrayLen {
3333

3434
pub fn normalize_array_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
3535
// We don't ever touch terminators, so no need to invalidate the CFG cache
36-
let (basic_blocks, local_decls, _) =
37-
body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate();
36+
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
37+
let local_decls = &mut body.local_decls;
3838

3939
// do a preliminary analysis to see if we ever have locals of type `[T;N]` or `&[T;N]`
4040
let mut interesting_locals = BitSet::new_empty(local_decls.len());

‎compiler/rustc_mir_transform/src/nrvo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ fn find_local_assigned_to_return_place(
133133
return local;
134134
}
135135

136-
match body.predecessors()[block].as_slice() {
136+
match body.basic_blocks.predecessors()[block].as_slice() {
137137
&[pred] => block = pred,
138138
_ => return None,
139139
}

‎compiler/rustc_mir_transform/src/remove_storage_markers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ impl<'tcx> MirPass<'tcx> for RemoveStorageMarkers {
1717
}
1818

1919
trace!("Running RemoveStorageMarkers on {:?}", body.source);
20-
for data in body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate().0 {
20+
for data in body.basic_blocks.as_mut_preserves_cfg() {
2121
data.statements.retain(|statement| match statement.kind {
2222
StatementKind::StorageLive(..)
2323
| StatementKind::StorageDead(..)

‎compiler/rustc_mir_transform/src/remove_unneeded_drops.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@ impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
2020
let param_env = tcx.param_env_reveal_all_normalized(did);
2121
let mut should_simplify = false;
2222

23-
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
24-
for block in basic_blocks {
23+
for block in body.basic_blocks.as_mut() {
2524
let terminator = block.terminator_mut();
2625
if let TerminatorKind::Drop { place, target, .. } = terminator.kind {
27-
let ty = place.ty(local_decls, tcx);
26+
let ty = place.ty(&body.local_decls, tcx);
2827
if ty.ty.needs_drop(tcx, param_env) {
2928
continue;
3029
}

‎compiler/rustc_mir_transform/src/remove_zsts.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
1818
return;
1919
}
2020
let param_env = tcx.param_env(body.source.def_id());
21-
let (basic_blocks, local_decls, _) =
22-
body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate();
23-
for block in basic_blocks.iter_mut() {
21+
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
22+
let local_decls = &body.local_decls;
23+
for block in basic_blocks {
2424
for statement in block.statements.iter_mut() {
2525
if let StatementKind::Assign(box (place, _)) | StatementKind::Deinit(box place) =
2626
statement.kind

‎compiler/rustc_mir_transform/src/separate_const_switch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<'tcx> MirPass<'tcx> for SeparateConstSwitch {
6161
/// Returns the amount of blocks that were duplicated
6262
pub fn separate_const_switch(body: &mut Body<'_>) -> usize {
6363
let mut new_blocks: SmallVec<[(BasicBlock, BasicBlock); 6]> = SmallVec::new();
64-
let predecessors = body.predecessors();
64+
let predecessors = body.basic_blocks.predecessors();
6565
'block_iter: for (block_id, block) in body.basic_blocks().iter_enumerated() {
6666
if let TerminatorKind::SwitchInt {
6767
discr: Operand::Copy(switch_place) | Operand::Move(switch_place),

‎compiler/rustc_mir_transform/src/simplify_try.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -386,14 +386,17 @@ impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
386386
trace!("running SimplifyArmIdentity on {:?}", source);
387387

388388
let local_uses = LocalUseCounter::get_local_uses(body);
389-
let (basic_blocks, local_decls, debug_info) =
390-
body.basic_blocks_local_decls_mut_and_var_debug_info();
391-
for bb in basic_blocks {
389+
for bb in body.basic_blocks.as_mut() {
392390
if let Some(opt_info) =
393-
get_arm_identity_info(&bb.statements, local_decls.len(), debug_info)
391+
get_arm_identity_info(&bb.statements, body.local_decls.len(), &body.var_debug_info)
394392
{
395393
trace!("got opt_info = {:#?}", opt_info);
396-
if !optimization_applies(&opt_info, local_decls, &local_uses, &debug_info) {
394+
if !optimization_applies(
395+
&opt_info,
396+
&body.local_decls,
397+
&local_uses,
398+
&body.var_debug_info,
399+
) {
397400
debug!("optimization skipped for {:?}", source);
398401
continue;
399402
}
@@ -431,7 +434,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
431434

432435
// Fix the debug info to point to the right local
433436
for dbg_index in opt_info.dbg_info_to_adjust {
434-
let dbg_info = &mut debug_info[dbg_index];
437+
let dbg_info = &mut body.var_debug_info[dbg_index];
435438
assert!(
436439
matches!(dbg_info.value, VarDebugInfoContents::Place(_)),
437440
"value was not a Place"

‎src/tools/clippy/clippy_lints/src/redundant_clone.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
161161
// `arg` is a reference as it is `.deref()`ed in the previous block.
162162
// Look into the predecessor block and find out the source of deref.
163163

164-
let ps = &mir.predecessors()[bb];
164+
let ps = &mir.basic_blocks.predecessors()[bb];
165165
if ps.len() != 1 {
166166
continue;
167167
}

0 commit comments

Comments
 (0)
Please sign in to comment.