Skip to content

Typestate 5 #343

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

Closed
wants to merge 11 commits into from
Closed
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
50 changes: 34 additions & 16 deletions src/boot/me/trans.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4793,18 +4793,28 @@ let trans_visitor
let trans_arm arm : quad_idx =
let (pat, block) = arm.node in

(* Translates the pattern and returns the addresses of the branch
* instructions that are taken if the match fails.
(* Translates the pattern and returns a pair where the first
component is a list of the addresses of the branch
instructions that are taken if the match fails,
and the second component is a thunk that, when invoked,
emits initialization code for the variables bound in this pattern.

trans_pat can't just emit the initialization code itself, because
then, pattern-bound variables could be taken without ever being
dropped if a nested pattern fails partway through (because the
drop code is part of the action for the pattern).
*)
let rec trans_pat
(pat:Ast.pat)
(src_cell:Il.cell)
(src_ty:Ast.ty)
: quad_idx list =
: (quad_idx list *
(unit -> unit)) =

match pat with
Ast.PAT_lit lit ->
trans_compare_simple Il.JNE (trans_lit lit) (Il.Cell src_cell)
(trans_compare_simple Il.JNE (trans_lit lit) (Il.Cell src_cell),
fun _ -> ())

| Ast.PAT_tag (lval, pats) ->
let tag_ident =
Expand All @@ -4815,7 +4825,7 @@ let trans_visitor
| Ast.LVAL_base { node = Ast.BASE_app (id, _); id = _ } ->
id
| _ -> bug cx "expected lval ending in ident"
in
in
let ttag =
match strip_mutable_or_constrained_ty src_ty with
Ast.TY_tag ttag -> ttag
Expand Down Expand Up @@ -4843,7 +4853,8 @@ let trans_visitor

let tup_cell:Il.cell = get_variant_ptr union_cell i in

let trans_elem_pat i elem_pat : quad_idx list =
let trans_elem_pat i elem_pat :
(quad_idx list * (unit -> unit)) =
let elem_cell =
get_element_ptr_dyn_in_current_frame tup_cell i
in
Expand All @@ -4852,24 +4863,31 @@ let trans_visitor
in

let elem_jumps =
List.concat (Array.to_list (Array.mapi trans_elem_pat pats))
(Array.to_list (Array.mapi trans_elem_pat pats)) in
let (elem_jump_addrs, ks) = List.split elem_jumps
in
next_jumps @ elem_jumps
(next_jumps @ (List.concat elem_jump_addrs),
(* Compose all the var-initialization thunks together
to make one thunk that initializes all the vars *)
List.fold_left (fun g f -> (fun x -> f (g x)))
(fun _ -> ()) ks)

| Ast.PAT_slot (dst, _) ->
let dst_slot = get_slot cx dst.id in
let dst_cell = cell_of_block_slot dst.id in
trans_init_slot_from_cell
(get_ty_params_of_current_frame())
CLONE_none dst_cell dst_slot
src_cell src_ty;
[] (* irrefutable *)

| Ast.PAT_wild -> [] (* irrefutable *)
(* irrefutable *)
([], (fun () -> (* init the slot later, inside the block,
once we know we had a match *)
trans_init_slot_from_cell
(get_ty_params_of_current_frame())
CLONE_none dst_cell dst_slot
src_cell src_ty))
| Ast.PAT_wild -> ([], fun _ -> ()) (* irrefutable *)
in

let (lval_cell, lval_ty) = trans_lval at.Ast.alt_tag_lval in
let next_jumps = trans_pat pat lval_cell lval_ty in
let (next_jumps, prologue) = trans_pat pat lval_cell lval_ty in
prologue (); (* binds any pattern-bound variables *)
trans_block block;
let last_jump = mark() in
emit (Il.jmp Il.JMP Il.CodeNone);
Expand Down
7 changes: 3 additions & 4 deletions src/comp/driver/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,11 @@ fn compile_input(session.session sess,
crate = resolve.resolve_crate(sess, crate);
capture.check_for_captures(sess, crate);

auto ty_cx = ty.mk_ctxt();
auto typeck_result = typeck.check_crate(sess, ty_cx, crate);
auto ty_cx = ty.mk_ctxt(sess);
auto typeck_result = typeck.check_crate(ty_cx, crate);
crate = typeck_result._0;
auto type_cache = typeck_result._1;
// FIXME: uncomment once typestate_check works
// crate = typestate_check.check_crate(crate);
crate = typestate_check.check_crate(crate);
trans.trans_crate(sess, crate, ty_cx, type_cache, output, shared,
optimize, verify, save_temps, ot);
}
Expand Down
2 changes: 2 additions & 0 deletions src/comp/middle/trans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3772,6 +3772,8 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
auto subpat_res = trans_pat_match(matched_cx, subpat,
llsubval, next_cx);
matched_cx = subpat_res.bcx;

i += 1;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/comp/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type mt = rec(t ty, ast.mutability mut);

// Contains information needed to resolve types and (in the future) look up
// the types of AST nodes.
type ctxt = rec(@type_store ts);
type ctxt = rec(@type_store ts, session.session sess);
type ty_ctxt = ctxt; // Needed for disambiguation from Unify.ctxt.

// Convert from method type to function type. Pretty easy; we just drop
Expand Down Expand Up @@ -200,7 +200,7 @@ fn mk_type_store() -> @type_store {
others=map.mk_hashmap[t,t](hasher, eqer));
}

fn mk_ctxt() -> ctxt { ret rec(ts=mk_type_store()); }
fn mk_ctxt(session.session s) -> ctxt { ret rec(ts=mk_type_store(), sess=s); }

// Type constructors

Expand Down
25 changes: 17 additions & 8 deletions src/comp/middle/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ fn substitute_ty_params(&@crate_ctxt ccx,


// Returns the type parameter count and the type for the given definition.
fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.span sp, &ast.def defn)
-> ty_param_count_and_ty {
alt (defn) {
case (ast.def_arg(?id)) {
Expand Down Expand Up @@ -157,7 +157,7 @@ fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
}

case (ast.def_ty(_)) {
fcx.ccx.sess.err("expected value but found type");
fcx.ccx.sess.span_err(sp, "expected value but found type");
fail;
}

Expand Down Expand Up @@ -308,7 +308,10 @@ fn ast_ty_to_ty(ty.ctxt tcx, ty_getter getter, &@ast.ty ast_ty) -> ty.t {
typ = instantiate(tcx, getter, id, path.node.types);
}
case (ast.def_ty_arg(?id)) { typ = ty.mk_param(tcx, id); }
case (_) { fail; }
case (_) {
tcx.sess.span_err(ast_ty.span,
"found type name used as a variable");
fail; }
}

cname = some(path_to_str(path));
Expand Down Expand Up @@ -1839,7 +1842,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
check (defopt != none[ast.def]);
auto defn = option.get[ast.def](defopt);

auto tpt = ty_param_count_and_ty_for_def(fcx, defn);
auto tpt = ty_param_count_and_ty_for_def(fcx, expr.span, defn);

if (ty.def_has_ty_params(defn)) {
auto ann = instantiate_path(fcx, pth, tpt, expr.span);
Expand Down Expand Up @@ -2623,22 +2626,27 @@ fn check_stmt(&@fn_ctxt fcx, &@ast.stmt stmt) -> @ast.stmt {
case (ast.decl_local(_)) {
auto decl_1 = check_decl_local(fcx, decl);
ret @fold.respan[ast.stmt_](stmt.span,
ast.stmt_decl(decl_1, a));
ast.stmt_decl(decl_1,
plain_ann(fcx.ccx.tcx)));
}

case (ast.decl_item(_)) {
// Ignore for now. We'll return later.
ret @fold.respan[ast.stmt_](stmt.span,
ast.stmt_decl(decl,
plain_ann(fcx.ccx.tcx)));
}
}

ret stmt;
// ret stmt;
}

case (ast.stmt_expr(?expr,?a)) {
auto expr_t = check_expr(fcx, expr);
expr_t = Pushdown.pushdown_expr(fcx, expr_ty(fcx.ccx.tcx, expr_t),
expr_t);
ret @fold.respan[ast.stmt_](stmt.span, ast.stmt_expr(expr_t, a));
ret @fold.respan[ast.stmt_](stmt.span,
ast.stmt_expr(expr_t, plain_ann(fcx.ccx.tcx)));
}
}

Expand Down Expand Up @@ -2787,8 +2795,9 @@ fn eq_unify_cache_entry(&unify_cache_entry a, &unify_cache_entry b) -> bool {

type typecheck_result = tup(@ast.crate, ty.type_cache);

fn check_crate(session.session sess, ty.ctxt tcx, @ast.crate crate)
fn check_crate(ty.ctxt tcx, @ast.crate crate)
-> typecheck_result {
auto sess = tcx.sess;
auto result = Collect.collect_item_types(sess, tcx, crate);

let vec[ast.obj_field] fields = vec();
Expand Down
Loading