fn do_nothing[T](&_fn f, &ty_param[] tp, &span sp, &fn_ident i,
node_id iid, &T cx, &visit::vt[T] v) {
}
+
+
+fn args_to_constr_args(&span sp, &arg[] args) -> (@constr_arg_use)[] {
+ let (@constr_arg_use)[] actuals = ~[];
+ for (arg a in args) {
+ actuals += ~[@respan(sp, carg_ident(tup(a.ident, a.id)))];
+ }
+ ret actuals;
+}
+
+fn ast_constr_to_ts_constr(&ty::ctxt tcx, &arg[] args, &@constr c)
+ -> tsconstr {
+ auto tconstr = ty::ast_constr_to_constr(tcx, c);
+ ret npred(tconstr.node.path, tconstr.node.id,
+ args_to_constr_args(tconstr.span, args));
+}
+
+fn ast_constr_to_sp_constr(&ty::ctxt tcx, &arg[] args, &@constr c)
+ -> sp_constr {
+ auto tconstr = ast_constr_to_ts_constr(tcx, args, c);
+ ret respan(c.span, tconstr);
+}
+
//
// Local Variables:
// mode: rust
ret set_in_poststate_(bit_num(fcx, ninit(id, ident)), t);
}
+fn set_in_prestate_constr(&fn_ctxt fcx, &tsconstr c, &prestate t) -> bool {
+ ret set_in_poststate_(bit_num(fcx, c), t);
+}
+
fn clear_in_poststate_ident(&fn_ctxt fcx, &node_id id, &ident ident,
&node_id parent) -> bool {
ret kill_poststate(fcx, parent, ninit(id, ident));
-
+import std::uint;
+import std::int;
import std::ivec;
import syntax::ast::*;
import util::ppaux::fn_ident_to_string;
to a bit number in the precondition/postcondition vectors */
fn mk_fn_info(&crate_ctxt ccx, &_fn f, &ty_param[] tp,
&span f_sp, &fn_ident f_name, node_id id) {
+ auto name = fn_ident_to_string(id, f_name);
auto res_map = @new_def_hash[constraint]();
let uint next = 0u;
for (sp_constr c in { *cx.cs }) {
next = add_constraint(cx.tcx, c, next, res_map);
}
+ /* if this function has any constraints, instantiate them to the
+ argument names and add them */
+ auto sc;
+ for (@constr c in f.decl.constraints) {
+ sc = ast_constr_to_sp_constr(cx.tcx, f.decl.inputs, c);
+ next = add_constraint(cx.tcx, sc, next, res_map);
+ }
+
/* add a pseudo-entry for the function's return value
we can safely use the function's name itself for this purpose */
- auto name = fn_ident_to_string(id, f_name);
add_constraint(cx.tcx, respan(f_sp, ninit(id, name)), next, res_map);
let @mutable node_id[] v = @mutable ~[];
auto rslt =
rec(constrs=res_map,
- num_constraints=ivec::len(*cx.cs) + 1u,
+ num_constraints=ivec::len(*cx.cs) + ivec::len(f.decl.constraints)
+ + 1u,
cf=f.decl.cf,
used_vars=v);
ccx.fm.insert(id, rslt);
+import syntax::print::pprust::path_to_str;
import std::ivec;
import std::option;
import std::option::get;
import tritv::tritv_set;
import tritv::ttrue;
+import bitvectors::*;
+/*
import bitvectors::set_in_poststate_ident;
import bitvectors::clear_in_poststate_expr;
import bitvectors::clear_in_prestate_ident;
import bitvectors::kill_poststate;
import bitvectors::clear_in_poststate_ident;
import bitvectors::intersect_states;
+*/
import syntax::ast::*;
import middle::ty::expr_ty;
import middle::ty::type_is_nil;
auto num_local_vars = num_constraints(fcx.enclosing);
// make sure the return bit starts out False
clear_in_prestate_ident(fcx, fcx.id, fcx.name, f.body.node.id);
- auto changed =
- find_pre_post_state_block(fcx, block_prestate(fcx.ccx, f.body),
- f.body);
+ // Instantiate any constraints on the arguments so we can use them
+ auto block_pre = block_prestate(fcx.ccx, f.body);
+ auto tsc;
+ for (@constr c in f.decl.constraints) {
+ tsc = ast_constr_to_ts_constr(fcx.ccx.tcx, f.decl.inputs, c);
+ set_in_prestate_constr(fcx, tsc, block_pre);
+ }
+
+ auto changed = find_pre_post_state_block(fcx, block_pre, f.body);
// Treat the tail expression as a return statement
alt (f.body.node.expr) {
--- /dev/null
+pred p(int i) -> bool { true }
+
+fn f(int i) : p(i) -> int { i }
+
+fn g(int i) : p(i) -> int { f(i) }
+
+fn main() {
+}