@@ -50,6 +50,7 @@ use rustfix::CodeFix;
50
50
use semver:: Version ;
51
51
use tracing:: { debug, trace, warn} ;
52
52
53
+ use crate :: core:: compiler:: CompileKind ;
53
54
use crate :: core:: compiler:: RustcTargetData ;
54
55
use crate :: core:: resolver:: features:: { DiffMap , FeatureOpts , FeatureResolver , FeaturesFor } ;
55
56
use crate :: core:: resolver:: { HasDevUnits , Resolve , ResolveBehavior } ;
@@ -78,6 +79,14 @@ const EDITION_ENV_INTERNAL: &str = "__CARGO_FIX_EDITION";
78
79
/// **Internal only.**
79
80
/// For passing [`FixOptions::idioms`] through to cargo running in proxy mode.
80
81
const IDIOMS_ENV_INTERNAL : & str = "__CARGO_FIX_IDIOMS" ;
82
+ /// **Internal only.**
83
+ /// The sysroot path.
84
+ ///
85
+ /// This is for preventing `cargo fix` from fixing rust std/core libs. See
86
+ ///
87
+ /// * <https://github.com/rust-lang/cargo/issues/9857>
88
+ /// * <https://github.com/rust-lang/rust/issues/88514#issuecomment-2043469384>
89
+ const SYSROOT_INTERNAL : & str = "__CARGO_FIX_RUST_SRC" ;
81
90
82
91
pub struct FixOptions {
83
92
pub edition : bool ,
@@ -97,6 +106,8 @@ pub fn fix(
97
106
) -> CargoResult < ( ) > {
98
107
check_version_control ( gctx, opts) ?;
99
108
109
+ let mut target_data =
110
+ RustcTargetData :: new ( original_ws, & opts. compile_opts . build_config . requested_kinds ) ?;
100
111
if opts. edition {
101
112
let specs = opts. compile_opts . spec . to_package_id_specs ( & original_ws) ?;
102
113
let members: Vec < & Package > = original_ws
@@ -105,7 +116,7 @@ pub fn fix(
105
116
. collect ( ) ;
106
117
migrate_manifests ( original_ws, & members) ?;
107
118
108
- check_resolver_change ( & original_ws, opts) ?;
119
+ check_resolver_change ( & original_ws, & mut target_data , opts) ?;
109
120
}
110
121
let mut ws = Workspace :: new ( & root_manifest, gctx) ?;
111
122
ws. set_honor_rust_version ( original_ws. honor_rust_version ( ) ) ;
@@ -129,6 +140,11 @@ pub fn fix(
129
140
wrapper. env ( IDIOMS_ENV_INTERNAL , "1" ) ;
130
141
}
131
142
143
+ let sysroot = & target_data. info ( CompileKind :: Host ) . sysroot ;
144
+ if sysroot. is_dir ( ) {
145
+ wrapper. env ( SYSROOT_INTERNAL , sysroot) ;
146
+ }
147
+
132
148
* opts
133
149
. compile_opts
134
150
. build_config
@@ -328,7 +344,11 @@ fn add_feature_for_unused_deps(pkg: &Package, parent: &mut dyn toml_edit::TableL
328
344
fixes
329
345
}
330
346
331
- fn check_resolver_change ( ws : & Workspace < ' _ > , opts : & FixOptions ) -> CargoResult < ( ) > {
347
+ fn check_resolver_change < ' gctx > (
348
+ ws : & Workspace < ' gctx > ,
349
+ target_data : & mut RustcTargetData < ' gctx > ,
350
+ opts : & FixOptions ,
351
+ ) -> CargoResult < ( ) > {
332
352
let root = ws. root_maybe ( ) ;
333
353
match root {
334
354
MaybePackage :: Package ( root_pkg) => {
@@ -355,12 +375,10 @@ fn check_resolver_change(ws: &Workspace<'_>, opts: &FixOptions) -> CargoResult<(
355
375
// 2018 without `resolver` set must be V1
356
376
assert_eq ! ( ws. resolve_behavior( ) , ResolveBehavior :: V1 ) ;
357
377
let specs = opts. compile_opts . spec . to_package_id_specs ( ws) ?;
358
- let mut target_data =
359
- RustcTargetData :: new ( ws, & opts. compile_opts . build_config . requested_kinds ) ?;
360
378
let mut resolve_differences = |has_dev_units| -> CargoResult < ( WorkspaceResolve < ' _ > , DiffMap ) > {
361
379
let ws_resolve = ops:: resolve_ws_with_opts (
362
380
ws,
363
- & mut target_data,
381
+ target_data,
364
382
& opts. compile_opts . build_config . requested_kinds ,
365
383
& opts. compile_opts . cli_features ,
366
384
& specs,
@@ -371,7 +389,7 @@ fn check_resolver_change(ws: &Workspace<'_>, opts: &FixOptions) -> CargoResult<(
371
389
let feature_opts = FeatureOpts :: new_behavior ( ResolveBehavior :: V2 , has_dev_units) ;
372
390
let v2_features = FeatureResolver :: resolve (
373
391
ws,
374
- & mut target_data,
392
+ target_data,
375
393
& ws_resolve. targeted_resolve ,
376
394
& ws_resolve. pkg_set ,
377
395
& opts. compile_opts . cli_features ,
@@ -677,7 +695,8 @@ fn rustfix_crate(
677
695
// We'll generate new errors below.
678
696
file. errors_applying_fixes . clear ( ) ;
679
697
}
680
- ( last_output, last_made_changes) = rustfix_and_fix ( & mut files, rustc, filename, gctx) ?;
698
+ ( last_output, last_made_changes) =
699
+ rustfix_and_fix ( & mut files, rustc, filename, args, gctx) ?;
681
700
if current_iteration == 0 {
682
701
first_output = Some ( last_output. clone ( ) ) ;
683
702
}
@@ -734,6 +753,7 @@ fn rustfix_and_fix(
734
753
files : & mut HashMap < String , FixedFile > ,
735
754
rustc : & ProcessBuilder ,
736
755
filename : & Path ,
756
+ args : & FixArgs ,
737
757
gctx : & GlobalContext ,
738
758
) -> CargoResult < ( Output , bool ) > {
739
759
// If not empty, filter by these lints.
@@ -798,10 +818,17 @@ fn rustfix_and_fix(
798
818
continue ;
799
819
} ;
800
820
821
+ let file_path = Path :: new ( & file_name) ;
801
822
// Do not write into registry cache. See rust-lang/cargo#9857.
802
- if Path :: new ( & file_name ) . starts_with ( home_path) {
823
+ if file_path . starts_with ( home_path) {
803
824
continue ;
804
825
}
826
+ // Do not write into standard library source. See rust-lang/cargo#9857.
827
+ if let Some ( sysroot) = args. sysroot . as_deref ( ) {
828
+ if file_path. starts_with ( sysroot) {
829
+ continue ;
830
+ }
831
+ }
805
832
806
833
if !file_names. clone ( ) . all ( |f| f == & file_name) {
807
834
trace ! ( "rejecting as it changes multiple files: {:?}" , suggestion) ;
@@ -958,6 +985,8 @@ struct FixArgs {
958
985
other : Vec < OsString > ,
959
986
/// Path to the `rustc` executable.
960
987
rustc : PathBuf ,
988
+ /// Path to host sysroot.
989
+ sysroot : Option < PathBuf > ,
961
990
}
962
991
963
992
impl FixArgs {
@@ -1029,13 +1058,19 @@ impl FixArgs {
1029
1058
. saturating_next ( )
1030
1059
} ) ;
1031
1060
1061
+ // ALLOWED: For the internal mechanism of `cargo fix` only.
1062
+ // Shouldn't be set directly by anyone.
1063
+ #[ allow( clippy:: disallowed_methods) ]
1064
+ let sysroot = env:: var_os ( SYSROOT_INTERNAL ) . map ( PathBuf :: from) ;
1065
+
1032
1066
Ok ( FixArgs {
1033
1067
file,
1034
1068
prepare_for_edition,
1035
1069
idioms,
1036
1070
enabled_edition,
1037
1071
other,
1038
1072
rustc,
1073
+ sysroot,
1039
1074
} )
1040
1075
}
1041
1076
0 commit comments