Skip to content

Commit

Permalink
More whack-a-mole with scopes (#905)
Browse files Browse the repository at this point in the history
* more push/scope/mysteries
  • Loading branch information
ranjitjhala authored Nov 25, 2024
1 parent 9837ed7 commit 27f7e7c
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 3 deletions.
1 change: 1 addition & 0 deletions crates/flux-infer/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub enum ConstrReason {
Assign,
Ret,
Fold,
FoldLocal,
Assert(&'static str),
Div,
Rem,
Expand Down
4 changes: 3 additions & 1 deletion crates/flux-refineck/src/checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -827,9 +827,11 @@ impl<'ck, 'genv, 'tcx, M: Mode> Checker<'ck, 'genv, 'tcx, M> {
.replace_evars(&evars_sol)
.replace_bound_refts_with(|sort, _, _| infcx.define_vars(sort));

infcx.push_scope();
env.update_ensures(infcx, &output, self.check_overflow());

fold_local_ptrs(infcx, env, span)?;
let evars_sol = infcx.pop_scope().with_span(span)?;
infcx.replace_evars(&evars_sol);

Ok(output.ret)
}
Expand Down
4 changes: 3 additions & 1 deletion crates/flux-refineck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,9 @@ fn report_errors(genv: GlobalEnv, errors: Vec<Tag>) -> Result<(), ErrorGuarantee
ConstrReason::Rem => genv.sess().emit_err(errors::RemError { span }),
ConstrReason::Goto(_) => genv.sess().emit_err(errors::GotoError { span }),
ConstrReason::Assert(msg) => genv.sess().emit_err(errors::AssertError { span, msg }),
ConstrReason::Fold => genv.sess().emit_err(errors::FoldError { span }),
ConstrReason::Fold | ConstrReason::FoldLocal => {
genv.sess().emit_err(errors::FoldError { span })
}
ConstrReason::Overflow => genv.sess().emit_err(errors::OverflowError { span }),
ConstrReason::Other => genv.sess().emit_err(errors::UnknownError { span }),
});
Expand Down
2 changes: 1 addition & 1 deletion crates/flux-refineck/src/type_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ impl<'a> TypeEnv<'a> {

pub(crate) fn fold_local_ptrs(&mut self, infcx: &mut InferCtxtAt) -> InferResult<()> {
for (loc, bound, ty) in self.bindings.local_ptrs() {
infcx.subtyping(&ty, &bound, ConstrReason::Fold)?;
infcx.subtyping(&ty, &bound, ConstrReason::FoldLocal)?;
self.bindings.remove_local(&loc);
}
Ok(())
Expand Down
58 changes: 58 additions & 0 deletions tests/tests/todo/issue-899c.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use core::slice::{Iter, SliceIndex};


pub trait Queue<T> {
/// Returns true if the queue is full, false otherwise.
fn is_full(&self) -> bool;

/// If the queue isn't full, add a new element to the back of the queue.
/// Returns whether the element was added.
#[flux_rs::sig(fn(self: &strg Self, _) -> bool ensures self: Self)]
fn enqueue(&mut self, val: T) -> bool;
}


#[flux_rs::extern_spec]
impl<T> [T] {
#[flux_rs::sig(fn(&[T][@len]) -> usize[len])]
fn len(v: &[T]) -> usize;
}


#[flux_rs::refined_by(ring_len: int, hd: int, tl: int)]
#[flux_rs::invariant(ring_len > 1)]
pub struct RingBuffer<'a, T: 'a> {
#[field({&mut [T][ring_len] | ring_len > 1})]
ring: &'a mut [T],
#[field({usize[hd] | hd < ring_len})]
head: usize,
#[field({usize[tl] | tl < ring_len})]
tail: usize,
}

impl<T: Copy> Queue<T> for RingBuffer<'_, T> {
fn is_full(&self) -> bool {
self.head == ((self.tail + 1) % self.ring.len())
}

#[flux_rs::sig(fn(self: &strg Self, _) -> bool ensures self: Self)]
fn enqueue(&mut self, val: T) -> bool {
if self.is_full() {
// Incrementing tail will overwrite head
false
} else {
self.ring[self.tail] = val;
self.tail = (self.tail + 1) % self.ring.len();
true
}
}
}

// This code causes an ICE
fn get_ring_buffer() -> &'static mut RingBuffer<'static, usize> {unimplemented!()}

fn enqueue_task() {
let rb = get_ring_buffer();
rb.enqueue(3);
}

0 comments on commit 27f7e7c

Please sign in to comment.