Split core's PanicInfo and std's PanicInfo. · model-checking/verify-rust-std@702405e (original) (raw)

`@@ -4,11 +4,162 @@

`

4

4

``

5

5

`use crate::any::Any;

`

6

6

`use crate::collections;

`

``

7

`+

use crate::fmt;

`

7

8

`use crate::panicking;

`

8

9

`use crate::sync::atomic::{AtomicU8, Ordering};

`

9

10

`use crate::sync::{Condvar, Mutex, RwLock};

`

10

11

`use crate::thread::Result;

`

11

12

``

``

13

`+

/// A struct providing information about a panic.

`

``

14

`+

///

`

``

15

`` +

/// PanicInfo structure is passed to a panic hook set by the [set_hook]

``

``

16

`+

/// function.

`

``

17

`+

///

`

``

18

`` +

/// [set_hook]: ../../std/panic/fn.set_hook.html

``

``

19

`+

///

`

``

20

`+

/// # Examples

`

``

21

`+

///

`

``

22


/// ```should_panic

``

23

`+

/// use std::panic;

`

``

24

`+

///

`

``

25

`+

/// panic::set_hook(Box::new(|panic_info| {

`

``

26

`+

/// println!("panic occurred: {panic_info}");

`

``

27

`+

/// }));

`

``

28

`+

///

`

``

29

`+

/// panic!("critical system failure");

`

``

30


/// ```

``

31

`+

#[stable(feature = "panic_hooks", since = "1.10.0")]

`

``

32

`+

#[derive(Debug)]

`

``

33

`+

pub struct PanicInfo<'a> {

`

``

34

`+

payload: &'a (dyn Any + Send),

`

``

35

`+

location: &'a Location<'a>,

`

``

36

`+

can_unwind: bool,

`

``

37

`+

force_no_backtrace: bool,

`

``

38

`+

}

`

``

39

+

``

40

`+

impl<'a> PanicInfo<'a> {

`

``

41

`+

#[unstable(feature = "panic_internals", issue = "none")]

`

``

42

`+

#[doc(hidden)]

`

``

43

`+

#[inline]

`

``

44

`+

pub fn internal_constructor(

`

``

45

`+

location: &'a Location<'a>,

`

``

46

`+

can_unwind: bool,

`

``

47

`+

force_no_backtrace: bool,

`

``

48

`+

) -> Self {

`

``

49

`+

struct NoPayload;

`

``

50

`+

PanicInfo { payload: &NoPayload, location, can_unwind, force_no_backtrace }

`

``

51

`+

}

`

``

52

+

``

53

`+

#[unstable(feature = "panic_internals", issue = "none")]

`

``

54

`+

#[doc(hidden)]

`

``

55

`+

#[inline]

`

``

56

`+

pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) {

`

``

57

`+

self.payload = info;

`

``

58

`+

}

`

``

59

+

``

60

`+

/// Returns the payload associated with the panic.

`

``

61

`+

///

`

``

62

`` +

/// This will commonly, but not always, be a &'static str or [String].

``

``

63

`+

///

`

``

64

`` +

/// [String]: ../../std/string/struct.String.html

``

``

65

`+

///

`

``

66

`+

/// # Examples

`

``

67

`+

///

`

``

68


/// ```should_panic

``

69

`+

/// use std::panic;

`

``

70

`+

///

`

``

71

`+

/// panic::set_hook(Box::new(|panic_info| {

`

``

72

`+

/// if let Some(s) = panic_info.payload().downcast_ref::<&str>() {

`

``

73

`+

/// println!("panic occurred: {s:?}");

`

``

74

`+

/// } else {

`

``

75

`+

/// println!("panic occurred");

`

``

76

`+

/// }

`

``

77

`+

/// }));

`

``

78

`+

///

`

``

79

`+

/// panic!("Normal panic");

`

``

80


/// ```

``

81

`+

#[must_use]

`

``

82

`+

#[stable(feature = "panic_hooks", since = "1.10.0")]

`

``

83

`+

pub fn payload(&self) -> &(dyn Any + Send) {

`

``

84

`+

self.payload

`

``

85

`+

}

`

``

86

+

``

87

`+

/// Returns information about the location from which the panic originated,

`

``

88

`+

/// if available.

`

``

89

`+

///

`

``

90

`` +

/// This method will currently always return [Some], but this may change

``

``

91

`+

/// in future versions.

`

``

92

`+

///

`

``

93

`+

/// # Examples

`

``

94

`+

///

`

``

95


/// ```should_panic

``

96

`+

/// use std::panic;

`

``

97

`+

///

`

``

98

`+

/// panic::set_hook(Box::new(|panic_info| {

`

``

99

`+

/// if let Some(location) = panic_info.location() {

`

``

100

`+

/// println!("panic occurred in file '{}' at line {}",

`

``

101

`+

/// location.file(),

`

``

102

`+

/// location.line(),

`

``

103

`+

/// );

`

``

104

`+

/// } else {

`

``

105

`+

/// println!("panic occurred but can't get location information...");

`

``

106

`+

/// }

`

``

107

`+

/// }));

`

``

108

`+

///

`

``

109

`+

/// panic!("Normal panic");

`

``

110


/// ```

``

111

`+

#[must_use]

`

``

112

`+

#[stable(feature = "panic_hooks", since = "1.10.0")]

`

``

113

`+

pub fn location(&self) -> Option<&Location<'_>> {

`

``

114

`+

// NOTE: If this is changed to sometimes return None,

`

``

115

`+

// deal with that case in std::panicking::default_hook and core::panicking::panic_fmt.

`

``

116

`+

Some(&self.location)

`

``

117

`+

}

`

``

118

+

``

119

`+

/// Returns whether the panic handler is allowed to unwind the stack from

`

``

120

`+

/// the point where the panic occurred.

`

``

121

`+

///

`

``

122

`+

/// This is true for most kinds of panics with the exception of panics

`

``

123

`` +

/// caused by trying to unwind out of a Drop implementation or a function

``

``

124

`+

/// whose ABI does not support unwinding.

`

``

125

`+

///

`

``

126

`+

/// It is safe for a panic handler to unwind even when this function returns

`

``

127

`+

/// false, however this will simply cause the panic handler to be called

`

``

128

`+

/// again.

`

``

129

`+

#[must_use]

`

``

130

`+

#[unstable(feature = "panic_can_unwind", issue = "92988")]

`

``

131

`+

pub fn can_unwind(&self) -> bool {

`

``

132

`+

self.can_unwind

`

``

133

`+

}

`

``

134

+

``

135

`+

#[unstable(

`

``

136

`+

feature = "panic_internals",

`

``

137

`` +

reason = "internal details of the implementation of the panic! and related macros",

``

``

138

`+

issue = "none"

`

``

139

`+

)]

`

``

140

`+

#[doc(hidden)]

`

``

141

`+

#[inline]

`

``

142

`+

pub fn force_no_backtrace(&self) -> bool {

`

``

143

`+

self.force_no_backtrace

`

``

144

`+

}

`

``

145

`+

}

`

``

146

+

``

147

`+

#[stable(feature = "panic_hook_display", since = "1.26.0")]

`

``

148

`+

impl fmt::Display for PanicInfo<'_> {

`

``

149

`+

fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {

`

``

150

`+

formatter.write_str("panicked at ")?;

`

``

151

`+

self.location.fmt(formatter)?;

`

``

152

`+

if let Some(payload) = self.payload.downcast_ref::<&'static str>() {

`

``

153

`+

formatter.write_str(":\n")?;

`

``

154

`+

formatter.write_str(payload)?;

`

``

155

`+

} else if let Some(payload) = self.payload.downcast_ref::() {

`

``

156

`+

formatter.write_str(":\n")?;

`

``

157

`+

formatter.write_str(payload)?;

`

``

158

`+

}

`

``

159

`+

Ok(())

`

``

160

`+

}

`

``

161

`+

}

`

``

162

+

12

163

`#[doc(hidden)]

`

13

164

`#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]

`

14

165

`#[allow_internal_unstable(libstd_sys_internals, const_format_args, panic_internals, rt)]

`

`@@ -43,7 +194,7 @@ pub use crate::panicking::{set_hook, take_hook};

`

43

194

`pub use crate::panicking::update_hook;

`

44

195

``

45

196

`#[stable(feature = "panic_hooks", since = "1.10.0")]

`

46

``

`-

pub use core::panic::{Location, PanicInfo};

`

``

197

`+

pub use core::panic::Location;

`

47

198

``

48

199

`#[stable(feature = "catch_unwind", since = "1.9.0")]

`

49

200

`pub use core::panic::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe};

`