Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Support new #[rustc_intrinsic] attribute and fallback bodies #18475

Merged
merged 1 commit into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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