@@ -89,51 +89,95 @@ fn safe_to_steal_expr(e: &@ast::expr) -> bool {
89
89
}
90
90
}
91
91
92
+ fn safe_to_steal_ty ( t: & @ast:: ty) -> bool {
93
+ // Same restrictions
94
+ safe_to_replace_ty ( t. node )
95
+ }
96
+
92
97
// Not type-parameterized: https://github.com/graydon/rust/issues/898
93
98
fn stash_expr_if ( c : fn ( & @ast:: expr) ->bool, es: @mutable [ ast:: expr] , e: & @ast:: expr) {
94
99
if c ( e) {
95
100
* es += [ * e] ;
96
101
} else { /* now my indices are wrong :( */ }
97
102
}
98
103
99
- fn steal_exprs ( crate : & ast:: crate ) -> [ ast:: expr ] {
100
- let exprs: @mutable [ ast:: expr ] = @mutable [ ] ;
104
+ fn stash_ty_if ( c : fn ( & @ast:: ty ) ->bool , es : @mutable [ ast:: ty ] , e : & @ast:: ty ) {
105
+ if c ( e) {
106
+ * es += [ * e] ;
107
+ } else { /* now my indices are wrong :( */ }
108
+ }
109
+
110
+ type stolen_stuff = { exprs : [ ast:: expr ] , tys : [ ast:: ty ] } ;
111
+
112
+ fn steal ( crate : & ast:: crate ) -> stolen_stuff {
113
+ let exprs = @mutable [ ] ;
114
+ let tys = @mutable [ ] ;
101
115
let v = visit:: mk_simple_visitor ( @{
102
- visit_expr: bind stash_expr_if ( safe_to_steal_expr, exprs, _)
116
+ visit_expr: bind stash_expr_if ( safe_to_steal_expr, exprs, _) ,
117
+ visit_ty: bind stash_ty_if ( safe_to_steal_ty, tys, _)
103
118
with * visit:: default_simple_visitor ( )
104
119
} ) ;
105
- visit:: visit_crate ( crate , ( ) , v) ; ;
106
- * exprs
120
+ visit:: visit_crate ( crate , ( ) , v) ;
121
+ { exprs : * exprs, tys : * tys }
107
122
}
108
123
109
124
// https://github.com/graydon/rust/issues/652
110
- fn safe_to_replace ( e : ast:: expr_ ) -> bool {
125
+ fn safe_to_replace_expr ( e : ast:: expr_ ) -> bool {
111
126
alt e {
112
127
ast : : expr_if ( _, _, _) { false }
113
128
ast:: expr_block ( _) { false }
114
129
_ { true }
115
130
}
116
131
}
117
132
133
+ fn safe_to_replace_ty ( t : ast:: ty_ ) -> bool {
134
+ alt t {
135
+ ast : : ty_infer. { false } // always implicit, always top level
136
+ ast:: ty_bot. { false } // in source, can only appear as the out type of a function
137
+ ast:: ty_mac ( _) { false }
138
+ _ { true }
139
+ }
140
+ }
141
+
118
142
// Replace the |i|th expr (in fold order) of |crate| with |newexpr|.
119
- fn replace_expr_in_crate ( crate : & ast:: crate , i : uint , newexpr : ast:: expr_ ) ->
143
+ fn replace_expr_in_crate ( crate : & ast:: crate , i : uint , newexpr : & ast:: expr ) ->
120
144
ast:: crate {
121
145
let j: @mutable uint = @mutable 0 u;
122
146
fn fold_expr_rep ( j_ : @mutable uint , i_ : uint , newexpr_ : & ast:: expr_ ,
123
147
original : & ast:: expr_ , fld : fold:: ast_fold ) ->
124
148
ast:: expr_ {
125
149
* j_ += 1 u;
126
- if i_ + 1 u == * j_ && safe_to_replace ( original) {
150
+ if i_ + 1 u == * j_ && safe_to_replace_expr ( original) {
127
151
newexpr_
128
152
} else { fold:: noop_fold_expr ( original, fld) }
129
153
}
130
154
let afp =
131
- { fold_expr: bind fold_expr_rep ( j, i, newexpr, _, _)
155
+ { fold_expr: bind fold_expr_rep ( j, i, newexpr. node , _, _)
156
+ with * fold:: default_ast_fold ( ) } ;
157
+ let af = fold:: make_fold ( afp) ;
158
+ let crate2: @ast:: crate = @af. fold_crate ( crate ) ;
159
+ fold:: dummy_out ( af) ; // work around a leak (https://github.com/graydon/rust/issues/651)
160
+ * crate2
161
+ }
162
+
163
+ // Replace the |i|th ty (in fold order) of |crate| with |newty|.
164
+ fn replace_ty_in_crate ( crate : & ast:: crate , i : uint , newty : & ast:: ty ) ->
165
+ ast:: crate {
166
+ let j: @mutable uint = @mutable 0 u;
167
+ fn fold_ty_rep ( j_ : @mutable uint , i_ : uint , newty_ : & ast:: ty_ ,
168
+ original : & ast:: ty_ , fld : fold:: ast_fold ) ->
169
+ ast:: ty_ {
170
+ * j_ += 1 u;
171
+ if i_ + 1 u == * j_ && safe_to_replace_ty ( original) {
172
+ newty_
173
+ } else { fold:: noop_fold_ty ( original, fld) }
174
+ }
175
+ let afp =
176
+ { fold_ty: bind fold_ty_rep ( j, i, newty. node , _, _)
132
177
with * fold:: default_ast_fold ( ) } ;
133
178
let af = fold:: make_fold ( afp) ;
134
179
let crate2: @ast:: crate = @af. fold_crate ( crate ) ;
135
180
fold:: dummy_out ( af) ; // work around a leak (https://github.com/graydon/rust/issues/651)
136
- ;
137
181
* crate2
138
182
}
139
183
@@ -152,14 +196,30 @@ fn as_str(f: fn(io::writer)) -> str {
152
196
153
197
fn check_variants_of_ast ( crate : & ast:: crate , codemap : & codemap:: codemap ,
154
198
filename : & str ) {
155
- let exprs = steal_exprs ( crate ) ;
156
- let exprsL = vec:: len ( exprs) ;
157
- if exprsL < 100 u {
158
- for each i: uint in under ( uint:: min ( exprsL, 20 u) ) {
159
- log_err "Replacing ... " + pprust::expr_to_str(@exprs[i]);
160
- for each j: uint in under(uint::min(exprsL, 5u)) {
161
- log_err " With ... " + pprust::expr_to_str(@exprs[j]);
162
- let crate2 = @replace_expr_in_crate(crate, i, exprs[j].node);
199
+ let stolen = steal ( crate ) ;
200
+ check_variants_T ( crate , codemap, filename, "expr" , stolen. exprs , pprust:: expr_to_str, replace_expr_in_crate) ;
201
+ check_variants_T ( crate , codemap, filename, "ty" , stolen. tys , pprust:: ty_to_str, replace_ty_in_crate) ;
202
+ }
203
+
204
+ fn check_variants_T < T > (
205
+ crate : & ast:: crate ,
206
+ codemap : & codemap:: codemap ,
207
+ filename : & str ,
208
+ thing_label : & str ,
209
+ things : [ T ] ,
210
+ stringifier : fn ( & @T ) -> str ,
211
+ replacer : fn ( & ast:: crate , uint , & T ) -> ast:: crate
212
+ ) {
213
+ log_err #fmt( "%s contains %u %s objects" , filename, vec:: len ( things) , thing_label) ;
214
+
215
+ let L = vec:: len ( things) ;
216
+
217
+ if L < 100 u {
218
+ for each i: uint in under ( uint:: min ( L , 20 u) ) {
219
+ log_err "Replacing ... " + stringifier(@things[i]);
220
+ for each j: uint in under(uint::min(L, 5u)) {
221
+ log_err " With ... " + stringifier(@things[j]);
222
+ let crate2 = @replacer(crate, i, things[j]);
163
223
// It would be best to test the *crate* for stability, but testing the
164
224
// string for stability is easier and ok for now.
165
225
let str3 =
@@ -168,8 +228,8 @@ fn check_variants_of_ast(crate: &ast::crate, codemap: &codemap::codemap,
168
228
io::string_reader(" ") , _,
169
229
pprust:: no_ann( ) ) ) ;
170
230
check_roundtrip_convergence ( str3, 1 u) ;
171
- //let label = #fmt("buggy_%s_%ud_%ud .rs", last_part(filename), i, j);
172
- //check_whole_compiler(str3, label );
231
+ //let file_label = #fmt("buggy_%s_%s_%u_%u .rs", last_part(filename), thing_label , i, j);
232
+ //check_whole_compiler(str3, file_label );
173
233
}
174
234
}
175
235
}
@@ -214,10 +274,21 @@ fn check_whole_compiler_inner(filename: &str) -> compile_result {
214
274
known_bug ( "https://github.com/graydon/rust/issues/892" )
215
275
} else if contains ( p. err , "(S->getType()->isPointerTy() && \" Invalid cast\" )" ) {
216
276
known_bug ( "https://github.com/graydon/rust/issues/895" )
277
+ } else if contains ( p. err , "Initializer type must match GlobalVariable type" ) {
278
+ known_bug ( "https://github.com/graydon/rust/issues/899" )
279
+ } else if contains ( p. err , "(castIsValid(op, S, Ty) && \" Invalid cast!\" ), function Create" ) {
280
+ known_bug ( "https://github.com/graydon/rust/issues/901" )
217
281
} else {
218
282
log_err "Stderr: " + p. err ;
219
283
failed ( "Unfamiliar error message" )
220
284
}
285
+ } else if p. status == 256 {
286
+ if contains ( p. out , "Out of stack space, sorry" ) {
287
+ known_bug ( "Recursive types - https://github.com/graydon/rust/issues/742" )
288
+ } else {
289
+ log_err "Stdout: " + p. out ;
290
+ failed ( "Unfamiliar sudden exit" )
291
+ }
221
292
} else if p. status == 6 {
222
293
if contains ( p. out , "get_id_ident: can't find item in ext_map" ) {
223
294
known_bug ( "https://github.com/graydon/rust/issues/876" )
@@ -235,7 +306,7 @@ fn check_whole_compiler_inner(filename: &str) -> compile_result {
235
306
passed ( "Accepted the input program" )
236
307
} else {
237
308
log_err p. status ;
238
- log_err p. out ;
309
+ log_err "!Stdout: " + p. out ;
239
310
failed ( "Unfamiliar status code" )
240
311
}
241
312
}
@@ -257,6 +328,7 @@ fn content_is_dangerous_to_modify(code: &str) -> bool {
257
328
let dangerous_patterns =
258
329
[ "#macro" , // not safe to steal things inside of it, because they have a special syntax
259
330
"#" , // strange representation of the arguments to #fmt, for example
331
+ "tag" , // typeck hang: https://github.com/graydon/rust/issues/900
260
332
" be " ] ; // don't want to replace its child with a non-call: "Non-call expression in tail call"
261
333
262
334
for p: str in dangerous_patterns { if contains ( code, p) { ret true ; } }
0 commit comments