aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-10-21 21:09:11 +0100
committerGitHub <[email protected]>2020-10-21 21:09:11 +0100
commit9eb6cbb80b7d2ccf196745f8e53fc22ae0f73030 (patch)
treed18c053f76b22c831e61cd9b5da2ec0ff5560b4f
parentcc63f153f07af0d494f6bdfba9291e821a839807 (diff)
parentaff04d81ba6a334c1ba20ea4e6e04ffc88221aee (diff)
Merge #6307
6307: Add whitelist of safe intrinsics r=frazar a=frazar This PR should fix #5996, where intrinsic operations where all marked as unsafe. I'm rather new to this codebase, so I might be doing something *very* wrong. Please forgive me! In particular, I'm not sure how to "check that we are in extern `rust-intrinsics`" as mentioned [in this comment](https://github.com/rust-analyzer/rust-analyzer/issues/5996#issuecomment-709234802). Co-authored-by: Francesco Zardi <[email protected]>
-rw-r--r--crates/hir_def/src/item_tree/lower.rs47
-rw-r--r--crates/hir_expand/src/name.rs36
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs18
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 @@
3use std::{collections::hash_map::Entry, mem, sync::Arc}; 3use std::{collections::hash_map::Entry, mem, sync::Arc};
4 4
5use arena::map::ArenaMap; 5use arena::map::ArenaMap;
6use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, HirFileId}; 6use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, name::known, HirFileId};
7use smallvec::SmallVec; 7use smallvec::SmallVec;
8use syntax::{ 8use 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.
719fn 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#"
210extern "rust-intrinsic" {
211 pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
212 pub fn floorf32(x: f32) -> f32; // Unsafe intrinsic
213}
214
215fn 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}