@@ -58,8 +58,16 @@ use std::str;
58
58
use std:: sync:: LazyLock ;
59
59
use std:: time:: Instant ;
60
60
61
+ // This import blocks the use of panicking `print` and `println` in all the code
62
+ // below. Please use `safe_print` and `safe_println` to avoid ICE when
63
+ // encountering an I/O error during print.
64
+ #[ allow( unused_imports) ]
65
+ use std:: { compile_error as print, compile_error as println} ;
66
+
61
67
pub mod args;
62
68
pub mod pretty;
69
+ #[ macro_use]
70
+ mod print;
63
71
mod session_diagnostics;
64
72
65
73
use crate :: session_diagnostics:: {
@@ -511,7 +519,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
511
519
if io:: stdout ( ) . is_terminal ( ) {
512
520
show_content_with_pager ( & text) ;
513
521
} else {
514
- print ! ( "{text}" ) ;
522
+ safe_print ! ( "{text}" ) ;
515
523
}
516
524
}
517
525
Err ( InvalidErrorCode ) => {
@@ -547,7 +555,7 @@ fn show_content_with_pager(content: &str) {
547
555
// If pager fails for whatever reason, we should still print the content
548
556
// to standard output
549
557
if fallback_to_println {
550
- print ! ( "{content}" ) ;
558
+ safe_print ! ( "{content}" ) ;
551
559
}
552
560
}
553
561
@@ -601,7 +609,7 @@ pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Co
601
609
let path = & ( * ifile) ;
602
610
let mut v = Vec :: new ( ) ;
603
611
locator:: list_file_metadata ( & sess. target , path, metadata_loader, & mut v) . unwrap ( ) ;
604
- println ! ( "{}" , String :: from_utf8( v) . unwrap( ) ) ;
612
+ safe_println ! ( "{}" , String :: from_utf8( v) . unwrap( ) ) ;
605
613
}
606
614
Input :: Str { .. } => {
607
615
early_error ( ErrorOutputType :: default ( ) , "cannot list metadata for stdin" ) ;
@@ -642,12 +650,12 @@ fn print_crate_info(
642
650
TargetList => {
643
651
let mut targets = rustc_target:: spec:: TARGETS . to_vec ( ) ;
644
652
targets. sort_unstable ( ) ;
645
- println ! ( "{}" , targets. join( "\n " ) ) ;
653
+ safe_println ! ( "{}" , targets. join( "\n " ) ) ;
646
654
}
647
- Sysroot => println ! ( "{}" , sess. sysroot. display( ) ) ,
648
- TargetLibdir => println ! ( "{}" , sess. target_tlib_path. dir. display( ) ) ,
655
+ Sysroot => safe_println ! ( "{}" , sess. sysroot. display( ) ) ,
656
+ TargetLibdir => safe_println ! ( "{}" , sess. target_tlib_path. dir. display( ) ) ,
649
657
TargetSpec => {
650
- println ! ( "{}" , serde_json:: to_string_pretty( & sess. target. to_json( ) ) . unwrap( ) ) ;
658
+ safe_println ! ( "{}" , serde_json:: to_string_pretty( & sess. target. to_json( ) ) . unwrap( ) ) ;
651
659
}
652
660
AllTargetSpecs => {
653
661
let mut targets = BTreeMap :: new ( ) ;
@@ -656,7 +664,7 @@ fn print_crate_info(
656
664
let target = Target :: expect_builtin ( & triple) ;
657
665
targets. insert ( name, target. to_json ( ) ) ;
658
666
}
659
- println ! ( "{}" , serde_json:: to_string_pretty( & targets) . unwrap( ) ) ;
667
+ safe_println ! ( "{}" , serde_json:: to_string_pretty( & targets) . unwrap( ) ) ;
660
668
}
661
669
FileNames | CrateName => {
662
670
let Some ( attrs) = attrs. as_ref ( ) else {
@@ -666,14 +674,14 @@ fn print_crate_info(
666
674
let t_outputs = rustc_interface:: util:: build_output_filenames ( attrs, sess) ;
667
675
let id = rustc_session:: output:: find_crate_name ( sess, attrs) ;
668
676
if * req == PrintRequest :: CrateName {
669
- println ! ( "{id}" ) ;
677
+ safe_println ! ( "{id}" ) ;
670
678
continue ;
671
679
}
672
680
let crate_types = collect_crate_types ( sess, attrs) ;
673
681
for & style in & crate_types {
674
682
let fname =
675
683
rustc_session:: output:: filename_for_input ( sess, style, id, & t_outputs) ;
676
- println ! ( "{}" , fname. file_name( ) . unwrap( ) . to_string_lossy( ) ) ;
684
+ safe_println ! ( "{}" , fname. file_name( ) . unwrap( ) . to_string_lossy( ) ) ;
677
685
}
678
686
}
679
687
Cfg => {
@@ -707,13 +715,13 @@ fn print_crate_info(
707
715
708
716
cfgs. sort ( ) ;
709
717
for cfg in cfgs {
710
- println ! ( "{cfg}" ) ;
718
+ safe_println ! ( "{cfg}" ) ;
711
719
}
712
720
}
713
721
CallingConventions => {
714
722
let mut calling_conventions = rustc_target:: spec:: abi:: all_names ( ) ;
715
723
calling_conventions. sort_unstable ( ) ;
716
- println ! ( "{}" , calling_conventions. join( "\n " ) ) ;
724
+ safe_println ! ( "{}" , calling_conventions. join( "\n " ) ) ;
717
725
}
718
726
RelocationModels
719
727
| CodeModels
@@ -733,7 +741,7 @@ fn print_crate_info(
733
741
let stable = sess. target . options . supported_split_debuginfo . contains ( split) ;
734
742
let unstable_ok = sess. unstable_options ( ) ;
735
743
if stable || unstable_ok {
736
- println ! ( "{split}" ) ;
744
+ safe_println ! ( "{split}" ) ;
737
745
}
738
746
}
739
747
}
@@ -770,14 +778,14 @@ pub fn version_at_macro_invocation(
770
778
) {
771
779
let verbose = matches. opt_present ( "verbose" ) ;
772
780
773
- println ! ( "{binary} {version}" ) ;
781
+ safe_println ! ( "{binary} {version}" ) ;
774
782
775
783
if verbose {
776
- println ! ( "binary: {binary}" ) ;
777
- println ! ( "commit-hash: {commit_hash}" ) ;
778
- println ! ( "commit-date: {commit_date}" ) ;
779
- println ! ( "host: {}" , config:: host_triple( ) ) ;
780
- println ! ( "release: {release}" ) ;
784
+ safe_println ! ( "binary: {binary}" ) ;
785
+ safe_println ! ( "commit-hash: {commit_hash}" ) ;
786
+ safe_println ! ( "commit-date: {commit_date}" ) ;
787
+ safe_println ! ( "host: {}" , config:: host_triple( ) ) ;
788
+ safe_println ! ( "release: {release}" ) ;
781
789
782
790
let debug_flags = matches. opt_strs ( "Z" ) ;
783
791
let backend_name = debug_flags. iter ( ) . find_map ( |x| x. strip_prefix ( "codegen-backend=" ) ) ;
@@ -807,7 +815,7 @@ fn usage(verbose: bool, include_unstable_options: bool, nightly_build: bool) {
807
815
} else {
808
816
""
809
817
} ;
810
- println ! (
818
+ safe_println ! (
811
819
"{options}{at_path}\n Additional help:
812
820
-C help Print codegen options
813
821
-W help \
@@ -820,7 +828,7 @@ fn usage(verbose: bool, include_unstable_options: bool, nightly_build: bool) {
820
828
}
821
829
822
830
fn print_wall_help ( ) {
823
- println ! (
831
+ safe_println ! (
824
832
"
825
833
The flag `-Wall` does not exist in `rustc`. Most useful lints are enabled by
826
834
default. Use `rustc -W help` to see all available lints. It's more common to put
@@ -832,7 +840,7 @@ the command line flag directly.
832
840
833
841
/// Write to stdout lint command options, together with a list of all available lints
834
842
pub fn describe_lints ( sess : & Session , lint_store : & LintStore , loaded_plugins : bool ) {
835
- println ! (
843
+ safe_println ! (
836
844
"
837
845
Available lint options:
838
846
-W <foo> Warn about <foo>
@@ -877,21 +885,21 @@ Available lint options:
877
885
s
878
886
} ;
879
887
880
- println ! ( "Lint checks provided by rustc:\n " ) ;
888
+ safe_println ! ( "Lint checks provided by rustc:\n " ) ;
881
889
882
890
let print_lints = |lints : Vec < & Lint > | {
883
- println ! ( " {} {:7.7} {}" , padded( "name" ) , "default" , "meaning" ) ;
884
- println ! ( " {} {:7.7} {}" , padded( "----" ) , "-------" , "-------" ) ;
891
+ safe_println ! ( " {} {:7.7} {}" , padded( "name" ) , "default" , "meaning" ) ;
892
+ safe_println ! ( " {} {:7.7} {}" , padded( "----" ) , "-------" , "-------" ) ;
885
893
for lint in lints {
886
894
let name = lint. name_lower ( ) . replace ( '_' , "-" ) ;
887
- println ! (
895
+ safe_println ! (
888
896
" {} {:7.7} {}" ,
889
897
padded( & name) ,
890
898
lint. default_level( sess. edition( ) ) . as_str( ) ,
891
899
lint. desc
892
900
) ;
893
901
}
894
- println ! ( "\n " ) ;
902
+ safe_println ! ( "\n " ) ;
895
903
} ;
896
904
897
905
print_lints ( builtin) ;
@@ -912,14 +920,14 @@ Available lint options:
912
920
s
913
921
} ;
914
922
915
- println ! ( "Lint groups provided by rustc:\n " ) ;
923
+ safe_println ! ( "Lint groups provided by rustc:\n " ) ;
916
924
917
925
let print_lint_groups = |lints : Vec < ( & ' static str , Vec < LintId > ) > , all_warnings| {
918
- println ! ( " {} sub-lints" , padded( "name" ) ) ;
919
- println ! ( " {} ---------" , padded( "----" ) ) ;
926
+ safe_println ! ( " {} sub-lints" , padded( "name" ) ) ;
927
+ safe_println ! ( " {} ---------" , padded( "----" ) ) ;
920
928
921
929
if all_warnings {
922
- println ! ( " {} all lints that are set to issue warnings" , padded( "warnings" ) ) ;
930
+ safe_println ! ( " {} all lints that are set to issue warnings" , padded( "warnings" ) ) ;
923
931
}
924
932
925
933
for ( name, to) in lints {
@@ -929,26 +937,26 @@ Available lint options:
929
937
. map ( |x| x. to_string ( ) . replace ( '_' , "-" ) )
930
938
. collect :: < Vec < String > > ( )
931
939
. join ( ", " ) ;
932
- println ! ( " {} {}" , padded( & name) , desc) ;
940
+ safe_println ! ( " {} {}" , padded( & name) , desc) ;
933
941
}
934
- println ! ( "\n " ) ;
942
+ safe_println ! ( "\n " ) ;
935
943
} ;
936
944
937
945
print_lint_groups ( builtin_groups, true ) ;
938
946
939
947
match ( loaded_plugins, plugin. len ( ) , plugin_groups. len ( ) ) {
940
948
( false , 0 , _) | ( false , _, 0 ) => {
941
- println ! ( "Lint tools like Clippy can provide additional lints and lint groups." ) ;
949
+ safe_println ! ( "Lint tools like Clippy can provide additional lints and lint groups." ) ;
942
950
}
943
951
( false , ..) => panic ! ( "didn't load lint plugins but got them anyway!" ) ,
944
- ( true , 0 , 0 ) => println ! ( "This crate does not load any lint plugins or lint groups." ) ,
952
+ ( true , 0 , 0 ) => safe_println ! ( "This crate does not load any lint plugins or lint groups." ) ,
945
953
( true , l, g) => {
946
954
if l > 0 {
947
- println ! ( "Lint checks provided by plugins loaded by this crate:\n " ) ;
955
+ safe_println ! ( "Lint checks provided by plugins loaded by this crate:\n " ) ;
948
956
print_lints ( plugin) ;
949
957
}
950
958
if g > 0 {
951
- println ! ( "Lint groups provided by plugins loaded by this crate:\n " ) ;
959
+ safe_println ! ( "Lint groups provided by plugins loaded by this crate:\n " ) ;
952
960
print_lint_groups ( plugin_groups, false ) ;
953
961
}
954
962
}
@@ -996,12 +1004,12 @@ pub fn describe_flag_categories(matches: &Matches) -> bool {
996
1004
}
997
1005
998
1006
fn describe_debug_flags ( ) {
999
- println ! ( "\n Available options:\n " ) ;
1007
+ safe_println ! ( "\n Available options:\n " ) ;
1000
1008
print_flag_list ( "-Z" , config:: Z_OPTIONS ) ;
1001
1009
}
1002
1010
1003
1011
fn describe_codegen_flags ( ) {
1004
- println ! ( "\n Available codegen options:\n " ) ;
1012
+ safe_println ! ( "\n Available codegen options:\n " ) ;
1005
1013
print_flag_list ( "-C" , config:: CG_OPTIONS ) ;
1006
1014
}
1007
1015
@@ -1012,7 +1020,7 @@ fn print_flag_list<T>(
1012
1020
let max_len = flag_list. iter ( ) . map ( |& ( name, _, _, _) | name. chars ( ) . count ( ) ) . max ( ) . unwrap_or ( 0 ) ;
1013
1021
1014
1022
for & ( name, _, _, desc) in flag_list {
1015
- println ! (
1023
+ safe_println ! (
1016
1024
" {} {:>width$}=val -- {}" ,
1017
1025
cmdline_opt,
1018
1026
name. replace( '_' , "-" ) ,
0 commit comments