@@ -8,35 +8,21 @@ import std::option::none;
8
8
import std:: option:: some;
9
9
import std:: option:: maybe;
10
10
11
- import front:: ast;
12
- import front:: ast:: def;
13
- import front:: ast:: def_fn;
14
- import front:: ast:: _fn;
15
- import front:: ast:: def_obj_field;
16
- import front:: ast:: def_id;
17
- import front:: ast:: expr_path;
18
- import front:: ast:: ident;
19
- import front:: ast:: controlflow;
20
- import front:: ast:: ann;
21
- import front:: ast:: stmt;
22
- import front:: ast:: expr;
23
- import front:: ast:: block;
24
- import front:: ast:: block_;
25
- import front:: ast:: stmt_decl;
26
- import front:: ast:: stmt_expr;
27
- import front:: ast:: stmt_crate_directive;
28
- import front:: ast:: return;
29
- import front:: ast:: expr_field;
11
+ import front:: ast:: * ;
30
12
31
13
import middle:: ty:: expr_ann;
32
14
33
15
import util:: common;
34
16
import util:: common:: span;
17
+ import util:: common:: respan;
35
18
import util:: common:: log_block;
36
19
import util:: common:: new_def_hash;
37
20
import util:: common:: new_uint_hash;
38
21
import util:: common:: log_expr_err;
39
22
import util:: common:: uistr;
23
+ import util:: common:: lit_eq;
24
+ import pretty:: pprust:: path_to_str;
25
+ import pretty:: pprust:: lit_to_str;
40
26
41
27
import tstate:: ann:: pre_and_post;
42
28
import tstate:: ann:: pre_and_post_state;
@@ -63,14 +49,51 @@ fn def_id_to_str(def_id d) -> str {
63
49
ret ( istr ( d. _0 ) + "," + istr ( d. _1 ) ) ;
64
50
}
65
51
52
+ fn comma_str ( vec[ @constr_arg] args ) -> str {
53
+ auto res = "" ;
54
+ auto comma = false ;
55
+ for ( @constr_arg a in args) {
56
+ if ( comma) {
57
+ res += ", " ;
58
+ }
59
+ else {
60
+ comma = true ;
61
+ }
62
+ alt ( a. node ) {
63
+ case ( carg_base) {
64
+ res += "*" ;
65
+ }
66
+ case ( carg_ident ( ?i) ) {
67
+ res += i;
68
+ }
69
+ case ( carg_lit ( ?l) ) {
70
+ res += lit_to_str ( l) ;
71
+ }
72
+ }
73
+ }
74
+ ret res;
75
+ }
76
+
77
+ fn constraint_to_str ( ty:: ctxt tcx, constr c) -> str {
78
+ alt ( c. node ) {
79
+ case ( ninit ( ?i) ) {
80
+ ret "init(" + i + " [" + tcx. sess . span_str ( c. span ) + "])" ;
81
+ }
82
+ case ( npred ( ?p, ?args) ) {
83
+ ret path_to_str ( p) + "(" + comma_str ( args) + ")"
84
+ + "[" + tcx. sess . span_str ( c. span ) + "]" ;
85
+ }
86
+ }
87
+ }
88
+
66
89
fn bitv_to_str ( fn_ctxt fcx, bitv:: t v) -> str {
67
90
auto s = "" ;
68
91
auto comma = false ;
69
92
70
- for each ( @tup ( def_id , var_info ) p in fcx . enclosing . vars . items ( ) ) {
71
- if ( bitv:: get ( v, p. _1 . bit_num ) ) {
93
+ for ( norm_constraint p in constraints ( fcx ) ) {
94
+ if ( bitv:: get ( v, p. bit_num ) ) {
72
95
s += ( if ( comma) { ", " } else { comma = true ; "" } )
73
- + p . _1 . name + " [" + fcx. ccx . tcx . sess . span_str ( p . _1 . sp ) + "]" ;
96
+ + aux :: constraint_to_str ( fcx. ccx . tcx , p . c ) ;
74
97
}
75
98
}
76
99
ret s;
@@ -84,19 +107,19 @@ fn first_difference_string(&fn_ctxt fcx, &bitv::t expected,
84
107
& bitv:: t actual ) -> str {
85
108
let str s = "" ;
86
109
auto done = false ;
87
- for each ( @tup ( def_id , var_info ) p in fcx . enclosing . vars . items ( ) ) {
110
+ for ( norm_constraint c in constraints ( fcx ) ) {
88
111
if ( !done) {
89
- if ( bitv:: get ( expected, p . _1 . bit_num ) &&
90
- !bitv:: get ( actual, p . _1 . bit_num ) ) {
112
+ if ( bitv:: get ( expected, c . bit_num ) &&
113
+ !bitv:: get ( actual, c . bit_num ) ) {
91
114
92
115
/*
116
+ FIXME
93
117
for fun, try either:
94
118
* "ret s" after the assignment to s
95
119
or
96
120
* using break here
97
121
*/
98
- s = ( p. _1 . name + " ["
99
- + fcx. ccx . tcx . sess . span_str ( p. _1 . sp ) + "]" ) ;
122
+ s = constraint_to_str ( fcx. ccx . tcx , c. c ) ;
100
123
101
124
done = true ;
102
125
}
@@ -183,14 +206,35 @@ fn print_idents(vec[ident] idents) -> () {
183
206
/* data structures */
184
207
185
208
/**********************************************************************/
186
- /* mapping from variable name (def_id is assumed to be for a local
187
- variable in a given function) to bit number
188
- (also remembers the ident and span for error-logging purposes) */
189
- type var_info = rec ( uint bit_num ,
190
- ident name,
191
- span sp) ;
192
- type fn_info = rec ( @std:: map:: hashmap[ def_id, var_info] vars ,
193
- controlflow cf) ;
209
+ /* mapping from def_id to bit number and other data
210
+ (ident/path/span are there for error-logging purposes) */
211
+
212
+ type pred_desc_ = rec ( vec[ @constr_arg] args ,
213
+ uint bit_num ) ;
214
+ type pred_desc = spanned[ pred_desc_ ] ;
215
+ tag constraint {
216
+ cinit( uint, span, ident) ;
217
+ cpred ( path, vec[ pred_desc] ) ;
218
+ }
219
+ tag constr_ {
220
+ ninit( ident) ;
221
+ npred ( path, vec[ @constr_arg] ) ;
222
+ }
223
+ type constr = spanned[ constr_ ] ;
224
+ type norm_constraint = rec ( uint bit_num ,
225
+ constr c) ;
226
+ /* "constraint occurrence" to disambiguate
227
+ between constraints. either "this is an
228
+ init constraint", or the list of args for
229
+ a pred. */
230
+ tag constr_occ {
231
+ occ_init;
232
+ occ_args ( vec[ @constr_arg] ) ;
233
+ }
234
+
235
+ type constr_map = @std:: map:: hashmap [ def_id, constraint] ;
236
+
237
+ type fn_info = rec ( constr_map constrs, uint num_constraints , controlflow cf) ;
194
238
195
239
/* mapping from node ID to typestate annotation */
196
240
type node_ann_table = @vec[ ts_ann ] ;
@@ -418,8 +462,8 @@ fn fixed_point_states(&fn_ctxt fcx,
418
462
}
419
463
}
420
464
421
- fn num_locals ( fn_info m) -> uint {
422
- ret m. vars . size ( ) ;
465
+ fn num_constraints ( fn_info m) -> uint {
466
+ ret m. num_constraints ;
423
467
}
424
468
425
469
fn new_crate_ctxt ( ty:: ctxt cx) -> crate_ctxt {
@@ -463,6 +507,89 @@ fn ann_to_def(&crate_ctxt ccx, &ann a) -> option::t[def] {
463
507
ret ccx. tcx . def_map . find ( a. id ) ;
464
508
}
465
509
510
+ fn norm_a_constraint ( & constraint c) -> vec[ norm_constraint ] {
511
+ alt ( c) {
512
+ case ( cinit ( ?n, ?sp, ?i) ) {
513
+ ret [ rec ( bit_num=n, c=respan ( sp, ninit ( i) ) ) ] ;
514
+ }
515
+ case ( cpred ( ?p, ?descs) ) {
516
+ let vec[ norm_constraint] res = [ ] ;
517
+ for ( pred_desc pd in descs) {
518
+ vec:: push ( res, rec ( bit_num=pd. node . bit_num ,
519
+ c=respan ( pd. span , npred ( p, pd. node . args ) ) ) ) ;
520
+ }
521
+ ret res;
522
+ }
523
+ }
524
+ }
525
+
526
+ // Tried to write this as an iterator, but I got a
527
+ // non-exhaustive match in trans.
528
+ fn constraints ( & fn_ctxt fcx) -> vec[ norm_constraint ] {
529
+ let vec[ norm_constraint] res = [ ] ;
530
+ for each ( @tup( def_id, constraint) p in
531
+ fcx. enclosing . constrs . items ( ) ) {
532
+ res += norm_a_constraint ( p. _1 ) ;
533
+ }
534
+ ret res;
535
+ }
536
+
537
+ fn arg_eq ( @constr_arg a , @constr_arg b ) -> bool {
538
+ alt ( a. node ) {
539
+ case ( carg_base) {
540
+ alt ( b. node ) {
541
+ case ( carg_base) {
542
+ ret true ;
543
+ }
544
+ case ( _) {
545
+ ret false ;
546
+ }
547
+ }
548
+ }
549
+ case ( carg_ident ( ?s) ) {
550
+ alt ( b. node ) {
551
+ case ( carg_ident ( ?t) ) {
552
+ ret ( s == t) ;
553
+ }
554
+ case ( _) {
555
+ ret false ;
556
+ }
557
+ }
558
+ }
559
+ case ( carg_lit ( ?l) ) {
560
+ alt ( b. node ) {
561
+ case ( carg_lit ( ?m) ) {
562
+ ret lit_eq ( l, m) ;
563
+ }
564
+ case ( _) {
565
+ ret false ;
566
+ }
567
+ }
568
+ }
569
+ }
570
+ }
571
+
572
+ fn args_eq ( vec[ @constr_arg] a , vec[ @constr_arg] b ) -> bool {
573
+ let uint i = 0 u;
574
+ for ( @constr_arg arg in a) {
575
+ if ( !arg_eq ( arg, b. ( i) ) ) {
576
+ ret false ;
577
+ }
578
+ i += 1 u;
579
+ }
580
+ ret true;
581
+ }
582
+
583
+ fn match_args ( & fn_ctxt fcx, vec[ pred_desc] occs ,
584
+ vec[ @constr_arg] occ ) -> uint {
585
+ for ( pred_desc pd in occs) {
586
+ if ( args_eq ( pd. node . args , occ) ) {
587
+ ret pd. node . bit_num ;
588
+ }
589
+ }
590
+ fcx. ccx . tcx . sess . bug ( "match_args: no match for occurring args" ) ;
591
+ }
592
+
466
593
//
467
594
// Local Variables:
468
595
// mode: rust
0 commit comments