Skip to content

Commit

Permalink
Support new #[rustc_intrinsic] attribute and fallback bodies
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Nov 4, 2024
1 parent 78f3112 commit 36d68c5
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 174 deletions.
4 changes: 0 additions & 4 deletions crates/hir-def/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use syntax::{ast, Parse};
use triomphe::Arc;

use crate::{
attr::Attrs,
db::DefDatabase,
expander::{Expander, Mark},
item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId},
Expand All @@ -37,8 +36,6 @@ pub struct FunctionData {
pub name: Name,
pub params: Box<[TypeRefId]>,
pub ret_type: TypeRefId,
// FIXME: why are these stored here? They should be accessed via the query
pub attrs: Attrs,
pub visibility: RawVisibility,
pub abi: Option<Symbol>,
pub legacy_const_generics_indices: Option<Box<Box<[u32]>>>,
Expand Down Expand Up @@ -115,7 +112,6 @@ impl FunctionData {
.filter_map(|(_, param)| param.type_ref)
.collect(),
ret_type: func.ret_type,
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
visibility,
abi: func.abi.clone(),
legacy_const_generics_indices,
Expand Down
13 changes: 13 additions & 0 deletions crates/hir-expand/src/inert_attr_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,19 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
"the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
),
rustc_attr!(
rustc_intrinsic, Normal, template!(Word), ErrorFollowing,
"the `#[rustc_intrinsic]` attribute is used to declare intrinsics with function bodies",
),
rustc_attr!(
rustc_no_mir_inline, Normal, template!(Word), WarnFollowing,
"#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen"
),
rustc_attr!(
rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing,
"the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies",
),

rustc_attr!(
rustc_deprecated_safe_2024, Normal, template!(Word), WarnFollowing,
"the `#[rustc_safe_intrinsic]` marks functions as unsafe in Rust 2024",
Expand Down
97 changes: 44 additions & 53 deletions crates/hir-ty/src/consteval/tests/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use super::*;
fn size_of() {
check_number(
r#"
extern "rust-intrinsic" {
pub fn size_of<T>() -> usize;
}
#[rustc_intrinsic]
pub fn size_of<T>() -> usize;
const GOAL: usize = size_of::<i32>();
"#,
Expand All @@ -19,9 +18,8 @@ fn size_of_val() {
check_number(
r#"
//- minicore: coerce_unsized
extern "rust-intrinsic" {
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
}
#[rustc_intrinsic]
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
struct X(i32, u8);
Expand All @@ -32,9 +30,8 @@ fn size_of_val() {
check_number(
r#"
//- minicore: coerce_unsized
extern "rust-intrinsic" {
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
}
#[rustc_intrinsic]
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
const GOAL: usize = {
let it: &[i32] = &[1, 2, 3];
Expand All @@ -48,9 +45,8 @@ fn size_of_val() {
//- minicore: coerce_unsized, transmute
use core::mem::transmute;
extern "rust-intrinsic" {
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
}
#[rustc_intrinsic]
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
struct X {
x: i64,
Expand All @@ -70,9 +66,8 @@ fn size_of_val() {
//- minicore: coerce_unsized, transmute
use core::mem::transmute;
extern "rust-intrinsic" {
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
}
#[rustc_intrinsic]
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
struct X {
x: i32,
Expand All @@ -90,9 +85,8 @@ fn size_of_val() {
check_number(
r#"
//- minicore: coerce_unsized, fmt, builtin_impls, dispatch_from_dyn
extern "rust-intrinsic" {
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
}
#[rustc_intrinsic]
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
const GOAL: usize = {
let x: &i16 = &5;
Expand All @@ -106,9 +100,8 @@ fn size_of_val() {
check_number(
r#"
//- minicore: coerce_unsized
extern "rust-intrinsic" {
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
}
#[rustc_intrinsic]
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
const GOAL: usize = {
size_of_val("salam")
Expand All @@ -123,9 +116,8 @@ fn min_align_of_val() {
check_number(
r#"
//- minicore: coerce_unsized
extern "rust-intrinsic" {
pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
}
#[rustc_intrinsic]
pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
struct X(i32, u8);
Expand All @@ -136,9 +128,8 @@ fn min_align_of_val() {
check_number(
r#"
//- minicore: coerce_unsized
extern "rust-intrinsic" {
pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
}
#[rustc_intrinsic]
pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
const GOAL: usize = {
let x: &[i32] = &[1, 2, 3];
Expand All @@ -153,19 +144,17 @@ fn min_align_of_val() {
fn type_name() {
check_str(
r#"
extern "rust-intrinsic" {
pub fn type_name<T: ?Sized>() -> &'static str;
}
#[rustc_intrinsic]
pub fn type_name<T: ?Sized>() -> &'static str;
const GOAL: &str = type_name::<i32>();
"#,
"i32",
);
check_str(
r#"
extern "rust-intrinsic" {
pub fn type_name<T: ?Sized>() -> &'static str;
}
#[rustc_intrinsic]
pub fn type_name<T: ?Sized>() -> &'static str;
mod mod1 {
pub mod mod2 {
Expand All @@ -183,9 +172,8 @@ fn type_name() {
fn transmute() {
check_number(
r#"
extern "rust-intrinsic" {
pub fn transmute<T, U>(e: T) -> U;
}
#[rustc_intrinsic]
pub fn transmute<T, U>(e: T) -> U;
const GOAL: i32 = transmute((1i16, 1i16));
"#,
Expand All @@ -197,10 +185,10 @@ fn transmute() {
fn read_via_copy() {
check_number(
r#"
extern "rust-intrinsic" {
pub fn read_via_copy<T>(e: *const T) -> T;
pub fn volatile_load<T>(e: *const T) -> T;
}
#[rustc_intrinsic]
pub fn read_via_copy<T>(e: *const T) -> T;
#[rustc_intrinsic]
pub fn volatile_load<T>(e: *const T) -> T;
const GOAL: i32 = {
let x = 2;
Expand Down Expand Up @@ -399,9 +387,14 @@ fn discriminant_value() {
fn likely() {
check_number(
r#"
extern "rust-intrinsic" {
pub fn likely(b: bool) -> bool;
pub fn unlikely(b: bool) -> bool;
#[rustc_intrinsic]
pub const fn likely(b: bool) -> bool {
b
}
#[rustc_intrinsic]
pub const fn unlikely(b: bool) -> bool {
b
}
const GOAL: bool = likely(true) && unlikely(true) && !likely(false) && !unlikely(false);
Expand Down Expand Up @@ -704,9 +697,8 @@ fn rotate() {
);
check_number(
r#"
extern "rust-intrinsic" {
pub fn rotate_right<T: Copy>(x: T, y: T) -> T;
}
#[rustc_intrinsic]
pub fn rotate_right<T: Copy>(x: T, y: T) -> T;
const GOAL: i32 = rotate_right(10006016, 1020315);
"#,
Expand All @@ -721,9 +713,8 @@ fn simd() {
pub struct i8x16(
i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,
);
extern "platform-intrinsic" {
pub fn simd_bitmask<T, U>(x: T) -> U;
}
#[rustc_intrinsic]
pub fn simd_bitmask<T, U>(x: T) -> U;
const GOAL: u16 = simd_bitmask(i8x16(
0, 1, 0, 0, 2, 255, 100, 0, 50, 0, 1, 1, 0, 0, 0, 0
));
Expand All @@ -735,10 +726,10 @@ fn simd() {
pub struct i8x16(
i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,
);
extern "platform-intrinsic" {
pub fn simd_lt<T, U>(x: T, y: T) -> U;
pub fn simd_bitmask<T, U>(x: T) -> U;
}
#[rustc_intrinsic]
pub fn simd_lt<T, U>(x: T, y: T) -> U;
#[rustc_intrinsic]
pub fn simd_bitmask<T, U>(x: T) -> U;
const GOAL: u16 = simd_bitmask(simd_lt::<i8x16, i8x16>(
i8x16(
-105, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-ty/src/diagnostics/decl_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ impl<'a> DeclValidator<'a> {

// Don't run the lint on extern "[not Rust]" fn items with the
// #[no_mangle] attribute.
let no_mangle = data.attrs.by_key(&sym::no_mangle).exists();
let no_mangle = self.db.attrs(func.into()).by_key(&sym::no_mangle).exists();
if no_mangle && data.abi.as_ref().is_some_and(|abi| *abi != sym::Rust) {
cov_mark::hit!(extern_func_no_mangle_ignored);
} else {
Expand Down
Loading

0 comments on commit 36d68c5

Please sign in to comment.