Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1730,10 +1730,10 @@ mod size_asserts {

use super::*;
// tidy-alphabetical-start
static_assert_size!(BasicBlockData<'_>, 160);
static_assert_size!(BasicBlockData<'_>, 144);
static_assert_size!(LocalDecl<'_>, 40);
static_assert_size!(SourceScopeData<'_>, 64);
static_assert_size!(Statement<'_>, 56);
static_assert_size!(Statement<'_>, 40);
static_assert_size!(Terminator<'_>, 104);
static_assert_size!(VarDebugInfo<'_>, 88);
// tidy-alphabetical-end
Expand Down
69 changes: 52 additions & 17 deletions compiler/rustc_middle/src/mir/statement.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Functionality for statements, operands, places, and things that appear in them.

use std::ops;

use tracing::{debug, instrument};

use super::interpret::GlobalAlloc;
Expand Down Expand Up @@ -1034,66 +1033,102 @@ impl RawPtrKind {
}
}

// FIXME(panstromek)
// I'd like to use real ThinVec here, but it fails to borrow check,
// probably because ThinVec doesn't have #[may_dangle] on Drop impl?
type ThinVec<T> = Option<Box<Vec<T>>>;

#[derive(Default, Debug, Clone, TyEncodable, TyDecodable, StableHash, TypeFoldable, TypeVisitable)]
pub struct StmtDebugInfos<'tcx>(Vec<StmtDebugInfo<'tcx>>);
pub struct StmtDebugInfos<'tcx>(ThinVec<StmtDebugInfo<'tcx>>);

impl<'tcx> StmtDebugInfos<'tcx> {
pub fn push(&mut self, debuginfo: StmtDebugInfo<'tcx>) {
self.0.push(debuginfo);
self.0.get_or_insert_default().push(debuginfo);
}

pub fn drop_debuginfo(&mut self) {
self.0.clear();
self.0.as_mut().map(|v| v.clear());
}

#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
match &self.0 {
None => true,
Some(v) => Self::is_empty_inner(v)
}
}

#[cold]
#[inline(never)]
fn is_empty_inner(v: &Box<Vec<StmtDebugInfo<'_>>>) -> bool {
v.is_empty()
}

pub fn prepend(&mut self, debuginfos: &mut Self) {
if debuginfos.is_empty() {
return;
};
debuginfos.0.append(self);
debuginfos.append(self);
std::mem::swap(debuginfos, self);
}

pub fn append(&mut self, debuginfos: &mut Self) {
if debuginfos.is_empty() {
return;
};
self.0.append(debuginfos);
self.0.get_or_insert_default().append(debuginfos.0.as_mut().unwrap().as_mut());
}

pub fn extend(&mut self, debuginfos: &Self) {
if debuginfos.is_empty() {
return;
};
self.0.extend_from_slice(debuginfos);
self.0.get_or_insert_default().extend_from_slice(debuginfos.as_slice());
}

#[inline]
pub fn as_slice(&self) -> &[StmtDebugInfo<'tcx>] {
match &self.0 {
None => &[],
Some(items) => items.as_slice(),
}
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut [StmtDebugInfo<'tcx>] {
match &mut self.0 {
None => &mut [],
Some(items) => items.as_mut_slice()
}
}

pub fn retain_locals(&mut self, locals: &DenseBitSet<Local>) {
self.retain(|debuginfo| match debuginfo {
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => {
locals.contains(*local)
match &mut self.0 {
None => (),
Some(items) => {
items.retain(|debuginfo| match debuginfo {
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => {
locals.contains(*local)
}
})
}
});
}
}
}

impl<'tcx> ops::Deref for StmtDebugInfos<'tcx> {
type Target = Vec<StmtDebugInfo<'tcx>>;
type Target = [StmtDebugInfo<'tcx>];

#[inline]
fn deref(&self) -> &Vec<StmtDebugInfo<'tcx>> {
&self.0
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}

impl<'tcx> ops::DerefMut for StmtDebugInfos<'tcx> {
#[inline]
fn deref_mut(&mut self) -> &mut Vec<StmtDebugInfo<'tcx>> {
&mut self.0
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_slice()
}
}

Expand Down
Loading