mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +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 {
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn size_of<T>() -> usize;
|
||||
pub fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn min_align_of<T>() -> usize;
|
||||
pub fn min_align_of_val<T: ?::Sized>(val: *const T) -> usize;
|
||||
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
||||
pub fn transmute<T, U>(e: T) -> U;
|
||||
pub fn ctlz_nonzero<T>(x: T) -> u32;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn needs_drop<T: ?::Sized>() -> bool;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn bitreverse<T>(x: T) -> T;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn bswap<T>(x: T) -> T;
|
||||
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn size_of<T>() -> usize {
|
||||
loop {}
|
||||
}
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||
loop {}
|
||||
}
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn min_align_of<T>() -> 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 {
|
||||
use crate::Sized;
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn size_of<T>() -> usize;
|
||||
pub fn size_of_val<T: ?Sized>(val: *const T) -> usize;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn min_align_of<T>() -> usize;
|
||||
pub fn min_align_of_val<T: ?Sized>(val: *const T) -> usize;
|
||||
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
||||
pub fn transmute<T, U>(e: T) -> U;
|
||||
pub fn ctlz_nonzero<T>(x: T) -> u32;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn needs_drop<T: ?Sized>() -> bool;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn bitreverse<T>(x: T) -> T;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn bswap<T>(x: T) -> T;
|
||||
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
|
||||
pub fn unreachable() -> !;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn size_of<T>() -> usize {
|
||||
loop {}
|
||||
}
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
|
||||
loop {}
|
||||
}
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn min_align_of<T>() -> 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 {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,11 @@ pub(crate) unsafe auto trait Freeze {}
|
||||
mod intrinsics {
|
||||
use super::Sized;
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,11 @@ pub(crate) unsafe auto trait Freeze {}
|
||||
mod intrinsics {
|
||||
use super::Sized;
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,9 +106,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,9 +56,11 @@ mod libc {
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,9 +98,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,9 +109,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,9 +103,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,9 +58,11 @@ mod libc {
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,9 +64,11 @@ mod libc {
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,9 +103,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,9 +103,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
||||
mod intrinsics {
|
||||
use super::Sized;
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,11 @@ pub(crate) unsafe auto trait Freeze {}
|
||||
mod intrinsics {
|
||||
use super::Sized;
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[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:
|
||||
|
||||
```compile_fail,E0094
|
||||
#![feature(intrinsics, rustc_attrs)]
|
||||
#![feature(intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
fn size_of<T, U>() -> usize; // error: intrinsic has wrong number
|
||||
// of type parameters
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
fn size_of<T, U>() -> usize // error: intrinsic has wrong number
|
||||
// of type parameters
|
||||
{
|
||||
loop {}
|
||||
}
|
||||
```
|
||||
|
||||
@ -18,11 +20,13 @@ and verify with the function declaration in the Rust source code.
|
||||
Example:
|
||||
|
||||
```
|
||||
#![feature(intrinsics, rustc_attrs)]
|
||||
#![feature(intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
fn size_of<T>() -> usize; // ok!
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
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:
|
||||
|
||||
```compile_fail
|
||||
#![feature(intrinsics, rustc_attrs)]
|
||||
#![feature(intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
fn size_of<T>(); // error: intrinsic has wrong type
|
||||
fn unreachable(); // error: intrinsic has wrong type
|
||||
}
|
||||
|
||||
// or:
|
||||
@ -41,12 +40,11 @@ impl Foo {
|
||||
For the first code example, please check the function definition. Example:
|
||||
|
||||
```
|
||||
#![feature(intrinsics, rustc_attrs)]
|
||||
#![feature(intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
fn size_of<T>() -> usize; // ok!
|
||||
fn unreachable() -> !; // ok!
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -997,23 +997,18 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
|
||||
EncodeCrossCrate::Yes, r#"`rustc_doc_primitive` is a rustc internal attribute"#,
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
|
||||
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,
|
||||
gated!(
|
||||
rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
|
||||
"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_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_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:
|
||||
|
@ -3,7 +3,7 @@
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_errors::codes::*;
|
||||
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::traits::{ObligationCause, ObligationCauseCode};
|
||||
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) {
|
||||
tcx.fn_sig(intrinsic_id).skip_binder().safety()
|
||||
} else {
|
||||
match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
|
||||
true => hir::Safety::Safe,
|
||||
false => hir::Safety::Unsafe,
|
||||
}
|
||||
// Old-style intrinsics are never safe
|
||||
Safety::Unsafe
|
||||
};
|
||||
let is_in_list = match tcx.item_name(intrinsic_id.into()) {
|
||||
// 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
|
||||
/// cause an ICE that we otherwise may want to prevent.
|
||||
pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
|
||||
if (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
|
||||
&& tcx.features().intrinsics())
|
||||
|| (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs())
|
||||
if tcx.features().intrinsics()
|
||||
&& (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
|
||||
|| tcx.has_attr(def_id, sym::rustc_intrinsic))
|
||||
{
|
||||
Some(ty::IntrinsicDef {
|
||||
name: tcx.item_name(def_id.into()),
|
||||
|
@ -679,10 +679,6 @@ passes_rustc_pub_transparent =
|
||||
attribute should be applied to `#[repr(transparent)]` types
|
||||
.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 =
|
||||
attribute should be applied to functions or statics
|
||||
.label = not a function or static
|
||||
|
@ -210,9 +210,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
| [sym::rustc_promotable, ..] => self.check_stability_promotable(attr, target),
|
||||
[sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, 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::link, ..] => self.check_link(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) {
|
||||
match target {
|
||||
Target::Fn | Target::Static => {}
|
||||
|
@ -641,15 +641,6 @@ pub(crate) struct RustcAllowConstFnUnstable {
|
||||
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)]
|
||||
#[diag(passes_rustc_std_internal_symbol)]
|
||||
pub(crate) struct RustcStdInternalSymbol {
|
||||
|
@ -1733,7 +1733,6 @@ symbols! {
|
||||
rustc_reallocator,
|
||||
rustc_regions,
|
||||
rustc_reservation_impl,
|
||||
rustc_safe_intrinsic,
|
||||
rustc_serialize,
|
||||
rustc_skip_during_method_dispatch,
|
||||
rustc_specialization_trait,
|
||||
|
@ -904,38 +904,6 @@ extern "rust-intrinsic" {
|
||||
#[rustc_nounwind]
|
||||
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.
|
||||
///
|
||||
/// This intrinsic does not have a stable counterpart.
|
||||
@ -943,6 +911,44 @@ extern "rust-intrinsic" {
|
||||
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,
|
||||
/// enabling further optimizations.
|
||||
///
|
||||
@ -1512,19 +1518,22 @@ pub const unsafe fn arith_offset<T>(_dst: *const T, _offset: isize) -> *const T
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
/// Masks out bits of the pointer according to a mask.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// Consider using [`pointer::mask`] instead.
|
||||
#[rustc_safe_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T;
|
||||
/// Masks out bits of the pointer according to a mask.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// Consider using [`pointer::mask`] instead.
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
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
|
||||
/// a size of `count` * `size_of::<T>()` and an alignment of
|
||||
/// `min_align_of::<T>()`
|
||||
@ -2140,41 +2149,6 @@ extern "rust-intrinsic" {
|
||||
#[rustc_nounwind]
|
||||
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
|
||||
/// (<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;
|
||||
}
|
||||
|
||||
/// 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`
|
||||
///
|
||||
/// 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.
|
||||
|
||||
```rust
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#[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:
|
||||
|
||||
```rust
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#[rustc_intrinsic]
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(intrinsics, rustc_attrs)]
|
||||
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
|
@ -50,9 +50,10 @@ enum Ordering {
|
||||
Greater = 1,
|
||||
}
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> Ordering;
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> Ordering {
|
||||
loop {}
|
||||
}
|
||||
|
||||
// ^^^^^ core
|
||||
|
@ -5,18 +5,17 @@
|
||||
#![no_core]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
//@ has 'foo/fn.abort.html'
|
||||
//@ has - '//pre[@class="rust item-decl"]' 'pub extern "rust-intrinsic" fn abort() -> !'
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
//@ has 'foo/fn.unreachable.html'
|
||||
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !'
|
||||
pub fn unreachable() -> !;
|
||||
//@ has 'foo/fn.abort.html'
|
||||
//@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !'
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub fn abort() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
//@ has 'foo/fn.needs_drop.html'
|
||||
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn needs_drop() -> !'
|
||||
pub fn needs_drop() -> !;
|
||||
//@ has 'foo/fn.unreachable.html'
|
||||
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !'
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub unsafe fn unreachable() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
#![feature(intrinsics, rustc_attrs)]
|
||||
#![feature(intrinsics)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
fn size_of<T, U>() -> usize; //~ ERROR E0094
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
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
|
||||
--> $DIR/E0094.rs:5:15
|
||||
--> $DIR/E0094.rs:5:11
|
||||
|
|
||||
LL | fn size_of<T, U>() -> usize;
|
||||
| ^^^^^^ expected 1 type parameter
|
||||
LL | fn size_of<T, U>() -> usize {
|
||||
| ^^^^^^ expected 1 type parameter
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
#![feature(intrinsics)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[rustc_safe_intrinsic]
|
||||
fn size_of<T>(); //~ ERROR E0308
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
fn size_of<T>() {
|
||||
//~^ ERROR E0308
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
fn main() {}
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0308]: intrinsic has wrong type
|
||||
--> $DIR/E0308.rs:6:20
|
||||
--> $DIR/E0308.rs:6:16
|
||||
|
|
||||
LL | fn size_of<T>();
|
||||
| ^ expected `usize`, found `()`
|
||||
LL | fn size_of<T>() {
|
||||
| ^ expected `usize`, found `()`
|
||||
|
|
||||
= note: expected signature `extern "rust-intrinsic" fn() -> usize`
|
||||
found signature `extern "rust-intrinsic" fn() -> ()`
|
||||
= note: expected signature `fn() -> usize`
|
||||
found signature `fn() -> ()`
|
||||
|
||||
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)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
// Real example from libcore
|
||||
#[rustc_safe_intrinsic]
|
||||
fn type_id<T: ?Sized + 'static>() -> u64;
|
||||
// Intrinsics are the only (?) extern blocks supporting generics.
|
||||
// Once intrinsics have to be declared via `#[rustc_intrinsic]`,
|
||||
// the entire support for generics in extern fn can probably be removed.
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
// Silent bounds made explicit to make sure they are actually
|
||||
// resolved.
|
||||
fn transmute<T: Sized, U: Sized>(val: T) -> U;
|
||||
|
||||
// Bounds aren't checked right now, so this should work
|
||||
// even though it's incorrect.
|
||||
#[rustc_safe_intrinsic]
|
||||
fn size_of<T: Clone>() -> usize;
|
||||
fn size_of_val<T: Clone>(x: *const T) -> usize;
|
||||
|
||||
// Unresolved bounds should still error.
|
||||
fn align_of<T: NoSuchTrait>() -> usize;
|
||||
|
@ -1,5 +1,5 @@
|
||||
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;
|
||||
| ^^^^^^^^^^^ not found in this scope
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Check that `vtable_size` gets overridden by llvm backend even if there is no
|
||||
//! `rustc_intrinsic_must_be_overridden` attribute on this usage.
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(intrinsics)]
|
||||
//@run-pass
|
||||
|
||||
#[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
|
||||
|
||||
#![feature(intrinsics, rustc_attrs)]
|
||||
#![feature(core_intrinsics, rustc_attrs)]
|
||||
|
||||
mod rusti {
|
||||
extern "rust-intrinsic" {
|
||||
pub fn pref_align_of<T>() -> usize;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn min_align_of<T>() -> usize;
|
||||
}
|
||||
}
|
||||
use std::intrinsics as rusti;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
|
@ -1,24 +1,8 @@
|
||||
//@ run-pass
|
||||
|
||||
#![feature(intrinsics)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
mod 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;
|
||||
}
|
||||
}
|
||||
use std::intrinsics as rusti;
|
||||
|
||||
pub fn main() {
|
||||
use rusti::*;
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Check that intrinsics that do not get overridden, but are marked as such,
|
||||
//! cause an error instead of silently invoking the body.
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(intrinsics)]
|
||||
//@ build-fail
|
||||
//@ failure-status:101
|
||||
//@ normalize-stderr-test: ".*note: .*\n\n" -> ""
|
||||
|
@ -3,17 +3,10 @@
|
||||
#![allow(unused_unsafe)]
|
||||
// Issue #2303
|
||||
|
||||
#![feature(intrinsics, rustc_attrs)]
|
||||
#![feature(core_intrinsics, rustc_attrs)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
mod rusti {
|
||||
extern "rust-intrinsic" {
|
||||
pub fn pref_align_of<T>() -> usize;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn min_align_of<T>() -> usize;
|
||||
}
|
||||
}
|
||||
use std::intrinsics;
|
||||
|
||||
// This is the type with the questionable alignment
|
||||
#[derive(Debug)]
|
||||
@ -41,12 +34,12 @@ pub fn main() {
|
||||
// Send it through the shape code
|
||||
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!("y = {:?}", y);
|
||||
|
||||
// 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
|
||||
// because `inner`s alignment was 4.
|
||||
|
@ -4,17 +4,10 @@
|
||||
|
||||
// Issue #2303
|
||||
|
||||
#![feature(intrinsics, rustc_attrs)]
|
||||
#![feature(core_intrinsics, rustc_attrs)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
mod rusti {
|
||||
extern "rust-intrinsic" {
|
||||
pub fn pref_align_of<T>() -> usize;
|
||||
#[rustc_safe_intrinsic]
|
||||
pub fn min_align_of<T>() -> usize;
|
||||
}
|
||||
}
|
||||
use std::intrinsics;
|
||||
|
||||
// This is the type with the questionable alignment
|
||||
#[derive(Debug)]
|
||||
@ -90,12 +83,12 @@ pub fn main() {
|
||||
|
||||
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!("y = {:?}", y);
|
||||
|
||||
// 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
|
||||
// because `Inner`s alignment was 4.
|
||||
|
Loading…
Reference in New Issue
Block a user