Skip to content

Commit ab39455

Browse files
authored
[aeneas] Preserve variable names (#3560)
In #3514, the LLBC does not keep the variable names from the Rust source. This PR extracts the names of variables from MIR and carries it over to the LLBC. For instance, for `tests/expected/llbc/basic1` which has the following Rust: ```rust fn select(s: bool, x: i32, y: i32) -> i32 { if s { x } else { y } } ``` without this PR, running Aeneas on the output LLBC produces: ```lean def select (b : Bool) (i : I32) (i1 : I32) : Result I32 := if b then Result.ok i else Result.ok i1 ``` but with this PR, it produces: ```lean def select (s : Bool) (x : I32) (y : I32) : Result I32 := if s then Result.ok x else Result.ok y ``` This should not be merged before #3514, so keeping it as a draft for the time being. The actual diff on top of #3514 can be viewed here: zhassan-aws/kani@llbc4...zhassan-aws:kani:llbc-names By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.
1 parent 0e03c1c commit ab39455

File tree

3 files changed

+29
-17
lines changed

3 files changed

+29
-17
lines changed

kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use charon_lib::ast::Rvalue as CharonRvalue;
1616
use charon_lib::ast::Span as CharonSpan;
1717
use charon_lib::ast::meta::{AttrInfo, Loc, RawSpan};
1818
use charon_lib::ast::types::Ty as CharonTy;
19-
use charon_lib::ast::{AbortKind, Body as CharonBody, Var, VarId, make_locals_generator};
19+
use charon_lib::ast::{AbortKind, Body as CharonBody, Var, VarId};
2020
use charon_lib::ast::{
2121
AnyTransId, Assert, BodyId, BuiltinTy, Disambiguator, FileName, FunDecl, FunSig, GenericArgs,
2222
GenericParams, IntegerTy, ItemKind, ItemMeta, ItemOpacity, Literal, LiteralTy, Name, Opaque,
@@ -39,14 +39,16 @@ use charon_lib::ullbc_ast::{
3939
Terminator as CharonTerminator,
4040
};
4141
use charon_lib::{error_assert, error_or_panic};
42+
use rustc_data_structures::fx::FxHashMap;
4243
use rustc_errors::MultiSpan;
4344
use rustc_middle::ty::TyCtxt;
4445
use rustc_smir::rustc_internal;
4546
use rustc_span::def_id::DefId as InternalDefId;
4647
use stable_mir::abi::PassMode;
48+
use stable_mir::mir::VarDebugInfoContents;
4749
use stable_mir::mir::mono::Instance;
4850
use stable_mir::mir::{
49-
BasicBlock, BinOp, Body, BorrowKind, CastKind, ConstOperand, Mutability, Operand, Place,
51+
BasicBlock, BinOp, Body, BorrowKind, CastKind, ConstOperand, Local, Mutability, Operand, Place,
5052
ProjectionElem, Rvalue, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind,
5153
};
5254
use stable_mir::ty::{
@@ -64,6 +66,7 @@ pub struct Context<'a, 'tcx> {
6466
instance: Instance,
6567
translated: &'a mut TranslatedCrate,
6668
errors: &'a mut ErrorCtx<'tcx>,
69+
local_names: FxHashMap<Local, String>,
6770
}
6871

6972
impl<'a, 'tcx> Context<'a, 'tcx> {
@@ -75,7 +78,17 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
7578
translated: &'a mut TranslatedCrate,
7679
errors: &'a mut ErrorCtx<'tcx>,
7780
) -> Self {
78-
Self { tcx, instance, translated, errors }
81+
let mut local_names = FxHashMap::default();
82+
// populate names of locals
83+
for info in instance.body().unwrap().var_debug_info {
84+
if let VarDebugInfoContents::Place(p) = info.value {
85+
if p.projection.is_empty() {
86+
local_names.insert(p.local, info.name);
87+
}
88+
}
89+
}
90+
91+
Self { tcx, instance, translated, errors, local_names }
7992
}
8093

8194
fn tcx(&self) -> TyCtxt<'tcx> {
@@ -466,12 +479,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
466479
// - the input arguments
467480
// - the remaining locals, used for the intermediate computations
468481
let mut locals = Vector::new();
469-
{
470-
let mut add_variable = make_locals_generator(&mut locals);
471-
mir_body.local_decls().for_each(|(_, local)| {
472-
add_variable(self.translate_ty(local.ty));
473-
});
474-
}
482+
mir_body.local_decls().for_each(|(local, local_decl)| {
483+
let ty = self.translate_ty(local_decl.ty);
484+
let name = self.local_names.get(&local);
485+
locals.push_with(|index| Var { index, name: name.cloned(), ty });
486+
});
475487
locals
476488
}
477489

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
fn test::is_zero(@1: i32) -> bool\
22
{\
33
let @0: bool; // return\
4-
let @1: i32; // arg #1\
4+
let i@1: i32; // arg #1\
55

6-
@0 := copy (@1) == const (0 : i32)\
6+
@0 := copy (i@1) == const (0 : i32)\
77
return\
88
}
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
fn test::select(@1: bool, @2: i32, @3: i32) -> i32
22
{
33
let @0: i32; // return
4-
let @1: bool; // arg #1
5-
let @2: i32; // arg #2
6-
let @3: i32; // arg #3
4+
let s@1: bool; // arg #1
5+
let x@2: i32; // arg #2
6+
let y@3: i32; // arg #3
77

8-
if copy (@1) {
9-
@0 := copy (@2)
8+
if copy (s@1) {
9+
@0 := copy (x@2)
1010
}
1111
else {
12-
@0 := copy (@3)
12+
@0 := copy (y@3)
1313
}
1414
return
1515
}

0 commit comments

Comments
 (0)