mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Use external stack in borrowck DFS
Because damnit, it can crash r-a. Why do people make this stupid DFSes anyway (I get it, it's easier until it blows).
This commit is contained in:
parent
5982d9c420
commit
13f853464c
1 changed files with 67 additions and 58 deletions
|
@ -386,10 +386,11 @@ fn ever_initialized_map(
|
|||
fn dfs(
|
||||
db: &dyn HirDatabase,
|
||||
body: &MirBody,
|
||||
b: BasicBlockId,
|
||||
l: LocalId,
|
||||
stack: &mut Vec<BasicBlockId>,
|
||||
result: &mut ArenaMap<BasicBlockId, ArenaMap<LocalId, bool>>,
|
||||
) {
|
||||
while let Some(b) = stack.pop() {
|
||||
let mut is_ever_initialized = result[b][l]; // It must be filled, as we use it as mark for dfs
|
||||
let block = &body.basic_blocks[b];
|
||||
for statement in &block.statements {
|
||||
|
@ -420,7 +421,7 @@ fn ever_initialized_map(
|
|||
let mut process = |target, is_ever_initialized| {
|
||||
if !result[target].contains_idx(l) || !result[target][l] && is_ever_initialized {
|
||||
result[target].insert(l, is_ever_initialized);
|
||||
dfs(db, body, target, l, result);
|
||||
stack.push(target);
|
||||
}
|
||||
};
|
||||
match &terminator.kind {
|
||||
|
@ -441,7 +442,9 @@ fn ever_initialized_map(
|
|||
target.iter().chain(cleanup).for_each(|&it| process(it, is_ever_initialized));
|
||||
}
|
||||
TerminatorKind::Drop { target, unwind, place: _ } => {
|
||||
iter::once(target).chain(unwind).for_each(|&it| process(it, is_ever_initialized));
|
||||
iter::once(target)
|
||||
.chain(unwind)
|
||||
.for_each(|&it| process(it, is_ever_initialized));
|
||||
}
|
||||
TerminatorKind::DropAndReplace { .. }
|
||||
| TerminatorKind::Assert { .. }
|
||||
|
@ -453,15 +456,21 @@ fn ever_initialized_map(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut stack = Vec::new();
|
||||
for &l in &body.param_locals {
|
||||
result[body.start_block].insert(l, true);
|
||||
dfs(db, body, body.start_block, l, &mut result);
|
||||
stack.clear();
|
||||
stack.push(body.start_block);
|
||||
dfs(db, body, l, &mut stack, &mut result);
|
||||
}
|
||||
for l in body.locals.iter().map(|it| it.0) {
|
||||
db.unwind_if_cancelled();
|
||||
if !result[body.start_block].contains_idx(l) {
|
||||
result[body.start_block].insert(l, false);
|
||||
dfs(db, body, body.start_block, l, &mut result);
|
||||
stack.clear();
|
||||
stack.push(body.start_block);
|
||||
dfs(db, body, l, &mut stack, &mut result);
|
||||
}
|
||||
}
|
||||
result
|
||||
|
|
Loading…
Reference in a new issue