diff options
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 47 | ||||
-rw-r--r-- | crates/hir_expand/src/name.rs | 36 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/unsafe_check.rs | 18 |
3 files changed, 99 insertions, 2 deletions
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 3328639cf..ca7fb4a43 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::{collections::hash_map::Entry, mem, sync::Arc}; | 3 | use std::{collections::hash_map::Entry, mem, sync::Arc}; |
4 | 4 | ||
5 | use arena::map::ArenaMap; | 5 | use arena::map::ArenaMap; |
6 | use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, HirFileId}; | 6 | use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, name::known, HirFileId}; |
7 | use smallvec::SmallVec; | 7 | use smallvec::SmallVec; |
8 | use syntax::{ | 8 | use syntax::{ |
9 | ast::{self, ModuleItemOwner}, | 9 | ast::{self, ModuleItemOwner}, |
@@ -555,7 +555,8 @@ impl Ctx { | |||
555 | let id: ModItem = match item { | 555 | let id: ModItem = match item { |
556 | ast::ExternItem::Fn(ast) => { | 556 | ast::ExternItem::Fn(ast) => { |
557 | let func = self.lower_function(&ast)?; | 557 | let func = self.lower_function(&ast)?; |
558 | self.data().functions[func.index].is_unsafe = true; | 558 | self.data().functions[func.index].is_unsafe = |
559 | is_intrinsic_fn_unsafe(&self.data().functions[func.index].name); | ||
559 | func.into() | 560 | func.into() |
560 | } | 561 | } |
561 | ast::ExternItem::Static(ast) => { | 562 | ast::ExternItem::Static(ast) => { |
@@ -713,3 +714,45 @@ enum GenericsOwner<'a> { | |||
713 | TypeAlias, | 714 | TypeAlias, |
714 | Impl, | 715 | Impl, |
715 | } | 716 | } |
717 | |||
718 | /// Returns `true` if the given intrinsic is unsafe to call, or false otherwise. | ||
719 | fn is_intrinsic_fn_unsafe(name: &Name) -> bool { | ||
720 | // Should be kept in sync with https://github.com/rust-lang/rust/blob/c6e4db620a7d2f569f11dcab627430921ea8aacf/compiler/rustc_typeck/src/check/intrinsic.rs#L68 | ||
721 | ![ | ||
722 | known::abort, | ||
723 | known::min_align_of, | ||
724 | known::needs_drop, | ||
725 | known::caller_location, | ||
726 | known::size_of_val, | ||
727 | known::min_align_of_val, | ||
728 | known::add_with_overflow, | ||
729 | known::sub_with_overflow, | ||
730 | known::mul_with_overflow, | ||
731 | known::wrapping_add, | ||
732 | known::wrapping_sub, | ||
733 | known::wrapping_mul, | ||
734 | known::saturating_add, | ||
735 | known::saturating_sub, | ||
736 | known::rotate_left, | ||
737 | known::rotate_right, | ||
738 | known::ctpop, | ||
739 | known::ctlz, | ||
740 | known::cttz, | ||
741 | known::bswap, | ||
742 | known::bitreverse, | ||
743 | known::discriminant_value, | ||
744 | known::type_id, | ||
745 | known::likely, | ||
746 | known::unlikely, | ||
747 | known::ptr_guaranteed_eq, | ||
748 | known::ptr_guaranteed_ne, | ||
749 | known::minnumf32, | ||
750 | known::minnumf64, | ||
751 | known::maxnumf32, | ||
752 | known::rustc_peek, | ||
753 | known::maxnumf64, | ||
754 | known::type_name, | ||
755 | known::variant_count, | ||
756 | ] | ||
757 | .contains(&name) | ||
758 | } | ||
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs index 63f828707..b26ffa1ef 100644 --- a/crates/hir_expand/src/name.rs +++ b/crates/hir_expand/src/name.rs | |||
@@ -208,6 +208,42 @@ pub mod known { | |||
208 | PartialOrd, | 208 | PartialOrd, |
209 | Eq, | 209 | Eq, |
210 | PartialEq, | 210 | PartialEq, |
211 | // Safe intrinsics | ||
212 | abort, | ||
213 | size_of, | ||
214 | min_align_of, | ||
215 | needs_drop, | ||
216 | caller_location, | ||
217 | size_of_val, | ||
218 | min_align_of_val, | ||
219 | add_with_overflow, | ||
220 | sub_with_overflow, | ||
221 | mul_with_overflow, | ||
222 | wrapping_add, | ||
223 | wrapping_sub, | ||
224 | wrapping_mul, | ||
225 | saturating_add, | ||
226 | saturating_sub, | ||
227 | rotate_left, | ||
228 | rotate_right, | ||
229 | ctpop, | ||
230 | ctlz, | ||
231 | cttz, | ||
232 | bswap, | ||
233 | bitreverse, | ||
234 | discriminant_value, | ||
235 | type_id, | ||
236 | likely, | ||
237 | unlikely, | ||
238 | ptr_guaranteed_eq, | ||
239 | ptr_guaranteed_ne, | ||
240 | minnumf32, | ||
241 | minnumf64, | ||
242 | maxnumf32, | ||
243 | rustc_peek, | ||
244 | maxnumf64, | ||
245 | type_name, | ||
246 | variant_count, | ||
211 | ); | 247 | ); |
212 | 248 | ||
213 | // self/Self cannot be used as an identifier | 249 | // self/Self cannot be used as an identifier |
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs index 21a121aad..2da9688ca 100644 --- a/crates/hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs | |||
@@ -202,4 +202,22 @@ fn main() { | |||
202 | "#, | 202 | "#, |
203 | ); | 203 | ); |
204 | } | 204 | } |
205 | |||
206 | #[test] | ||
207 | fn no_missing_unsafe_diagnostic_with_safe_intrinsic() { | ||
208 | check_diagnostics( | ||
209 | r#" | ||
210 | extern "rust-intrinsic" { | ||
211 | pub fn bitreverse(x: u32) -> u32; // Safe intrinsic | ||
212 | pub fn floorf32(x: f32) -> f32; // Unsafe intrinsic | ||
213 | } | ||
214 | |||
215 | fn main() { | ||
216 | let _ = bitreverse(12); | ||
217 | let _ = floorf32(12.0); | ||
218 | //^^^^^^^^^^^^^^ This operation is unsafe and requires an unsafe function or block | ||
219 | } | ||
220 | "#, | ||
221 | ); | ||
222 | } | ||
205 | } | 223 | } |