MIR: Enum value panics when payload is a `repr(transparent)` struct with a type error
RyanGlScott opened this issue · comments
Given this Rust code:
// test.rs
#[repr(transparent)]
pub struct S(u32);
pub enum E {
E1(S),
E2,
}
pub fn f(e: E) -> E {
e
}
I tried to write this SAW spec:
// test.saw
enable_experimental;
m <- mir_load_module "test.linked-mir.json";
let s_adt = mir_find_adt m "test::S" [];
let e_adt = mir_find_adt m "test::E" [];
let f_spec = do {
x <- mir_fresh_var "f::x" mir_u64;
let s = mir_struct_value s_adt [mir_term x];
let e = mir_enum_value e_adt "E1" [s];
mir_execute_func [e];
mir_return e;
};
mir_verify m "test::f" [] false f_spec z3;
This spec contains an error: the payload of S
should be a u32
, but I have supplied a mir_u64
, not a mir_u32
, in the SAW spec. Surprisingly, SAW doesn't catch this mistake, and it instead produces a rather ugly panic:
$ saw-rustc test.rs
$ ~/Software/saw-1.1/bin/saw test.saw
[20:30:18.899] Loading file "/home/ryanscott/Documents/Hacking/SAW/test.saw"
[20:30:18.903] Verifying test/c8ab1cdc::f[0] ...
[20:30:18.903] You have encountered a bug in SAW's implementation.
*** Please create an issue at https://github.com/GaloisInc/saw-script/issues
%< ---------------------------------------------------
Revision: 5c16c876f35f0abdf0b412a5387e220b15b7f990
Branch: release-1.1 (uncommited files present)
Location: resolveSetupVal
Message: Enum field shape mismatch
Expected: [ReqField (TransparentShape (TyAdt test/c8ab1cdc::S[0]::_adtb7803c2264daf0ec[0] test/c8ab1cdc::S[0] (Substs [])) (PrimShape (TyUint B32) (BaseBVRepr 32)))]
Actual: [ReqField (TransparentShape (TyAdt test/c8ab1cdc::S[0]::_adtb7803c2264daf0ec[0] test/c8ab1cdc::S[0] (Substs [])) (PrimShape (TyUint B64) (BaseBVRepr 64)))]
CallStack (from HasCallStack):
panic, called at src/SAWScript/Panic.hs:27:9 in saw-script-1.1-inplace:SAWScript.Panic
panic, called at src/SAWScript/Crucible/MIR/ResolveSetupValue.hs:458:21 in saw-script-1.1-inplace:SAWScript.Crucible.MIR.ResolveSetupValue
%< ---------------------------------------------------
The use of #[repr(transparent)]
is important. If I comment out that line, SAW instead produces a much nicer type error:
$ saw-rustc test.rs
$ ~/Software/saw-1.1/bin/saw test.saw
[20:35:04.712] Loading file "/home/ryanscott/Documents/Hacking/SAW/test.saw"
[20:35:04.715] Verifying test/fb14f06a::f[0] ...
[20:35:04.715] Stack trace:
"mir_verify" (/home/ryanscott/Documents/Hacking/SAW/test.saw:19:1-19:11)
Struct field type mismatch
Field name: test/fb14f06a::S[0]::0[0]
Expected type: u32
Given type: u64