@@ -2,13 +2,8 @@ use super::{link, LinkResult, Options};
2
2
use crate :: codegen_cx:: SpirvMetadata ;
3
3
use pipe:: pipe;
4
4
use rspirv:: dr:: { Loader , Module } ;
5
- use rustc_driver:: handle_options;
6
5
use rustc_errors:: registry:: Registry ;
7
- use rustc_session:: config:: build_session_options;
8
- use rustc_session:: config:: Input ;
9
- use rustc_session:: DiagnosticOutput ;
10
6
use std:: io:: Read ;
11
- use std:: path:: PathBuf ;
12
7
13
8
// https://github.com/colin-kiegel/rust-pretty-assertions/issues/24
14
9
#[ derive( PartialEq , Eq ) ]
@@ -62,60 +57,90 @@ fn load(bytes: &[u8]) -> Module {
62
57
fn assemble_and_link ( binaries : & [ & [ u8 ] ] ) -> Result < Module , PrettyString > {
63
58
let modules = binaries. iter ( ) . cloned ( ) . map ( load) . collect :: < Vec < _ > > ( ) ;
64
59
65
- // need pipe here because Config takes ownership of the writer, and the writer must be 'static.
60
+ // FIXME(eddyb) this seems ridiculous, we should be able to write to
61
+ // some kind of `Arc<Mutex<Vec<u8>>>` without a separate thread.
62
+ //
63
+ // need pipe here because the writer must be 'static.
66
64
let ( mut read_diags, write_diags) = pipe ( ) ;
67
65
let read_diags_thread = std:: thread:: spawn ( move || {
68
66
// must spawn thread because pipe crate is synchronous
69
67
let mut diags = String :: new ( ) ;
70
68
read_diags. read_to_string ( & mut diags) . unwrap ( ) ;
71
- let suffix = "\n \n error: aborting due to previous error\n \n " ;
72
- if diags. ends_with ( suffix) {
73
- diags. truncate ( diags. len ( ) - suffix. len ( ) ) ;
69
+ if let Some ( diags_without_trailing_newlines) = diags. strip_suffix ( "\n \n " ) {
70
+ diags. truncate ( diags_without_trailing_newlines. len ( ) ) ;
74
71
}
75
72
diags
76
73
} ) ;
77
- let matches = handle_options ( & [ "" . to_string ( ) , "x.rs" . to_string ( ) ] ) . unwrap ( ) ;
78
- let sopts = build_session_options ( & matches) ;
79
- let config = rustc_interface:: Config {
80
- opts : sopts,
81
- crate_cfg : Default :: default ( ) ,
82
- crate_check_cfg : Default :: default ( ) ,
83
- input : Input :: File ( PathBuf :: new ( ) ) ,
84
- input_path : None ,
85
- output_file : None ,
86
- output_dir : None ,
87
- file_loader : None ,
88
- diagnostic_output : DiagnosticOutput :: Raw ( Box :: new ( write_diags) ) ,
89
- lint_caps : Default :: default ( ) ,
90
- parse_sess_created : None ,
91
- register_lints : None ,
92
- override_queries : None ,
93
- make_codegen_backend : None ,
94
- registry : Registry :: new ( & [ ] ) ,
95
- } ;
74
+
96
75
// NOTE(eddyb) without `catch_fatal_errors`, you'd get the really strange
97
76
// effect of test failures with no output (because the `FatalError` "panic"
98
77
// is really a silent unwinding device, that should be treated the same as
99
- // `Err(ErrorGuaranteed)` returns from `run_compiler`/` link`).
78
+ // `Err(ErrorGuaranteed)` returns from `link`).
100
79
rustc_driver:: catch_fatal_errors ( || {
101
- rustc_interface:: interface:: run_compiler ( config, |compiler| {
102
- let res = link (
103
- compiler. session ( ) ,
104
- modules,
105
- & Options {
106
- compact_ids : true ,
107
- dce : false ,
108
- structurize : false ,
109
- emit_multiple_modules : false ,
110
- spirv_metadata : SpirvMetadata :: None ,
111
- } ,
112
- ) ;
113
- assert_eq ! ( compiler. session( ) . has_errors( ) , res. as_ref( ) . err( ) . copied( ) ) ;
114
- res. map ( |res| match res {
115
- LinkResult :: SingleModule ( m) => * m,
116
- LinkResult :: MultipleModules ( _) => unreachable ! ( ) ,
117
- } )
118
- } )
80
+ let matches = rustc_driver:: handle_options ( & [ "" . to_string ( ) , "x.rs" . to_string ( ) ] ) . unwrap ( ) ;
81
+ let sopts = rustc_session:: config:: build_session_options ( & matches) ;
82
+
83
+ rustc_interface:: util:: run_in_thread_pool_with_globals (
84
+ sopts. edition ,
85
+ sopts. unstable_opts . threads ,
86
+ || {
87
+ let mut sess = rustc_session:: build_session (
88
+ sopts,
89
+ None ,
90
+ None ,
91
+ Registry :: new ( & [ ] ) ,
92
+ rustc_session:: DiagnosticOutput :: Default ,
93
+ Default :: default ( ) ,
94
+ None ,
95
+ None ,
96
+ ) ;
97
+
98
+ // HACK(eddyb) inject `write_diags` into `sess`, to work around
99
+ // the removals in https://github.com/rust-lang/rust/pull/102992.
100
+ sess. parse_sess . span_diagnostic = {
101
+ let fallback_bundle = {
102
+ extern crate rustc_error_messages;
103
+ rustc_error_messages:: fallback_fluent_bundle (
104
+ rustc_errors:: DEFAULT_LOCALE_RESOURCES ,
105
+ sess. opts . unstable_opts . translate_directionality_markers ,
106
+ )
107
+ } ;
108
+ let emitter = rustc_errors:: emitter:: EmitterWriter :: new (
109
+ Box :: new ( write_diags) ,
110
+ Some ( sess. parse_sess . clone_source_map ( ) ) ,
111
+ None ,
112
+ fallback_bundle,
113
+ false ,
114
+ false ,
115
+ false ,
116
+ None ,
117
+ false ,
118
+ ) ;
119
+
120
+ rustc_errors:: Handler :: with_emitter_and_flags (
121
+ Box :: new ( emitter) ,
122
+ sess. opts . unstable_opts . diagnostic_handler_flags ( true ) ,
123
+ )
124
+ } ;
125
+
126
+ let res = link (
127
+ & sess,
128
+ modules,
129
+ & Options {
130
+ compact_ids : true ,
131
+ dce : false ,
132
+ structurize : false ,
133
+ emit_multiple_modules : false ,
134
+ spirv_metadata : SpirvMetadata :: None ,
135
+ } ,
136
+ ) ;
137
+ assert_eq ! ( sess. has_errors( ) , res. as_ref( ) . err( ) . copied( ) ) ;
138
+ res. map ( |res| match res {
139
+ LinkResult :: SingleModule ( m) => * m,
140
+ LinkResult :: MultipleModules ( _) => unreachable ! ( ) ,
141
+ } )
142
+ } ,
143
+ )
119
144
} )
120
145
. flatten ( )
121
146
. map_err ( |_e| read_diags_thread. join ( ) . unwrap ( ) )
0 commit comments