1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use std::collections::HashMap;
use crate::blocks::FlatBlocks;
use crate::borrow_check::analysis::{Analyzer, BackAnalysis, StatementLocation};
use crate::utils::{Rebuilder, RebuilderEx};
use crate::{BlockId, FlatBlock, FlatLowered, MatchInfo, VariableId};
pub fn topological_sort(lowered: &mut FlatLowered) {
if !lowered.blocks.is_empty() {
let ctx = TopSortContext { old_block_rev_order: Default::default() };
let mut analysis =
BackAnalysis { lowered: &*lowered, cache: Default::default(), analyzer: ctx };
analysis.get_root_info();
let mut ctx = analysis.analyzer;
let mut new_blocks = FlatBlocks::default();
let old_block_rev_order = std::mem::take(&mut ctx.old_block_rev_order);
let n_visited_blocks = old_block_rev_order.len();
let mut rebuilder = RebuildContext {
block_remapping: HashMap::from_iter(
old_block_rev_order
.iter()
.enumerate()
.map(|(idx, block_id)| (*block_id, BlockId(n_visited_blocks - idx - 1))),
),
};
for block_id in old_block_rev_order.into_iter().rev() {
new_blocks.alloc(rebuilder.rebuild_block(&lowered.blocks[block_id]));
}
lowered.blocks = new_blocks;
}
}
pub struct TopSortContext {
old_block_rev_order: Vec<BlockId>,
}
impl Analyzer for TopSortContext {
type Info = ();
fn visit_block_start(&mut self, _info: &mut Self::Info, block_id: BlockId, _block: &FlatBlock) {
self.old_block_rev_order.push(block_id);
}
fn merge_match(
&mut self,
_statement_location: StatementLocation,
_match_info: &MatchInfo,
_arms: &[(BlockId, Self::Info)],
) -> Self::Info {
}
fn info_from_return(
&mut self,
_statement_location: StatementLocation,
_vars: &[VariableId],
) -> Self::Info {
}
fn info_from_panic(
&mut self,
_statement_location: StatementLocation,
_data: &VariableId,
) -> Self::Info {
}
}
pub struct RebuildContext {
block_remapping: HashMap<BlockId, BlockId>,
}
impl Rebuilder for RebuildContext {
fn map_var_id(&mut self, var: VariableId) -> VariableId {
var
}
fn map_block_id(&mut self, block: BlockId) -> BlockId {
self.block_remapping[&block]
}
}