@@ -8,7 +8,7 @@ use either::Either;
88use itertools:: Itertools ;
99use rspirv:: dr:: Operand ;
1010use rspirv:: spirv:: { Op , Word } ;
11- use rustc_abi:: BackendRepr ;
11+ use rustc_abi:: { Align , BackendRepr } ;
1212use rustc_data_structures:: fx:: FxHashSet ;
1313use rustc_middle:: ty:: Ty ;
1414use rustc_middle:: ty:: layout:: LayoutOf ;
@@ -17,6 +17,8 @@ use smallvec::SmallVec;
1717use std:: borrow:: Cow ;
1818use std:: cell:: Cell ;
1919
20+ use crate :: maybe_pqp_cg_ssa:: traits:: BuilderMethods ;
21+
2022// HACK(eddyb) Rust 2021 `panic!` always uses `format_args!`, even
2123// in the simple case that used to pass a `&str` constant, which
2224// would not remain reachable in the SPIR-V - but `format_args!` is
@@ -233,6 +235,42 @@ impl<'tcx> DecodedFormatArgs<'tcx> {
233235 _ => None ,
234236 }
235237 } ;
238+ let mut spill_value_to_local = |value : SpirvValue | {
239+ let ptr = builder. typed_alloca ( value. ty , Align :: ONE ) ;
240+ builder. store ( value, ptr, Align :: ONE ) ;
241+ match ptr. kind {
242+ SpirvValueKind :: Def ( id) => Some ( id) ,
243+ _ => None ,
244+ }
245+ } ;
246+
247+ if panic_def_id. is_some_and ( |def_id| {
248+ cx. tcx . def_path_str ( def_id) == "core::panicking::panic_bounds_check"
249+ } ) && args. len ( ) >= 2
250+ {
251+ let index = args[ 0 ] . clone ( ) ;
252+ let len = args[ 1 ] . clone ( ) ;
253+ if let ( Some ( len_ref_id) , Some ( index_ref_id) ) =
254+ ( spill_value_to_local ( len) , spill_value_to_local ( index) )
255+ {
256+ decoded_format_args. const_pieces = Some (
257+ [
258+ "index out of bounds: the len is " . into ( ) ,
259+ " but the index is " . into ( ) ,
260+ String :: new ( ) ,
261+ ]
262+ . into_iter ( )
263+ . collect ( ) ,
264+ ) ;
265+ decoded_format_args. ref_arg_ids_with_ty_and_spec = [
266+ ( len_ref_id, cx. tcx . types . usize , ' ' ) ,
267+ ( index_ref_id, cx. tcx . types . usize , ' ' ) ,
268+ ]
269+ . into_iter ( )
270+ . collect ( ) ;
271+ return Ok ( decoded_format_args) ;
272+ }
273+ }
236274
237275 // HACK(eddyb) `panic_explicit` doesn't take any regular arguments,
238276 // only an (implicit) `&'static panic::Location<'static>`.
0 commit comments