@@ -109,7 +109,6 @@ fn broken_fixes_backed_out() {
109
109
fs::File::create(&first).unwrap();
110
110
}
111
111
}
112
-
113
112
let status = Command::new("rustc")
114
113
.args(env::args().skip(1))
115
114
.status()
@@ -160,7 +159,153 @@ fn broken_fixes_backed_out() {
160
159
and we would appreciate a bug report! You're likely to see \n \
161
160
a number of compiler warnings after this message which cargo\n \
162
161
attempted to fix but failed. If you could open an issue at\n \
163
- [..]\n \
162
+ https://github.com/rust-lang/rust/issues\n \
163
+ quoting the full output of this command we'd be very appreciative!\n \
164
+ Note that you may be able to make some more progress in the near-term\n \
165
+ fixing code with the `--broken-code` flag\n \
166
+ \n \
167
+ The following errors were reported:\n \
168
+ error: expected one of `!` or `::`, found `rust`\n \
169
+ ",
170
+ )
171
+ . with_stderr_contains ( "Original diagnostics will follow." )
172
+ . with_stderr_contains ( "[WARNING] variable does not need to be mutable" )
173
+ . with_stderr_does_not_contain ( "[..][FIXED][..]" )
174
+ . run ( ) ;
175
+
176
+ // Make sure the fix which should have been applied was backed out
177
+ assert ! ( p. read_file( "bar/src/lib.rs" ) . contains( "let mut x = 3;" ) ) ;
178
+ }
179
+
180
+ #[ cargo_test]
181
+ fn broken_clippy_fixes_backed_out ( ) {
182
+ // A dummy clippy-driver.
183
+ let clippy_driver = project ( )
184
+ . at ( cargo_test_support:: paths:: global_root ( ) . join ( "clippy-driver" ) )
185
+ . file ( "Cargo.toml" , & basic_manifest ( "clippy-driver" , "0.0.1" ) )
186
+ . file (
187
+ "src/main.rs" ,
188
+ r#"
189
+ fn main() {
190
+ // Do nothing.
191
+ }
192
+ "# ,
193
+ )
194
+ . build ( ) ;
195
+ clippy_driver. cargo ( "build" ) . run ( ) ;
196
+
197
+ // This works as follows:
198
+ // - Create a `rustc` shim (the "foo" project) which will pretend that the
199
+ // verification step fails.
200
+ // - There is an empty build script so `foo` has `OUT_DIR` to track the steps.
201
+ // - The first "check", `foo` creates a file in OUT_DIR, and it completes
202
+ // successfully with a warning diagnostic to remove unused `mut`.
203
+ // - rustfix removes the `mut`.
204
+ // - The second "check" to verify the changes, `foo` swaps out the content
205
+ // with something that fails to compile. It creates a second file so it
206
+ // won't do anything in the third check.
207
+ // - cargo fix discovers that the fix failed, and it backs out the changes.
208
+ // - The third "check" is done to display the original diagnostics of the
209
+ // original code.
210
+ let p = project ( )
211
+ . file (
212
+ "foo/Cargo.toml" ,
213
+ r#"
214
+ [package]
215
+ name = 'foo'
216
+ version = '0.1.0'
217
+ [workspace]
218
+ "# ,
219
+ )
220
+ . file (
221
+ "foo/src/main.rs" ,
222
+ r#"
223
+ use std::env;
224
+ use std::fs;
225
+ use std::io::Write;
226
+ use std::path::{Path, PathBuf};
227
+ use std::process::{self, Command};
228
+
229
+ fn main() {
230
+ // Ignore calls to things like --print=file-names and compiling build.rs.
231
+ // Also compatible for rustc invocations with `@path` argfile.
232
+ let is_lib_rs = env::args_os()
233
+ .map(PathBuf::from)
234
+ .flat_map(|p| if let Some(p) = p.to_str().unwrap_or_default().strip_prefix("@") {
235
+ fs::read_to_string(p).unwrap().lines().map(PathBuf::from).collect()
236
+ } else {
237
+ vec![p]
238
+ })
239
+ .any(|l| l == Path::new("src/lib.rs"));
240
+ if is_lib_rs {
241
+ let path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
242
+ let first = path.join("first");
243
+ let second = path.join("second");
244
+ if first.exists() && !second.exists() {
245
+ fs::write("src/lib.rs", b"not rust code").unwrap();
246
+ fs::File::create(&second).unwrap();
247
+ } else {
248
+ fs::File::create(&first).unwrap();
249
+ }
250
+ }
251
+ let status = Command::new("rustc")
252
+ .args(env::args().skip(1))
253
+ .status()
254
+ .expect("failed to run rustc");
255
+ process::exit(status.code().unwrap_or(2));
256
+ }
257
+ "# ,
258
+ )
259
+ . file (
260
+ "bar/Cargo.toml" ,
261
+ r#"
262
+ [package]
263
+ name = 'bar'
264
+ version = '0.1.0'
265
+ [workspace]
266
+ "# ,
267
+ )
268
+ . file ( "bar/build.rs" , "fn main() {}" )
269
+ . file (
270
+ "bar/src/lib.rs" ,
271
+ r#"
272
+ pub fn foo() {
273
+ let mut x = 3;
274
+ drop(x);
275
+ }
276
+ "# ,
277
+ )
278
+ . build ( ) ;
279
+
280
+ // Build our rustc shim
281
+ p. cargo ( "build" ) . cwd ( "foo" ) . run ( ) ;
282
+
283
+ // Attempt to fix code, but our shim will always fail the second compile.
284
+ // Also, we use `clippy` as a workspace wrapper to make sure that we properly
285
+ // generate the report bug text.
286
+ p. cargo ( "fix --allow-no-vcs --lib" )
287
+ . cwd ( "bar" )
288
+ . env ( "__CARGO_FIX_YOLO" , "1" )
289
+ . env ( "RUSTC" , p. root ( ) . join ( "foo/target/debug/foo" ) )
290
+ // We can't use `clippy` so we use a dummy `clippy-driver` instead.
291
+ . env (
292
+ "RUSTC_WORKSPACE_WRAPPER" ,
293
+ clippy_driver. bin ( "clippy-driver" ) ,
294
+ )
295
+ . with_stderr_contains (
296
+ "warning: failed to automatically apply fixes suggested by rustc \
297
+ to crate `bar`\n \
298
+ \n \
299
+ after fixes were automatically applied the compiler reported \
300
+ errors within these files:\n \
301
+ \n \
302
+ * src/lib.rs\n \
303
+ \n \
304
+ This likely indicates a bug in either rustc or cargo itself,\n \
305
+ and we would appreciate a bug report! You're likely to see \n \
306
+ a number of compiler warnings after this message which cargo\n \
307
+ attempted to fix but failed. If you could open an issue at\n \
308
+ https://github.com/rust-lang/rust-clippy/issues\n \
164
309
quoting the full output of this command we'd be very appreciative!\n \
165
310
Note that you may be able to make some more progress in the near-term\n \
166
311
fixing code with the `--broken-code` flag\n \
0 commit comments