1use std::fs;
4use std::path::{Path, PathBuf};
5
6use crate::core::backend::CodegenBackendKind;
7use crate::core::build_steps::compile::{
8 ArtifactKeepMode, add_to_sysroot, run_cargo, rustc_cargo, std_cargo, std_crates_for_make_run,
9};
10use crate::core::build_steps::tool;
11use crate::core::build_steps::tool::{
12 SourceType, TEST_FLOAT_PARSE_ALLOW_FEATURES, ToolTargetBuildMode, get_tool_target_compiler,
13 prepare_tool_cargo,
14};
15use crate::core::builder::{
16 self, Alias, Builder, Cargo, CommandLineStep, Kind, RunConfig, ShouldRun, Step, StepMetadata,
17 crate_description,
18};
19use crate::core::compiler::Compiler;
20use crate::core::config::TargetSelection;
21use crate::core::session::Mode;
22use crate::utils::build_stamp::{self, BuildStamp};
23use crate::utils::helpers::t;
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28enum CheckKind {
29 Check,
30 Fix,
31}
32
33impl CheckKind {
34 fn to_kind(self) -> Kind {
35 match self {
36 CheckKind::Check => Kind::Check,
37 CheckKind::Fix => Kind::Fix,
38 }
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq, Hash)]
43pub struct Std {
44 pub build_compiler: Compiler,
46 pub target: TargetSelection,
47 crates: Vec<String>,
53}
54
55impl Std {
56 const CRATE_OR_DEPS: &[&str] = &["sysroot", "coretests", "alloctests"];
57}
58
59impl CommandLineStep for Std {
60 type Output = BuildStamp;
61
62 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
63 let mut run = run;
64 for c in Std::CRATE_OR_DEPS {
65 run = run.crate_or_deps(c);
66 }
67
68 run.path("library")
69 }
70
71 fn is_default_step(_builder: &Builder<'_>) -> bool {
72 true
73 }
74
75 fn make_run(run: RunConfig<'_>) {
76 if !run.builder.download_rustc() && run.builder.config.skip_std_check_if_no_download_rustc {
77 eprintln!(
78 "WARNING: `--skip-std-check-if-no-download-rustc` flag was passed and `rust.download-rustc` is not available. Skipping."
79 );
80 return;
81 }
82
83 if run.builder.config.compile_time_deps {
84 return;
86 }
87
88 let crates = std_crates_for_make_run(&run);
92 run.builder.ensure(Std {
93 build_compiler: prepare_compiler_for_check(run.builder, run.target, Mode::Std)
94 .build_compiler(),
95 target: run.target,
96 crates,
97 });
98 }
99
100 fn run(self, builder: &Builder<'_>) -> Self::Output {
101 let build_compiler = self.build_compiler;
102 let target = self.target;
103
104 let mut cargo = builder::Cargo::new(
105 builder,
106 build_compiler,
107 Mode::Std,
108 SourceType::InTree,
109 target,
110 builder.kind,
111 );
112
113 std_cargo(builder, target, &mut cargo, &self.crates);
114 if matches!(builder.kind, Kind::Fix) {
115 cargo.arg("--lib");
117 }
118
119 let _guard = builder.msg(
120 builder.kind,
121 format_args!("library artifacts{}", crate_description(&self.crates)),
122 Mode::Std,
123 build_compiler,
124 target,
125 );
126
127 let check_stamp =
128 build_stamp::libstd_stamp(builder, build_compiler, target).with_prefix("check");
129 run_cargo(
130 builder,
131 cargo,
132 builder.config.free_args.clone(),
133 &check_stamp,
134 vec![],
135 ArtifactKeepMode::OnlyRmeta,
136 );
137
138 drop(_guard);
139
140 if !self.crates.iter().any(|krate| krate == "test") {
142 return check_stamp;
143 }
144
145 let mut cargo = builder::Cargo::new(
152 builder,
153 build_compiler,
154 Mode::Std,
155 SourceType::InTree,
156 target,
157 Kind::Check,
158 );
159
160 std_cargo(builder, target, &mut cargo, &self.crates);
161
162 let stamp =
163 build_stamp::libstd_stamp(builder, build_compiler, target).with_prefix("check-test");
164 let _guard = builder.msg(
165 Kind::Check,
166 "library test/bench/example targets",
167 Mode::Std,
168 build_compiler,
169 target,
170 );
171 run_cargo(
172 builder,
173 cargo,
174 builder.config.free_args.clone(),
175 &stamp,
176 vec![],
177 ArtifactKeepMode::OnlyRmeta,
178 );
179 check_stamp
180 }
181
182 fn metadata(&self) -> Option<StepMetadata> {
183 Some(StepMetadata::check("std", self.target).built_by(self.build_compiler))
184 }
185}
186
187#[derive(Debug, Clone, PartialEq, Eq, Hash)]
191struct RmetaSysroot {
192 host_dir: PathBuf,
193 target_dir: PathBuf,
194}
195
196impl RmetaSysroot {
197 fn from_stamp(
199 builder: &Builder<'_>,
200 stamp: BuildStamp,
201 target: TargetSelection,
202 directory: &Path,
203 ) -> Self {
204 let host_dir = directory.join("host");
205 let target_dir = directory.join(target);
206 let _ = fs::remove_dir_all(directory);
207 t!(fs::create_dir_all(directory));
208 add_to_sysroot(builder, &target_dir, &host_dir, &stamp);
209
210 Self { host_dir, target_dir }
211 }
212
213 fn configure_cargo(&self, cargo: &mut Cargo) {
216 cargo.append_to_env(
217 "RUSTC_ADDITIONAL_SYSROOT_PATHS",
218 format!("{},{}", self.host_dir.to_str().unwrap(), self.target_dir.to_str().unwrap()),
219 ",",
220 );
221 }
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Hash)]
231struct PrepareRustcRmetaSysroot {
232 build_compiler: CompilerForCheck,
233 target: TargetSelection,
234}
235
236impl PrepareRustcRmetaSysroot {
237 fn new(build_compiler: CompilerForCheck, target: TargetSelection) -> Self {
238 Self { build_compiler, target }
239 }
240}
241
242impl Step for PrepareRustcRmetaSysroot {
243 type Output = RmetaSysroot;
244
245 fn run(self, builder: &Builder<'_>) -> Self::Output {
246 let stamp = Rustc::check_rustc_for_preparing_sysroot(builder, &self);
248
249 let build_compiler = self.build_compiler.build_compiler();
250
251 let dir = builder
253 .config
254 .out
255 .join(build_compiler.host)
256 .join(format!("stage{}-rustc-rmeta-artifacts", build_compiler.stage + 1));
257 RmetaSysroot::from_stamp(builder, stamp, self.target, &dir)
258 }
259}
260
261#[derive(Debug, Clone, PartialEq, Eq, Hash)]
268struct PrepareStdRmetaSysroot {
269 build_compiler: Compiler,
270 target: TargetSelection,
271}
272
273impl PrepareStdRmetaSysroot {
274 fn new(build_compiler: Compiler, target: TargetSelection) -> Self {
275 Self { build_compiler, target }
276 }
277}
278
279impl Step for PrepareStdRmetaSysroot {
280 type Output = RmetaSysroot;
281
282 fn run(self, builder: &Builder<'_>) -> Self::Output {
283 let stamp = builder.ensure(Std {
285 build_compiler: self.build_compiler,
286 target: self.target,
287 crates: vec![],
288 });
289
290 let dir = builder
292 .config
293 .out
294 .join(self.build_compiler.host)
295 .join(format!("stage{}-std-rmeta-artifacts", self.build_compiler.stage));
296
297 RmetaSysroot::from_stamp(builder, stamp, self.target, &dir)
298 }
299}
300
301#[derive(Debug, Clone, PartialEq, Eq, Hash)]
303pub struct Rustc {
304 check_kind: CheckKind,
305
306 build_compiler: CompilerForCheck,
308 target: TargetSelection,
309
310 crates: Vec<String>,
316}
317
318impl Rustc {
319 fn check_rustc_for_preparing_sysroot(
320 builder: &Builder<'_>,
321 prepare: &PrepareRustcRmetaSysroot,
322 ) -> BuildStamp {
323 builder.ensure(Rustc {
324 check_kind: CheckKind::Check,
326 build_compiler: prepare.build_compiler.clone(),
327 target: prepare.target,
328 crates: vec![],
329 })
330 }
331}
332
333impl CommandLineStep for Rustc {
334 type Output = BuildStamp;
335 const IS_HOST: bool = true;
336
337 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
338 run.crate_or_deps("rustc-main").path("compiler")
339 }
340
341 fn is_default_step(_builder: &Builder<'_>) -> bool {
342 true
343 }
344
345 fn make_run(run: RunConfig<'_>) {
346 let check_kind = match run.builder.kind {
347 Kind::Check => CheckKind::Check,
348 Kind::Fix => CheckKind::Fix,
349 kind => panic!("unexpected kind for `check::Rustc`: {kind:?}"),
350 };
351
352 let target = run.target;
353 let build_compiler = prepare_compiler_for_check(run.builder, target, Mode::Rustc);
354 let crates = run.make_run_crates(Alias::Compiler);
355
356 run.builder.ensure(Rustc { check_kind, build_compiler, target, crates });
357 }
358
359 fn run(self, builder: &Builder<'_>) -> Self::Output {
367 let build_compiler = self.build_compiler.build_compiler;
368 let target = self.target;
369
370 let mut cargo = builder::Cargo::new(
371 builder,
372 build_compiler,
373 Mode::Rustc,
374 SourceType::InTree,
375 target,
376 self.check_kind.to_kind(),
377 );
378
379 rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates);
380 self.build_compiler.configure_cargo(&mut cargo);
381
382 for krate in &*self.crates {
386 cargo.arg("-p").arg(krate);
387 }
388
389 let _guard = builder.msg(
390 self.check_kind.to_kind(),
391 format_args!("compiler artifacts{}", crate_description(&self.crates)),
392 Mode::Rustc,
393 self.build_compiler.build_compiler(),
394 target,
395 );
396
397 let stamp =
398 build_stamp::librustc_stamp(builder, build_compiler, target).with_prefix("check");
399
400 run_cargo(
401 builder,
402 cargo,
403 builder.config.free_args.clone(),
404 &stamp,
405 vec![],
406 ArtifactKeepMode::OnlyRmeta,
407 );
408
409 stamp
410 }
411
412 fn metadata(&self) -> Option<StepMetadata> {
413 let mut metadata = StepMetadata::new("rustc", self.target, self.check_kind.to_kind())
414 .built_by(self.build_compiler.build_compiler());
415 if !self.crates.is_empty() {
416 metadata = metadata.with_metadata(format!("({} crates)", self.crates.len()));
417 }
418 Some(metadata)
419 }
420}
421
422#[derive(Debug, Clone, PartialEq, Eq, Hash)]
431pub struct CompilerForCheck {
432 build_compiler: Compiler,
433 rustc_rmeta_sysroot: Option<RmetaSysroot>,
434 std_rmeta_sysroot: Option<RmetaSysroot>,
435}
436
437impl CompilerForCheck {
438 pub fn build_compiler(&self) -> Compiler {
439 self.build_compiler
440 }
441
442 pub fn configure_cargo(&self, cargo: &mut Cargo) {
445 if let Some(sysroot) = &self.rustc_rmeta_sysroot {
446 sysroot.configure_cargo(cargo);
447 }
448 if let Some(sysroot) = &self.std_rmeta_sysroot {
449 sysroot.configure_cargo(cargo);
450 }
451 }
452}
453
454fn prepare_std(
457 builder: &Builder<'_>,
458 build_compiler: Compiler,
459 target: TargetSelection,
460) -> Option<RmetaSysroot> {
461 builder.std(build_compiler, builder.host_target);
464
465 if builder.host_target != target {
469 Some(builder.ensure(PrepareStdRmetaSysroot::new(build_compiler, target)))
470 } else {
471 None
472 }
473}
474
475pub fn prepare_compiler_for_check(
477 builder: &Builder<'_>,
478 target: TargetSelection,
479 mode: Mode,
480) -> CompilerForCheck {
481 let host = builder.host_target;
482
483 let mut rustc_rmeta_sysroot = None;
484 let mut std_rmeta_sysroot = None;
485 let build_compiler = match mode {
486 Mode::ToolBootstrap => builder.compiler(0, host),
487 Mode::ToolTarget => get_tool_target_compiler(builder, ToolTargetBuildMode::Build(target)),
491 Mode::ToolStd => {
492 if builder.config.compile_time_deps {
493 builder.compiler(0, host)
497 } else {
498 let build_compiler = builder.compiler(builder.top_stage, host);
500 std_rmeta_sysroot = prepare_std(builder, build_compiler, target);
501 build_compiler
502 }
503 }
504 Mode::ToolRustcPrivate | Mode::Codegen => {
505 let compiler_for_rustc = prepare_compiler_for_check(builder, target, Mode::Rustc);
510 rustc_rmeta_sysroot = Some(
511 builder.ensure(PrepareRustcRmetaSysroot::new(compiler_for_rustc.clone(), target)),
512 );
513 let build_compiler = compiler_for_rustc.build_compiler();
514
515 std_rmeta_sysroot = prepare_std(builder, build_compiler, target);
517 build_compiler
518 }
519 Mode::Rustc => {
520 let stage = if host == target { builder.top_stage - 1 } else { builder.top_stage };
528 let build_compiler = builder.compiler(stage, host);
529
530 std_rmeta_sysroot = prepare_std(builder, build_compiler, target);
532 build_compiler
533 }
534 Mode::Std => {
535 builder.compiler(builder.top_stage, host)
539 }
540 };
541 CompilerForCheck { build_compiler, rustc_rmeta_sysroot, std_rmeta_sysroot }
542}
543
544#[derive(Debug, Clone, PartialEq, Eq, Hash)]
546pub struct CraneliftCodegenBackend {
547 build_compiler: CompilerForCheck,
548 target: TargetSelection,
549}
550
551impl CommandLineStep for CraneliftCodegenBackend {
552 type Output = ();
553 const IS_HOST: bool = true;
554
555 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
556 run.alias("rustc_codegen_cranelift").alias("cg_clif")
557 }
558
559 fn is_default_step(_builder: &Builder<'_>) -> bool {
560 true
561 }
562
563 fn make_run(run: RunConfig<'_>) {
564 run.builder.ensure(CraneliftCodegenBackend {
565 build_compiler: prepare_compiler_for_check(run.builder, run.target, Mode::Codegen),
566 target: run.target,
567 });
568 }
569
570 fn run(self, builder: &Builder<'_>) {
571 let build_compiler = self.build_compiler.build_compiler();
572 let target = self.target;
573
574 let mut cargo = builder::Cargo::new(
575 builder,
576 build_compiler,
577 Mode::Codegen,
578 SourceType::InTree,
579 target,
580 builder.kind,
581 );
582
583 cargo
584 .arg("--manifest-path")
585 .arg(builder.src.join("compiler/rustc_codegen_cranelift/Cargo.toml"));
586 self.build_compiler.configure_cargo(&mut cargo);
587
588 let _guard = builder.msg(
589 Kind::Check,
590 "rustc_codegen_cranelift",
591 Mode::Codegen,
592 build_compiler,
593 target,
594 );
595
596 let stamp = build_stamp::codegen_backend_stamp(
597 builder,
598 build_compiler,
599 target,
600 &CodegenBackendKind::Cranelift,
601 )
602 .with_prefix("check");
603
604 run_cargo(
605 builder,
606 cargo,
607 builder.config.free_args.clone(),
608 &stamp,
609 vec![],
610 ArtifactKeepMode::OnlyRmeta,
611 );
612 }
613
614 fn metadata(&self) -> Option<StepMetadata> {
615 Some(
616 StepMetadata::check("rustc_codegen_cranelift", self.target)
617 .built_by(self.build_compiler.build_compiler()),
618 )
619 }
620}
621
622#[derive(Debug, Clone, PartialEq, Eq, Hash)]
624pub struct GccCodegenBackend {
625 build_compiler: CompilerForCheck,
626 target: TargetSelection,
627}
628
629impl CommandLineStep for GccCodegenBackend {
630 type Output = ();
631 const IS_HOST: bool = true;
632
633 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
634 run.alias("rustc_codegen_gcc").alias("cg_gcc")
635 }
636
637 fn is_default_step(_builder: &Builder<'_>) -> bool {
638 true
639 }
640
641 fn make_run(run: RunConfig<'_>) {
642 run.builder.ensure(GccCodegenBackend {
643 build_compiler: prepare_compiler_for_check(run.builder, run.target, Mode::Codegen),
644 target: run.target,
645 });
646 }
647
648 fn run(self, builder: &Builder<'_>) {
649 if builder.sess.config.vendor {
651 println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
652 return;
653 }
654
655 let build_compiler = self.build_compiler.build_compiler();
656 let target = self.target;
657
658 let mut cargo = builder::Cargo::new(
659 builder,
660 build_compiler,
661 Mode::Codegen,
662 SourceType::InTree,
663 target,
664 builder.kind,
665 );
666
667 cargo.arg("--manifest-path").arg(builder.src.join("compiler/rustc_codegen_gcc/Cargo.toml"));
668 self.build_compiler.configure_cargo(&mut cargo);
669
670 let _guard =
671 builder.msg(Kind::Check, "rustc_codegen_gcc", Mode::Codegen, build_compiler, target);
672
673 let stamp = build_stamp::codegen_backend_stamp(
674 builder,
675 build_compiler,
676 target,
677 &CodegenBackendKind::Gcc,
678 )
679 .with_prefix("check");
680
681 run_cargo(
682 builder,
683 cargo,
684 builder.config.free_args.clone(),
685 &stamp,
686 vec![],
687 ArtifactKeepMode::OnlyRmeta,
688 );
689 }
690
691 fn metadata(&self) -> Option<StepMetadata> {
692 Some(
693 StepMetadata::check("rustc_codegen_gcc", self.target)
694 .built_by(self.build_compiler.build_compiler()),
695 )
696 }
697}
698
699macro_rules! tool_check_step {
700 (
701 $name:ident {
702 path: $path:literal
704 $(, alt_path: $alt_path:literal )*
705 , mode: $mode:expr
707 $(, allow_features: $allow_features:expr )?
709 $(, enable_features: [$($enable_features:expr),*] )?
711 $(, default_features: $default_features:expr )?
712 $(, default: $default:literal )?
713 $( , )?
714 }
715 ) => {
716 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
717 pub struct $name {
718 compiler: CompilerForCheck,
719 target: TargetSelection,
720 }
721
722 impl CommandLineStep for $name {
723 type Output = ();
724 const IS_HOST: bool = true;
725
726 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
727 run.multi_path(&[$path $(, $alt_path )*])
728 }
729
730 fn is_default_step(_builder: &Builder<'_>) -> bool {
731 true $( && const { $default } )?
733 }
734
735 fn make_run(run: RunConfig<'_>) {
736 let target = run.target;
737 let mode: Mode = $mode;
738
739 let compiler = prepare_compiler_for_check(run.builder, target, mode);
740
741 if mode == Mode::ToolBootstrap && target != run.builder.host_target {
743 println!("WARNING: not checking bootstrap tool {} for target {target} as it is a bootstrap (host-only) tool", stringify!($path));
744 return;
745 };
746
747 run.builder.ensure($name { target, compiler });
748 }
749
750 fn run(self, builder: &Builder<'_>) {
751 let Self { target, compiler } = self;
752 let allow_features = {
753 let mut _value = "";
754 $( _value = $allow_features; )?
755 _value
756 };
757 let extra_features: &[&str] = &[$($($enable_features),*)?];
758 let default_features = {
759 let mut _value = true;
760 $( _value = $default_features; )?
761 _value
762 };
763 let mode: Mode = $mode;
764 run_tool_check_step(builder, compiler, target, $path, mode, allow_features, extra_features, default_features);
765 }
766
767 fn metadata(&self) -> Option<StepMetadata> {
768 Some(StepMetadata::check(stringify!($name), self.target).built_by(self.compiler.build_compiler))
769 }
770 }
771 }
772}
773
774#[allow(clippy::too_many_arguments)]
776fn run_tool_check_step(
777 builder: &Builder<'_>,
778 compiler: CompilerForCheck,
779 target: TargetSelection,
780 path: &str,
781 mode: Mode,
782 allow_features: &str,
783 extra_features: &[&str],
784 default_features: bool,
785) {
786 let display_name = path.rsplit('/').next().unwrap();
787
788 let build_compiler = compiler.build_compiler();
789
790 let extra_features = extra_features.iter().map(|f| f.to_string()).collect::<Vec<String>>();
791 let mut cargo = prepare_tool_cargo(
792 builder,
793 build_compiler,
794 mode,
795 target,
796 builder.kind,
797 path,
798 SourceType::InTree,
803 &extra_features,
804 );
805 cargo.allow_features(allow_features);
806 compiler.configure_cargo(&mut cargo);
807
808 if display_name == "rust-analyzer" {
811 cargo.arg("--bins");
812 cargo.arg("--tests");
813 cargo.arg("--benches");
814 } else {
815 cargo.arg("--all-targets");
816 }
817
818 if !default_features {
819 cargo.arg("--no-default-features");
820 }
821
822 let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, mode, target))
823 .with_prefix(&format!("{display_name}-check"));
824
825 let _guard = builder.msg(builder.kind, display_name, mode, build_compiler, target);
826 run_cargo(
827 builder,
828 cargo,
829 builder.config.free_args.clone(),
830 &stamp,
831 vec![],
832 ArtifactKeepMode::OnlyRmeta,
833 );
834}
835
836tool_check_step!(Rustdoc {
837 path: "src/tools/rustdoc",
838 alt_path: "src/librustdoc",
839 mode: Mode::ToolRustcPrivate
840});
841tool_check_step!(Clippy { path: "src/tools/clippy", mode: Mode::ToolRustcPrivate });
846tool_check_step!(Miri {
847 path: "src/tools/miri",
848 mode: Mode::ToolRustcPrivate,
849 enable_features: ["check_only"],
850});
851tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: Mode::ToolRustcPrivate });
852tool_check_step!(Priroda { path: "src/tools/miri/priroda", mode: Mode::ToolRustcPrivate });
853tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: Mode::ToolRustcPrivate });
854tool_check_step!(RustAnalyzer {
855 path: "src/tools/rust-analyzer",
856 mode: Mode::ToolRustcPrivate,
857 allow_features: tool::RustAnalyzer::ALLOW_FEATURES,
858 enable_features: ["in-rust-tree"],
859});
860tool_check_step!(MiroptTestTools {
861 path: "src/tools/miropt-test-tools",
862 mode: Mode::ToolBootstrap
863});
864tool_check_step!(TestFloatParse {
866 path: "src/tools/test-float-parse",
867 mode: Mode::ToolStd,
868 allow_features: TEST_FLOAT_PARSE_ALLOW_FEATURES
869});
870tool_check_step!(FeaturesStatusDump {
871 path: "src/tools/features-status-dump",
872 mode: Mode::ToolBootstrap
873});
874
875tool_check_step!(Bootstrap { path: "src/bootstrap", mode: Mode::ToolBootstrap, default: false });
876
877tool_check_step!(RunMakeSupport {
880 path: "src/tools/run-make-support",
881 mode: Mode::ToolBootstrap,
882 default: false
883});
884
885tool_check_step!(CoverageDump {
886 path: "src/tools/coverage-dump",
887 mode: Mode::ToolBootstrap,
888 default: false
889});
890
891tool_check_step!(Compiletest {
894 path: "src/tools/compiletest",
895 mode: Mode::ToolBootstrap,
896 default: false,
897});
898
899tool_check_step!(RustdocGuiTest {
903 path: "src/tools/rustdoc-gui-test",
904 mode: Mode::ToolBootstrap,
905 default: false,
906});
907
908tool_check_step!(Linkchecker {
909 path: "src/tools/linkchecker",
910 mode: Mode::ToolBootstrap,
911 default: false
912});
913
914tool_check_step!(BumpStage0 {
915 path: "src/tools/bump-stage0",
916 mode: Mode::ToolBootstrap,
917 default: false
918});
919
920tool_check_step!(Tidy { path: "src/tools/tidy", mode: Mode::ToolBootstrap, default: false });