@@ -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_resolve_honors_rust_version ( Some ( original_ws. resolve_honors_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
@@ -395,7 +411,11 @@ fn add_feature_for_unused_deps(pkg: &Package, parent: &mut dyn toml_edit::TableL
395
411
fixes
396
412
}
397
413
398
- fn check_resolver_change ( ws : & Workspace < ' _ > , opts : & FixOptions ) -> CargoResult < ( ) > {
414
+ fn check_resolver_change < ' gctx > (
415
+ ws : & Workspace < ' gctx > ,
416
+ target_data : & mut RustcTargetData < ' gctx > ,
417
+ opts : & FixOptions ,
418
+ ) -> CargoResult < ( ) > {
399
419
let root = ws. root_maybe ( ) ;
400
420
match root {
401
421
MaybePackage :: Package ( root_pkg) => {
@@ -422,12 +442,10 @@ fn check_resolver_change(ws: &Workspace<'_>, opts: &FixOptions) -> CargoResult<(
422
442
// 2018 without `resolver` set must be V1
423
443
assert_eq ! ( ws. resolve_behavior( ) , ResolveBehavior :: V1 ) ;
424
444
let specs = opts. compile_opts . spec . to_package_id_specs ( ws) ?;
425
- let mut target_data =
426
- RustcTargetData :: new ( ws, & opts. compile_opts . build_config . requested_kinds ) ?;
427
445
let mut resolve_differences = |has_dev_units| -> CargoResult < ( WorkspaceResolve < ' _ > , DiffMap ) > {
428
446
let ws_resolve = ops:: resolve_ws_with_opts (
429
447
ws,
430
- & mut target_data,
448
+ target_data,
431
449
& opts. compile_opts . build_config . requested_kinds ,
432
450
& opts. compile_opts . cli_features ,
433
451
& specs,
@@ -438,7 +456,7 @@ fn check_resolver_change(ws: &Workspace<'_>, opts: &FixOptions) -> CargoResult<(
438
456
let feature_opts = FeatureOpts :: new_behavior ( ResolveBehavior :: V2 , has_dev_units) ;
439
457
let v2_features = FeatureResolver :: resolve (
440
458
ws,
441
- & mut target_data,
459
+ target_data,
442
460
& ws_resolve. targeted_resolve ,
443
461
& ws_resolve. pkg_set ,
444
462
& opts. compile_opts . cli_features ,
@@ -744,7 +762,8 @@ fn rustfix_crate(
744
762
// We'll generate new errors below.
745
763
file. errors_applying_fixes . clear ( ) ;
746
764
}
747
- ( last_output, last_made_changes) = rustfix_and_fix ( & mut files, rustc, filename, gctx) ?;
765
+ ( last_output, last_made_changes) =
766
+ rustfix_and_fix ( & mut files, rustc, filename, args, gctx) ?;
748
767
if current_iteration == 0 {
749
768
first_output = Some ( last_output. clone ( ) ) ;
750
769
}
@@ -801,6 +820,7 @@ fn rustfix_and_fix(
801
820
files : & mut HashMap < String , FixedFile > ,
802
821
rustc : & ProcessBuilder ,
803
822
filename : & Path ,
823
+ args : & FixArgs ,
804
824
gctx : & GlobalContext ,
805
825
) -> CargoResult < ( Output , bool ) > {
806
826
// If not empty, filter by these lints.
@@ -865,10 +885,17 @@ fn rustfix_and_fix(
865
885
continue ;
866
886
} ;
867
887
888
+ let file_path = Path :: new ( & file_name) ;
868
889
// Do not write into registry cache. See rust-lang/cargo#9857.
869
- if Path :: new ( & file_name ) . starts_with ( home_path) {
890
+ if file_path . starts_with ( home_path) {
870
891
continue ;
871
892
}
893
+ // Do not write into standard library source. See rust-lang/cargo#9857.
894
+ if let Some ( sysroot) = args. sysroot . as_deref ( ) {
895
+ if file_path. starts_with ( sysroot) {
896
+ continue ;
897
+ }
898
+ }
872
899
873
900
if !file_names. clone ( ) . all ( |f| f == & file_name) {
874
901
trace ! ( "rejecting as it changes multiple files: {:?}" , suggestion) ;
@@ -1025,6 +1052,8 @@ struct FixArgs {
1025
1052
other : Vec < OsString > ,
1026
1053
/// Path to the `rustc` executable.
1027
1054
rustc : PathBuf ,
1055
+ /// Path to host sysroot.
1056
+ sysroot : Option < PathBuf > ,
1028
1057
}
1029
1058
1030
1059
impl FixArgs {
@@ -1096,13 +1125,19 @@ impl FixArgs {
1096
1125
. saturating_next ( )
1097
1126
} ) ;
1098
1127
1128
+ // ALLOWED: For the internal mechanism of `cargo fix` only.
1129
+ // Shouldn't be set directly by anyone.
1130
+ #[ allow( clippy:: disallowed_methods) ]
1131
+ let sysroot = env:: var_os ( SYSROOT_INTERNAL ) . map ( PathBuf :: from) ;
1132
+
1099
1133
Ok ( FixArgs {
1100
1134
file,
1101
1135
prepare_for_edition,
1102
1136
idioms,
1103
1137
enabled_edition,
1104
1138
other,
1105
1139
rustc,
1140
+ sysroot,
1106
1141
} )
1107
1142
}
1108
1143
0 commit comments