6262//! - `reader`: the `LiveNode` ID of some node which will read the value
6363//! that `V` holds on entry to `N`. Formally: a node `M` such
6464//! that there exists a path `P` from `N` to `M` where `P` does not
65- //! write `V`. If the `reader` is `invalid_node() `, then the current
65+ //! write `V`. If the `reader` is `INVALID_NODE `, then the current
6666//! value will never be read (the variable is dead, essentially).
6767//!
6868//! - `writer`: the `LiveNode` ID of some node which will write the
6969//! variable `V` and which is reachable from `N`. Formally: a node `M`
7070//! such that there exists a path `P` from `N` to `M` and `M` writes
71- //! `V`. If the `writer` is `invalid_node() `, then there is no writer
71+ //! `V`. If the `writer` is `INVALID_NODE `, then there is no writer
7272//! of `V` that follows `N`.
7373//!
7474//! - `used`: a boolean value indicating whether `V` is *used*. We
@@ -92,6 +92,7 @@ use rustc_hir::def::*;
9292use rustc_hir::def_id::LocalDefId;
9393use rustc_hir::intravisit::{self, FnKind, NestedVisitorMap, Visitor};
9494use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet, Node};
95+ use rustc_index::vec::IndexVec;
9596use rustc_middle::hir::map::Map;
9697use rustc_middle::ty::query::Providers;
9798use rustc_middle::ty::{self, TyCtxt};
@@ -100,26 +101,20 @@ use rustc_span::symbol::{kw, sym, Symbol};
100101use rustc_span::Span;
101102
102103use std::collections::VecDeque;
103- use std::fmt;
104104use std::io;
105105use std::io::prelude::*;
106106use std::rc::Rc;
107107
108- #[derive(Copy, Clone, PartialEq)]
109- struct Variable(u32);
110-
111- #[derive(Copy, Clone, PartialEq)]
112- struct LiveNode(u32);
113-
114- impl Variable {
115- fn get(&self) -> usize {
116- self.0 as usize
108+ rustc_index::newtype_index! {
109+ pub struct Variable {
110+ DEBUG_FORMAT = "v({})",
117111 }
118112}
119113
120- impl LiveNode {
121- fn get(&self) -> usize {
122- self.0 as usize
114+ rustc_index::newtype_index! {
115+ pub struct LiveNode {
116+ DEBUG_FORMAT = "ln({})",
117+ const INVALID_NODE = LiveNode::MAX_AS_U32,
123118 }
124119}
125120
@@ -183,18 +178,6 @@ pub fn provide(providers: &mut Providers) {
183178 *providers = Providers { check_mod_liveness, ..*providers };
184179}
185180
186- impl fmt::Debug for LiveNode {
187- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188- write!(f, "ln({})", self.get())
189- }
190- }
191-
192- impl fmt::Debug for Variable {
193- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194- write!(f, "v({})", self.get())
195- }
196- }
197-
198181// ______________________________________________________________________
199182// Creating ir_maps
200183//
@@ -218,15 +201,11 @@ impl fmt::Debug for Variable {
218201// assignment. And so forth.
219202
220203impl LiveNode {
221- fn is_valid(& self) -> bool {
222- self.0 != u32::MAX
204+ fn is_valid(self) -> bool {
205+ self != INVALID_NODE
223206 }
224207}
225208
226- fn invalid_node() -> LiveNode {
227- LiveNode(u32::MAX)
228- }
229-
230209struct CaptureInfo {
231210 ln: LiveNode,
232211 var_hid: HirId,
@@ -252,8 +231,8 @@ struct IrMaps<'tcx> {
252231 live_node_map: HirIdMap<LiveNode>,
253232 variable_map: HirIdMap<Variable>,
254233 capture_info_map: HirIdMap<Rc<Vec<CaptureInfo>>>,
255- var_kinds: Vec< VarKind>,
256- lnks: Vec< LiveNodeKind>,
234+ var_kinds: IndexVec<Variable, VarKind>,
235+ lnks: IndexVec<LiveNode, LiveNodeKind>,
257236}
258237
259238impl IrMaps<'tcx> {
@@ -264,14 +243,13 @@ impl IrMaps<'tcx> {
264243 live_node_map: HirIdMap::default(),
265244 variable_map: HirIdMap::default(),
266245 capture_info_map: Default::default(),
267- var_kinds: Vec ::new(),
268- lnks: Vec ::new(),
246+ var_kinds: IndexVec ::new(),
247+ lnks: IndexVec ::new(),
269248 }
270249 }
271250
272251 fn add_live_node(&mut self, lnk: LiveNodeKind) -> LiveNode {
273- let ln = LiveNode(self.lnks.len() as u32);
274- self.lnks.push(lnk);
252+ let ln = self.lnks.push(lnk);
275253
276254 debug!("{:?} is of kind {}", ln, live_node_kind_to_string(lnk, self.tcx));
277255
@@ -286,8 +264,7 @@ impl IrMaps<'tcx> {
286264 }
287265
288266 fn add_variable(&mut self, vk: VarKind) -> Variable {
289- let v = Variable(self.var_kinds.len() as u32);
290- self.var_kinds.push(vk);
267+ let v = self.var_kinds.push(vk);
291268
292269 match vk {
293270 Local(LocalInfo { id: node_id, .. }) | Param(node_id, _) | Upvar(node_id, _) => {
@@ -310,13 +287,13 @@ impl IrMaps<'tcx> {
310287 }
311288
312289 fn variable_name(&self, var: Variable) -> Symbol {
313- match self.var_kinds[var.get() ] {
290+ match self.var_kinds[var] {
314291 Local(LocalInfo { name, .. }) | Param(_, name) | Upvar(_, name) => name,
315292 }
316293 }
317294
318295 fn variable_is_shorthand(&self, var: Variable) -> bool {
319- match self.var_kinds[var.get() ] {
296+ match self.var_kinds[var] {
320297 Local(LocalInfo { is_shorthand, .. }) => is_shorthand,
321298 Param(..) | Upvar(..) => false,
322299 }
@@ -327,7 +304,7 @@ impl IrMaps<'tcx> {
327304 }
328305
329306 fn lnk(&self, ln: LiveNode) -> LiveNodeKind {
330- self.lnks[ln.get() ]
307+ self.lnks[ln]
331308 }
332309}
333310
@@ -556,10 +533,10 @@ struct RWUTable {
556533 unpacked_rwus: Vec<RWU>,
557534}
558535
559- // A constant representing `RWU { reader: invalid_node() ; writer: invalid_node() ; used: false }`.
536+ // A constant representing `RWU { reader: INVALID_NODE ; writer: INVALID_NODE ; used: false }`.
560537const INV_INV_FALSE: u32 = u32::MAX;
561538
562- // A constant representing `RWU { reader: invalid_node() ; writer: invalid_node() ; used: true }`.
539+ // A constant representing `RWU { reader: INVALID_NODE ; writer: INVALID_NODE ; used: true }`.
563540const INV_INV_TRUE: u32 = u32::MAX - 1;
564541
565542impl RWUTable {
@@ -570,24 +547,24 @@ impl RWUTable {
570547 fn get(&self, idx: usize) -> RWU {
571548 let packed_rwu = self.packed_rwus[idx];
572549 match packed_rwu {
573- INV_INV_FALSE => RWU { reader: invalid_node() , writer: invalid_node() , used: false },
574- INV_INV_TRUE => RWU { reader: invalid_node() , writer: invalid_node() , used: true },
550+ INV_INV_FALSE => RWU { reader: INVALID_NODE , writer: INVALID_NODE , used: false },
551+ INV_INV_TRUE => RWU { reader: INVALID_NODE , writer: INVALID_NODE , used: true },
575552 _ => self.unpacked_rwus[packed_rwu as usize],
576553 }
577554 }
578555
579556 fn get_reader(&self, idx: usize) -> LiveNode {
580557 let packed_rwu = self.packed_rwus[idx];
581558 match packed_rwu {
582- INV_INV_FALSE | INV_INV_TRUE => invalid_node() ,
559+ INV_INV_FALSE | INV_INV_TRUE => INVALID_NODE ,
583560 _ => self.unpacked_rwus[packed_rwu as usize].reader,
584561 }
585562 }
586563
587564 fn get_writer(&self, idx: usize) -> LiveNode {
588565 let packed_rwu = self.packed_rwus[idx];
589566 match packed_rwu {
590- INV_INV_FALSE | INV_INV_TRUE => invalid_node() ,
567+ INV_INV_FALSE | INV_INV_TRUE => INVALID_NODE ,
591568 _ => self.unpacked_rwus[packed_rwu as usize].writer,
592569 }
593570 }
@@ -607,7 +584,7 @@ impl RWUTable {
607584 }
608585
609586 fn assign_unpacked(&mut self, idx: usize, rwu: RWU) {
610- if rwu.reader == invalid_node() && rwu.writer == invalid_node() {
587+ if rwu.reader == INVALID_NODE && rwu.writer == INVALID_NODE {
611588 // When we overwrite an indexing entry in `self.packed_rwus` with
612589 // `INV_INV_{TRUE,FALSE}` we don't remove the corresponding entry
613590 // from `self.unpacked_rwus`; it's not worth the effort, and we
@@ -634,7 +611,7 @@ struct Liveness<'a, 'tcx> {
634611 ir: &'a mut IrMaps<'tcx>,
635612 typeck_results: &'a ty::TypeckResults<'tcx>,
636613 param_env: ty::ParamEnv<'tcx>,
637- successors: Vec< LiveNode>,
614+ successors: IndexVec<LiveNode, LiveNode>,
638615 rwu_table: RWUTable,
639616
640617 /// A live node representing a point of execution before closure entry &
@@ -667,7 +644,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
667644 ir,
668645 typeck_results,
669646 param_env,
670- successors: vec![invalid_node(); num_live_nodes] ,
647+ successors: IndexVec::from_elem_n(INVALID_NODE, num_live_nodes) ,
671648 rwu_table: RWUTable::new(num_live_nodes * num_vars),
672649 closure_ln,
673650 exit_ln,
@@ -708,7 +685,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
708685 }
709686
710687 fn idx(&self, ln: LiveNode, var: Variable) -> usize {
711- ln.get () * self.ir.var_kinds.len() + var.get ()
688+ ln.index () * self.ir.var_kinds.len() + var.index ()
712689 }
713690
714691 fn live_on_entry(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
@@ -719,7 +696,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
719696
720697 // Is this variable live on entry to any of its successor nodes?
721698 fn live_on_exit(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
722- let successor = self.successors[ln.get() ];
699+ let successor = self.successors[ln];
723700 self.live_on_entry(successor, var)
724701 }
725702
@@ -735,16 +712,16 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
735712 }
736713
737714 fn assigned_on_exit(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
738- let successor = self.successors[ln.get() ];
715+ let successor = self.successors[ln];
739716 self.assigned_on_entry(successor, var)
740717 }
741718
742719 fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F)
743720 where
744721 F: FnMut(&mut Liveness<'a, 'tcx>, usize, usize),
745722 {
746- let node_base_idx = self.idx(ln, Variable(0 ));
747- let succ_base_idx = self.idx(succ_ln, Variable(0 ));
723+ let node_base_idx = self.idx(ln, Variable::from(0u32 ));
724+ let succ_base_idx = self.idx(succ_ln, Variable::from(0u32 ));
748725 for var_idx in 0..self.ir.var_kinds.len() {
749726 op(self, node_base_idx + var_idx, succ_base_idx + var_idx);
750727 }
@@ -754,11 +731,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
754731 where
755732 F: FnMut(usize) -> bool,
756733 {
757- let node_base_idx = self.idx(ln, Variable(0 ));
734+ let node_base_idx = self.idx(ln, Variable::from(0u32 ));
758735 for var_idx in 0..self.ir.var_kinds.len() {
759736 let idx = node_base_idx + var_idx;
760737 if test(idx) {
761- write!(wr, " {:?}", Variable(var_idx as u32 ))?;
738+ write!(wr, " {:?}", Variable::from (var_idx))?;
762739 }
763740 }
764741 Ok(())
@@ -769,14 +746,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
769746 let mut wr = Vec::new();
770747 {
771748 let wr = &mut wr as &mut dyn Write;
772- write!(wr, "[ln( {:?}) of kind {:?} reads", ln.get() , self.ir.lnk(ln));
749+ write!(wr, "[{:?} of kind {:?} reads", ln, self.ir.lnk(ln));
773750 self.write_vars(wr, ln, |idx| self.rwu_table.get_reader(idx).is_valid());
774751 write!(wr, " writes");
775752 self.write_vars(wr, ln, |idx| self.rwu_table.get_writer(idx).is_valid());
776753 write!(wr, " uses");
777754 self.write_vars(wr, ln, |idx| self.rwu_table.get_used(idx));
778755
779- write!(wr, " precedes {:?}]", self.successors[ln.get() ]);
756+ write!(wr, " precedes {:?}]", self.successors[ln]);
780757 }
781758 String::from_utf8(wr).unwrap()
782759 }
@@ -787,7 +764,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
787764 "^^ liveness computation results for body {} (entry={:?})",
788765 {
789766 for ln_idx in 0..self.ir.lnks.len() {
790- debug!("{:?}", self.ln_str(LiveNode(ln_idx as u32 )));
767+ debug!("{:?}", self.ln_str(LiveNode::from (ln_idx)));
791768 }
792769 hir_id
793770 },
@@ -796,7 +773,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
796773 }
797774
798775 fn init_empty(&mut self, ln: LiveNode, succ_ln: LiveNode) {
799- self.successors[ln.get() ] = succ_ln;
776+ self.successors[ln] = succ_ln;
800777
801778 // It is not necessary to initialize the RWUs here because they are all
802779 // set to INV_INV_FALSE when they are created, and the sets only grow
@@ -805,7 +782,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
805782
806783 fn init_from_succ(&mut self, ln: LiveNode, succ_ln: LiveNode) {
807784 // more efficient version of init_empty() / merge_from_succ()
808- self.successors[ln.get() ] = succ_ln;
785+ self.successors[ln] = succ_ln;
809786
810787 self.indices2(ln, succ_ln, |this, idx, succ_idx| {
811788 this.rwu_table.copy_packed(idx, succ_idx);
@@ -878,7 +855,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
878855 let mut rwu = self.rwu_table.get(idx);
879856
880857 if (acc & ACC_WRITE) != 0 {
881- rwu.reader = invalid_node() ;
858+ rwu.reader = INVALID_NODE ;
882859 rwu.writer = ln;
883860 }
884861
0 commit comments