Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(engine) Attempt to fix double return bug. #1223

Merged
merged 2 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions engine/lib/phases/phase_and_mut_defsite.ml
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,16 @@ struct
match e.e with
| GlobalVar (`TupleCons 0) -> e
| _ ->
let lhs = UB.make_var_pat var e.typ e.span in
let rhs = e in
let body = { e with e = LocalVar var } in
let lhs, body =
if [%eq: ty] e.typ UB.unit_typ then
(* This case has been added to fix https://github.com/hacspec/hax/issues/720.
It might need a better solution. *)
( UB.M.pat_PWild ~span:e.span ~typ:e.typ,
UB.M.expr_unit ~span:e.span )
else
(UB.make_var_pat var e.typ e.span, { e with e = LocalVar var })
in
{ body with e = Let { monadic = None; lhs; rhs; body } }
in
UB.map_body_of_nested_lets f e
Expand Down
48 changes: 27 additions & 21 deletions engine/lib/phases/phase_local_mutation.ml
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ struct
}
| Loop { body; kind; state; label; witness; _ } ->
let variables_to_output = s.expr_level in
let drop_expr = s.drop_expr in
(* [adapt]: should we reorder shadowings? *)
let observable_mutations, adapt =
let set =
Expand Down Expand Up @@ -338,27 +339,32 @@ struct
span;
}
in
if adapt && not (List.is_empty variables_to_output) then
(* here, we need to introduce the shadowings as bindings *)
let out =
UB.make_tuple_expr ~span
@@ List.map
~f:(fun (ident, typ) -> B.{ e = LocalVar ident; typ; span })
variables_to_output
in
let lhs =
UB.make_tuple_pat
@@ List.map
~f:(fun (ident, typ) -> UB.make_var_pat ident typ span)
observable_mutations
in
B.
{
e = Let { monadic = None; lhs; rhs = loop; body = out };
span;
typ = out.typ;
}
else loop
let vars =
if adapt && not (List.is_empty variables_to_output) then
(* here, we need to introduce the shadowings as bindings *)
let out =
UB.make_tuple_expr ~span
@@ List.map
~f:(fun (ident, typ) ->
B.{ e = LocalVar ident; typ; span })
variables_to_output
in
let lhs =
UB.make_tuple_pat
@@ List.map
~f:(fun (ident, typ) -> UB.make_var_pat ident typ span)
observable_mutations
in
B.
{
e = Let { monadic = None; lhs; rhs = loop; body = out };
span;
typ = out.typ;
}
else loop
in
if drop_expr then vars
else UB.make_tuple_expr ~span [ vars; UB.unit_expr span ]
| [%inline_arms
"dexpr'.*" - Let - Assign - Closure - Loop - If - Match - Break
- Return] ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ let impl: t_Foo Prims.unit =
f_i
=
fun (x: u8) (y: u8) ->
let hax_temp_output:Prims.unit = () <: Prims.unit in
let _:Prims.unit = () <: Prims.unit in
y
}
'''
Expand Down
86 changes: 76 additions & 10 deletions test-harness/src/snapshots/toolchain__loops into-fstar.snap
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,57 @@ stderr = 'Finished `dev` profile [unoptimized + debuginfo] target(s) in XXs'
diagnostics = []

[stdout.files]
"Loops.And_mut_side_effect_loop.fst" = '''
module Loops.And_mut_side_effect_loop
#set-options "--fuel 0 --ifuel 1 --z3rlimit 15"
open Core
open FStar.Mul

let looping (array: t_Array u8 (sz 5)) : t_Array u8 (sz 5) =
let array:t_Array u8 (sz 5) =
Rust_primitives.Hax.Folds.fold_range (sz 0)
(Core.Slice.impl__len #u8 (array <: t_Slice u8) <: usize)
(fun array temp_1_ ->
let array:t_Array u8 (sz 5) = array in
let _:usize = temp_1_ in
true)
array
(fun array i ->
let array:t_Array u8 (sz 5) = array in
let i:usize = i in
Rust_primitives.Hax.Monomorphized_update_at.update_at_usize array
i
(cast (i <: usize) <: u8)
<:
t_Array u8 (sz 5))
in
array

let looping_2_ (array: t_Array u8 (sz 5)) : t_Array u8 (sz 5) =
let array, result:(t_Array u8 (sz 5) & Prims.unit) =
Rust_primitives.Hax.Folds.fold_range (sz 0)
(Core.Slice.impl__len #u8 (array <: t_Slice u8) <: usize)
(fun array temp_1_ ->
let array:t_Array u8 (sz 5) = array in
let _:usize = temp_1_ in
true)
array
(fun array i ->
let array:t_Array u8 (sz 5) = array in
let i:usize = i in
Rust_primitives.Hax.Monomorphized_update_at.update_at_usize array
i
(cast (i <: usize) <: u8)
<:
t_Array u8 (sz 5)),
()
<:
(t_Array u8 (sz 5) & Prims.unit)
in
let _:Prims.unit = admit () (* Panic freedom *) in
let _:Prims.unit = result in
array
'''
"Loops.Control_flow.fst" = '''
module Loops.Control_flow
#set-options "--fuel 0 --ifuel 1 --z3rlimit 15"
Expand Down Expand Up @@ -463,7 +514,7 @@ let enumerate_chunks (arr: Alloc.Vec.t_Vec usize Alloc.Alloc.t_Global) : usize =
in
acc

let f (_: Prims.unit) : u8 =
let f (_: Prims.unit) : (u8 & Prims.unit) =
let acc:u8 = 0uy in
Rust_primitives.Hax.Folds.fold_range 1uy
10uy
Expand All @@ -477,7 +528,10 @@ let f (_: Prims.unit) : u8 =
let i:u8 = i in
let acc:u8 = acc +! i in
let _:bool = bool_returning i in
acc)
acc),
()
<:
(u8 & Prims.unit)

let iterator (arr: Alloc.Vec.t_Vec usize Alloc.Alloc.t_Global) : usize =
let acc:usize = sz 0 in
Expand Down Expand Up @@ -653,7 +707,7 @@ module Loops.Recognized_loops
open Core
open FStar.Mul

let enumerated_chunked_slice (#v_T: Type0) (slice: t_Slice v_T) : u64 =
let enumerated_chunked_slice (#v_T: Type0) (slice: t_Slice v_T) : (u64 & Prims.unit) =
let count:u64 = 0uL in
Rust_primitives.Hax.Folds.fold_enumerated_chunked_slice (sz 3)
slice
Expand All @@ -666,9 +720,12 @@ let enumerated_chunked_slice (#v_T: Type0) (slice: t_Slice v_T) : u64 =
let count:u64 = count in
let i:(usize & t_Slice v_T) = i in
let count:u64 = count +! 3uL in
count)
count),
()
<:
(u64 & Prims.unit)

let enumerated_slice (#v_T: Type0) (slice: t_Slice v_T) : u64 =
let enumerated_slice (#v_T: Type0) (slice: t_Slice v_T) : (u64 & Prims.unit) =
let count:u64 = 0uL in
Rust_primitives.Hax.Folds.fold_enumerated_slice slice
(fun count i ->
Expand All @@ -680,9 +737,12 @@ let enumerated_slice (#v_T: Type0) (slice: t_Slice v_T) : u64 =
let count:u64 = count in
let i:(usize & v_T) = i in
let count:u64 = count +! 2uL in
count)
count),
()
<:
(u64 & Prims.unit)

let range (_: Prims.unit) : u64 =
let range (_: Prims.unit) : (u64 & Prims.unit) =
let count:u64 = 0uL in
Rust_primitives.Hax.Folds.fold_range 0uy
10uy
Expand All @@ -695,9 +755,12 @@ let range (_: Prims.unit) : u64 =
let count:u64 = count in
let i:u8 = i in
let count:u64 = count +! 1uL in
count)
count),
()
<:
(u64 & Prims.unit)

let range_step_by (_: Prims.unit) : u64 =
let range_step_by (_: Prims.unit) : (u64 & Prims.unit) =
let count:u64 = 0uL in
Rust_primitives.Hax.Folds.fold_range_step_by 0uy
10uy
Expand All @@ -711,7 +774,10 @@ let range_step_by (_: Prims.unit) : u64 =
let count:u64 = count in
let i:u8 = i in
let count:u64 = count +! 1uL in
count)
count),
()
<:
(u64 & Prims.unit)
'''
"Loops.While_loops.fst" = '''
module Loops.While_loops
Expand Down
16 changes: 16 additions & 0 deletions tests/loops/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,19 @@ mod control_flow {
sum
}
}

mod and_mut_side_effect_loop {
// https://github.com/hacspec/hax/issues/720
fn looping(array: &mut [u8; 5]) {
for i in 0..array.len() {
array[i] = i as u8;
}
}

#[hax_lib::fstar::verification_status(panic_free)]
fn looping_2(array: &mut [u8; 5]) {
for i in 0..array.len() {
array[i] = i as u8;
}
}
}
Loading