Skip to content

Commit b9bd7a8

Browse files
authored
Upgrade toolchain to nightly-2024-04-15 (#3144)
Related changes: - rust-lang/rust#118310: Add `Ord::cmp` for primitives as a `BinOp` in MIR - rust-lang/rust#120131: Add support to `Pat` pattern type - rust-lang/rust#122935: Rename CastKind::PointerWithExposedProvenance - rust-lang/rust#123097: Adapt to changes to local_def_path_hash_to_def_id Resolves #3130, #3142
1 parent e906cde commit b9bd7a8

File tree

8 files changed

+110
-40
lines changed

8 files changed

+110
-40
lines changed

cprover_bindings/src/goto_program/expr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ impl Expr {
389389
source.is_integer() || source.is_pointer() || source.is_bool()
390390
} else if target.is_integer() {
391391
source.is_c_bool()
392+
|| source.is_bool()
392393
|| source.is_integer()
393394
|| source.is_floating_point()
394395
|| source.is_pointer()

kani-compiler/src/codegen_cprover_gotoc/codegen/place.rs

+5
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,11 @@ impl<'tcx> GotocCtx<'tcx> {
292292
"element of {parent_ty:?} is not accessed via field projection"
293293
)
294294
}
295+
TyKind::RigidTy(RigidTy::Pat(..)) => {
296+
// See https://github.com/rust-lang/types-team/issues/126
297+
// for what is currently supported.
298+
unreachable!("projection inside a pattern is not supported, only transmute")
299+
}
295300
}
296301
}
297302
// if we fall here, then we are handling an enum

kani-compiler/src/codegen_cprover_gotoc/codegen/rvalue.rs

+86-36
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use num::bigint::BigInt;
2020
use rustc_middle::ty::{TyCtxt, VtblEntry};
2121
use rustc_smir::rustc_internal;
2222
use rustc_target::abi::{FieldsShape, TagEncoding, Variants};
23+
use stable_mir::abi::{Primitive, Scalar, ValueAbi};
2324
use stable_mir::mir::mono::Instance;
2425
use stable_mir::mir::{
2526
AggregateKind, BinOp, CastKind, NullOp, Operand, Place, PointerCoercion, Rvalue, UnOp,
@@ -32,9 +33,11 @@ impl<'tcx> GotocCtx<'tcx> {
3233
fn codegen_comparison(&mut self, op: &BinOp, e1: &Operand, e2: &Operand) -> Expr {
3334
let left_op = self.codegen_operand_stable(e1);
3435
let right_op = self.codegen_operand_stable(e2);
35-
let is_float =
36-
matches!(self.operand_ty_stable(e1).kind(), TyKind::RigidTy(RigidTy::Float(..)));
37-
comparison_expr(op, left_op, right_op, is_float)
36+
let left_ty = self.operand_ty_stable(e1);
37+
let right_ty = self.operand_ty_stable(e2);
38+
let res_ty = op.ty(left_ty, right_ty);
39+
let is_float = matches!(left_ty.kind(), TyKind::RigidTy(RigidTy::Float(..)));
40+
self.comparison_expr(op, left_op, right_op, res_ty, is_float)
3841
}
3942

4043
/// This function codegen comparison for fat pointers.
@@ -72,16 +75,18 @@ impl<'tcx> GotocCtx<'tcx> {
7275
Expr::statement_expression(body, ret_type).with_location(loc)
7376
} else {
7477
// Compare data pointer.
78+
let res_ty = op.ty(left_typ, right_typ);
7579
let left_ptr = self.codegen_operand_stable(left_op);
7680
let left_data = left_ptr.clone().member("data", &self.symbol_table);
7781
let right_ptr = self.codegen_operand_stable(right_op);
7882
let right_data = right_ptr.clone().member("data", &self.symbol_table);
79-
let data_cmp = comparison_expr(op, left_data.clone(), right_data.clone(), false);
83+
let data_cmp =
84+
self.comparison_expr(op, left_data.clone(), right_data.clone(), res_ty, false);
8085

8186
// Compare the slice metadata (this logic could be adapted to compare vtable if needed).
8287
let left_len = left_ptr.member("len", &self.symbol_table);
8388
let right_len = right_ptr.member("len", &self.symbol_table);
84-
let metadata_cmp = comparison_expr(op, left_len, right_len, false);
89+
let metadata_cmp = self.comparison_expr(op, left_len, right_len, res_ty, false);
8590

8691
// Join the results.
8792
// https://github.com/rust-lang/rust/pull/29781
@@ -93,10 +98,20 @@ impl<'tcx> GotocCtx<'tcx> {
9398
// If data is different, only compare data.
9499
// If data is equal, apply operator to metadata.
95100
BinOp::Lt | BinOp::Le | BinOp::Ge | BinOp::Gt => {
96-
let data_eq =
97-
comparison_expr(&BinOp::Eq, left_data.clone(), right_data.clone(), false);
98-
let data_strict_comp =
99-
comparison_expr(&get_strict_operator(op), left_data, right_data, false);
101+
let data_eq = self.comparison_expr(
102+
&BinOp::Eq,
103+
left_data.clone(),
104+
right_data.clone(),
105+
res_ty,
106+
false,
107+
);
108+
let data_strict_comp = self.comparison_expr(
109+
&get_strict_operator(op),
110+
left_data,
111+
right_data,
112+
res_ty,
113+
false,
114+
);
100115
data_strict_comp.or(data_eq.and(metadata_cmp))
101116
}
102117
_ => unreachable!("Unexpected operator {:?}", op),
@@ -376,7 +391,7 @@ impl<'tcx> GotocCtx<'tcx> {
376391
BinOp::BitXor | BinOp::BitAnd | BinOp::BitOr => {
377392
self.codegen_unchecked_scalar_binop(op, e1, e2)
378393
}
379-
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
394+
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt | BinOp::Cmp => {
380395
let op_ty = self.operand_ty_stable(e1);
381396
if self.is_fat_pointer_stable(op_ty) {
382397
self.codegen_comparison_fat_ptr(op, e1, e2, loc)
@@ -681,7 +696,7 @@ impl<'tcx> GotocCtx<'tcx> {
681696
| CastKind::FnPtrToPtr
682697
| CastKind::PtrToPtr
683698
| CastKind::PointerExposeAddress
684-
| CastKind::PointerFromExposedAddress,
699+
| CastKind::PointerWithExposedProvenance,
685700
e,
686701
t,
687702
) => self.codegen_misc_cast(e, *t),
@@ -1260,7 +1275,7 @@ impl<'tcx> GotocCtx<'tcx> {
12601275
fn check_vtable_size(&mut self, operand_type: Ty, vt_size: Expr) -> Stmt {
12611276
// Check against the size we get from the layout from the what we
12621277
// get constructing a value of that type
1263-
let ty: Type = self.codegen_ty_stable(operand_type);
1278+
let ty = self.codegen_ty_stable(operand_type);
12641279
let codegen_size = ty.sizeof(&self.symbol_table);
12651280
assert_eq!(vt_size.int_constant_value().unwrap(), BigInt::from(codegen_size));
12661281

@@ -1423,6 +1438,65 @@ impl<'tcx> GotocCtx<'tcx> {
14231438
}
14241439
}
14251440
}
1441+
1442+
fn comparison_expr(
1443+
&mut self,
1444+
op: &BinOp,
1445+
left: Expr,
1446+
right: Expr,
1447+
res_ty: Ty,
1448+
is_float: bool,
1449+
) -> Expr {
1450+
match op {
1451+
BinOp::Eq => {
1452+
if is_float {
1453+
left.feq(right)
1454+
} else {
1455+
left.eq(right)
1456+
}
1457+
}
1458+
BinOp::Lt => left.lt(right),
1459+
BinOp::Le => left.le(right),
1460+
BinOp::Ne => {
1461+
if is_float {
1462+
left.fneq(right)
1463+
} else {
1464+
left.neq(right)
1465+
}
1466+
}
1467+
BinOp::Ge => left.ge(right),
1468+
BinOp::Gt => left.gt(right),
1469+
BinOp::Cmp => {
1470+
// Implement https://doc.rust-lang.org/core/cmp/trait.Ord.html as done in cranelift,
1471+
// i.e., (left > right) - (left < right)
1472+
// Return value is the Ordering enumeration:
1473+
// ```
1474+
// #[repr(i8)]
1475+
// pub enum Ordering {
1476+
// Less = -1,
1477+
// Equal = 0,
1478+
// Greater = 1,
1479+
// }
1480+
// ```
1481+
let res_typ = self.codegen_ty_stable(res_ty);
1482+
let ValueAbi::Scalar(Scalar::Initialized { value, valid_range }) =
1483+
res_ty.layout().unwrap().shape().abi
1484+
else {
1485+
unreachable!("Unexpected layout")
1486+
};
1487+
assert_eq!(valid_range.start, -1i8 as u8 as u128);
1488+
assert_eq!(valid_range.end, 1);
1489+
let Primitive::Int { length, signed: true } = value else { unreachable!() };
1490+
let scalar_typ = Type::signed_int(length.bits());
1491+
left.clone()
1492+
.gt(right.clone())
1493+
.cast_to(scalar_typ.clone())
1494+
.sub(left.lt(right).cast_to(scalar_typ))
1495+
.transmute_to(res_typ, &self.symbol_table)
1496+
}
1497+
_ => unreachable!(),
1498+
}
1499+
}
14261500
}
14271501

14281502
/// Perform a wrapping subtraction of an Expr with a constant "expr - constant"
@@ -1445,30 +1519,6 @@ fn wrapping_sub(expr: &Expr, constant: u64) -> Expr {
14451519
}
14461520
}
14471521

1448-
fn comparison_expr(op: &BinOp, left: Expr, right: Expr, is_float: bool) -> Expr {
1449-
match op {
1450-
BinOp::Eq => {
1451-
if is_float {
1452-
left.feq(right)
1453-
} else {
1454-
left.eq(right)
1455-
}
1456-
}
1457-
BinOp::Lt => left.lt(right),
1458-
BinOp::Le => left.le(right),
1459-
BinOp::Ne => {
1460-
if is_float {
1461-
left.fneq(right)
1462-
} else {
1463-
left.neq(right)
1464-
}
1465-
}
1466-
BinOp::Ge => left.ge(right),
1467-
BinOp::Gt => left.gt(right),
1468-
_ => unreachable!(),
1469-
}
1470-
}
1471-
14721522
/// Remove the equality from an operator. Translates `<=` to `<` and `>=` to `>`
14731523
fn get_strict_operator(op: &BinOp) -> BinOp {
14741524
match op {

kani-compiler/src/codegen_cprover_gotoc/codegen/typ.rs

+8
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,13 @@ impl<'tcx> GotocCtx<'tcx> {
595595
)
596596
}
597597
}
598+
// This object has the same layout as base. For now, translate this into `(base)`.
599+
// The only difference is the niche.
600+
ty::Pat(base_ty, ..) => {
601+
self.ensure_struct(self.ty_mangled_name(ty), self.ty_pretty_name(ty), |tcx, _| {
602+
tcx.codegen_ty_tuple_like(ty, vec![*base_ty])
603+
})
604+
}
598605
ty::Alias(..) => {
599606
unreachable!("Type should've been normalized already")
600607
}
@@ -995,6 +1002,7 @@ impl<'tcx> GotocCtx<'tcx> {
9951002
| ty::Int(_)
9961003
| ty::RawPtr(_, _)
9971004
| ty::Ref(..)
1005+
| ty::Pat(..)
9981006
| ty::Tuple(_)
9991007
| ty::Uint(_) => self.codegen_ty(pointee_type).to_pointer(),
10001008

kani-compiler/src/kani_middle/stubbing/annotations.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub fn update_stub_mapping(
5656
"duplicate stub mapping: {} mapped to {} and {}",
5757
tcx.def_path_str(orig_id),
5858
tcx.def_path_str(stub_id),
59-
tcx.def_path_str(tcx.def_path_hash_to_def_id(other, &mut || panic!()))
59+
tcx.def_path_str(tcx.def_path_hash_to_def_id(other, &()))
6060
),
6161
);
6262
}

kani-compiler/src/kani_middle/stubbing/transform.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ fn deserialize_mapping(tcx: TyCtxt, val: &str) -> HashMap<DefId, DefId> {
234234
type Item = (u64, u64);
235235
let item_to_def_id = |item: Item| -> DefId {
236236
let hash = DefPathHash(Fingerprint::new(item.0, item.1));
237-
tcx.def_path_hash_to_def_id(hash, &mut || panic!())
237+
tcx.def_path_hash_to_def_id(hash, &())
238238
};
239239
let pairs: Vec<(Item, Item)> = serde_json::from_str(val).unwrap();
240240
let mut m = HashMap::default();

kani-compiler/src/kani_middle/transform/check_values.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ impl<'a> MirVisitor for CheckValueVisitor<'a> {
631631
ty: (rvalue.ty(self.locals).unwrap()),
632632
}),
633633
CastKind::PointerExposeAddress
634-
| CastKind::PointerFromExposedAddress
634+
| CastKind::PointerWithExposedProvenance
635635
| CastKind::PointerCoercion(_)
636636
| CastKind::IntToInt
637637
| CastKind::FloatToInt
@@ -898,6 +898,12 @@ fn ty_validity_per_offset(
898898
}
899899
}
900900
}
901+
RigidTy::Pat(base_ty, ..) => {
902+
// This is similar to a structure with one field and with niche defined.
903+
let mut pat_validity = ty_req();
904+
pat_validity.append(&mut ty_validity_per_offset(machine_info, *base_ty, 0)?);
905+
Ok(pat_validity)
906+
}
901907
RigidTy::Tuple(tys) => {
902908
let mut tuple_validity = vec![];
903909
for idx in layout.fields.fields_by_offset_order() {

rust-toolchain.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
# SPDX-License-Identifier: Apache-2.0 OR MIT
33

44
[toolchain]
5-
channel = "nightly-2024-04-02"
5+
channel = "nightly-2024-04-15"
66
components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"]

0 commit comments

Comments
 (0)