Remove some allocations in borrowck

This commit is contained in:
Lukas Wirth 2023-09-01 19:17:57 +02:00
parent c09f175d59
commit 70e21dc30b

View file

@ -42,30 +42,27 @@ pub struct BorrowckResult {
fn all_mir_bodies( fn all_mir_bodies(
db: &dyn HirDatabase, db: &dyn HirDatabase,
def: DefWithBodyId, def: DefWithBodyId,
) -> Box<dyn Iterator<Item = Result<Arc<MirBody>, MirLowerError>> + '_> { mut cb: impl FnMut(Arc<MirBody>),
) -> Result<(), MirLowerError> {
fn for_closure( fn for_closure(
db: &dyn HirDatabase, db: &dyn HirDatabase,
c: ClosureId, c: ClosureId,
) -> Box<dyn Iterator<Item = Result<Arc<MirBody>, MirLowerError>> + '_> { cb: &mut impl FnMut(Arc<MirBody>),
) -> Result<(), MirLowerError> {
match db.mir_body_for_closure(c) { match db.mir_body_for_closure(c) {
Ok(body) => { Ok(body) => {
let closures = body.closures.clone(); cb(body.clone());
Box::new( body.closures.iter().map(|&it| for_closure(db, it, cb)).collect()
iter::once(Ok(body))
.chain(closures.into_iter().flat_map(|it| for_closure(db, it))),
)
} }
Err(e) => Box::new(iter::once(Err(e))), Err(e) => Err(e),
} }
} }
match db.mir_body(def) { match db.mir_body(def) {
Ok(body) => { Ok(body) => {
let closures = body.closures.clone(); cb(body.clone());
Box::new( body.closures.iter().map(|&it| for_closure(db, it, &mut cb)).collect()
iter::once(Ok(body)).chain(closures.into_iter().flat_map(|it| for_closure(db, it))),
)
} }
Err(e) => Box::new(iter::once(Err(e))), Err(e) => Err(e),
} }
} }
@ -74,17 +71,15 @@ pub fn borrowck_query(
def: DefWithBodyId, def: DefWithBodyId,
) -> Result<Arc<[BorrowckResult]>, MirLowerError> { ) -> Result<Arc<[BorrowckResult]>, MirLowerError> {
let _p = profile::span("borrowck_query"); let _p = profile::span("borrowck_query");
let r = all_mir_bodies(db, def) let mut res = vec![];
.map(|body| { all_mir_bodies(db, def, |body| {
let body = body?; res.push(BorrowckResult {
Ok(BorrowckResult {
mutability_of_locals: mutability_of_locals(db, &body), mutability_of_locals: mutability_of_locals(db, &body),
moved_out_of_ref: moved_out_of_ref(db, &body), moved_out_of_ref: moved_out_of_ref(db, &body),
mir_body: body, mir_body: body,
}) });
}) })?;
.collect::<Result<Vec<_>, MirLowerError>>()?; Ok(res.into())
Ok(r.into())
} }
fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef> { fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef> {
@ -277,21 +272,35 @@ fn ever_initialized_map(
); );
return; return;
}; };
let targets = match &terminator.kind { let mut process = |target, is_ever_initialized| {
TerminatorKind::Goto { target } => vec![*target], if !result[target].contains_idx(l) || !result[target][l] && is_ever_initialized {
TerminatorKind::SwitchInt { targets, .. } => targets.all_targets().to_vec(), result[target].insert(l, is_ever_initialized);
dfs(db, body, target, l, result);
}
};
match &terminator.kind {
TerminatorKind::Goto { target } => process(*target, is_ever_initialized),
TerminatorKind::SwitchInt { targets, .. } => {
targets.all_targets().iter().for_each(|&it| process(it, is_ever_initialized));
}
TerminatorKind::UnwindResume TerminatorKind::UnwindResume
| TerminatorKind::Abort | TerminatorKind::Abort
| TerminatorKind::Return | TerminatorKind::Return
| TerminatorKind::Unreachable => vec![], | TerminatorKind::Unreachable => (),
TerminatorKind::Call { target, cleanup, destination, .. } => { TerminatorKind::Call { target, cleanup, destination, .. } => {
if destination.projection.len() == 0 && destination.local == l { if destination.projection.len() == 0 && destination.local == l {
is_ever_initialized = true; is_ever_initialized = true;
} }
target.into_iter().chain(cleanup.into_iter()).copied().collect() target
.into_iter()
.chain(cleanup.into_iter())
.for_each(|&it| process(it, is_ever_initialized));
} }
TerminatorKind::Drop { target, unwind, place: _ } => { TerminatorKind::Drop { target, unwind, place: _ } => {
Some(target).into_iter().chain(unwind.into_iter()).copied().collect() iter::once(target)
.into_iter()
.chain(unwind.into_iter())
.for_each(|&it| process(it, is_ever_initialized));
} }
TerminatorKind::DropAndReplace { .. } TerminatorKind::DropAndReplace { .. }
| TerminatorKind::Assert { .. } | TerminatorKind::Assert { .. }
@ -300,13 +309,7 @@ fn ever_initialized_map(
| TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseEdge { .. }
| TerminatorKind::FalseUnwind { .. } => { | TerminatorKind::FalseUnwind { .. } => {
never!("We don't emit these MIR terminators yet"); never!("We don't emit these MIR terminators yet");
vec![] ()
}
};
for target in targets {
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);
} }
} }
} }