mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Auto merge of #132717 - RalfJung:rustc_safe_intrinsic, r=compiler-errors
remove support for rustc_safe_intrinsic attribute; use rustc_intrinsic functions instead This brings us one step closer towards removing support for `extern "rust-intrinsic"` blocks, in favor of `#[rustc_intrinsic]` functions. Also move `#[rustc_intrinsic]` under the `intrinsics` feature gate, to match the `extern "rust-intrinsic"` style.
This commit is contained in:
commit
209799f3b9
@ -616,25 +616,70 @@ pub union MaybeUninit<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod intrinsics {
|
pub mod intrinsics {
|
||||||
extern "rust-intrinsic" {
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub fn abort() -> !;
|
pub fn abort() -> ! {
|
||||||
#[rustc_safe_intrinsic]
|
loop {}
|
||||||
pub fn size_of<T>() -> usize;
|
}
|
||||||
pub fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub fn min_align_of<T>() -> usize;
|
pub fn size_of<T>() -> usize {
|
||||||
pub fn min_align_of_val<T: ?::Sized>(val: *const T) -> usize;
|
loop {}
|
||||||
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
}
|
||||||
pub fn transmute<T, U>(e: T) -> U;
|
#[rustc_intrinsic]
|
||||||
pub fn ctlz_nonzero<T>(x: T) -> u32;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
#[rustc_safe_intrinsic]
|
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||||
pub fn needs_drop<T: ?::Sized>() -> bool;
|
loop {}
|
||||||
#[rustc_safe_intrinsic]
|
}
|
||||||
pub fn bitreverse<T>(x: T) -> T;
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub fn bswap<T>(x: T) -> T;
|
pub fn min_align_of<T>() -> usize {
|
||||||
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize) {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn transmute<T, U>(_e: T) -> U {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32 {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn needs_drop<T: ?::Sized>() -> bool {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn bitreverse<T>(_x: T) -> T {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn bswap<T>(_x: T) -> T {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize) {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn unreachable() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,28 +579,70 @@ pub union MaybeUninit<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod intrinsics {
|
pub mod intrinsics {
|
||||||
use crate::Sized;
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
extern "rust-intrinsic" {
|
pub fn abort() -> ! {
|
||||||
#[rustc_safe_intrinsic]
|
loop {}
|
||||||
pub fn abort() -> !;
|
}
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn size_of<T>() -> usize;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub fn size_of_val<T: ?Sized>(val: *const T) -> usize;
|
pub fn size_of<T>() -> usize {
|
||||||
#[rustc_safe_intrinsic]
|
loop {}
|
||||||
pub fn min_align_of<T>() -> usize;
|
}
|
||||||
pub fn min_align_of_val<T: ?Sized>(val: *const T) -> usize;
|
#[rustc_intrinsic]
|
||||||
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub fn transmute<T, U>(e: T) -> U;
|
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||||
pub fn ctlz_nonzero<T>(x: T) -> u32;
|
loop {}
|
||||||
#[rustc_safe_intrinsic]
|
}
|
||||||
pub fn needs_drop<T: ?Sized>() -> bool;
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub fn bitreverse<T>(x: T) -> T;
|
pub fn min_align_of<T>() -> usize {
|
||||||
#[rustc_safe_intrinsic]
|
loop {}
|
||||||
pub fn bswap<T>(x: T) -> T;
|
}
|
||||||
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
|
#[rustc_intrinsic]
|
||||||
pub fn unreachable() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize) {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn transmute<T, U>(_e: T) -> U {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32 {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn needs_drop<T: ?::Sized>() -> bool {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn bitreverse<T>(_x: T) -> T {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn bswap<T>(_x: T) -> T {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize) {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub unsafe fn unreachable() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,11 @@ pub(crate) unsafe auto trait Freeze {}
|
|||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
use super::Sized;
|
use super::Sized;
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,11 @@ pub(crate) unsafe auto trait Freeze {}
|
|||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
use super::Sized;
|
use super::Sized;
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,9 +106,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,9 +56,11 @@ mod libc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,9 +98,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,9 +109,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +103,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +58,11 @@ mod libc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,9 +64,11 @@ mod libc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +103,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +103,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
|||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
use super::Sized;
|
use super::Sized;
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,9 +46,11 @@ pub(crate) unsafe auto trait Freeze {}
|
|||||||
mod intrinsics {
|
mod intrinsics {
|
||||||
use super::Sized;
|
use super::Sized;
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
pub fn abort() -> !;
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,13 +3,15 @@ An invalid number of generic parameters was passed to an intrinsic function.
|
|||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0094
|
```compile_fail,E0094
|
||||||
#![feature(intrinsics, rustc_attrs)]
|
#![feature(intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_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 {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -18,11 +20,13 @@ and verify with the function declaration in the Rust source code.
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
```
|
```
|
||||||
#![feature(intrinsics, rustc_attrs)]
|
#![feature(intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
fn size_of<T>() -> usize; // ok!
|
fn size_of<T>() -> usize // ok!
|
||||||
|
{
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -4,12 +4,11 @@ You used a function or type which doesn't fit the requirements for where it was
|
|||||||
used. Erroneous code examples:
|
used. Erroneous code examples:
|
||||||
|
|
||||||
```compile_fail
|
```compile_fail
|
||||||
#![feature(intrinsics, rustc_attrs)]
|
#![feature(intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
extern "rust-intrinsic" {
|
||||||
#[rustc_safe_intrinsic]
|
fn unreachable(); // error: intrinsic has wrong type
|
||||||
fn size_of<T>(); // error: intrinsic has wrong type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// or:
|
// or:
|
||||||
@ -41,12 +40,11 @@ impl Foo {
|
|||||||
For the first code example, please check the function definition. Example:
|
For the first code example, please check the function definition. Example:
|
||||||
|
|
||||||
```
|
```
|
||||||
#![feature(intrinsics, rustc_attrs)]
|
#![feature(intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
extern "rust-intrinsic" {
|
||||||
#[rustc_safe_intrinsic]
|
fn unreachable() -> !; // ok!
|
||||||
fn size_of<T>() -> usize; // ok!
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -997,23 +997,18 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
|
rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
|
||||||
EncodeCrossCrate::Yes, r#"`rustc_doc_primitive` is a rustc internal attribute"#,
|
EncodeCrossCrate::Yes, r#"`rustc_doc_primitive` is a rustc internal attribute"#,
|
||||||
),
|
),
|
||||||
rustc_attr!(
|
gated!(
|
||||||
rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
|
rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
|
||||||
EncodeCrossCrate::No,
|
|
||||||
"the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
|
|
||||||
),
|
|
||||||
rustc_attr!(
|
|
||||||
rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes,
|
|
||||||
"the `#[rustc_intrinsic]` attribute is used to declare intrinsics with function bodies",
|
"the `#[rustc_intrinsic]` attribute is used to declare intrinsics with function bodies",
|
||||||
),
|
),
|
||||||
|
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"
|
||||||
),
|
),
|
||||||
rustc_attr!(
|
|
||||||
rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes,
|
|
||||||
"the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies",
|
|
||||||
),
|
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Internal attributes, Testing:
|
// Internal attributes, Testing:
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use rustc_abi::ExternAbi;
|
use rustc_abi::ExternAbi;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{DiagMessage, struct_span_code_err};
|
use rustc_errors::{DiagMessage, struct_span_code_err};
|
||||||
use rustc_hir as hir;
|
use rustc_hir::{self as hir, Safety};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
@ -75,10 +75,8 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
|
|||||||
let has_safe_attr = if tcx.has_attr(intrinsic_id, sym::rustc_intrinsic) {
|
let has_safe_attr = if tcx.has_attr(intrinsic_id, sym::rustc_intrinsic) {
|
||||||
tcx.fn_sig(intrinsic_id).skip_binder().safety()
|
tcx.fn_sig(intrinsic_id).skip_binder().safety()
|
||||||
} else {
|
} else {
|
||||||
match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
|
// Old-style intrinsics are never safe
|
||||||
true => hir::Safety::Safe,
|
Safety::Unsafe
|
||||||
false => hir::Safety::Unsafe,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let is_in_list = match tcx.item_name(intrinsic_id.into()) {
|
let is_in_list = match tcx.item_name(intrinsic_id.into()) {
|
||||||
// When adding a new intrinsic to this list,
|
// When adding a new intrinsic to this list,
|
||||||
|
@ -1785,9 +1785,9 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||||||
/// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may
|
/// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may
|
||||||
/// cause an ICE that we otherwise may want to prevent.
|
/// cause an ICE that we otherwise may want to prevent.
|
||||||
pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
|
pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
|
||||||
if (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
|
if tcx.features().intrinsics()
|
||||||
&& tcx.features().intrinsics())
|
&& (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
|
||||||
|| (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs())
|
|| tcx.has_attr(def_id, sym::rustc_intrinsic))
|
||||||
{
|
{
|
||||||
Some(ty::IntrinsicDef {
|
Some(ty::IntrinsicDef {
|
||||||
name: tcx.item_name(def_id.into()),
|
name: tcx.item_name(def_id.into()),
|
||||||
|
@ -679,10 +679,6 @@ passes_rustc_pub_transparent =
|
|||||||
attribute should be applied to `#[repr(transparent)]` types
|
attribute should be applied to `#[repr(transparent)]` types
|
||||||
.label = not a `#[repr(transparent)]` type
|
.label = not a `#[repr(transparent)]` type
|
||||||
|
|
||||||
passes_rustc_safe_intrinsic =
|
|
||||||
attribute should be applied to intrinsic functions
|
|
||||||
.label = not an intrinsic function
|
|
||||||
|
|
||||||
passes_rustc_std_internal_symbol =
|
passes_rustc_std_internal_symbol =
|
||||||
attribute should be applied to functions or statics
|
attribute should be applied to functions or statics
|
||||||
.label = not a function or static
|
.label = not a function or static
|
||||||
|
@ -210,9 +210,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||||||
| [sym::rustc_promotable, ..] => self.check_stability_promotable(attr, target),
|
| [sym::rustc_promotable, ..] => self.check_stability_promotable(attr, target),
|
||||||
[sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target),
|
[sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target),
|
||||||
[sym::rustc_confusables, ..] => self.check_confusables(attr, target),
|
[sym::rustc_confusables, ..] => self.check_confusables(attr, target),
|
||||||
[sym::rustc_safe_intrinsic, ..] => {
|
|
||||||
self.check_rustc_safe_intrinsic(hir_id, attr, span, target)
|
|
||||||
}
|
|
||||||
[sym::cold, ..] => self.check_cold(hir_id, attr, span, target),
|
[sym::cold, ..] => self.check_cold(hir_id, attr, span, target),
|
||||||
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
|
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
|
||||||
[sym::link_name, ..] => self.check_link_name(hir_id, attr, span, target),
|
[sym::link_name, ..] => self.check_link_name(hir_id, attr, span, target),
|
||||||
@ -2055,25 +2052,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_rustc_safe_intrinsic(
|
|
||||||
&self,
|
|
||||||
hir_id: HirId,
|
|
||||||
attr: &Attribute,
|
|
||||||
span: Span,
|
|
||||||
target: Target,
|
|
||||||
) {
|
|
||||||
if let Target::ForeignFn = target
|
|
||||||
&& let hir::Node::Item(Item {
|
|
||||||
kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic, .. },
|
|
||||||
..
|
|
||||||
}) = self.tcx.parent_hir_node(hir_id)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.dcx().emit_err(errors::RustcSafeIntrinsic { attr_span: attr.span, span });
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_rustc_std_internal_symbol(&self, attr: &Attribute, span: Span, target: Target) {
|
fn check_rustc_std_internal_symbol(&self, attr: &Attribute, span: Span, target: Target) {
|
||||||
match target {
|
match target {
|
||||||
Target::Fn | Target::Static => {}
|
Target::Fn | Target::Static => {}
|
||||||
|
@ -641,15 +641,6 @@ pub(crate) struct RustcAllowConstFnUnstable {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(passes_rustc_safe_intrinsic)]
|
|
||||||
pub(crate) struct RustcSafeIntrinsic {
|
|
||||||
#[primary_span]
|
|
||||||
pub attr_span: Span,
|
|
||||||
#[label]
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(passes_rustc_std_internal_symbol)]
|
#[diag(passes_rustc_std_internal_symbol)]
|
||||||
pub(crate) struct RustcStdInternalSymbol {
|
pub(crate) struct RustcStdInternalSymbol {
|
||||||
|
@ -1733,7 +1733,6 @@ symbols! {
|
|||||||
rustc_reallocator,
|
rustc_reallocator,
|
||||||
rustc_regions,
|
rustc_regions,
|
||||||
rustc_reservation_impl,
|
rustc_reservation_impl,
|
||||||
rustc_safe_intrinsic,
|
|
||||||
rustc_serialize,
|
rustc_serialize,
|
||||||
rustc_skip_during_method_dispatch,
|
rustc_skip_during_method_dispatch,
|
||||||
rustc_specialization_trait,
|
rustc_specialization_trait,
|
||||||
|
@ -904,38 +904,6 @@ extern "rust-intrinsic" {
|
|||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
pub fn prefetch_write_instruction<T>(data: *const T, locality: i32);
|
pub fn prefetch_write_instruction<T>(data: *const T, locality: i32);
|
||||||
|
|
||||||
/// Magic intrinsic that derives its meaning from attributes
|
|
||||||
/// attached to the function.
|
|
||||||
///
|
|
||||||
/// For example, dataflow uses this to inject static assertions so
|
|
||||||
/// that `rustc_peek(potentially_uninitialized)` would actually
|
|
||||||
/// double-check that dataflow did indeed compute that it is
|
|
||||||
/// uninitialized at that point in the control flow.
|
|
||||||
///
|
|
||||||
/// This intrinsic should not be used outside of the compiler.
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
#[rustc_nounwind]
|
|
||||||
pub fn rustc_peek<T>(_: T) -> T;
|
|
||||||
|
|
||||||
/// Aborts the execution of the process.
|
|
||||||
///
|
|
||||||
/// Note that, unlike most intrinsics, this is safe to call;
|
|
||||||
/// it does not require an `unsafe` block.
|
|
||||||
/// Therefore, implementations must not require the user to uphold
|
|
||||||
/// any safety invariants.
|
|
||||||
///
|
|
||||||
/// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible,
|
|
||||||
/// as its behavior is more user-friendly and more stable.
|
|
||||||
///
|
|
||||||
/// The current implementation of `intrinsics::abort` is to invoke an invalid instruction,
|
|
||||||
/// on most platforms.
|
|
||||||
/// On Unix, the
|
|
||||||
/// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
|
|
||||||
/// `SIGBUS`. The precise behavior is not guaranteed and not stable.
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
#[rustc_nounwind]
|
|
||||||
pub fn abort() -> !;
|
|
||||||
|
|
||||||
/// Executes a breakpoint trap, for inspection by a debugger.
|
/// Executes a breakpoint trap, for inspection by a debugger.
|
||||||
///
|
///
|
||||||
/// This intrinsic does not have a stable counterpart.
|
/// This intrinsic does not have a stable counterpart.
|
||||||
@ -943,6 +911,44 @@ extern "rust-intrinsic" {
|
|||||||
pub fn breakpoint();
|
pub fn breakpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Magic intrinsic that derives its meaning from attributes
|
||||||
|
/// attached to the function.
|
||||||
|
///
|
||||||
|
/// For example, dataflow uses this to inject static assertions so
|
||||||
|
/// that `rustc_peek(potentially_uninitialized)` would actually
|
||||||
|
/// double-check that dataflow did indeed compute that it is
|
||||||
|
/// uninitialized at that point in the control flow.
|
||||||
|
///
|
||||||
|
/// This intrinsic should not be used outside of the compiler.
|
||||||
|
#[rustc_nounwind]
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn rustc_peek<T>(_: T) -> T {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Aborts the execution of the process.
|
||||||
|
///
|
||||||
|
/// Note that, unlike most intrinsics, this is safe to call;
|
||||||
|
/// it does not require an `unsafe` block.
|
||||||
|
/// Therefore, implementations must not require the user to uphold
|
||||||
|
/// any safety invariants.
|
||||||
|
///
|
||||||
|
/// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible,
|
||||||
|
/// as its behavior is more user-friendly and more stable.
|
||||||
|
///
|
||||||
|
/// The current implementation of `intrinsics::abort` is to invoke an invalid instruction,
|
||||||
|
/// on most platforms.
|
||||||
|
/// On Unix, the
|
||||||
|
/// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
|
||||||
|
/// `SIGBUS`. The precise behavior is not guaranteed and not stable.
|
||||||
|
#[rustc_nounwind]
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Informs the optimizer that this point in the code is not reachable,
|
/// Informs the optimizer that this point in the code is not reachable,
|
||||||
/// enabling further optimizations.
|
/// enabling further optimizations.
|
||||||
///
|
///
|
||||||
@ -1512,19 +1518,22 @@ pub const unsafe fn arith_offset<T>(_dst: *const T, _offset: isize) -> *const T
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
/// Masks out bits of the pointer according to a mask.
|
||||||
/// Masks out bits of the pointer according to a mask.
|
///
|
||||||
///
|
/// Note that, unlike most intrinsics, this is safe to call;
|
||||||
/// Note that, unlike most intrinsics, this is safe to call;
|
/// it does not require an `unsafe` block.
|
||||||
/// it does not require an `unsafe` block.
|
/// Therefore, implementations must not require the user to uphold
|
||||||
/// Therefore, implementations must not require the user to uphold
|
/// any safety invariants.
|
||||||
/// any safety invariants.
|
///
|
||||||
///
|
/// Consider using [`pointer::mask`] instead.
|
||||||
/// Consider using [`pointer::mask`] instead.
|
#[rustc_nounwind]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic]
|
||||||
#[rustc_nounwind]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T;
|
pub fn ptr_mask<T>(_ptr: *const T, _mask: usize) -> *const T {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "rust-intrinsic" {
|
||||||
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
|
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
|
||||||
/// a size of `count` * `size_of::<T>()` and an alignment of
|
/// a size of `count` * `size_of::<T>()` and an alignment of
|
||||||
/// `min_align_of::<T>()`
|
/// `min_align_of::<T>()`
|
||||||
@ -2140,41 +2149,6 @@ extern "rust-intrinsic" {
|
|||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
pub fn frem_fast<T: Copy>(a: T, b: T) -> T;
|
pub fn frem_fast<T: Copy>(a: T, b: T) -> T;
|
||||||
|
|
||||||
/// Float addition that allows optimizations based on algebraic rules.
|
|
||||||
///
|
|
||||||
/// This intrinsic does not have a stable counterpart.
|
|
||||||
#[rustc_nounwind]
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
|
|
||||||
|
|
||||||
/// Float subtraction that allows optimizations based on algebraic rules.
|
|
||||||
///
|
|
||||||
/// This intrinsic does not have a stable counterpart.
|
|
||||||
#[rustc_nounwind]
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn fsub_algebraic<T: Copy>(a: T, b: T) -> T;
|
|
||||||
|
|
||||||
/// Float multiplication that allows optimizations based on algebraic rules.
|
|
||||||
///
|
|
||||||
/// This intrinsic does not have a stable counterpart.
|
|
||||||
#[rustc_nounwind]
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn fmul_algebraic<T: Copy>(a: T, b: T) -> T;
|
|
||||||
|
|
||||||
/// Float division that allows optimizations based on algebraic rules.
|
|
||||||
///
|
|
||||||
/// This intrinsic does not have a stable counterpart.
|
|
||||||
#[rustc_nounwind]
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T;
|
|
||||||
|
|
||||||
/// Float remainder that allows optimizations based on algebraic rules.
|
|
||||||
///
|
|
||||||
/// This intrinsic does not have a stable counterpart.
|
|
||||||
#[rustc_nounwind]
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn frem_algebraic<T: Copy>(a: T, b: T) -> T;
|
|
||||||
|
|
||||||
/// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range
|
/// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range
|
||||||
/// (<https://github.com/rust-lang/rust/issues/10184>)
|
/// (<https://github.com/rust-lang/rust/issues/10184>)
|
||||||
///
|
///
|
||||||
@ -2183,6 +2157,56 @@ extern "rust-intrinsic" {
|
|||||||
pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
|
pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Float addition that allows optimizations based on algebraic rules.
|
||||||
|
///
|
||||||
|
/// This intrinsic does not have a stable counterpart.
|
||||||
|
#[rustc_nounwind]
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn fadd_algebraic<T: Copy>(_a: T, _b: T) -> T {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Float subtraction that allows optimizations based on algebraic rules.
|
||||||
|
///
|
||||||
|
/// This intrinsic does not have a stable counterpart.
|
||||||
|
#[rustc_nounwind]
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn fsub_algebraic<T: Copy>(_a: T, _b: T) -> T {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Float multiplication that allows optimizations based on algebraic rules.
|
||||||
|
///
|
||||||
|
/// This intrinsic does not have a stable counterpart.
|
||||||
|
#[rustc_nounwind]
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn fmul_algebraic<T: Copy>(_a: T, _b: T) -> T {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Float division that allows optimizations based on algebraic rules.
|
||||||
|
///
|
||||||
|
/// This intrinsic does not have a stable counterpart.
|
||||||
|
#[rustc_nounwind]
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn fdiv_algebraic<T: Copy>(_a: T, _b: T) -> T {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Float remainder that allows optimizations based on algebraic rules.
|
||||||
|
///
|
||||||
|
/// This intrinsic does not have a stable counterpart.
|
||||||
|
#[rustc_nounwind]
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
pub fn frem_algebraic<T: Copy>(_a: T, _b: T) -> T {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the number of bits set in an integer type `T`
|
/// Returns the number of bits set in an integer type `T`
|
||||||
///
|
///
|
||||||
/// Note that, unlike most intrinsics, this is safe to call;
|
/// Note that, unlike most intrinsics, this is safe to call;
|
||||||
|
@ -18,7 +18,7 @@ All intrinsic fallback bodies are automatically made cross-crate inlineable (lik
|
|||||||
by the codegen backend, but not the MIR inliner.
|
by the codegen backend, but not the MIR inliner.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#![feature(rustc_attrs)]
|
#![feature(intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
@ -28,7 +28,7 @@ const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
|
|||||||
Since these are just regular functions, it is perfectly ok to create the intrinsic twice:
|
Since these are just regular functions, it is perfectly ok to create the intrinsic twice:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#![feature(rustc_attrs)]
|
#![feature(intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![feature(rustc_attrs)]
|
#![feature(intrinsics, rustc_attrs)]
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
|
@ -50,9 +50,10 @@ enum Ordering {
|
|||||||
Greater = 1,
|
Greater = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_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
|
||||||
|
@ -5,18 +5,17 @@
|
|||||||
#![no_core]
|
#![no_core]
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
//@ 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 extern "rust-intrinsic" fn abort() -> !'
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub fn abort() -> !;
|
pub fn abort() -> ! {
|
||||||
//@ has 'foo/fn.unreachable.html'
|
loop {}
|
||||||
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !'
|
|
||||||
pub fn unreachable() -> !;
|
|
||||||
}
|
}
|
||||||
|
//@ has 'foo/fn.unreachable.html'
|
||||||
extern "C" {
|
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !'
|
||||||
//@ has 'foo/fn.needs_drop.html'
|
#[rustc_intrinsic]
|
||||||
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn needs_drop() -> !'
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub fn needs_drop() -> !;
|
pub unsafe fn unreachable() -> ! {
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#![feature(intrinsics, rustc_attrs)]
|
#![feature(intrinsics)]
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
fn size_of<T, U>() -> usize; //~ ERROR E0094
|
fn size_of<T, U>() -> usize {
|
||||||
|
//~^ ERROR E0094
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {}
|
||||||
}
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
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:15
|
--> $DIR/E0094.rs:5: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
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#![feature(intrinsics)]
|
#![feature(intrinsics)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
#[rustc_intrinsic]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
fn size_of<T>(); //~ ERROR E0308
|
fn size_of<T>() {
|
||||||
|
//~^ ERROR E0308
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {}
|
||||||
}
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
error[E0308]: intrinsic has wrong type
|
error[E0308]: intrinsic has wrong type
|
||||||
--> $DIR/E0308.rs:6:20
|
--> $DIR/E0308.rs:6:16
|
||||||
|
|
|
|
||||||
LL | fn size_of<T>();
|
LL | fn size_of<T>() {
|
||||||
| ^ expected `usize`, found `()`
|
| ^ expected `usize`, found `()`
|
||||||
|
|
|
|
||||||
= note: expected signature `extern "rust-intrinsic" fn() -> usize`
|
= note: expected signature `fn() -> usize`
|
||||||
found signature `extern "rust-intrinsic" fn() -> ()`
|
found signature `fn() -> ()`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
11
tests/ui/extern/extern-with-type-bounds.rs
vendored
11
tests/ui/extern/extern-with-type-bounds.rs
vendored
@ -1,18 +1,17 @@
|
|||||||
#![feature(intrinsics, rustc_attrs)]
|
#![feature(intrinsics, rustc_attrs)]
|
||||||
|
|
||||||
extern "rust-intrinsic" {
|
// Intrinsics are the only (?) extern blocks supporting generics.
|
||||||
// Real example from libcore
|
// Once intrinsics have to be declared via `#[rustc_intrinsic]`,
|
||||||
#[rustc_safe_intrinsic]
|
// the entire support for generics in extern fn can probably be removed.
|
||||||
fn type_id<T: ?Sized + 'static>() -> u64;
|
|
||||||
|
|
||||||
|
extern "rust-intrinsic" {
|
||||||
// Silent bounds made explicit to make sure they are actually
|
// Silent bounds made explicit to make sure they are actually
|
||||||
// resolved.
|
// resolved.
|
||||||
fn transmute<T: Sized, U: Sized>(val: T) -> U;
|
fn transmute<T: Sized, U: Sized>(val: T) -> U;
|
||||||
|
|
||||||
// Bounds aren't checked right now, so this should work
|
// Bounds aren't checked right now, so this should work
|
||||||
// even though it's incorrect.
|
// even though it's incorrect.
|
||||||
#[rustc_safe_intrinsic]
|
fn size_of_val<T: Clone>(x: *const T) -> usize;
|
||||||
fn size_of<T: Clone>() -> usize;
|
|
||||||
|
|
||||||
// Unresolved bounds should still error.
|
// Unresolved bounds should still error.
|
||||||
fn align_of<T: NoSuchTrait>() -> usize;
|
fn align_of<T: NoSuchTrait>() -> usize;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0405]: cannot find trait `NoSuchTrait` in this scope
|
error[E0405]: cannot find trait `NoSuchTrait` in this scope
|
||||||
--> $DIR/extern-with-type-bounds.rs:18:20
|
--> $DIR/extern-with-type-bounds.rs:17:20
|
||||||
|
|
|
|
||||||
LL | fn align_of<T: NoSuchTrait>() -> usize;
|
LL | fn align_of<T: NoSuchTrait>() -> usize;
|
||||||
| ^^^^^^^^^^^ not found in this scope
|
| ^^^^^^^^^^^ not found in this scope
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! 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 no
|
||||||
//! `rustc_intrinsic_must_be_overridden` attribute on this usage.
|
//! `rustc_intrinsic_must_be_overridden` attribute on this usage.
|
||||||
#![feature(rustc_attrs)]
|
#![feature(intrinsics)]
|
||||||
//@run-pass
|
//@run-pass
|
||||||
|
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#[rustc_safe_intrinsic]
|
|
||||||
//~^ ERROR the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe
|
|
||||||
//~| ERROR attribute should be applied to intrinsic functions
|
|
||||||
fn safe() {}
|
|
||||||
|
|
||||||
fn main() {}
|
|
@ -1,21 +0,0 @@
|
|||||||
error[E0658]: the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe
|
|
||||||
--> $DIR/feature-gate-safe-intrinsic.rs:1:1
|
|
||||||
|
|
|
||||||
LL | #[rustc_safe_intrinsic]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
|
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error: attribute should be applied to intrinsic functions
|
|
||||||
--> $DIR/feature-gate-safe-intrinsic.rs:1:1
|
|
||||||
|
|
|
||||||
LL | #[rustc_safe_intrinsic]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | fn safe() {}
|
|
||||||
| ------------ not an intrinsic function
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -1,14 +1,8 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![feature(intrinsics, rustc_attrs)]
|
#![feature(core_intrinsics, rustc_attrs)]
|
||||||
|
|
||||||
mod rusti {
|
use std::intrinsics as rusti;
|
||||||
extern "rust-intrinsic" {
|
|
||||||
pub fn pref_align_of<T>() -> usize;
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn min_align_of<T>() -> usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
|
@ -1,24 +1,8 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![feature(intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(rustc_attrs)]
|
|
||||||
|
|
||||||
mod rusti {
|
use std::intrinsics as rusti;
|
||||||
extern "rust-intrinsic" {
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn ctpop<T>(x: T) -> u32;
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn ctlz<T>(x: T) -> u32;
|
|
||||||
pub fn ctlz_nonzero<T>(x: T) -> u32;
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn cttz<T>(x: T) -> u32;
|
|
||||||
pub fn cttz_nonzero<T>(x: T) -> u32;
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn bswap<T>(x: T) -> T;
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn bitreverse<T>(x: T) -> T;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
use rusti::*;
|
use rusti::*;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Check that intrinsics that do not get overridden, but are marked as such,
|
//! Check that intrinsics that do not get overridden, but are marked as such,
|
||||||
//! cause an error instead of silently invoking the body.
|
//! cause an error instead of silently invoking the body.
|
||||||
#![feature(rustc_attrs)]
|
#![feature(intrinsics)]
|
||||||
//@ build-fail
|
//@ build-fail
|
||||||
//@ failure-status:101
|
//@ failure-status:101
|
||||||
//@ normalize-stderr-test: ".*note: .*\n\n" -> ""
|
//@ normalize-stderr-test: ".*note: .*\n\n" -> ""
|
||||||
|
@ -3,17 +3,10 @@
|
|||||||
#![allow(unused_unsafe)]
|
#![allow(unused_unsafe)]
|
||||||
// Issue #2303
|
// Issue #2303
|
||||||
|
|
||||||
#![feature(intrinsics, rustc_attrs)]
|
#![feature(core_intrinsics, rustc_attrs)]
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::intrinsics;
|
||||||
mod rusti {
|
|
||||||
extern "rust-intrinsic" {
|
|
||||||
pub fn pref_align_of<T>() -> usize;
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn min_align_of<T>() -> usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the type with the questionable alignment
|
// This is the type with the questionable alignment
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -41,12 +34,12 @@ pub fn main() {
|
|||||||
// Send it through the shape code
|
// Send it through the shape code
|
||||||
let y = format!("{:?}", x);
|
let y = format!("{:?}", x);
|
||||||
|
|
||||||
println!("align inner = {:?}", rusti::min_align_of::<Inner>());
|
println!("align inner = {:?}", intrinsics::min_align_of::<Inner>());
|
||||||
println!("size outer = {:?}", mem::size_of::<Outer>());
|
println!("size outer = {:?}", mem::size_of::<Outer>());
|
||||||
println!("y = {:?}", y);
|
println!("y = {:?}", y);
|
||||||
|
|
||||||
// per clang/gcc the alignment of `inner` is 4 on x86.
|
// per clang/gcc the alignment of `inner` is 4 on x86.
|
||||||
assert_eq!(rusti::min_align_of::<Inner>(), m::align());
|
assert_eq!(intrinsics::min_align_of::<Inner>(), m::align());
|
||||||
|
|
||||||
// per clang/gcc the size of `outer` should be 12
|
// per clang/gcc the size of `outer` should be 12
|
||||||
// because `inner`s alignment was 4.
|
// because `inner`s alignment was 4.
|
||||||
|
@ -4,17 +4,10 @@
|
|||||||
|
|
||||||
// Issue #2303
|
// Issue #2303
|
||||||
|
|
||||||
#![feature(intrinsics, rustc_attrs)]
|
#![feature(core_intrinsics, rustc_attrs)]
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::intrinsics;
|
||||||
mod rusti {
|
|
||||||
extern "rust-intrinsic" {
|
|
||||||
pub fn pref_align_of<T>() -> usize;
|
|
||||||
#[rustc_safe_intrinsic]
|
|
||||||
pub fn min_align_of<T>() -> usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the type with the questionable alignment
|
// This is the type with the questionable alignment
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -90,12 +83,12 @@ pub fn main() {
|
|||||||
|
|
||||||
let y = format!("{:?}", x);
|
let y = format!("{:?}", x);
|
||||||
|
|
||||||
println!("align inner = {:?}", rusti::min_align_of::<Inner>());
|
println!("align inner = {:?}", intrinsics::min_align_of::<Inner>());
|
||||||
println!("size outer = {:?}", mem::size_of::<Outer>());
|
println!("size outer = {:?}", mem::size_of::<Outer>());
|
||||||
println!("y = {:?}", y);
|
println!("y = {:?}", y);
|
||||||
|
|
||||||
// per clang/gcc the alignment of `Inner` is 4 on x86.
|
// per clang/gcc the alignment of `Inner` is 4 on x86.
|
||||||
assert_eq!(rusti::min_align_of::<Inner>(), m::m::align());
|
assert_eq!(intrinsics::min_align_of::<Inner>(), m::m::align());
|
||||||
|
|
||||||
// per clang/gcc the size of `Outer` should be 12
|
// per clang/gcc the size of `Outer` should be 12
|
||||||
// because `Inner`s alignment was 4.
|
// because `Inner`s alignment was 4.
|
||||||
|
Loading…
Reference in New Issue
Block a user