Skip to content

Commit 0e726d0

Browse files
committed
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.
1 parent aae084d commit 0e726d0

File tree

2 files changed

+37
-13
lines changed

2 files changed

+37
-13
lines changed

compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,8 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
281281
type T = stable_mir::mir::Body;
282282

283283
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
284-
stable_mir::mir::Body {
285-
blocks: self
286-
.basic_blocks
284+
stable_mir::mir::Body::new(
285+
self.basic_blocks
287286
.iter()
288287
.map(|block| stable_mir::mir::BasicBlock {
289288
terminator: block.terminator().stable(tables),
@@ -294,16 +293,15 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
294293
.collect(),
295294
})
296295
.collect(),
297-
locals: self
298-
.local_decls
296+
self.local_decls
299297
.iter()
300298
.map(|decl| stable_mir::mir::LocalDecl {
301299
ty: tables.intern_ty(decl.ty),
302300
span: decl.source_info.span.stable(tables),
303301
})
304302
.collect(),
305-
arg_count: self.arg_count,
306-
}
303+
self.arg_count,
304+
)
307305
}
308306
}
309307

compiler/stable_mir/src/mir/body.rs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,40 @@ pub struct Body {
88
pub blocks: Vec<BasicBlock>,
99

1010
/// Declarations of locals.
11-
///
12-
/// The first local is the return value pointer, followed by `arg_count`
13-
/// locals for the function arguments, followed by any user-declared
14-
/// variables and temporaries.
11+
//
12+
// The first local is the return value pointer, followed by `arg_count`
13+
// locals for the function arguments, followed by any user-declared
14+
// variables and temporaries.
1515
pub locals: LocalDecls,
1616

17-
/// The number of arguments this function takes.
18-
pub arg_count: usize,
17+
// The number of arguments this function takes.
18+
arg_count: usize,
19+
}
20+
21+
impl Body {
22+
/// Constructs a `Body`.
23+
///
24+
/// A constructor is required to build a `Body` from outside the crate
25+
/// because the `arg_count` field is private.
26+
pub fn new(blocks: Vec<BasicBlock>, locals: LocalDecls, arg_count: usize) -> Self {
27+
// If locals doesn't contain enough entries, it can lead to panics in
28+
// `ret_local` and `arg_locals`.
29+
assert!(
30+
locals.len() >= arg_count + 1,
31+
"A Body must contain at least a local for the return value and each of the function's arguments"
32+
);
33+
Self { blocks, locals, arg_count }
34+
}
35+
36+
/// Gets the function's return local.
37+
pub fn ret_local(&self) -> &LocalDecl {
38+
&self.locals[0]
39+
}
40+
41+
/// Gets the locals in `self` that correspond to the function's arguments.
42+
pub fn arg_locals(&self) -> &[LocalDecl] {
43+
&self.locals[1..self.arg_count + 1]
44+
}
1945
}
2046

2147
type LocalDecls = Vec<LocalDecl>;

0 commit comments

Comments
 (0)