mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Remove some allocations in borrowck
This commit is contained in:
parent
c09f175d59
commit
70e21dc30b
1 changed files with 40 additions and 37 deletions
|
@ -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,
|
});
|
||||||
})
|
})?;
|
||||||
})
|
Ok(res.into())
|
||||||
.collect::<Result<Vec<_>, MirLowerError>>()?;
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue