Skip to content

Commit 4a8c964

Browse files
committed
Support some of std::vec::Vec methods
1 parent ce3b57a commit 4a8c964

8 files changed

Lines changed: 167 additions & 0 deletions

File tree

src/refine/template.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ impl<'tcx> TypeBuilder<'tcx> {
141141
mir_ty::TyKind::Adt(def, params) if def.is_box() => {
142142
rty::PointerType::own(self.build(params.type_at(0))).into()
143143
}
144+
// TODO: Declare this in std.rs
145+
mir_ty::TyKind::Adt(def, params)
146+
if self.tcx.is_diagnostic_item(rustc_span::sym::Vec, def.did()) =>
147+
{
148+
let content = rty::ArrayType::new(rty::Type::Int, self.build(params.type_at(0)));
149+
rty::TupleType::new(vec![content.into(), rty::Type::Int.into()]).into()
150+
}
144151
mir_ty::TyKind::Adt(def, params) => {
145152
if def.is_enum() {
146153
let sym = refine::datatype_symbol(self.tcx, def.did());
@@ -269,6 +276,15 @@ where
269276
mir_ty::TyKind::Adt(def, params) if def.is_box() => {
270277
rty::PointerType::own(self.build(params.type_at(0))).into()
271278
}
279+
mir_ty::TyKind::Adt(def, params)
280+
if self
281+
.inner
282+
.tcx
283+
.is_diagnostic_item(rustc_span::sym::Vec, def.did()) =>
284+
{
285+
let content = rty::ArrayType::new(rty::Type::Int, self.build(params.type_at(0)));
286+
rty::TupleType::new(vec![content.into(), rty::Type::Int.into()]).into()
287+
}
272288
mir_ty::TyKind::Adt(def, params) => {
273289
if def.is_enum() {
274290
let sym = refine::datatype_symbol(self.inner.tcx, def.did());

std.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,88 @@ fn _extern_spec_i32_is_positive(x: i32) -> bool {
201201
fn _extern_spec_i32_is_negative(x: i32) -> bool {
202202
i32::is_negative(x)
203203
}
204+
205+
#[thrust::extern_spec_fn]
206+
#[thrust::requires(true)]
207+
#[thrust::ensures(result.1 == 0)]
208+
fn _extern_spec_vec_new<T>() -> Vec<T> {
209+
Vec::<T>::new()
210+
}
211+
212+
#[thrust::extern_spec_fn]
213+
#[thrust::requires(true)]
214+
#[thrust::ensures(^vec == ((*vec).0.store((*vec).1, elem), (*vec).1 + 1))]
215+
fn _extern_spec_vec_push<T>(vec: &mut Vec<T>, elem: T) {
216+
Vec::push(vec, elem)
217+
}
218+
219+
#[thrust::extern_spec_fn]
220+
#[thrust::requires(true)]
221+
#[thrust::ensures(result == (*vec).1)]
222+
fn _extern_spec_vec_len<T>(vec: &Vec<T>) -> usize {
223+
Vec::len(vec)
224+
}
225+
226+
#[thrust::extern_spec_fn]
227+
#[thrust::requires(index < (*vec).1)]
228+
#[thrust::ensures(*result == (*vec).0.select(index))]
229+
fn _extern_spec_vec_index<T>(vec: &Vec<T>, index: usize) -> &T {
230+
<Vec<T> as std::ops::Index<usize>>::index(vec, index)
231+
}
232+
233+
#[thrust::extern_spec_fn]
234+
#[thrust::requires(index < (*vec).1)]
235+
#[thrust::ensures(
236+
*result == (*vec).0.select(index) &&
237+
^result == (^vec).0.select(index) &&
238+
^vec == ((*vec).0.store(index, ^result), (*vec).1)
239+
)]
240+
fn _extern_spec_vec_index_mut<T>(vec: &mut Vec<T>, index: usize) -> &mut T {
241+
<Vec<T> as std::ops::IndexMut<usize>>::index_mut(vec, index)
242+
}
243+
244+
#[thrust::extern_spec_fn]
245+
#[thrust::requires(true)]
246+
#[thrust::ensures((^vec).1 == 0)]
247+
fn _extern_spec_vec_clear<T>(vec: &mut Vec<T>) {
248+
Vec::clear(vec)
249+
}
250+
251+
#[thrust::extern_spec_fn]
252+
#[thrust::requires(true)]
253+
#[thrust::ensures(
254+
(
255+
(*vec).1 > 0 &&
256+
(^vec).1 == (*vec).1 - 1 &&
257+
result == std::option::Option::<T0>::Some((*vec).0.select((*vec).1 - 1))
258+
) || (
259+
(*vec).1 == 0 &&
260+
(^vec).1 == 0 &&
261+
result == std::option::Option::<T0>::None()
262+
)
263+
)]
264+
fn _extern_spec_vec_pop<T>(vec: &mut Vec<T>) -> Option<T> {
265+
Vec::pop(vec)
266+
}
267+
268+
#[thrust::extern_spec_fn]
269+
#[thrust::requires(true)]
270+
#[thrust::ensures(result == ((*vec).1 == 0))]
271+
fn _extern_spec_vec_is_empty<T>(vec: &Vec<T>) -> bool {
272+
Vec::is_empty(vec)
273+
}
274+
275+
#[thrust::extern_spec_fn]
276+
#[thrust::requires(true)]
277+
#[thrust::ensures(
278+
(
279+
(*vec).1 > len &&
280+
^vec == ((*vec).0, len)
281+
) || (
282+
(*vec).1 <= len &&
283+
^vec == *vec
284+
)
285+
)]
286+
fn _extern_spec_vec_truncate<T>(vec: &mut Vec<T>, len: usize) {
287+
Vec::truncate(vec, len)
288+
}

tests/ui/fail/vec_1.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@error-in-other-file: Unsat
2+
//@compile-flags: -C debug-assertions=off
3+
4+
fn main() {
5+
let mut v = Vec::new();
6+
v.push(0);
7+
assert!(v.len() == 0);
8+
}

tests/ui/fail/vec_2.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@error-in-other-file: Unsat
2+
//@compile-flags: -C debug-assertions=off
3+
4+
fn main() {
5+
let mut v = Vec::new();
6+
v.push(0);
7+
v[0] += 1;
8+
assert!(v.pop().unwrap() == 1);
9+
assert!(v.pop().unwrap() == 1);
10+
}

tests/ui/fail/vec_3.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@error-in-other-file: Unsat
2+
//@compile-flags: -C debug-assertions=off
3+
4+
fn main() {
5+
let mut v = Vec::new();
6+
v.push(0);
7+
v.push(1);
8+
v.push(2);
9+
assert!(v.len() == 2);
10+
v.truncate(1);
11+
assert!(v[1] == 0);
12+
v.clear();
13+
assert!(v.len() == 1);
14+
}

tests/ui/pass/vec_1.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@check-pass
2+
//@compile-flags: -C debug-assertions=off
3+
4+
fn main() {
5+
let mut v = Vec::new();
6+
v.push(0);
7+
assert!(v.len() == 1);
8+
assert!(v[0] == 0);
9+
}

tests/ui/pass/vec_2.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@check-pass
2+
//@compile-flags: -C debug-assertions=off
3+
4+
fn main() {
5+
let mut v = Vec::new();
6+
v.push(0);
7+
v[0] += 1;
8+
v.push(1);
9+
assert!(v.pop().unwrap() == 1);
10+
assert!(v.pop().unwrap() == 1);
11+
}

tests/ui/pass/vec_3.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@check-pass
2+
//@compile-flags: -C debug-assertions=off
3+
4+
fn main() {
5+
let mut v = Vec::new();
6+
v.push(0);
7+
v.push(1);
8+
v.push(2);
9+
assert!(v.len() == 3);
10+
v.truncate(1);
11+
assert!(v[0] == 0);
12+
v.clear();
13+
assert!(v.len() == 0);
14+
}

0 commit comments

Comments
 (0)