Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Stablilize const_int_{rotate,wrapping,sign} #57105

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@
#![feature(const_slice_len)]
#![feature(const_str_as_bytes)]
#![feature(const_str_len)]
#![feature(const_int_rotate)]
#![feature(const_int_wrapping)]
#![feature(const_int_sign)]
#![cfg_attr(stage0, feature(const_int_rotate))]
#![feature(const_int_conversion)]
#![feature(const_transmute)]
#![feature(reverse_bits)]
Expand Down
54 changes: 38 additions & 16 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ let m = ", $rot_result, ";
assert_eq!(n.rotate_left(", $rot, "), m);
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_rotate")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))]
#[inline]
pub const fn rotate_left(self, n: u32) -> Self {
(self as $UnsignedT).rotate_left(n) as Self
Expand All @@ -382,7 +382,7 @@ let m = ", $rot_op, ";
assert_eq!(n.rotate_right(", $rot, "), m);
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_rotate")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))]
#[inline]
pub const fn rotate_right(self, n: u32) -> Self {
(self as $UnsignedT).rotate_right(n) as Self
Expand Down Expand Up @@ -994,12 +994,15 @@ assert_eq!(", stringify!($SelfT), "::max_value().wrapping_add(2), ", stringify!(
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_add(self, rhs: Self) -> Self {
#[cfg(stage0)]
unsafe {
intrinsics::overflowing_add(self, rhs)
}
#[cfg(not(stage0))]
intrinsics::overflowing_add(self, rhs)
}
}

Expand All @@ -1018,12 +1021,15 @@ stringify!($SelfT), "::max_value());",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_sub(self, rhs: Self) -> Self {
#[cfg(stage0)]
unsafe {
intrinsics::overflowing_sub(self, rhs)
}
#[cfg(not(stage0))]
intrinsics::overflowing_sub(self, rhs)
}
}

Expand All @@ -1041,12 +1047,15 @@ assert_eq!(11i8.wrapping_mul(12), -124);",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_mul(self, rhs: Self) -> Self {
#[cfg(stage0)]
unsafe {
intrinsics::overflowing_mul(self, rhs)
}
#[cfg(not(stage0))]
intrinsics::overflowing_mul(self, rhs)
}
}

Expand Down Expand Up @@ -1205,7 +1214,7 @@ assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);",
$EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_shl(self, rhs: u32) -> Self {
unsafe {
Expand Down Expand Up @@ -1233,7 +1242,7 @@ assert_eq!((-128i16).wrapping_shr(64), -128);",
$EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_shr(self, rhs: u32) -> Self {
unsafe {
Expand Down Expand Up @@ -1886,7 +1895,6 @@ assert!(!(-10", stringify!($SelfT), ").is_positive());",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_sign")]
#[inline]
pub const fn is_positive(self) -> bool { self > 0 }
}
Expand All @@ -1905,7 +1913,6 @@ assert!(!10", stringify!($SelfT), ".is_negative());",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_sign")]
#[inline]
pub const fn is_negative(self) -> bool { self < 0 }
}
Expand Down Expand Up @@ -2310,10 +2317,13 @@ let m = ", $rot_result, ";
assert_eq!(n.rotate_left(", $rot, "), m);
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_rotate")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))]
#[inline]
pub const fn rotate_left(self, n: u32) -> Self {
#[cfg(stage0)]
unsafe { intrinsics::rotate_left(self, n as $SelfT) }
#[cfg(not(stage0))]
intrinsics::rotate_left(self, n as $SelfT)
}
}

Expand All @@ -2335,10 +2345,13 @@ let m = ", $rot_op, ";
assert_eq!(n.rotate_right(", $rot, "), m);
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_rotate")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))]
#[inline]
pub const fn rotate_right(self, n: u32) -> Self {
#[cfg(stage0)]
unsafe { intrinsics::rotate_right(self, n as $SelfT) }
#[cfg(not(stage0))]
intrinsics::rotate_right(self, n as $SelfT)
}
}

Expand Down Expand Up @@ -2884,12 +2897,15 @@ assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::ma
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_add(self, rhs: Self) -> Self {
#[cfg(stage0)]
unsafe {
intrinsics::overflowing_add(self, rhs)
}
#[cfg(not(stage0))]
intrinsics::overflowing_add(self, rhs)
}
}

Expand All @@ -2907,12 +2923,15 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::ma
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_sub(self, rhs: Self) -> Self {
#[cfg(stage0)]
unsafe {
intrinsics::overflowing_sub(self, rhs)
}
#[cfg(not(stage0))]
intrinsics::overflowing_sub(self, rhs)
}
}

Expand All @@ -2931,12 +2950,15 @@ $EndFeature, "
/// assert_eq!(25u8.wrapping_mul(12), 44);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_mul(self, rhs: Self) -> Self {
#[cfg(stage0)]
unsafe {
intrinsics::overflowing_mul(self, rhs)
}
#[cfg(not(stage0))]
Centril marked this conversation as resolved.
Show resolved Hide resolved
intrinsics::overflowing_mul(self, rhs)
}

doc_comment! {
Expand Down Expand Up @@ -3081,7 +3103,7 @@ Basic usage:
assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_shl(self, rhs: u32) -> Self {
unsafe {
Expand Down Expand Up @@ -3111,7 +3133,7 @@ Basic usage:
assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[rustc_const_unstable(feature = "const_int_wrapping")]
#[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
#[inline]
pub const fn wrapping_shr(self, rhs: u32) -> Self {
unsafe {
Expand Down
32 changes: 25 additions & 7 deletions src/librustc_mir/transform/qualify_min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,15 +342,11 @@ fn check_terminator(
// some intrinsics are waved through if called inside the
// standard library. Users never need to call them directly
match tcx.fn_sig(def_id).abi() {
abi::Abi::RustIntrinsic => match &tcx.item_name(def_id).as_str()[..] {
| "size_of"
| "min_align_of"
| "needs_drop"
=> {},
_ => return Err((
abi::Abi::RustIntrinsic => if !is_intrinsic_whitelisted(tcx, def_id) {
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
return Err((
span,
"can only call a curated list of intrinsics in `min_const_fn`".into(),
)),
))
},
abi::Abi::Rust if tcx.is_min_const_fn(def_id) => {},
abi::Abi::Rust => return Err((
Expand Down Expand Up @@ -390,3 +386,25 @@ fn check_terminator(
},
}
}

/// Returns true if the `def_id` refers to an intrisic which we've whitelisted
/// for being called from stable `const fn`s (`min_const_fn`).
///
/// Adding more intrinsics requires sign-off from @rust-lang/lang.
fn is_intrinsic_whitelisted(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
match &tcx.item_name(def_id).as_str()[..] {
| "size_of"
| "min_align_of"
| "needs_drop"
// Arithmetic:
| "overflowing_add" // ~> .wrapping_add
| "overflowing_sub" // ~> .wrapping_sub
| "overflowing_mul" // ~> .wrapping_mul
| "unchecked_shl" // ~> .wrapping_shl
| "unchecked_shr" // ~> .wrapping_shr
| "rotate_left" // ~> .rotate_left
| "rotate_right" // ~> .rotate_right
=> true,
_ => false,
}
}
16 changes: 12 additions & 4 deletions src/librustc_typeck/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ fn equate_intrinsic_type<'a, 'tcx>(
require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(def_id)), fty);
}

/// Returns whether the given intrinsic is unsafe to call or not.
pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
match intrinsic {
"size_of" | "min_align_of" | "needs_drop" |
"overflowing_add" | "overflowing_sub" | "overflowing_mul" |
"rotate_left" | "rotate_right"
=> hir::Unsafety::Normal,
_ => hir::Unsafety::Unsafe,
}
}

/// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs,
/// and in libcore/intrinsics.rs
pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Expand Down Expand Up @@ -117,10 +128,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
} else if &name[..] == "abort" || &name[..] == "unreachable" {
(0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe)
} else {
let unsafety = match &name[..] {
"size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
_ => hir::Unsafety::Unsafe,
};
let unsafety = intrisic_operation_unsafety(&name[..]);
let (n_tps, inputs, output) = match &name[..] {
"breakpoint" => (0, Vec::new(), tcx.mk_unit()),
"size_of" |
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ mod closure;
mod callee;
mod compare_method;
mod generator_interior;
mod intrinsic;
pub mod intrinsic;
mod op;

use astconv::{AstConv, PathSeg};
Expand Down
6 changes: 2 additions & 4 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use astconv::{AstConv, Bounds};
use constrained_type_params as ctp;
use check::intrinsic::intrisic_operation_unsafety;
use lint;
use middle::lang_items::SizedTraitLangItem;
use middle::resolve_lifetime as rl;
Expand Down Expand Up @@ -2076,10 +2077,7 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
abi: abi::Abi,
) -> ty::PolyFnSig<'tcx> {
let unsafety = if abi == abi::Abi::RustIntrinsic {
match &*tcx.item_name(def_id).as_str() {
"size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
_ => hir::Unsafety::Unsafe,
}
intrisic_operation_unsafety(&*tcx.item_name(def_id).as_str())
} else {
hir::Unsafety::Unsafe
};
Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/const-int-rotate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(const_int_rotate)]

const LEFT: u32 = 0x10000b3u32.rotate_left(8);
const RIGHT: u32 = 0xb301u32.rotate_right(8);

Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/const-int-sign.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(const_int_sign)]

const NEGATIVE_A: bool = (-10i32).is_negative();
const NEGATIVE_B: bool = 10i32.is_negative();
const POSITIVE_A: bool= (-10i32).is_positive();
Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/const-int-wrapping.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(const_int_wrapping)]

const ADD_A: u32 = 200u32.wrapping_add(55);
const ADD_B: u32 = 200u32.wrapping_add(u32::max_value());

Expand Down
Loading