29
29
use crate :: fmt;
30
30
use crate :: panic:: { Location , PanicInfo } ;
31
31
32
+ #[ cfg( bootstrap) ]
32
33
#[ cold]
33
34
// never inline unless panic_immediate_abort to avoid code
34
35
// 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)) -> ! {
49
50
panic_fmt ( fmt:: Arguments :: new_v1 ( & [ expr] , & [ ] ) , & ( file, line, col) )
50
51
}
51
52
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) ]
52
74
#[ cold]
53
75
#[ cfg_attr( not( feature="panic_immediate_abort" ) , inline( never) ) ]
54
76
#[ lang = "panic_bounds_check" ]
@@ -62,6 +84,22 @@ fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
62
84
len, index) , file_line_col)
63
85
}
64
86
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) ]
65
103
#[ cold]
66
104
#[ cfg_attr( not( feature="panic_immediate_abort" ) , inline( never) ) ]
67
105
#[ 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
77
115
}
78
116
79
117
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) ;
84
139
unsafe { panic_impl ( & pi) }
85
140
}
0 commit comments