@@ -1906,6 +1906,380 @@ warning: `foo` (lib) generated 1 warning (run `cargo fix --lib -p foo` to apply
1906
1906
. run ( ) ;
1907
1907
}
1908
1908
1909
+ #[ cargo_test]
1910
+ fn fix_in_rust_src ( ) {
1911
+ // Tests what happens if rustc emits a suggestion to modify the standard
1912
+ // library in rust source. This should never happen, and indicates a bug in
1913
+ // rustc. However, there are several known bugs in rustc where it does this
1914
+ // (often involving macros), so `cargo fix` has a guard that says if the
1915
+ // suggestion points to rust source under sysroot to not apply it.
1916
+ //
1917
+ // See https://github.com/rust-lang/cargo/issues/9857 for some other
1918
+ // examples.
1919
+ //
1920
+ // This test uses a simulated rustc which replays a suggestion via a JSON
1921
+ // message that points into rust-src. This does not use the real rustc
1922
+ // because as the bugs are fixed in the real rustc, that would cause this
1923
+ // test to stop working.
1924
+
1925
+ let p = project ( )
1926
+ . file (
1927
+ "Cargo.toml" ,
1928
+ r#"
1929
+ [package]
1930
+ name = "foo"
1931
+ edition = "2021"
1932
+ "# ,
1933
+ )
1934
+ . file (
1935
+ "src/lib.rs" ,
1936
+ r#"
1937
+ pub fn bug_report<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
1938
+ if true {
1939
+ writeln!(w, "`;?` here ->")?;
1940
+ } else {
1941
+ writeln!(w, "but not here")
1942
+ }
1943
+ Ok(())
1944
+ }
1945
+ "# ,
1946
+ )
1947
+ . build ( ) ;
1948
+ p. cargo ( "fetch" ) . run ( ) ;
1949
+
1950
+ // Since this is a substitution into a Rust string (representing a JSON
1951
+ // string), deal with backslashes like on Windows.
1952
+ let sysroot = paths:: sysroot ( ) . replace ( "\\ " , "/" ) ;
1953
+
1954
+ // This is a fake rustc that will emit a JSON message when the `foo` crate
1955
+ // builds that tells cargo to modify a file it shouldn't.
1956
+ let rustc = project ( )
1957
+ . at ( "rustc-replay" )
1958
+ . file ( "Cargo.toml" , & basic_manifest ( "rustc-replay" , "1.0.0" ) )
1959
+ . file ( "src/main.rs" ,
1960
+ & r##"
1961
+ fn main() {
1962
+ let pkg_name = match std::env::var("CARGO_PKG_NAME") {
1963
+ Ok(pkg_name) => pkg_name,
1964
+ Err(_) => {
1965
+ let r = std::process::Command::new("rustc")
1966
+ .args(std::env::args_os().skip(1))
1967
+ .status();
1968
+ std::process::exit(r.unwrap().code().unwrap_or(2));
1969
+ }
1970
+ };
1971
+ if pkg_name == "foo" {
1972
+ eprintln!("{}", r#"{
1973
+ "$message_type": "diagnostic",
1974
+ "message": "mismatched types",
1975
+ "code":
1976
+ {
1977
+ "code": "E0308",
1978
+ "explanation": "Expected type did not match the received type.\n\nErroneous code examples:\n\n```compile_fail,E0308\nfn plus_one(x: i32) -> i32 {\n x + 1\n}\n\nplus_one(\"Not a number\");\n// ^^^^^^^^^^^^^^ expected `i32`, found `&str`\n\nif \"Not a bool\" {\n// ^^^^^^^^^^^^ expected `bool`, found `&str`\n}\n\nlet x: f32 = \"Not a float\";\n// --- ^^^^^^^^^^^^^ expected `f32`, found `&str`\n// |\n// expected due to this\n```\n\nThis error occurs when an expression was used in a place where the compiler\nexpected an expression of a different type. It can occur in several cases, the\nmost common being when calling a function and passing an argument which has a\ndifferent type than the matching type in the function declaration.\n"
1979
+ },
1980
+ "level": "error",
1981
+ "spans":
1982
+ [
1983
+ {
1984
+ "file_name": "__SYSROOT__/lib/rustlib/src/rust/library/core/src/macros/mod.rs",
1985
+ "byte_start": 23568,
1986
+ "byte_end": 23617,
1987
+ "line_start": 670,
1988
+ "line_end": 670,
1989
+ "column_start": 9,
1990
+ "column_end": 58,
1991
+ "is_primary": true,
1992
+ "text":
1993
+ [
1994
+ {
1995
+ "text": " $dst.write_fmt($crate::format_args_nl!($($arg)*))",
1996
+ "highlight_start": 9,
1997
+ "highlight_end": 58
1998
+ }
1999
+ ],
2000
+ "label": "expected `()`, found `Result<(), Error>`",
2001
+ "suggested_replacement": null,
2002
+ "suggestion_applicability": null,
2003
+ "expansion":
2004
+ {
2005
+ "span":
2006
+ {
2007
+ "file_name": "lib.rs",
2008
+ "byte_start": 144,
2009
+ "byte_end": 171,
2010
+ "line_start": 5,
2011
+ "line_end": 5,
2012
+ "column_start": 9,
2013
+ "column_end": 36,
2014
+ "is_primary": false,
2015
+ "text":
2016
+ [
2017
+ {
2018
+ "text": " writeln!(w, \"but not here\")",
2019
+ "highlight_start": 9,
2020
+ "highlight_end": 36
2021
+ }
2022
+ ],
2023
+ "label": null,
2024
+ "suggested_replacement": null,
2025
+ "suggestion_applicability": null,
2026
+ "expansion": null
2027
+ },
2028
+ "macro_decl_name": "writeln!",
2029
+ "def_site_span":
2030
+ {
2031
+ "file_name": "__SYSROOT__/lib/rustlib/src/rust/library/core/src/macros/mod.rs",
2032
+ "byte_start": 23434,
2033
+ "byte_end": 23454,
2034
+ "line_start": 665,
2035
+ "line_end": 665,
2036
+ "column_start": 1,
2037
+ "column_end": 21,
2038
+ "is_primary": false,
2039
+ "text":
2040
+ [
2041
+ {
2042
+ "text": "macro_rules! writeln {",
2043
+ "highlight_start": 1,
2044
+ "highlight_end": 21
2045
+ }
2046
+ ],
2047
+ "label": null,
2048
+ "suggested_replacement": null,
2049
+ "suggestion_applicability": null,
2050
+ "expansion": null
2051
+ }
2052
+ }
2053
+ },
2054
+ {
2055
+ "file_name": "lib.rs",
2056
+ "byte_start": 75,
2057
+ "byte_end": 177,
2058
+ "line_start": 2,
2059
+ "line_end": 6,
2060
+ "column_start": 5,
2061
+ "column_end": 6,
2062
+ "is_primary": false,
2063
+ "text":
2064
+ [
2065
+ {
2066
+ "text": " if true {",
2067
+ "highlight_start": 5,
2068
+ "highlight_end": 14
2069
+ },
2070
+ {
2071
+ "text": " writeln!(w, \"`;?` here ->\")?;",
2072
+ "highlight_start": 1,
2073
+ "highlight_end": 38
2074
+ },
2075
+ {
2076
+ "text": " } else {",
2077
+ "highlight_start": 1,
2078
+ "highlight_end": 13
2079
+ },
2080
+ {
2081
+ "text": " writeln!(w, \"but not here\")",
2082
+ "highlight_start": 1,
2083
+ "highlight_end": 36
2084
+ },
2085
+ {
2086
+ "text": " }",
2087
+ "highlight_start": 1,
2088
+ "highlight_end": 6
2089
+ }
2090
+ ],
2091
+ "label": "expected this to be `()`",
2092
+ "suggested_replacement": null,
2093
+ "suggestion_applicability": null,
2094
+ "expansion": null
2095
+ }
2096
+ ],
2097
+ "children":
2098
+ [
2099
+ {
2100
+ "message": "use the `?` operator to extract the `Result<(), std::fmt::Error>` value, propagating a `Result::Err` value to the caller",
2101
+ "code": null,
2102
+ "level": "help",
2103
+ "spans":
2104
+ [
2105
+ {
2106
+ "file_name": "__SYSROOT__/lib/rustlib/src/rust/library/core/src/macros/mod.rs",
2107
+ "byte_start": 23617,
2108
+ "byte_end": 23617,
2109
+ "line_start": 670,
2110
+ "line_end": 670,
2111
+ "column_start": 58,
2112
+ "column_end": 58,
2113
+ "is_primary": true,
2114
+ "text":
2115
+ [
2116
+ {
2117
+ "text": " $dst.write_fmt($crate::format_args_nl!($($arg)*))",
2118
+ "highlight_start": 58,
2119
+ "highlight_end": 58
2120
+ }
2121
+ ],
2122
+ "label": null,
2123
+ "suggested_replacement": "?",
2124
+ "suggestion_applicability": "HasPlaceholders",
2125
+ "expansion":
2126
+ {
2127
+ "span":
2128
+ {
2129
+ "file_name": "lib.rs",
2130
+ "byte_start": 144,
2131
+ "byte_end": 171,
2132
+ "line_start": 5,
2133
+ "line_end": 5,
2134
+ "column_start": 9,
2135
+ "column_end": 36,
2136
+ "is_primary": false,
2137
+ "text":
2138
+ [
2139
+ {
2140
+ "text": " writeln!(w, \"but not here\")",
2141
+ "highlight_start": 9,
2142
+ "highlight_end": 36
2143
+ }
2144
+ ],
2145
+ "label": null,
2146
+ "suggested_replacement": null,
2147
+ "suggestion_applicability": null,
2148
+ "expansion": null
2149
+ },
2150
+ "macro_decl_name": "writeln!",
2151
+ "def_site_span":
2152
+ {
2153
+ "file_name": "__SYSROOT__/lib/rustlib/src/rust/library/core/src/macros/mod.rs",
2154
+ "byte_start": 23434,
2155
+ "byte_end": 23454,
2156
+ "line_start": 665,
2157
+ "line_end": 665,
2158
+ "column_start": 1,
2159
+ "column_end": 21,
2160
+ "is_primary": false,
2161
+ "text":
2162
+ [
2163
+ {
2164
+ "text": "macro_rules! writeln {",
2165
+ "highlight_start": 1,
2166
+ "highlight_end": 21
2167
+ }
2168
+ ],
2169
+ "label": null,
2170
+ "suggested_replacement": null,
2171
+ "suggestion_applicability": null,
2172
+ "expansion": null
2173
+ }
2174
+ }
2175
+ }
2176
+ ],
2177
+ "children":
2178
+ [],
2179
+ "rendered": null
2180
+ }
2181
+ ],
2182
+ "rendered": "error[E0308]: mismatched types\n --> lib.rs:5:9\n |\n2 | / if true {\n3 | | writeln!(w, \"`;?` here ->\")?;\n4 | | } else {\n5 | | writeln!(w, \"but not here\")\n | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Result<(), Error>`\n6 | | }\n | |_____- expected this to be `()`\n |\n = note: expected unit type `()`\n found enum `Result<(), std::fmt::Error>`\n = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: consider using a semicolon here\n |\n6 | };\n | +\nhelp: you might have meant to return this value\n |\n5 | return writeln!(w, \"but not here\");\n | ++++++ +\nhelp: use the `?` operator to extract the `Result<(), std::fmt::Error>` value, propagating a `Result::Err` value to the caller\n --> __SYSROOT__/lib/rustlib/src/rust/library/core/src/macros/mod.rs:670:58\n |\n67| $dst.write_fmt($crate::format_args_nl!($($arg)*))?\n | +\n\n"
2183
+ }"#.replace("\n", ""));
2184
+
2185
+ std::process::exit(2);
2186
+ }
2187
+ }
2188
+ "## . replace ( "__SYSROOT__" , & sysroot) )
2189
+ . build ( ) ;
2190
+ rustc. cargo ( "build" ) . run ( ) ;
2191
+ let rustc_bin = rustc. bin ( "rustc-replay" ) ;
2192
+
2193
+ // The output here should not say `Fixed`.
2194
+ //
2195
+ // It is OK to compare the full diagnostic output here because the text is
2196
+ // hard-coded in rustc-replay. Normally tests should not be checking the
2197
+ // compiler output.
2198
+ p. cargo ( "fix --lib --allow-no-vcs --broken-code" )
2199
+ . env ( "__CARGO_FIX_YOLO" , "1" )
2200
+ . env ( "RUSTC" , & rustc_bin)
2201
+ . with_status ( 101 )
2202
+ . with_stderr ( r#"[CHECKING] foo v0.0.0 ([..])
2203
+ [WARNING] failed to automatically apply fixes suggested by rustc to crate `foo`
2204
+
2205
+ after fixes were automatically applied the compiler reported errors within these files:
2206
+
2207
+ * [..]/lib/rustlib/src/rust/library/core/src/macros/mod.rs
2208
+ * lib.rs
2209
+
2210
+ This likely indicates a bug in either rustc or cargo itself,
2211
+ and we would appreciate a bug report! You're likely to see
2212
+ a number of compiler warnings after this message which cargo
2213
+ attempted to fix but failed. If you could open an issue at
2214
+ https://github.com/rust-lang/rust/issues
2215
+ quoting the full output of this command we'd be very appreciative!
2216
+ Note that you may be able to make some more progress in the near-term
2217
+ fixing code with the `--broken-code` flag
2218
+
2219
+ The following errors were reported:
2220
+ error[E0308]: mismatched types
2221
+ --> lib.rs:5:9
2222
+ |
2223
+ 2 | / if true {
2224
+ 3 | | writeln!(w, "`;?` here ->")?;
2225
+ 4 | | } else {
2226
+ 5 | | writeln!(w, "but not here")
2227
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Result<(), Error>`
2228
+ 6 | | }
2229
+ | |_____- expected this to be `()`
2230
+ |
2231
+ = note: expected unit type `()`
2232
+ found enum `Result<(), std::fmt::Error>`
2233
+ = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
2234
+ help: consider using a semicolon here
2235
+ |
2236
+ 6 | };
2237
+ | +
2238
+ help: you might have meant to return this value
2239
+ |
2240
+ 5 | return writeln!(w, "but not here");
2241
+ | ++++++ +
2242
+ help: use the `?` operator to extract the `Result<(), std::fmt::Error>` value, propagating a `Result::Err` value to the caller
2243
+ --> [..]/lib/rustlib/src/rust/library/core/src/macros/mod.rs:670:58
2244
+ |
2245
+ 67| $dst.write_fmt($crate::format_args_nl!($($arg)*))?
2246
+ | +
2247
+
2248
+ Original diagnostics will follow.
2249
+
2250
+ error[E0308]: mismatched types
2251
+ --> lib.rs:5:9
2252
+ |
2253
+ 2 | / if true {
2254
+ 3 | | writeln!(w, "`;?` here ->")?;
2255
+ 4 | | } else {
2256
+ 5 | | writeln!(w, "but not here")
2257
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Result<(), Error>`
2258
+ 6 | | }
2259
+ | |_____- expected this to be `()`
2260
+ |
2261
+ = note: expected unit type `()`
2262
+ found enum `Result<(), std::fmt::Error>`
2263
+ = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
2264
+ help: consider using a semicolon here
2265
+ |
2266
+ 6 | };
2267
+ | +
2268
+ help: you might have meant to return this value
2269
+ |
2270
+ 5 | return writeln!(w, "but not here");
2271
+ | ++++++ +
2272
+ help: use the `?` operator to extract the `Result<(), std::fmt::Error>` value, propagating a `Result::Err` value to the caller
2273
+ --> [..]/lib/rustlib/src/rust/library/core/src/macros/mod.rs:670:58
2274
+ |
2275
+ 67| $dst.write_fmt($crate::format_args_nl!($($arg)*))?
2276
+ | +
2277
+
2278
+ [ERROR] could not compile `foo` (lib) due to 1 previous error
2279
+ "# )
2280
+ . run ( ) ;
2281
+ }
2282
+
1909
2283
// This fixes rust-lang/rust#123304.
1910
2284
// If that lint stops emitting duplicate suggestions,
1911
2285
// we might need to find a substitution.
0 commit comments