Skip to content

Commit 0ed5c5c

Browse files
committed
---
yaml --- r: 16023 b: refs/heads/try c: f5c51b0 h: refs/heads/master i: 16021: 0424af3 16019: c5d06b2 16015: b4e18c3 v: v3
1 parent 666649c commit 0ed5c5c

File tree

9 files changed

+90
-501
lines changed

9 files changed

+90
-501
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: 0d3811e2759acfea03ee60892c15e018a59c12c0
5+
refs/heads/try: f5c51b0a9c084418ae90b8909dc10b13ff318d72
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/rustc/middle/tstate/auxiliary.rs

Lines changed: 58 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,10 @@ fn comma_str(args: [@constr_arg_use]) -> str {
4949
}
5050

5151
fn constraint_to_str(tcx: ty::ctxt, c: sp_constr) -> str {
52-
alt c.node {
53-
ninit(id, i) {
54-
ret #fmt("init(%s id=%d - arising from %s)",
55-
i, id, codemap::span_to_str(c.span, tcx.sess.codemap));
56-
}
57-
npred(p, _, args) {
58-
ret #fmt("%s(%s) - arising from %s",
59-
path_to_str(p),
60-
comma_str(args),
61-
codemap::span_to_str(c.span, tcx.sess.codemap));
62-
}
63-
}
52+
ret #fmt("%s(%s) - arising from %s",
53+
path_to_str(c.node.path),
54+
comma_str(c.node.args),
55+
codemap::span_to_str(c.span, tcx.sess.codemap));
6456
}
6557

6658
fn tritv_to_str(fcx: fn_ctxt, v: tritv::t) -> str {
@@ -167,16 +159,14 @@ fn print_idents(&idents: [ident]) {
167159
/* Two different data structures represent constraints in different
168160
contexts: constraint and norm_constraint.
169161
170-
constraint gets used to record constraints in a table keyed by def_ids.
171-
cinit constraints represent a single constraint, for the initialization
172-
state of a variable; a cpred constraint, with a single operator and a
173-
list of possible argument lists, could represent several constraints at
174-
once.
162+
constraint gets used to record constraints in a table keyed by def_ids. Each
163+
constraint has a single operator but a list of possible argument lists, and
164+
thus represents several constraints at once, one for each possible argument
165+
list.
175166
176-
norm_constraint, in contrast, gets used when handling an instance
177-
of a constraint rather than a definition of a constraint. It can
178-
also be init or pred (ninit or npred), but the npred case just has
179-
a single argument list.
167+
norm_constraint, in contrast, gets used when handling an instance of a
168+
constraint rather than a definition of a constraint. It has only a single
169+
argument list.
180170
181171
The representation of constraints, where multiple instances of the
182172
same predicate are collapsed into one entry in the table, makes it
@@ -198,37 +188,23 @@ type pred_args = spanned<pred_args_>;
198188
// for this local.
199189
type constr_arg_use = spanned<constr_arg_general_<inst>>;
200190
201-
/*
202-
A constraint is either an init constraint, referring to the initialization
203-
state of a variable (not initialized, definitely initialized, or maybe
204-
initialized) or a predicate constraint, referring to the truth value of a
205-
predicate on variables (definitely false, maybe true, or definitely true).
206-
207-
cinit and ninit represent init constraints, while cpred and npred
208-
represent predicate constraints.
209-
210-
In a predicate constraint, the <path> field (and the <def_id> field
211-
in the npred constructor) names a user-defined function that may
212-
be the operator in a "check" expression in the source.
213-
*/
214-
215-
enum constraint {
216-
cinit(uint, span, ident),
191+
/* Predicate constraints refer to the truth value of a predicate on variables
192+
(definitely false, maybe true, or definitely true). The <path> field (and the
193+
<def_id> field in the npred constructor) names a user-defined function that
194+
may be the operator in a "check" expression in the source. */
217195

196+
type constraint = {
197+
path: @path,
218198
// FIXME: really only want it to be mut during collect_locals.
219199
// freeze it after that.
220-
cpred(@path, @mut [pred_args]),
221-
}
200+
descs: @mut [pred_args]
201+
};
222202

223-
// An ninit variant has a node_id because it refers to a local var.
224-
// An npred has a def_id since the definition of the typestate
225-
// predicate need not be local.
226-
// FIXME: would be nice to give both a def_id field,
227-
// and give ninit a constraint saying it's local.
228-
enum tsconstr {
229-
ninit(node_id, ident),
230-
npred(@path, def_id, [@constr_arg_use]),
231-
}
203+
type tsconstr = {
204+
path: @path,
205+
def_id: def_id,
206+
args: [@constr_arg_use]
207+
};
232208

233209
type sp_constr = spanned<tsconstr>;
234210

@@ -238,34 +214,8 @@ type constr_map = std::map::hashmap<def_id, constraint>;
238214

239215
/* Contains stuff that has to be computed up front */
240216
/* For easy access, the fn_info stores two special constraints for each
241-
function. i_return holds if all control paths in this function terminate
242-
in either a return expression, or an appropriate tail expression.
243-
i_diverge holds if all control paths in this function terminate in a fail
244-
or diverging call.
245-
246-
It might be tempting to use a single constraint C for both properties,
247-
where C represents i_return and !C represents i_diverge. This is
248-
inadvisable, because then the sense of the bit depends on context. If we're
249-
inside a ! function, that reverses the sense of the bit: C would be
250-
i_diverge and !C would be i_return. That's awkward, because we have to
251-
pass extra context around to functions that shouldn't care.
252-
253-
Okay, suppose C represents i_return and !C represents i_diverge, regardless
254-
of context. Consider this code:
255-
256-
if (foo) { ret; } else { fail; }
257-
258-
C is true in the consequent and false in the alternative. What's T `join`
259-
F, then? ? doesn't work, because this code should definitely-return if the
260-
context is a returning function (and be definitely-rejected if the context
261-
is a ! function). F doesn't work, because then the code gets incorrectly
262-
rejected if the context is a returning function. T would work, but it
263-
doesn't make sense for T `join` F to be T (consider init constraints, for
264-
example).;
265-
266-
So we need context. And so it seems clearer to just have separate
267-
constraints.
268-
*/
217+
function. So we need context. And so it seems clearer to just have separate
218+
constraints. */
269219
type fn_info =
270220
/* list, accumulated during pre/postcondition
271221
computation, of all local variables that may be
@@ -274,21 +224,8 @@ type fn_info =
274224
{constrs: constr_map,
275225
num_constraints: uint,
276226
cf: ret_style,
277-
i_return: tsconstr,
278-
i_diverge: tsconstr,
279227
used_vars: @mut [node_id]};
280228

281-
fn tsconstr_to_def_id(t: tsconstr) -> def_id {
282-
alt t { ninit(id, _) { local_def(id) } npred(_, id, _) { id } }
283-
}
284-
285-
fn tsconstr_to_node_id(t: tsconstr) -> node_id {
286-
alt t {
287-
ninit(id, _) { id }
288-
npred(_, id, _) { fail "tsconstr_to_node_id called on pred constraint" }
289-
}
290-
}
291-
292229
/* mapping from node ID to typestate annotation */
293230
type node_ann_table = @mut [mut ts_ann];
294231

@@ -534,20 +471,15 @@ fn node_id_to_def(ccx: crate_ctxt, id: node_id) -> option<def> {
534471
}
535472

536473
fn norm_a_constraint(id: def_id, c: constraint) -> [norm_constraint] {
537-
alt c {
538-
cinit(n, sp, i) {
539-
ret [{bit_num: n, c: respan(sp, ninit(id.node, i))}];
540-
}
541-
cpred(p, descs) {
542-
let mut rslt: [norm_constraint] = [];
543-
for vec::each(*descs) {|pd|
544-
rslt +=
545-
[{bit_num: pd.node.bit_num,
546-
c: respan(pd.span, npred(p, id, pd.node.args))}];
547-
}
548-
ret rslt;
549-
}
474+
let mut rslt: [norm_constraint] = [];
475+
for vec::each(*c.descs) {|pd|
476+
rslt +=
477+
[{bit_num: pd.node.bit_num,
478+
c: respan(pd.span, {path: c.path,
479+
def_id: id,
480+
args: pd.node.args})}];
550481
}
482+
ret rslt;
551483
}
552484

553485

@@ -630,8 +562,9 @@ fn expr_to_constr(tcx: ty::ctxt, e: @expr) -> sp_constr {
630562
alt operator.node {
631563
expr_path(p) {
632564
ret respan(e.span,
633-
npred(p, def_id_for_constr(tcx, operator.id),
634-
exprs_to_constr_args(tcx, args)));
565+
{path: p,
566+
def_id: def_id_for_constr(tcx, operator.id),
567+
args: exprs_to_constr_args(tcx, args)});
635568
}
636569
_ {
637570
tcx.sess.span_bug(operator.span,
@@ -657,7 +590,9 @@ fn substitute_constr_args(cx: ty::ctxt, actuals: [@expr], c: @ty::constr) ->
657590
for c.node.args.each {|a|
658591
rslt += [substitute_arg(cx, actuals, a)];
659592
}
660-
ret npred(c.node.path, c.node.id, rslt);
593+
ret {path: c.node.path,
594+
def_id: c.node.id,
595+
args: rslt};
661596
}
662597

663598
fn substitute_arg(cx: ty::ctxt, actuals: [@expr], a: @constr_arg) ->
@@ -718,31 +653,22 @@ enum dest {
718653

719654
type subst = [{from: inst, to: inst}];
720655

721-
fn find_instances(_fcx: fn_ctxt, subst: subst, c: constraint) ->
722-
[{from: uint, to: uint}] {
723-
724-
let mut rslt = [];
725-
if vec::len(subst) == 0u { ret rslt; }
726-
727-
alt c {
728-
cinit(_, _, _) {/* this is dealt with separately */ }
729-
cpred(p, descs) {
730-
// FIXME (#2280): this temporary shouldn't be
731-
// necessary, but seems to be, for borrowing.
732-
let ds = copy *descs;
733-
for vec::each(ds) {|d|
734-
if args_mention(d.node.args, find_in_subst_bool, subst) {
735-
let old_bit_num = d.node.bit_num;
736-
let newv = replace(subst, d);
737-
alt find_instance_(newv, *descs) {
738-
some(d1) { rslt += [{from: old_bit_num, to: d1}]; }
739-
_ { }
740-
}
656+
fn find_instances(_fcx: fn_ctxt, subst: subst,
657+
c: constraint) -> [{from: uint, to: uint}] {
658+
659+
if vec::len(subst) == 0u { ret []; }
660+
let mut res = [];
661+
for (*c.descs).each { |d|
662+
if args_mention(d.node.args, find_in_subst_bool, subst) {
663+
let old_bit_num = d.node.bit_num;
664+
let newv = replace(subst, d);
665+
alt find_instance_(newv, *c.descs) {
666+
some(d1) {res += [{from: old_bit_num, to: d1}]}
667+
_ {}
741668
}
742-
}
743-
}
669+
} else {}
744670
}
745-
rslt
671+
ret res;
746672
}
747673

748674
fn find_in_subst(id: node_id, s: subst) -> option<inst> {
@@ -912,25 +838,6 @@ fn forget_in_postcond(fcx: fn_ctxt, parent_exp: node_id, dead_v: node_id) {
912838
}
913839
}
914840

915-
fn forget_in_postcond_still_init(fcx: fn_ctxt, parent_exp: node_id,
916-
dead_v: node_id) {
917-
// In the postcondition given by parent_exp, clear the bits
918-
// for any constraints mentioning dead_v
919-
let d = local_node_id_to_local_def_id(fcx, dead_v);
920-
alt d {
921-
some(d_id) {
922-
for constraints(fcx).each {|c|
923-
if non_init_constraint_mentions(fcx, c, d_id) {
924-
clear_in_postcond(c.bit_num,
925-
node_id_to_ts_ann(fcx.ccx,
926-
parent_exp).conditions);
927-
}
928-
}
929-
}
930-
_ { }
931-
}
932-
}
933-
934841
fn forget_in_poststate(fcx: fn_ctxt, p: poststate, dead_v: node_id) -> bool {
935842
// In the poststate given by parent_exp, clear the bits
936843
// for any constraints mentioning dead_v
@@ -949,44 +856,14 @@ fn forget_in_poststate(fcx: fn_ctxt, p: poststate, dead_v: node_id) -> bool {
949856
ret changed;
950857
}
951858

952-
fn forget_in_poststate_still_init(fcx: fn_ctxt, p: poststate, dead_v: node_id)
953-
-> bool {
954-
// In the poststate given by parent_exp, clear the bits
955-
// for any constraints mentioning dead_v
956-
let d = local_node_id_to_local_def_id(fcx, dead_v);
957-
let mut changed = false;
958-
alt d {
959-
some(d_id) {
960-
for constraints(fcx).each {|c|
961-
if non_init_constraint_mentions(fcx, c, d_id) {
962-
changed |= clear_in_poststate_(c.bit_num, p);
963-
}
964-
}
965-
}
966-
_ { }
967-
}
968-
ret changed;
969-
}
970-
971859
fn any_eq(v: [node_id], d: node_id) -> bool {
972860
for v.each {|i| if i == d { ret true; } }
973861
false
974862
}
975863

976864
fn constraint_mentions(_fcx: fn_ctxt, c: norm_constraint, v: node_id) ->
977865
bool {
978-
ret alt c.c.node {
979-
ninit(id, _) { v == id }
980-
npred(_, _, args) { args_mention(args, any_eq, [v]) }
981-
};
982-
}
983-
984-
fn non_init_constraint_mentions(_fcx: fn_ctxt, c: norm_constraint, v: node_id)
985-
-> bool {
986-
ret alt c.c.node {
987-
ninit(_, _) { false }
988-
npred(_, _, args) { args_mention(args, any_eq, [v]) }
989-
};
866+
ret args_mention(c.c.node.args, any_eq, [v]);
990867
}
991868

992869
fn args_mention<T>(args: [@constr_arg_use],
@@ -1063,8 +940,9 @@ fn args_to_constr_args(tcx: ty::ctxt, args: [arg],
1063940
fn ast_constr_to_ts_constr(tcx: ty::ctxt, args: [arg], c: @constr) ->
1064941
tsconstr {
1065942
let tconstr = ty::ast_constr_to_constr(tcx, c);
1066-
ret npred(tconstr.node.path, tconstr.node.id,
1067-
args_to_constr_args(tcx, args, tconstr.node.args));
943+
ret {path: tconstr.node.path,
944+
def_id: tconstr.node.id,
945+
args: args_to_constr_args(tcx, args, tconstr.node.args)};
1068946
}
1069947

1070948
fn ast_constr_to_sp_constr(tcx: ty::ctxt, args: [arg], c: @constr) ->

0 commit comments

Comments
 (0)