]>
Commit | Line | Data |
---|---|---|
064997fb FG |
1 | use crate::{Diagnostic, DiagnosticsContext}; |
2 | ||
3 | // Diagnostic: missing-unsafe | |
4 | // | |
5 | // This diagnostic is triggered if an operation marked as `unsafe` is used outside of an `unsafe` function or block. | |
6 | pub(crate) fn missing_unsafe(ctx: &DiagnosticsContext<'_>, d: &hir::MissingUnsafe) -> Diagnostic { | |
7 | Diagnostic::new( | |
8 | "missing-unsafe", | |
9 | "this operation is unsafe and requires an unsafe function or block", | |
10 | ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range, | |
11 | ) | |
12 | } | |
13 | ||
14 | #[cfg(test)] | |
15 | mod tests { | |
16 | use crate::tests::check_diagnostics; | |
17 | ||
18 | #[test] | |
19 | fn missing_unsafe_diagnostic_with_raw_ptr() { | |
20 | check_diagnostics( | |
21 | r#" | |
22 | fn main() { | |
23 | let x = &5 as *const usize; | |
24 | unsafe { let y = *x; } | |
25 | let z = *x; | |
26 | } //^^ error: this operation is unsafe and requires an unsafe function or block | |
27 | "#, | |
28 | ) | |
29 | } | |
30 | ||
31 | #[test] | |
32 | fn missing_unsafe_diagnostic_with_unsafe_call() { | |
33 | check_diagnostics( | |
34 | r#" | |
35 | struct HasUnsafe; | |
36 | ||
37 | impl HasUnsafe { | |
38 | unsafe fn unsafe_fn(&self) { | |
39 | let x = &5 as *const usize; | |
40 | let y = *x; | |
41 | } | |
42 | } | |
43 | ||
44 | unsafe fn unsafe_fn() { | |
45 | let x = &5 as *const usize; | |
46 | let y = *x; | |
47 | } | |
48 | ||
49 | fn main() { | |
50 | unsafe_fn(); | |
51 | //^^^^^^^^^^^ error: this operation is unsafe and requires an unsafe function or block | |
52 | HasUnsafe.unsafe_fn(); | |
53 | //^^^^^^^^^^^^^^^^^^^^^ error: this operation is unsafe and requires an unsafe function or block | |
54 | unsafe { | |
55 | unsafe_fn(); | |
56 | HasUnsafe.unsafe_fn(); | |
57 | } | |
58 | } | |
59 | "#, | |
60 | ); | |
61 | } | |
62 | ||
63 | #[test] | |
64 | fn missing_unsafe_diagnostic_with_static_mut() { | |
65 | check_diagnostics( | |
66 | r#" | |
67 | struct Ty { | |
68 | a: u8, | |
69 | } | |
70 | ||
71 | static mut STATIC_MUT: Ty = Ty { a: 0 }; | |
72 | ||
73 | fn main() { | |
74 | let x = STATIC_MUT.a; | |
75 | //^^^^^^^^^^ error: this operation is unsafe and requires an unsafe function or block | |
76 | unsafe { | |
77 | let x = STATIC_MUT.a; | |
78 | } | |
79 | } | |
80 | "#, | |
81 | ); | |
82 | } | |
83 | ||
84 | #[test] | |
85 | fn no_missing_unsafe_diagnostic_with_safe_intrinsic() { | |
86 | check_diagnostics( | |
87 | r#" | |
88 | extern "rust-intrinsic" { | |
f25598a0 | 89 | #[rustc_safe_intrinsic] |
064997fb FG |
90 | pub fn bitreverse(x: u32) -> u32; // Safe intrinsic |
91 | pub fn floorf32(x: f32) -> f32; // Unsafe intrinsic | |
92 | } | |
93 | ||
94 | fn main() { | |
95 | let _ = bitreverse(12); | |
96 | let _ = floorf32(12.0); | |
97 | //^^^^^^^^^^^^^^ error: this operation is unsafe and requires an unsafe function or block | |
98 | } | |
99 | "#, | |
100 | ); | |
101 | } | |
102 | } |