Skip to content

Commit 93d1b3e

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 e4c41b0 commit 93d1b3e

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
@@ -287,9 +287,8 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
287287
type T = stable_mir::mir::Body;
288288

289289
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
290-
stable_mir::mir::Body {
291-
blocks: self
292-
.basic_blocks
290+
stable_mir::mir::Body::new(
291+
self.basic_blocks
293292
.iter()
294293
.map(|block| stable_mir::mir::BasicBlock {
295294
terminator: block.terminator().stable(tables),
@@ -300,16 +299,15 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
300299
.collect(),
301300
})
302301
.collect(),
303-
locals: self
304-
.local_decls
302+
self.local_decls
305303
.iter()
306304
.map(|decl| stable_mir::mir::LocalDecl {
307305
ty: decl.ty.stable(tables),
308306
span: decl.source_info.span.stable(tables),
309307
})
310308
.collect(),
311-
arg_count: self.arg_count,
312-
}
309+
self.arg_count,
310+
)
313311
}
314312
}
315313

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)