Skip to content

Commit cda82fa

Browse files
committed
---
yaml --- r: 2992 b: refs/heads/master c: b34a97d h: refs/heads/master v: v3
1 parent c690f9c commit cda82fa

File tree

5 files changed

+62
-4
lines changed

5 files changed

+62
-4
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 17ff2a0d7960c58b12898cb0142917a0cffb7559
2+
refs/heads/master: b34a97de39e3b34d5121d9b6eb5ad91d22cd2d04

trunk/src/comp/middle/tstate/ann.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ fn pps_len(&pre_and_post p) -> uint {
8989
ret p.precondition.nbits;
9090
}
9191

92+
fn require(uint i, &pre_and_post p) -> () {
93+
// sets the ith bit in p's pre
94+
bitv::set(p.precondition, i, true);
95+
}
96+
9297
fn require_and_preserve(uint i, &pre_and_post p) -> () {
9398
// sets the ith bit in p's pre and post
9499
bitv::set(p.precondition, i, true);

trunk/src/comp/middle/tstate/bitvectors.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ fn intersect_postconds(&vec[postcond] pcs) -> postcond {
144144
}
145145

146146
fn gen(&fn_ctxt fcx, &ann a, &def_id id, &constr_occ o) -> bool {
147-
log "gen";
148147
ret set_in_postcond(bit_num(fcx, id, o),
149148
(ann_to_ts_ann(fcx.ccx, a)).conditions);
150149
}

trunk/src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ import std::option;
44
import std::option::none;
55
import std::option::some;
66

7+
// FIXME: needs to be tstate::ann because ann is also a type name...
8+
// that's probably a bug.
79
import tstate::ann::pre_and_post;
810
import tstate::ann::get_post;
911
import tstate::ann::postcond;
1012
import tstate::ann::true_precond;
1113
import tstate::ann::false_postcond;
1214
import tstate::ann::empty_poststate;
15+
import tstate::ann::require;
1316
import tstate::ann::require_and_preserve;
1417
import tstate::ann::union;
1518
import tstate::ann::intersect;
@@ -22,6 +25,7 @@ import aux::fn_ctxt;
2225
import aux::occ_init;
2326
import aux::num_constraints;
2427
import aux::constraint;
28+
import aux::constr_occ;
2529
import aux::expr_pp;
2630
import aux::stmt_pp;
2731
import aux::block_pp;
@@ -41,6 +45,11 @@ import aux::ann_to_def_strict;
4145
import aux::ann_to_ts_ann;
4246
import aux::set_postcond_false;
4347
import aux::controlflow_expr;
48+
import aux::expr_to_constr;
49+
import aux::constraint_info;
50+
import aux::constr_to_constr_occ;
51+
import aux::constraints_expr;
52+
import aux::substitute_constr_args;
4453

4554
import bitvectors::seq_preconds;
4655
import bitvectors::union_postconds;
@@ -52,6 +61,7 @@ import bitvectors::gen;
5261
import front::ast::*;
5362

5463
import middle::ty::expr_ann;
64+
import middle::ty::lookup_fn_decl;
5565

5666
import util::common::new_def_hash;
5767
import util::common::decl_lhs;
@@ -210,6 +220,38 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) -> () {
210220
auto args = vec::clone[@expr](operands);
211221
vec::push[@expr](args, operator);
212222
find_pre_post_exprs(fcx, args, a);
223+
224+
/* see if the call has any constraints on its in type */
225+
let option::t[tup(fn_decl, def_id)] decl_and_id =
226+
lookup_fn_decl(fcx.ccx.tcx, expr_ann(operator));
227+
alt (decl_and_id) {
228+
case (some(?p)) {
229+
log("known function: " );
230+
log_expr(*operator);
231+
let def_id f_id = p._1;
232+
let fn_decl f_decl = p._0;
233+
auto pp = expr_pp(fcx.ccx, e);
234+
for (@constr c in constraints_expr(fcx.ccx, operator)) {
235+
auto i = bit_num(fcx, f_id,
236+
substitute_constr_args(fcx.ccx.tcx, operands,
237+
f_decl.inputs, c));
238+
require(i, pp);
239+
}
240+
}
241+
// FIXME: Soundness? If a function is constrained...
242+
// shouldn't be able to pass it as an argument
243+
// But typechecking guarantees that. However, we could
244+
// have an unknown function w/ a constrained type =>
245+
// no decl... but need to know the argument names.
246+
// Fix that and then make a test w/ a higher-order
247+
// constrained function.
248+
case (_) {
249+
log("unknown function: " );
250+
log_expr(*operator);
251+
/* unknown function -- do nothing */ }
252+
}
253+
// FIXME: constraints on result type
254+
213255
/* if this is a failing call, its postcondition sets everything */
214256
alt (controlflow_expr(fcx.ccx, operator)) {
215257
case (noreturn) {
@@ -471,9 +513,14 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) -> () {
471513
copy_pre_post(fcx.ccx, a, p);
472514
}
473515
case (expr_check(?p, ?a)) {
474-
/* will need to change when we support arbitrary predicates... */
516+
/* FIXME: Can we bypass this by having a
517+
node-id-to-constr_occ table? */
475518
find_pre_post_expr(fcx, p);
476519
copy_pre_post(fcx.ccx, a, p);
520+
/* predicate p holds after this expression executes */
521+
let constraint_info c = expr_to_constr(fcx.ccx.tcx, p);
522+
let constr_occ o = constr_to_constr_occ(fcx.ccx.tcx, c.c.node);
523+
gen(fcx, a, c.id, o);
477524
}
478525
case(expr_bind(?operator, ?maybe_args, ?a)) {
479526
auto args = vec::cat_options[@expr](maybe_args);

trunk/src/comp/middle/tstate/states.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ import aux::block_states;
4949
import aux::controlflow_expr;
5050
import aux::ann_to_def;
5151
import aux::occ_init;
52+
import aux::expr_to_constr;
53+
import aux::constraint_info;
54+
import aux::constr_to_constr_occ;
55+
import aux::constr_occ;
5256

5357
import bitvectors::seq_preconds;
5458
import bitvectors::union_postconds;
@@ -521,8 +525,11 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
521525
case (expr_check(?p, ?a)) {
522526
changed = extend_prestate_ann(fcx.ccx, a, pres) || changed;
523527
changed = find_pre_post_state_expr(fcx, pres, p) || changed;
524-
/* FIXME: update the postcondition to reflect that p holds */
525528
changed = extend_poststate_ann(fcx.ccx, a, pres) || changed;
529+
/* predicate p holds after this expression executes */
530+
let constraint_info c = expr_to_constr(fcx.ccx.tcx, p);
531+
let constr_occ o = constr_to_constr_occ(fcx.ccx.tcx, c.c.node);
532+
changed = gen_poststate(fcx, a, c.id, o) || changed;
526533
ret changed;
527534
}
528535
case (expr_break(?a)) {

0 commit comments

Comments
 (0)