2929use crate :: fmt;
3030use crate :: panic:: { Location , PanicInfo } ;
3131
32+ #[ cfg( bootstrap) ]
3233#[ cold]
3334// never inline unless panic_immediate_abort to avoid code
3435// bloat at the call sites as much as possible
@@ -49,6 +50,27 @@ pub fn panic(expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
4950 panic_fmt ( fmt:: Arguments :: new_v1 ( & [ expr] , & [ ] ) , & ( file, line, col) )
5051}
5152
53+ #[ cfg( not( bootstrap) ) ]
54+ #[ cold]
55+ // never inline unless panic_immediate_abort to avoid code
56+ // bloat at the call sites as much as possible
57+ #[ cfg_attr( not( feature="panic_immediate_abort" ) , inline( never) ) ]
58+ #[ lang = "panic" ]
59+ pub fn panic ( expr : & str , location : & Location < ' _ > ) -> ! {
60+ if cfg ! ( feature = "panic_immediate_abort" ) {
61+ unsafe { super :: intrinsics:: abort ( ) }
62+ }
63+
64+ // Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially
65+ // reduce size overhead. The format_args! macro uses str's Display trait to
66+ // write expr, which calls Formatter::pad, which must accommodate string
67+ // truncation and padding (even though none is used here). Using
68+ // Arguments::new_v1 may allow the compiler to omit Formatter::pad from the
69+ // output binary, saving up to a few kilobytes.
70+ panic_fmt ( fmt:: Arguments :: new_v1 ( & [ expr] , & [ ] ) , location)
71+ }
72+
73+ #[ cfg( bootstrap) ]
5274#[ cold]
5375#[ cfg_attr( not( feature="panic_immediate_abort" ) , inline( never) ) ]
5476#[ lang = "panic_bounds_check" ]
@@ -62,6 +84,22 @@ fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
6284 len, index) , file_line_col)
6385}
6486
87+ #[ cfg( not( bootstrap) ) ]
88+ #[ cold]
89+ #[ cfg_attr( not( feature="panic_immediate_abort" ) , inline( never) ) ]
90+ #[ lang = "panic_bounds_check" ]
91+ fn panic_bounds_check ( location : & Location < ' _ > , index : usize , len : usize ) -> ! {
92+ if cfg ! ( feature = "panic_immediate_abort" ) {
93+ unsafe { super :: intrinsics:: abort ( ) }
94+ }
95+
96+ panic_fmt (
97+ format_args ! ( "index out of bounds: the len is {} but the index is {}" , len, index) ,
98+ location
99+ )
100+ }
101+
102+ #[ cfg( bootstrap) ]
65103#[ cold]
66104#[ cfg_attr( not( feature="panic_immediate_abort" ) , inline( never) ) ]
67105#[ cfg_attr( feature="panic_immediate_abort" , inline) ]
@@ -77,9 +115,26 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, file_line_col: &(&'static str, u32, u3
77115 }
78116
79117 let ( file, line, col) = * file_line_col;
80- let pi = PanicInfo :: internal_constructor (
81- Some ( & fmt) ,
82- Location :: internal_constructor ( file, line, col) ,
83- ) ;
118+ let location = Location :: internal_constructor ( file, line, col) ;
119+ let pi = PanicInfo :: internal_constructor ( Some ( & fmt) , & location) ;
120+ unsafe { panic_impl ( & pi) }
121+ }
122+
123+ #[ cfg( not( bootstrap) ) ]
124+ #[ cold]
125+ #[ cfg_attr( not( feature="panic_immediate_abort" ) , inline( never) ) ]
126+ #[ cfg_attr( feature="panic_immediate_abort" , inline) ]
127+ pub fn panic_fmt ( fmt : fmt:: Arguments < ' _ > , location : & Location < ' _ > ) -> ! {
128+ if cfg ! ( feature = "panic_immediate_abort" ) {
129+ unsafe { super :: intrinsics:: abort ( ) }
130+ }
131+
132+ // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
133+ extern "Rust" {
134+ #[ lang = "panic_impl" ]
135+ fn panic_impl ( pi : & PanicInfo < ' _ > ) -> !;
136+ }
137+
138+ let pi = PanicInfo :: internal_constructor ( Some ( & fmt) , location) ;
84139 unsafe { panic_impl ( & pi) }
85140}
0 commit comments