@@ -49,18 +49,10 @@ fn comma_str(args: [@constr_arg_use]) -> str {
49
49
}
50
50
51
51
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 ) ) ;
64
56
}
65
57
66
58
fn tritv_to_str ( fcx : fn_ctxt , v : tritv:: t ) -> str {
@@ -167,16 +159,14 @@ fn print_idents(&idents: [ident]) {
167
159
/* Two different data structures represent constraints in different
168
160
contexts: constraint and norm_constraint.
169
161
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.
175
166
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.
180
170
181
171
The representation of constraints, where multiple instances of the
182
172
same predicate are collapsed into one entry in the table, makes it
@@ -198,37 +188,23 @@ type pred_args = spanned<pred_args_>;
198
188
// for this local.
199
189
type constr_arg_use = spanned<constr_arg_general_<inst>>;
200
190
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. * /
217
195
196
+ type constraint = {
197
+ path: @path,
218
198
// FIXME: really only want it to be mut during collect_locals.
219
199
// freeze it after that.
220
- cpred ( @path , @mut [ pred_args] ) ,
221
- }
200
+ descs : @mut [ pred_args]
201
+ } ;
222
202
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
+ } ;
232
208
233
209
type sp_constr = spanned<tsconstr>;
234
210
@@ -238,34 +214,8 @@ type constr_map = std::map::hashmap<def_id, constraint>;
238
214
239
215
/* Contains stuff that has to be computed up front */
240
216
/* 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. */
269
219
type fn_info =
270
220
/* list, accumulated during pre/postcondition
271
221
computation, of all local variables that may be
@@ -274,21 +224,8 @@ type fn_info =
274
224
{ constrs: constr_map,
275
225
num_constraints: uint,
276
226
cf: ret_style,
277
- i_return: tsconstr,
278
- i_diverge: tsconstr,
279
227
used_vars: @mut [ node_id] } ;
280
228
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
-
292
229
/* mapping from node ID to typestate annotation */
293
230
type node_ann_table = @mut [ mut ts_ann] ;
294
231
@@ -534,20 +471,15 @@ fn node_id_to_def(ccx: crate_ctxt, id: node_id) -> option<def> {
534
471
}
535
472
536
473
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} ) } ] ;
550
481
}
482
+ ret rslt;
551
483
}
552
484
553
485
@@ -630,8 +562,9 @@ fn expr_to_constr(tcx: ty::ctxt, e: @expr) -> sp_constr {
630
562
alt operator. node {
631
563
expr_path( p) {
632
564
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) } ) ;
635
568
}
636
569
_ {
637
570
tcx. sess. span_bug( operator. span,
@@ -657,7 +590,9 @@ fn substitute_constr_args(cx: ty::ctxt, actuals: [@expr], c: @ty::constr) ->
657
590
for c. node. args. each { |a|
658
591
rslt += [ substitute_arg( cx, actuals, a) ] ;
659
592
}
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} ;
661
596
}
662
597
663
598
fn substitute_arg ( cx : ty:: ctxt , actuals : [ @expr] , a : @constr_arg ) ->
@@ -718,31 +653,22 @@ enum dest {
718
653
719
654
type subst = [ { from: inst, to: inst} ] ;
720
655
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) == 0 u { 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) == 0 u { 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
+ _ { }
741
668
}
742
- }
743
- }
669
+ } else { }
744
670
}
745
- rslt
671
+ ret res ;
746
672
}
747
673
748
674
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) {
912
838
}
913
839
}
914
840
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
-
934
841
fn forget_in_poststate( fcx: fn_ctxt, p: poststate, dead_v: node_id) -> bool {
935
842
// In the poststate given by parent_exp, clear the bits
936
843
// for any constraints mentioning dead_v
@@ -949,44 +856,14 @@ fn forget_in_poststate(fcx: fn_ctxt, p: poststate, dead_v: node_id) -> bool {
949
856
ret changed;
950
857
}
951
858
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
-
971
859
fn any_eq( v: [ node_id] , d: node_id) -> bool {
972
860
for v. each { |i| if i == d { ret true; } }
973
861
false
974
862
}
975
863
976
864
fn constraint_mentions( _fcx: fn_ctxt, c: norm_constraint, v: node_id) ->
977
865
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] ) ;
990
867
}
991
868
992
869
fn args_mention < T > ( args: [ @constr_arg_use] ,
@@ -1063,8 +940,9 @@ fn args_to_constr_args(tcx: ty::ctxt, args: [arg],
1063
940
fn ast_constr_to_ts_constr ( tcx : ty:: ctxt , args : [ arg ] , c : @constr ) ->
1064
941
tsconstr {
1065
942
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 ) } ;
1068
946
}
1069
947
1070
948
fn ast_constr_to_sp_constr ( tcx : ty:: ctxt , args : [ arg ] , c : @constr ) ->
0 commit comments