1
Fork 0

remove support for rustc_intrinsic_must_be_overridden from the compiler

This commit is contained in:
Ralf Jung 2025-02-23 17:34:50 +01:00
parent 5a58a922e2
commit 6eea027aa9
24 changed files with 70 additions and 203 deletions

View file

@ -620,70 +620,31 @@ pub union MaybeUninit<T> {
pub mod intrinsics { pub mod intrinsics {
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn abort() -> !;
pub fn abort() -> ! {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn size_of<T>() -> usize;
pub fn size_of<T>() -> usize {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize;
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn min_align_of<T>() -> usize;
pub fn min_align_of<T>() -> usize {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize;
pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize);
pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize) {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn transmute<T, U>(_e: T) -> U;
pub unsafe fn transmute<T, U>(_e: T) -> U {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32;
pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32 {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn needs_drop<T: ?::Sized>() -> bool;
pub fn needs_drop<T: ?::Sized>() -> bool {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn bitreverse<T>(_x: T) -> T;
pub fn bitreverse<T>(_x: T) -> T {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn bswap<T>(_x: T) -> T;
pub fn bswap<T>(_x: T) -> T {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize);
pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize) {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn unreachable() -> !;
pub unsafe fn unreachable() -> ! {
loop {}
}
} }
pub mod libc { pub mod libc {

View file

@ -591,70 +591,31 @@ pub union MaybeUninit<T> {
pub mod intrinsics { pub mod intrinsics {
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn abort() -> !;
pub fn abort() -> ! {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn size_of<T>() -> usize;
pub fn size_of<T>() -> usize {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize;
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn min_align_of<T>() -> usize;
pub fn min_align_of<T>() -> usize {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize;
pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize);
pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize) {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn transmute<T, U>(_e: T) -> U;
pub unsafe fn transmute<T, U>(_e: T) -> U {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32;
pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32 {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn needs_drop<T: ?::Sized>() -> bool;
pub fn needs_drop<T: ?::Sized>() -> bool {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn bitreverse<T>(_x: T) -> T;
pub fn bitreverse<T>(_x: T) -> T {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn bswap<T>(_x: T) -> T;
pub fn bswap<T>(_x: T) -> T {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize);
pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize) {
loop {}
}
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn unreachable() -> !;
pub unsafe fn unreachable() -> ! {
loop {}
}
} }
pub mod libc { pub mod libc {

View file

@ -36,10 +36,7 @@ mod intrinsics {
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn abort() -> !;
pub fn abort() -> ! {
loop {}
}
} }
/* /*

View file

@ -36,10 +36,7 @@ mod intrinsics {
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn abort() -> !;
pub fn abort() -> ! {
loop {}
}
} }
/* /*

View file

@ -59,10 +59,7 @@ mod libc {
mod intrinsics { mod intrinsics {
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn abort() -> !;
pub fn abort() -> ! {
loop {}
}
} }
#[lang = "panic"] #[lang = "panic"]

View file

@ -61,10 +61,7 @@ mod libc {
mod intrinsics { mod intrinsics {
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn abort() -> !;
pub fn abort() -> ! {
loop {}
}
} }
#[lang = "panic"] #[lang = "panic"]

View file

@ -67,10 +67,7 @@ mod libc {
mod intrinsics { mod intrinsics {
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn abort() -> !;
pub fn abort() -> ! {
loop {}
}
} }
#[lang = "panic"] #[lang = "panic"]

View file

@ -49,10 +49,7 @@ mod intrinsics {
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn abort() -> !;
pub fn abort() -> ! {
loop {}
}
} }
mod libc { mod libc {

View file

@ -7,12 +7,8 @@ Erroneous code example:
#![allow(internal_features)] #![allow(internal_features)]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] fn size_of<T, U>() -> usize; // error: intrinsic has wrong number
fn size_of<T, U>() -> usize // error: intrinsic has wrong number
// of type parameters // of type parameters
{
loop {}
}
``` ```
Please check that you provided the right number of type parameters Please check that you provided the right number of type parameters
@ -24,9 +20,5 @@ Example:
#![allow(internal_features)] #![allow(internal_features)]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] fn size_of<T>() -> usize; // ok!
fn size_of<T>() -> usize // ok!
{
loop {}
}
``` ```

View file

@ -1005,10 +1005,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics, rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
"the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items", "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items",
), ),
gated!(
rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
"the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies",
),
rustc_attr!( rustc_attr!(
rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
"#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen" "#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen"

View file

@ -1755,8 +1755,7 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Intrinsi
&& (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic) && (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
|| tcx.has_attr(def_id, sym::rustc_intrinsic)) || tcx.has_attr(def_id, sym::rustc_intrinsic))
{ {
let must_be_overridden = tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden) let must_be_overridden = match tcx.hir_node_by_def_id(def_id) {
|| match tcx.hir_node_by_def_id(def_id) {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { has_body, .. }, .. }) => { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { has_body, .. }, .. }) => {
!has_body !has_body
} }

View file

@ -1764,7 +1764,6 @@ symbols! {
rustc_insignificant_dtor, rustc_insignificant_dtor,
rustc_intrinsic, rustc_intrinsic,
rustc_intrinsic_const_stable_indirect, rustc_intrinsic_const_stable_indirect,
rustc_intrinsic_must_be_overridden,
rustc_layout, rustc_layout,
rustc_layout_scalar_valid_range_end, rustc_layout_scalar_valid_range_end,
rustc_layout_scalar_valid_range_start, rustc_layout_scalar_valid_range_start,

View file

@ -62,13 +62,19 @@ These must be implemented by all backends.
### `#[rustc_intrinsic]` declarations ### `#[rustc_intrinsic]` declarations
These are written like intrinsics with fallback bodies, but the body is irrelevant. These are written without a body:
Use `loop {}` for the body or call the intrinsic recursively and add ```rust
`#[rustc_intrinsic_must_be_overridden]` to the function to ensure that backends don't #![feature(intrinsics)]
invoke the body. #![allow(internal_features)]
#[rustc_intrinsic]
pub fn abort() -> !;
```
### Legacy extern ABI based intrinsics ### Legacy extern ABI based intrinsics
*This style is deprecated, always prefer the above form.*
These are imported as if they were FFI functions, with the special These are imported as if they were FFI functions, with the special
`rust-intrinsic` ABI. For example, if one was in a freestanding `rust-intrinsic` ABI. For example, if one was in a freestanding
context, but wished to be able to `transmute` between types, and context, but wished to be able to `transmute` between types, and

View file

@ -51,10 +51,7 @@ enum Ordering {
} }
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> Ordering;
fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> Ordering {
loop {}
}
// ^^^^^ core // ^^^^^ core

View file

@ -9,19 +9,13 @@
#[stable(since="1.0.0", feature="rust1")] #[stable(since="1.0.0", feature="rust1")]
#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")] #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub const unsafe fn transmute<T, U>(_: T) -> U;
pub const unsafe fn transmute<T, U>(_: T) -> U {
loop {}
}
//@ has 'foo/fn.unreachable.html' //@ has 'foo/fn.unreachable.html'
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !' //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !'
#[stable(since="1.0.0", feature="rust1")] #[stable(since="1.0.0", feature="rust1")]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn unreachable() -> !;
pub unsafe fn unreachable() -> ! {
loop {}
}
extern "C" { extern "C" {
//@ has 'foo/fn.needs_drop.html' //@ has 'foo/fn.needs_drop.html'

View file

@ -11,14 +11,8 @@ trait Sized {}
//@ has 'foo/fn.abort.html' //@ has 'foo/fn.abort.html'
//@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !' //@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !'
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub fn abort() -> !;
pub fn abort() -> ! {
loop {}
}
//@ has 'foo/fn.unreachable.html' //@ has 'foo/fn.unreachable.html'
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !' //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !'
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] pub unsafe fn unreachable() -> !;
pub unsafe fn unreachable() -> ! {
loop {}
}

View file

@ -51,13 +51,11 @@ fn test_intrinsics() -> ControlFlow<()> {
/// This check is unfortunately tight to the implementation of intrinsics. /// This check is unfortunately tight to the implementation of intrinsics.
/// ///
/// We want to ensure that StableMIR can handle intrinsics with and without fallback body. /// We want to ensure that StableMIR can handle intrinsics with and without fallback body:
/// for intrinsics without a body, obviously we cannot expose anything.
/// ///
/// If by any chance this test breaks because you changed how an intrinsic is implemented, please /// If by any chance this test breaks because you changed how an intrinsic is implemented, please
/// update the test to invoke a different intrinsic. /// update the test to invoke a different intrinsic.
///
/// In StableMIR, we only expose intrinsic body if they are not marked with
/// `rustc_intrinsic_must_be_overridden`.
fn check_instance(instance: &Instance) { fn check_instance(instance: &Instance) {
assert_eq!(instance.kind, InstanceKind::Intrinsic); assert_eq!(instance.kind, InstanceKind::Intrinsic);
let name = instance.intrinsic_name().unwrap(); let name = instance.intrinsic_name().unwrap();

View file

@ -1,10 +1,7 @@
#![feature(intrinsics)] #![feature(intrinsics)]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] fn size_of<T, U>() -> usize;
fn size_of<T, U>() -> usize {
//~^ ERROR E0094 //~^ ERROR E0094
loop {}
}
fn main() {} fn main() {}

View file

@ -1,7 +1,7 @@
error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1 error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1
--> $DIR/E0094.rs:5:11 --> $DIR/E0094.rs:4:11
| |
LL | fn size_of<T, U>() -> usize { LL | fn size_of<T, U>() -> usize;
| ^^^^^^ expected 1 type parameter | ^^^^^^ expected 1 type parameter
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -2,10 +2,7 @@
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] fn size_of<T>();
fn size_of<T>() {
//~^ ERROR E0308 //~^ ERROR E0308
loop {}
}
fn main() {} fn main() {}

View file

@ -1,7 +1,7 @@
error[E0308]: intrinsic has wrong type error[E0308]: intrinsic has wrong type
--> $DIR/E0308.rs:6:16 --> $DIR/E0308.rs:5:16
| |
LL | fn size_of<T>() { LL | fn size_of<T>();
| ^ expected `usize`, found `()` | ^ expected `usize`, found `()`
| |
= note: expected signature `fn() -> usize` = note: expected signature `fn() -> usize`

View file

@ -1,5 +1,5 @@
//! Check that `vtable_size` gets overridden by llvm backend even if there is no //! Check that `vtable_size` gets overridden by llvm backend even if there is a
//! `rustc_intrinsic_must_be_overridden` attribute on this usage. //! fallback body.
#![feature(intrinsics)] #![feature(intrinsics)]
//@run-pass //@run-pass

View file

@ -24,10 +24,7 @@ enum Foo {
#[stable(feature = "intrinsics_for_test", since = "3.3.3")] #[stable(feature = "intrinsics_for_test", since = "3.3.3")]
#[rustc_const_stable(feature = "intrinsics_for_test", since = "3.3.3")] #[rustc_const_stable(feature = "intrinsics_for_test", since = "3.3.3")]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] const fn size_of<T>() -> usize;
const fn size_of<T>() -> usize {
loop {}
}
#[lang="sized"] #[lang="sized"]
trait Sized {} trait Sized {}

View file

@ -21,10 +21,7 @@ impl Copy for bool {}
#[stable(feature = "test", since = "1.0.0")] #[stable(feature = "test", since = "1.0.0")]
#[rustc_const_stable(feature = "test", since = "1.0.0")] #[rustc_const_stable(feature = "test", since = "1.0.0")]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden] const unsafe fn unreachable() -> !;
const unsafe fn unreachable() -> ! {
loop {}
}
#[rustc_builtin_macro] #[rustc_builtin_macro]
macro_rules! cfg { macro_rules! cfg {