Skip to content

Commit 88eff84

Browse files
authored
Merge pull request creusot-rs#805 from xldenis/tyinv-open
Add `open_inv` attribute to pass arguments with an open type invariant
2 parents 179de6d + 6b49bd1 commit 88eff84

38 files changed

+1277
-1240
lines changed

creusot-contracts/src/invariant.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ pub trait Invariant {
2424
impl<'a, T: Invariant + ?Sized> Invariant for &'a T {
2525
#[predicate]
2626
#[open]
27-
#[creusot::ignore_type_invariant = "maybe"]
2827
fn invariant(self) -> bool {
2928
pearlite! { (*self).invariant() }
3029
}
@@ -33,7 +32,6 @@ impl<'a, T: Invariant + ?Sized> Invariant for &'a T {
3332
impl<'a, T: Invariant + ?Sized> Invariant for &'a mut T {
3433
#[predicate]
3534
#[open]
36-
#[creusot::ignore_type_invariant = "maybe"]
3735
fn invariant(self) -> bool {
3836
pearlite! { (*self).invariant() }
3937
}
@@ -42,7 +40,6 @@ impl<'a, T: Invariant + ?Sized> Invariant for &'a mut T {
4240
impl<T: Invariant + ?Sized> Invariant for Box<T> {
4341
#[predicate]
4442
#[open]
45-
#[creusot::ignore_type_invariant = "maybe"]
4643
fn invariant(self) -> bool {
4744
pearlite! { (*self).invariant() }
4845
}
@@ -51,7 +48,6 @@ impl<T: Invariant + ?Sized> Invariant for Box<T> {
5148
impl<T: Invariant, U: Invariant> Invariant for (T, U) {
5249
#[predicate]
5350
#[open]
54-
#[creusot::ignore_type_invariant = "maybe"]
5551
fn invariant(self) -> bool {
5652
pearlite! { self.0.invariant() && self.1.invariant() }
5753
}
@@ -60,7 +56,6 @@ impl<T: Invariant, U: Invariant> Invariant for (T, U) {
6056
impl<T: Invariant> Invariant for Option<T> {
6157
#[predicate]
6258
#[open]
63-
#[creusot::ignore_type_invariant = "maybe"]
6459
fn invariant(self) -> bool {
6560
pearlite! {
6661
match self {

creusot-contracts/src/std/iter/map_inv.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ impl<I: Iterator, B, F: FnMut(I::Item, Ghost<Seq<I::Item>>) -> B> Invariant
6565
// Should not quantify over self or the `invariant` cannot be made into a type invariant
6666
#[open(self)]
6767
#[predicate]
68-
#[creusot::ignore_type_invariant]
6968
fn invariant(self) -> bool {
7069
pearlite! {
7170
Self::reinitialize() &&
@@ -108,6 +107,7 @@ impl<I: Iterator, B, F: FnMut(I::Item, Ghost<Seq<I::Item>>) -> B> ::std::iter::I
108107
impl<I: Iterator, B, F: FnMut(I::Item, Ghost<Seq<I::Item>>) -> B> MapInv<I, I::Item, F> {
109108
#[open]
110109
#[predicate]
110+
#[creusot::open_inv]
111111
pub fn next_precondition(self) -> bool {
112112
pearlite! {
113113
forall<e: I::Item, i: I>
@@ -131,6 +131,7 @@ impl<I: Iterator, B, F: FnMut(I::Item, Ghost<Seq<I::Item>>) -> B> MapInv<I, I::I
131131
#[open(self)]
132132
#[predicate]
133133
#[ensures(self.produced.inner() == Seq::EMPTY ==> result == Self::preservation(self.iter, self.func))]
134+
#[creusot::open_inv]
134135
pub fn preservation_inv(self) -> bool {
135136
pearlite! {
136137
forall<s: Seq<I::Item>, e1: I::Item, e2: I::Item, f: &mut F, b: B, i: I>

creusot-contracts/src/std/slice.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@ extern_spec! {
279279
fn iter(&self) -> Iter<'_, T>;
280280

281281
#[ensures(result@ == self)]
282-
#[ensures(result.invariant())]
283282
fn iter_mut(&mut self) -> IterMut<'_, T>;
284283

285284
#[ensures(result == None ==> self@.len() == 0)]
@@ -400,6 +399,7 @@ impl<'a, T> ShallowModel for IterMut<'a, T> {
400399
#[open(self)]
401400
#[trusted]
402401
#[ensures((^result)@.len() == (*result)@.len())]
402+
#[creusot::open_inv]
403403
fn shallow_model(self) -> Self::ShallowModelTy {
404404
absurd
405405
}
@@ -417,7 +417,6 @@ impl<'a, T> Resolve for IterMut<'a, T> {
417417
impl<'a, T> Invariant for IterMut<'a, T> {
418418
#[predicate]
419419
#[open]
420-
#[creusot::ignore_type_invariant]
421420
fn invariant(self) -> bool {
422421
// Property that is always true but we must carry around..
423422
pearlite! { (^self@)@.len() == (*self@)@.len() }

creusot/src/ctx.rs

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ use rustc_infer::traits::{Obligation, ObligationCause};
2929
use rustc_middle::{
3030
mir::{Body, Promoted},
3131
thir,
32-
ty::{
33-
subst::{GenericArgKind, InternalSubsts},
34-
GenericArg, ParamEnv, SubstsRef, Ty, TyCtxt, Visibility,
35-
},
32+
ty::{subst::InternalSubsts, GenericArg, ParamEnv, SubstsRef, Ty, TyCtxt, Visibility},
3633
};
3734
use rustc_span::{RealFileName, Span, Symbol, DUMMY_SP};
3835
use rustc_trait_selection::traits::SelectionContext;
@@ -209,6 +206,10 @@ impl<'tcx, 'sess> TranslationCtx<'tcx> {
209206
def_id: DefId,
210207
ty: Ty<'tcx>,
211208
) -> Option<(DefId, SubstsRef<'tcx>)> {
209+
if util::is_open_ty_inv(self.tcx, def_id) {
210+
return None;
211+
}
212+
212213
debug!("resolving type invariant of {ty:?} in {def_id:?}");
213214
let param_env = self.param_env(def_id);
214215
let trait_did = self.get_diagnostic_item(Symbol::intern("creusot_invariant_method"))?;
@@ -221,41 +222,7 @@ impl<'tcx, 'sess> TranslationCtx<'tcx> {
221222
return None;
222223
}
223224

224-
match util::ignore_type_invariant(self.tcx, inv.0) {
225-
util::TypeInvariantAttr::None => return Some(inv),
226-
util::TypeInvariantAttr::AlwaysIgnore => return None,
227-
util::TypeInvariantAttr::MaybeIgnore => {}
228-
}
229-
230-
let mut walker = ty.walk();
231-
walker.next(); // skip root type
232-
while let Some(arg) = walker.next() {
233-
if !matches!(arg.unpack(), GenericArgKind::Type(_)) {
234-
walker.skip_current_subtree();
235-
continue;
236-
}
237-
238-
let substs = self.mk_substs(&[arg]);
239-
let Some(arg_inv) = traits::resolve_opt(self.tcx, param_env, trait_did, substs) else {
240-
walker.skip_current_subtree();
241-
continue;
242-
};
243-
244-
if arg_inv.0 == trait_did
245-
&& !traits::still_specializable(self.tcx, param_env, arg_inv.0, arg_inv.1)
246-
{
247-
walker.skip_current_subtree();
248-
continue;
249-
}
250-
251-
match util::ignore_type_invariant(self.tcx, arg_inv.0) {
252-
util::TypeInvariantAttr::None => return Some(inv),
253-
util::TypeInvariantAttr::AlwaysIgnore => walker.skip_current_subtree(),
254-
util::TypeInvariantAttr::MaybeIgnore => {}
255-
}
256-
}
257-
258-
None
225+
Some(inv)
259226
}
260227

261228
pub(crate) fn crash_and_error(&self, span: Span, msg: &str) -> ! {

creusot/src/util.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ pub(crate) fn is_extern_spec(tcx: TyCtxt, def_id: DefId) -> bool {
9393
get_attr(tcx.get_attrs_unchecked(def_id), &["creusot", "extern_spec"]).is_some()
9494
}
9595

96+
pub(crate) fn is_open_ty_inv(tcx: TyCtxt, def_id: DefId) -> bool {
97+
get_attr(tcx.get_attrs_unchecked(def_id), &["creusot", "open_inv"]).is_some()
98+
}
99+
96100
pub(crate) fn is_type_invariant(tcx: TyCtxt, def_id: DefId) -> bool {
97101
let Some(assoc_item) = tcx.opt_associated_item(def_id) else { return false };
98102
let Some(trait_item_did) = (match assoc_item.container {
@@ -114,24 +118,6 @@ pub(crate) fn opacity_witness_name(tcx: TyCtxt, def_id: DefId) -> Option<Symbol>
114118
})
115119
}
116120

117-
pub(crate) enum TypeInvariantAttr {
118-
None,
119-
MaybeIgnore,
120-
AlwaysIgnore,
121-
}
122-
123-
pub(crate) fn ignore_type_invariant(tcx: TyCtxt, def_id: DefId) -> TypeInvariantAttr {
124-
match get_attr(tcx.get_attrs_unchecked(def_id), &["creusot", "ignore_type_invariant"]) {
125-
None => TypeInvariantAttr::None,
126-
Some(AttrItem { args: AttrArgs::Eq(_, AttrArgsEq::Hir(v)), .. })
127-
if v.symbol.as_str() == "maybe" =>
128-
{
129-
TypeInvariantAttr::MaybeIgnore
130-
}
131-
_ => TypeInvariantAttr::AlwaysIgnore,
132-
}
133-
}
134-
135121
pub(crate) fn why3_attrs(tcx: TyCtxt, def_id: DefId) -> Vec<why3::declaration::Attribute> {
136122
let matches = get_attrs(tcx.get_attrs_unchecked(def_id), &["why3", "attr"]);
137123
matches
@@ -471,7 +457,17 @@ fn elaborate_type_invariants<'tcx>(
471457
}
472458

473459
let subst = InternalSubsts::identity_for_item(ctx.tcx, def_id);
474-
for (name, span, ty) in pre_sig.inputs.iter() {
460+
461+
let param_attrs = def_id
462+
.as_local()
463+
.and_then(|def_id| get_param_attrs(ctx.tcx, def_id))
464+
.filter(|attrs| attrs.len() == pre_sig.inputs.len());
465+
466+
for (i, (name, span, ty)) in pre_sig.inputs.iter().enumerate() {
467+
if let Some(attrs) = &param_attrs && get_attr(attrs[i], &["creusot", "open_inv"]).is_some() {
468+
continue;
469+
}
470+
475471
if let Some(term) = pearlite::type_invariant_term(ctx, def_id, *name, *span, *ty) {
476472
let term = EarlyBinder(term).subst(ctx.tcx, subst);
477473

@@ -480,8 +476,9 @@ fn elaborate_type_invariants<'tcx>(
480476
let arg = Term { ty: *ty, span: *span, kind: TermKind::Var(*name) };
481477
let arg =
482478
Term { ty: inner, span: *span, kind: TermKind::Fin { term: Box::new(arg) } };
483-
let term =
484-
pearlite::type_invariant_term_with_arg(ctx, def_id, arg, *span, inner).unwrap();
479+
// FIXME: why can this be none?
480+
let Some(term) =
481+
pearlite::type_invariant_term_with_arg(ctx, def_id, arg, *span, inner) else {continue; };
485482
pre_sig.contract.ensures.push(term);
486483
}
487484

@@ -568,6 +565,16 @@ pub(crate) fn is_attr(attr: &Attribute, str: &str) -> bool {
568565
}
569566
}
570567

568+
/// Returns `None` if the `def_id` does not refer to a body owner.
569+
pub(crate) fn get_param_attrs<'tcx>(
570+
tcx: TyCtxt<'tcx>,
571+
def_id: LocalDefId,
572+
) -> Option<Vec<&'tcx [Attribute]>> {
573+
let body_id = tcx.hir().maybe_body_owned_by(def_id)?;
574+
let params = tcx.hir().body(body_id).params;
575+
Some(params.iter().map(|p| tcx.hir().attrs(p.hir_id)).collect())
576+
}
577+
571578
use rustc_span::def_id::LocalDefId;
572579
use rustc_target::abi::FieldIdx;
573580

creusot/tests/should_succeed/hillel.mlcfg

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ module CreusotContracts_Std1_Slice_Impl15_Produces
11101110
predicate produces (self : Core_Slice_Iter_Iter_Type.t_iter t) (visited : Seq.seq t) (tl : Core_Slice_Iter_Iter_Type.t_iter t)
11111111

11121112
=
1113-
[#"../../../../creusot-contracts/src/std/slice.rs" 379 12 379 66] ToRefSeq0.to_ref_seq (ShallowModel0.shallow_model self) = Seq.(++) visited (ToRefSeq0.to_ref_seq (ShallowModel0.shallow_model tl))
1113+
[#"../../../../creusot-contracts/src/std/slice.rs" 378 12 378 66] ToRefSeq0.to_ref_seq (ShallowModel0.shallow_model self) = Seq.(++) visited (ToRefSeq0.to_ref_seq (ShallowModel0.shallow_model tl))
11141114
val produces (self : Core_Slice_Iter_Iter_Type.t_iter t) (visited : Seq.seq t) (tl : Core_Slice_Iter_Iter_Type.t_iter t) : bool
11151115
ensures { result = produces self visited tl }
11161116

@@ -1183,7 +1183,7 @@ module Core_Slice_Impl0_Iter_Interface
11831183
clone CreusotContracts_Std1_Slice_Impl13_ShallowModel_Stub as ShallowModel0 with
11841184
type t = t
11851185
val iter (self : slice t) : Core_Slice_Iter_Iter_Type.t_iter t
1186-
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 232 0 325 1] ShallowModel0.shallow_model result = self }
1186+
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 232 0 324 1] ShallowModel0.shallow_model result = self }
11871187

11881188
end
11891189
module CreusotContracts_Std1_Iter_IntoIterator_IntoIterPre_Stub
@@ -1320,7 +1320,7 @@ module CreusotContracts_Std1_Slice_Impl15_Completed
13201320
clone CreusotContracts_Resolve_Impl1_Resolve_Stub as Resolve0 with
13211321
type t = Core_Slice_Iter_Iter_Type.t_iter t
13221322
predicate completed (self : borrowed (Core_Slice_Iter_Iter_Type.t_iter t)) =
1323-
[#"../../../../creusot-contracts/src/std/slice.rs" 372 20 372 61] Resolve0.resolve self /\ ShallowModel1.shallow_model (ShallowModel0.shallow_model self) = Seq.empty
1323+
[#"../../../../creusot-contracts/src/std/slice.rs" 371 20 371 61] Resolve0.resolve self /\ ShallowModel1.shallow_model (ShallowModel0.shallow_model self) = Seq.empty
13241324
val completed (self : borrowed (Core_Slice_Iter_Iter_Type.t_iter t)) : bool
13251325
ensures { result = completed self }
13261326

@@ -1451,10 +1451,10 @@ module CreusotContracts_Std1_Slice_Impl15_ProducesRefl_Interface
14511451
type t = t
14521452
function produces_refl (a : Core_Slice_Iter_Iter_Type.t_iter t) : ()
14531453
val produces_refl (a : Core_Slice_Iter_Iter_Type.t_iter t) : ()
1454-
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 385 14 385 39] Produces0.produces a (Seq.empty ) a }
1454+
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 384 14 384 39] Produces0.produces a (Seq.empty ) a }
14551455
ensures { result = produces_refl a }
14561456

1457-
axiom produces_refl_spec : forall a : Core_Slice_Iter_Iter_Type.t_iter t . [#"../../../../creusot-contracts/src/std/slice.rs" 385 14 385 39] Produces0.produces a (Seq.empty ) a
1457+
axiom produces_refl_spec : forall a : Core_Slice_Iter_Iter_Type.t_iter t . [#"../../../../creusot-contracts/src/std/slice.rs" 384 14 384 39] Produces0.produces a (Seq.empty ) a
14581458
end
14591459
module CreusotContracts_Std1_Slice_Impl15_ProducesRefl
14601460
type t
@@ -1463,12 +1463,12 @@ module CreusotContracts_Std1_Slice_Impl15_ProducesRefl
14631463
clone CreusotContracts_Std1_Slice_Impl15_Produces_Stub as Produces0 with
14641464
type t = t
14651465
function produces_refl (a : Core_Slice_Iter_Iter_Type.t_iter t) : () =
1466-
[#"../../../../creusot-contracts/src/std/slice.rs" 383 4 383 10] ()
1466+
[#"../../../../creusot-contracts/src/std/slice.rs" 382 4 382 10] ()
14671467
val produces_refl (a : Core_Slice_Iter_Iter_Type.t_iter t) : ()
1468-
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 385 14 385 39] Produces0.produces a (Seq.empty ) a }
1468+
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 384 14 384 39] Produces0.produces a (Seq.empty ) a }
14691469
ensures { result = produces_refl a }
14701470

1471-
axiom produces_refl_spec : forall a : Core_Slice_Iter_Iter_Type.t_iter t . [#"../../../../creusot-contracts/src/std/slice.rs" 385 14 385 39] Produces0.produces a (Seq.empty ) a
1471+
axiom produces_refl_spec : forall a : Core_Slice_Iter_Iter_Type.t_iter t . [#"../../../../creusot-contracts/src/std/slice.rs" 384 14 384 39] Produces0.produces a (Seq.empty ) a
14721472
end
14731473
module CreusotContracts_Std1_Slice_Impl15_ProducesTrans_Stub
14741474
type t
@@ -1490,12 +1490,12 @@ module CreusotContracts_Std1_Slice_Impl15_ProducesTrans_Interface
14901490
function produces_trans (a : Core_Slice_Iter_Iter_Type.t_iter t) (ab : Seq.seq t) (b : Core_Slice_Iter_Iter_Type.t_iter t) (bc : Seq.seq t) (c : Core_Slice_Iter_Iter_Type.t_iter t) : ()
14911491

14921492
val produces_trans (a : Core_Slice_Iter_Iter_Type.t_iter t) (ab : Seq.seq t) (b : Core_Slice_Iter_Iter_Type.t_iter t) (bc : Seq.seq t) (c : Core_Slice_Iter_Iter_Type.t_iter t) : ()
1493-
requires {[#"../../../../creusot-contracts/src/std/slice.rs" 390 15 390 32] Produces0.produces a ab b}
1494-
requires {[#"../../../../creusot-contracts/src/std/slice.rs" 391 15 391 32] Produces0.produces b bc c}
1495-
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 392 14 392 42] Produces0.produces a (Seq.(++) ab bc) c }
1493+
requires {[#"../../../../creusot-contracts/src/std/slice.rs" 389 15 389 32] Produces0.produces a ab b}
1494+
requires {[#"../../../../creusot-contracts/src/std/slice.rs" 390 15 390 32] Produces0.produces b bc c}
1495+
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 391 14 391 42] Produces0.produces a (Seq.(++) ab bc) c }
14961496
ensures { result = produces_trans a ab b bc c }
14971497

1498-
axiom produces_trans_spec : forall a : Core_Slice_Iter_Iter_Type.t_iter t, ab : Seq.seq t, b : Core_Slice_Iter_Iter_Type.t_iter t, bc : Seq.seq t, c : Core_Slice_Iter_Iter_Type.t_iter t . ([#"../../../../creusot-contracts/src/std/slice.rs" 390 15 390 32] Produces0.produces a ab b) -> ([#"../../../../creusot-contracts/src/std/slice.rs" 391 15 391 32] Produces0.produces b bc c) -> ([#"../../../../creusot-contracts/src/std/slice.rs" 392 14 392 42] Produces0.produces a (Seq.(++) ab bc) c)
1498+
axiom produces_trans_spec : forall a : Core_Slice_Iter_Iter_Type.t_iter t, ab : Seq.seq t, b : Core_Slice_Iter_Iter_Type.t_iter t, bc : Seq.seq t, c : Core_Slice_Iter_Iter_Type.t_iter t . ([#"../../../../creusot-contracts/src/std/slice.rs" 389 15 389 32] Produces0.produces a ab b) -> ([#"../../../../creusot-contracts/src/std/slice.rs" 390 15 390 32] Produces0.produces b bc c) -> ([#"../../../../creusot-contracts/src/std/slice.rs" 391 14 391 42] Produces0.produces a (Seq.(++) ab bc) c)
14991499
end
15001500
module CreusotContracts_Std1_Slice_Impl15_ProducesTrans
15011501
type t
@@ -1507,14 +1507,14 @@ module CreusotContracts_Std1_Slice_Impl15_ProducesTrans
15071507
function produces_trans (a : Core_Slice_Iter_Iter_Type.t_iter t) (ab : Seq.seq t) (b : Core_Slice_Iter_Iter_Type.t_iter t) (bc : Seq.seq t) (c : Core_Slice_Iter_Iter_Type.t_iter t) : ()
15081508

15091509
=
1510-
[#"../../../../creusot-contracts/src/std/slice.rs" 388 4 388 10] ()
1510+
[#"../../../../creusot-contracts/src/std/slice.rs" 387 4 387 10] ()
15111511
val produces_trans (a : Core_Slice_Iter_Iter_Type.t_iter t) (ab : Seq.seq t) (b : Core_Slice_Iter_Iter_Type.t_iter t) (bc : Seq.seq t) (c : Core_Slice_Iter_Iter_Type.t_iter t) : ()
1512-
requires {[#"../../../../creusot-contracts/src/std/slice.rs" 390 15 390 32] Produces0.produces a ab b}
1513-
requires {[#"../../../../creusot-contracts/src/std/slice.rs" 391 15 391 32] Produces0.produces b bc c}
1514-
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 392 14 392 42] Produces0.produces a (Seq.(++) ab bc) c }
1512+
requires {[#"../../../../creusot-contracts/src/std/slice.rs" 389 15 389 32] Produces0.produces a ab b}
1513+
requires {[#"../../../../creusot-contracts/src/std/slice.rs" 390 15 390 32] Produces0.produces b bc c}
1514+
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 391 14 391 42] Produces0.produces a (Seq.(++) ab bc) c }
15151515
ensures { result = produces_trans a ab b bc c }
15161516

1517-
axiom produces_trans_spec : forall a : Core_Slice_Iter_Iter_Type.t_iter t, ab : Seq.seq t, b : Core_Slice_Iter_Iter_Type.t_iter t, bc : Seq.seq t, c : Core_Slice_Iter_Iter_Type.t_iter t . ([#"../../../../creusot-contracts/src/std/slice.rs" 390 15 390 32] Produces0.produces a ab b) -> ([#"../../../../creusot-contracts/src/std/slice.rs" 391 15 391 32] Produces0.produces b bc c) -> ([#"../../../../creusot-contracts/src/std/slice.rs" 392 14 392 42] Produces0.produces a (Seq.(++) ab bc) c)
1517+
axiom produces_trans_spec : forall a : Core_Slice_Iter_Iter_Type.t_iter t, ab : Seq.seq t, b : Core_Slice_Iter_Iter_Type.t_iter t, bc : Seq.seq t, c : Core_Slice_Iter_Iter_Type.t_iter t . ([#"../../../../creusot-contracts/src/std/slice.rs" 389 15 389 32] Produces0.produces a ab b) -> ([#"../../../../creusot-contracts/src/std/slice.rs" 390 15 390 32] Produces0.produces b bc c) -> ([#"../../../../creusot-contracts/src/std/slice.rs" 391 14 391 42] Produces0.produces a (Seq.(++) ab bc) c)
15181518
end
15191519
module Hillel_InsertUnique_Interface
15201520
type t
@@ -2034,7 +2034,7 @@ module Core_Slice_Impl0_Len_Interface
20342034
type t = slice t,
20352035
type ShallowModelTy0.shallowModelTy = Seq.seq t
20362036
val len (self : slice t) : usize
2037-
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 232 0 325 1] Seq.length (ShallowModel0.shallow_model self) = UIntSize.to_int result }
2037+
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 232 0 324 1] Seq.length (ShallowModel0.shallow_model self) = UIntSize.to_int result }
20382038

20392039
end
20402040
module CreusotContracts_Std1_Iter_Iterator_Completed_Stub
@@ -2857,7 +2857,7 @@ module CreusotContracts_Std1_Slice_Impl11_IntoIterPre
28572857
use prelude.Borrow
28582858
use prelude.Slice
28592859
predicate into_iter_pre (self : slice t) =
2860-
[#"../../../../creusot-contracts/src/std/slice.rs" 331 20 331 24] true
2860+
[#"../../../../creusot-contracts/src/std/slice.rs" 330 20 330 24] true
28612861
val into_iter_pre (self : slice t) : bool
28622862
ensures { result = into_iter_pre self }
28632863

@@ -2887,7 +2887,7 @@ module CreusotContracts_Std1_Slice_Impl11_IntoIterPost
28872887
clone CreusotContracts_Std1_Slice_Impl13_ShallowModel_Stub as ShallowModel0 with
28882888
type t = t
28892889
predicate into_iter_post (self : slice t) (res : Core_Slice_Iter_Iter_Type.t_iter t) =
2890-
[#"../../../../creusot-contracts/src/std/slice.rs" 337 20 337 32] self = ShallowModel0.shallow_model res
2890+
[#"../../../../creusot-contracts/src/std/slice.rs" 336 20 336 32] self = ShallowModel0.shallow_model res
28912891
val into_iter_post (self : slice t) (res : Core_Slice_Iter_Iter_Type.t_iter t) : bool
28922892
ensures { result = into_iter_post self res }
28932893

creusot/tests/should_succeed/index_range.mlcfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ module Core_Slice_Impl0_Len_Interface
563563
type t = slice t,
564564
type ShallowModelTy0.shallowModelTy = Seq.seq t
565565
val len (self : slice t) : usize
566-
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 232 0 325 1] Seq.length (ShallowModel0.shallow_model self) = UIntSize.to_int result }
566+
ensures { [#"../../../../creusot-contracts/src/std/slice.rs" 232 0 324 1] Seq.length (ShallowModel0.shallow_model self) = UIntSize.to_int result }
567567

568568
end
569569
module Alloc_Vec_Impl9_Deref_Interface

0 commit comments

Comments
 (0)