Replace arg_count in public API with return/arg getters
This commit hides the arg_count field in Body and instead exposes more stable and user-friendly methods to get the return and argument locals. As a result, Body instances must now be constructed using the `new` function.
This commit is contained in:
parent
e4c41b07f0
commit
93d1b3e92a
@ -287,9 +287,8 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
|
|||||||
type T = stable_mir::mir::Body;
|
type T = stable_mir::mir::Body;
|
||||||
|
|
||||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||||
stable_mir::mir::Body {
|
stable_mir::mir::Body::new(
|
||||||
blocks: self
|
self.basic_blocks
|
||||||
.basic_blocks
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|block| stable_mir::mir::BasicBlock {
|
.map(|block| stable_mir::mir::BasicBlock {
|
||||||
terminator: block.terminator().stable(tables),
|
terminator: block.terminator().stable(tables),
|
||||||
@ -300,16 +299,15 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
|
|||||||
.collect(),
|
.collect(),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
locals: self
|
self.local_decls
|
||||||
.local_decls
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|decl| stable_mir::mir::LocalDecl {
|
.map(|decl| stable_mir::mir::LocalDecl {
|
||||||
ty: decl.ty.stable(tables),
|
ty: decl.ty.stable(tables),
|
||||||
span: decl.source_info.span.stable(tables),
|
span: decl.source_info.span.stable(tables),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
arg_count: self.arg_count,
|
self.arg_count,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,40 @@ pub struct Body {
|
|||||||
pub blocks: Vec<BasicBlock>,
|
pub blocks: Vec<BasicBlock>,
|
||||||
|
|
||||||
/// Declarations of locals.
|
/// Declarations of locals.
|
||||||
///
|
//
|
||||||
/// The first local is the return value pointer, followed by `arg_count`
|
// The first local is the return value pointer, followed by `arg_count`
|
||||||
/// locals for the function arguments, followed by any user-declared
|
// locals for the function arguments, followed by any user-declared
|
||||||
/// variables and temporaries.
|
// variables and temporaries.
|
||||||
pub locals: LocalDecls,
|
pub locals: LocalDecls,
|
||||||
|
|
||||||
/// The number of arguments this function takes.
|
// The number of arguments this function takes.
|
||||||
pub arg_count: usize,
|
arg_count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Body {
|
||||||
|
/// Constructs a `Body`.
|
||||||
|
///
|
||||||
|
/// A constructor is required to build a `Body` from outside the crate
|
||||||
|
/// because the `arg_count` field is private.
|
||||||
|
pub fn new(blocks: Vec<BasicBlock>, locals: LocalDecls, arg_count: usize) -> Self {
|
||||||
|
// If locals doesn't contain enough entries, it can lead to panics in
|
||||||
|
// `ret_local` and `arg_locals`.
|
||||||
|
assert!(
|
||||||
|
locals.len() >= arg_count + 1,
|
||||||
|
"A Body must contain at least a local for the return value and each of the function's arguments"
|
||||||
|
);
|
||||||
|
Self { blocks, locals, arg_count }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the function's return local.
|
||||||
|
pub fn ret_local(&self) -> &LocalDecl {
|
||||||
|
&self.locals[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the locals in `self` that correspond to the function's arguments.
|
||||||
|
pub fn arg_locals(&self) -> &[LocalDecl] {
|
||||||
|
&self.locals[1..self.arg_count + 1]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type LocalDecls = Vec<LocalDecl>;
|
type LocalDecls = Vec<LocalDecl>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user