@@ -12,20 +12,22 @@ import std::vec;
12
12
import std:: ivec;
13
13
import std:: str;
14
14
import std:: uint;
15
+ import std:: option;
15
16
16
17
import rustc:: syntax:: ast;
17
18
import rustc:: syntax:: fold;
18
19
import rustc:: syntax:: walk;
19
20
import rustc:: syntax:: codemap;
21
+ import rustc:: syntax:: parse:: parser;
20
22
import rustc:: syntax:: print:: pprust;
21
23
24
+ /*
25
+ // Imports for "the rest of driver::compile_input"
22
26
import driver = rustc::driver::rustc; // see https://github.com/graydon/rust/issues/624
23
27
import rustc::back::link;
24
28
import rustc::driver::rustc::time;
25
29
import rustc::driver::session;
26
30
27
- /*
28
- // Imports for "the rest of driver::compile_input"
29
31
import rustc::metadata::creader;
30
32
import rustc::metadata::cstore;
31
33
import rustc::syntax::parse::parser;
@@ -43,21 +45,21 @@ import rustc::util::ppaux;
43
45
import rustc::lib::llvm;
44
46
*/
45
47
48
+ fn read_whole_file ( & str filename ) -> str {
49
+ str:: unsafe_from_bytes ( io:: file_reader ( filename) . read_whole_stream ( ) )
50
+ }
51
+
46
52
fn file_contains ( & str filename , & str needle ) -> bool {
47
- auto r = io:: file_reader ( filename) ;
48
- auto contents = str:: unsafe_from_bytes ( r. read_whole_stream ( ) ) ;
53
+ auto contents = read_whole_file ( filename) ;
49
54
ret str:: find ( contents, needle) != -1 ;
50
55
}
51
56
57
+ fn contains ( & str haystack , & str needle ) -> bool { str:: find ( haystack, needle) != -1 }
58
+
52
59
fn find_rust_files( & mutable str[ ] files, str path) {
53
60
if ( str:: ends_with( path, ".rs" ) ) {
54
61
if ( file_contains( path, "xfail-stage1" ) ) {
55
62
//log_err "Skipping " + path + " because it is marked as xfail-stage1";
56
- } else if (
57
- !str:: ends_with( path, "constrained-type.rs" ) && // https://github.com/graydon/rust/issues/653
58
- str:: find( path, "utf8" ) != -1 && // https://github.com/graydon/rust/issues/654
59
- true ) {
60
- //log_err "Skipping " + path + " because of a known bug";
61
63
} else {
62
64
files += ~[ path] ;
63
65
}
@@ -68,10 +70,43 @@ fn find_rust_files(&mutable str[] files, str path) {
68
70
}
69
71
}
70
72
73
+ fn safe_to_steal( ast:: expr_ e) -> bool {
74
+ alt ( e) {
75
+ // pretty-printer precedence issues -- https://github.com/graydon/rust/issues/670
76
+ case ( ast:: expr_unary( _, _) ) { false }
77
+ case ( ast:: expr_lit( ?lit) ) {
78
+ alt( lit. node) {
79
+ case( ast:: lit_str( _, _) ) { true }
80
+ case( ast:: lit_char( _) ) { true }
81
+ case( ast:: lit_int( _) ) { false }
82
+ case( ast:: lit_uint( _) ) { false }
83
+ case( ast:: lit_mach_int( _, _) ) { false }
84
+ case( ast:: lit_float( _) ) { false }
85
+ case( ast:: lit_mach_float( _, _) ) { false }
86
+ case( ast:: lit_nil) { true }
87
+ case( ast:: lit_bool( _) ) { true }
88
+ }
89
+ }
90
+ case ( ast:: expr_cast( _, _) ) { false }
91
+ case ( ast:: expr_send( _, _) ) { false }
92
+ case ( ast:: expr_recv( _, _) ) { false }
93
+ case ( ast:: expr_assert( _) ) { false }
94
+ case ( ast:: expr_binary( _, _, _) ) { false }
95
+ case ( ast:: expr_assign( _, _) ) { false }
96
+ case ( ast:: expr_assign_op( _, _, _) ) { false }
97
+
98
+ // "if (ret) { }" doesn't make sense, at least from a typecheck point of view, but for some reason it's rejected by the *parser*
99
+ case ( ast:: expr_ret( option:: none) ) { false }
100
+ case ( ast:: expr_put( option:: none) ) { false }
101
+
102
+ case ( _) { true }
103
+ }
104
+ }
105
+
71
106
fn steal_exprs( & ast:: crate crate) -> ast:: expr[ ] {
72
107
let @mutable ast:: expr[ ] exprs = @mutable ~[ ] ;
73
- // "Stash" cannot be type-parameterized because of https://github.com/graydon/rust/issues/375
74
- fn stash_expr( @mutable ast:: expr[ ] es, & @ast:: expr e) { * es += ~[ * e] ; }
108
+ // "Stash" is not type-parameterized because of the need for safe_to_steal
109
+ fn stash_expr( @mutable ast:: expr[ ] es, & @ast:: expr e) { if ( safe_to_steal ( e . node ) ) { * es += ~[ * e] ; } else { /* now my indices are wrong :( */ } }
75
110
auto v = rec( visit_expr_pre = bind stash_expr( exprs, _) with walk:: default_visitor( ) ) ;
76
111
walk:: walk_crate( v, crate ) ;
77
112
* exprs
@@ -108,7 +143,9 @@ iter under(uint n) -> uint { let uint i = 0u; while (i < n) { put i; i += 1u; }
108
143
109
144
fn devnull ( ) -> io:: writer { std : : io:: string_writer ( ) . get_writer ( ) }
110
145
111
- fn pp_variants ( & ast:: crate crate, & session:: session sess, & str filename) {
146
+ fn as_str ( fn ( io:: writer) f) -> str { auto w = std:: io:: string_writer ( ) ; f ( w. get_writer ( ) ) ; w. get_str ( ) }
147
+
148
+ fn pp_variants ( & ast:: crate crate, & codemap:: codemap cmap, & str filename) {
112
149
auto exprs = steal_exprs ( crate ) ;
113
150
auto exprsL = ivec:: len ( exprs) ;
114
151
if ( exprsL < 100 u) {
@@ -117,44 +154,56 @@ fn pp_variants(&ast::crate crate, &session::session sess, &str filename) {
117
154
for each (uint j in under(uint::min(exprsL, 5u))) {
118
155
log_err " With ... " + pprust::expr_to_str(@exprs.(j));
119
156
auto crate2 = @replace_expr_in_crate(crate, i, exprs.(j).node);
120
- pprust::print_crate(sess.get_codemap(), crate2 , filename, devnull(), pprust::no_ann() );
157
+ check_roundtrip(crate2, cmap , filename + " . 4 . rs" ) ;
121
158
}
122
159
}
123
160
}
124
161
}
125
162
163
+ fn check_roundtrip( @ast:: crate crate2, & codemap:: codemap cmap, & str fakefilename) {
164
+ auto str3 = as_str( bind pprust:: print_crate( cmap, crate2, "empty.rs" , _, pprust:: no_ann( ) ) ) ;
165
+ auto cm4 = codemap:: new_codemap( ) ;
166
+ if ( true
167
+ && !contains( str3, "][]" ) // https://github.com/graydon/rust/issues/669
168
+ && !contains( str3, "][mutable]" ) // https://github.com/graydon/rust/issues/669
169
+ && !contains( str3, "][mutable ]" ) // https://github.com/graydon/rust/issues/669
170
+ && !contains( str3, "self" ) // crazy rules enforced by parser rather than typechecker?
171
+ && !contains( str3, "spawn" ) // more precedence issues
172
+ && !contains( str3, "bind" ) // more precedence issues?
173
+ ) {
174
+ auto crate4 = parser:: parse_crate_from_source_str( fakefilename, str3, ~[ ] , cm4) ;
175
+ // should compare crates at this point, but it's easier to compare strings
176
+ auto str5 = as_str( bind pprust:: print_crate( cmap, crate4, "empty.rs" , _, pprust:: no_ann( ) ) ) ;
177
+ if ( !str:: is_ascii( str3) ) {
178
+ log_err "Non-ASCII in " + fakefilename; // why does non-ASCII work correctly with "rustc --pretty normal" but not here???
179
+ } else if ( str3 ! = str5) {
180
+ log_err "Mismatch: " + fakefilename;
181
+ log_err "str3:\n " + str3;
182
+ log_err "str5:\n " + str5;
183
+ fail "Mismatch" ;
184
+ }
185
+ }
186
+ }
187
+
126
188
fn main( vec[ str ] args) {
127
189
auto files = ~[ ] ;
128
190
auto root = "/Users/jruderman/code/rust/src/" ; // XXX
129
191
find_rust_files( files, root) ; // not using time here because that currently screws with passing-a-mutable-array
130
192
log_err uint:: str( ivec:: len( files) ) + " files" ;
131
193
132
- auto binary = vec:: shift[ str] ( args) ;
133
- auto binary_dir = fs:: dirname( binary) ;
134
-
135
- let @session:: options sopts =
136
- @rec( library=false,
137
- static=false,
138
- optimize=0 u,
139
- debuginfo=false,
140
- verify=true,
141
- run_typestate=true,
142
- save_temps=false,
143
- stats=false,
144
- time_passes=false,
145
- time_llvm_passes=false,
146
- output_type=link:: output_type_bitcode,
147
- library_search_paths=[ binary_dir + "/lib" ] ,
148
- sysroot=driver:: get_default_sysroot( binary) ,
149
- cfg=~[ ] ,
150
- test=false ) ;
151
-
152
194
for ( str file in files) {
153
195
log_err "=== " + file + " ===" ;
154
- let session:: session sess = driver:: build_session ( sopts) ;
155
- let @ast:: crate crate = time ( true , "parsing " + file, bind driver:: parse_input ( sess, ~[ ] , file) ) ;
156
- pprust:: print_crate ( sess. get_codemap ( ) , crate , file, devnull ( ) , pprust:: no_ann ( ) ) ;
157
- pp_variants ( * crate , sess, file) ;
196
+ auto cm = codemap:: new_codemap( ) ;
197
+ auto src = read_whole_file( file) ;
198
+ auto crate = parser:: parse_crate_from_source_str( file, src, ~[ ] , cm) ;
199
+ if ( !contains( src, "#macro" ) // https://github.com/graydon/rust/issues/671
200
+ && !str:: ends_with( file, "block-expr-precedence.rs" ) // https://github.com/graydon/rust/issues/674
201
+ && !str:: ends_with( file, "syntax-extension-fmt.rs" ) // an issue where -2147483648 gains an extra negative sign each time through, which i can't reproduce using "rustc --pretty normal"???
202
+ ) {
203
+ check_roundtrip( crate , cm, file + ".pp.rs" ) ;
204
+ }
205
+ //pprust::print_crate(cm, crate, file, devnull(), pprust::no_ann());
206
+ //pp_variants(*crate, cm, file);
158
207
}
159
208
}
160
209
0 commit comments