Skip to content

Commit daf0e86

Browse files
authored
Fix signed discriminant in pure code (#1502)
1 parent 45405dc commit daf0e86

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

Diff for: prusti-tests/tests/verify/fail/issues/issue-1501.rs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use prusti_contracts::prusti_assert;
2+
3+
// An enum with *signed* and *explicit* discriminants
4+
enum Ordering {
5+
Less = -10,
6+
Equal = 0,
7+
Greater = 100,
8+
}
9+
10+
fn good() {
11+
assert!(matches!(Ordering::Less, Ordering::Less));
12+
assert!(matches!(Ordering::Equal, Ordering::Equal));
13+
assert!(matches!(Ordering::Greater, Ordering::Greater));
14+
prusti_assert!(matches!(Ordering::Less, Ordering::Less));
15+
prusti_assert!(matches!(Ordering::Equal, Ordering::Equal));
16+
prusti_assert!(matches!(Ordering::Greater, Ordering::Greater));
17+
18+
// Smoke test
19+
assert!(false); //~ ERROR: asserted expression might not hold
20+
}
21+
22+
fn bad_1() {
23+
assert!(!matches!(Ordering::Less, Ordering::Less)); //~ ERROR: asserted expression might not hold
24+
}
25+
26+
fn bad_2() {
27+
assert!(!matches!(Ordering::Equal, Ordering::Equal)); //~ ERROR: asserted expression might not hold
28+
}
29+
30+
fn bad_3() {
31+
assert!(!matches!(Ordering::Greater, Ordering::Greater)); //~ ERROR: asserted expression might not hold
32+
}
33+
34+
fn bad_4() {
35+
prusti_assert!(!matches!(Ordering::Less, Ordering::Less)); //~ ERROR: asserted expression might not hold
36+
}
37+
38+
fn bad_5() {
39+
prusti_assert!(!matches!(Ordering::Equal, Ordering::Equal)); //~ ERROR: asserted expression might not hold
40+
}
41+
42+
fn bad_6() {
43+
prusti_assert!(!matches!(Ordering::Greater, Ordering::Greater)); //~ ERROR: asserted expression might not hold
44+
}
45+
46+
fn main() {}

Diff for: prusti-viper/src/encoder/mir/pure/interpreter/interpreter_poly.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
},
1818
sequences::MirSequencesEncoderInterface,
1919
specifications::SpecificationsInterface,
20-
types::MirTypeEncoderInterface,
20+
types::{compute_discriminant_values, MirTypeEncoderInterface},
2121
},
2222
mir_encoder::{
2323
MirEncoder, PlaceEncoder, PlaceEncoding, PRECONDITION_LABEL, WAND_LHS_LABEL,
@@ -936,9 +936,11 @@ impl<'p, 'v: 'p, 'tcx: 'v> BackwardMirInterpreter<'tcx>
936936
let mut encoded_lhs_variant = encoded_lhs.clone();
937937
if num_variants > 1 {
938938
let discr_field = self.encoder.encode_discriminant_field();
939+
let discr_values = compute_discriminant_values(adt_def, tcx);
940+
let discr_value = discr_values[variant_index.as_usize()];
939941
state.substitute_value(
940942
&encoded_lhs.clone().field(discr_field),
941-
variant_index.index().into(),
943+
discr_value.into(),
942944
);
943945
encoded_lhs_variant =
944946
encoded_lhs_variant.variant(variant_def.ident(tcx).as_str());

Diff for: prusti-viper/src/encoder/mir/types/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod interface;
77
mod lifetimes;
88

99
pub(crate) use self::{
10-
helpers::compute_discriminant_bounds,
10+
helpers::{compute_discriminant_bounds, compute_discriminant_values},
1111
interface::{MirTypeEncoderInterface, MirTypeEncoderState},
1212
};
1313

0 commit comments

Comments
 (0)