Move all intrinsic whitelists into the constness check file
This commit is contained in:
parent
52be0b07ae
commit
46c00a21e1
4 changed files with 42 additions and 56 deletions
|
@ -36,12 +36,47 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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_min_const_fn(self, def_id: DefId) -> bool {
|
||||||
|
match self.item_name(def_id) {
|
||||||
|
| sym::size_of
|
||||||
|
| sym::min_align_of
|
||||||
|
| sym::needs_drop
|
||||||
|
// Arithmetic:
|
||||||
|
| sym::add_with_overflow // ~> .overflowing_add
|
||||||
|
| sym::sub_with_overflow // ~> .overflowing_sub
|
||||||
|
| sym::mul_with_overflow // ~> .overflowing_mul
|
||||||
|
| sym::wrapping_add // ~> .wrapping_add
|
||||||
|
| sym::wrapping_sub // ~> .wrapping_sub
|
||||||
|
| sym::wrapping_mul // ~> .wrapping_mul
|
||||||
|
| sym::saturating_add // ~> .saturating_add
|
||||||
|
| sym::saturating_sub // ~> .saturating_sub
|
||||||
|
| sym::unchecked_shl // ~> .wrapping_shl
|
||||||
|
| sym::unchecked_shr // ~> .wrapping_shr
|
||||||
|
| sym::rotate_left // ~> .rotate_left
|
||||||
|
| sym::rotate_right // ~> .rotate_right
|
||||||
|
| sym::ctpop // ~> .count_ones
|
||||||
|
| sym::ctlz // ~> .leading_zeros
|
||||||
|
| sym::cttz // ~> .trailing_zeros
|
||||||
|
| sym::bswap // ~> .swap_bytes
|
||||||
|
| sym::bitreverse // ~> .reverse_bits
|
||||||
|
=> true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if this function must conform to `min_const_fn`
|
/// Returns `true` if this function must conform to `min_const_fn`
|
||||||
pub fn is_min_const_fn(self, def_id: DefId) -> bool {
|
pub fn is_min_const_fn(self, def_id: DefId) -> bool {
|
||||||
// Bail out if the signature doesn't contain `const`
|
// Bail out if the signature doesn't contain `const`
|
||||||
if !self.is_const_fn_raw(def_id) {
|
if !self.is_const_fn_raw(def_id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if let Abi::RustIntrinsic = self.fn_sig(def_id).abi() {
|
||||||
|
return self.is_intrinsic_min_const_fn(def_id);
|
||||||
|
}
|
||||||
|
|
||||||
if self.features().staged_api {
|
if self.features().staged_api {
|
||||||
// in order for a libstd function to be considered min_const_fn
|
// in order for a libstd function to be considered min_const_fn
|
||||||
|
|
|
@ -2,7 +2,6 @@ use rustc::hir::def_id::DefId;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::ty::{self, Predicate, Ty, TyCtxt, adjustment::{PointerCast}};
|
use rustc::ty::{self, Predicate, Ty, TyCtxt, adjustment::{PointerCast}};
|
||||||
use rustc_target::spec::abi;
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax::symbol::{sym, Symbol};
|
use syntax::symbol::{sym, Symbol};
|
||||||
|
@ -356,18 +355,8 @@ fn check_terminator(
|
||||||
} => {
|
} => {
|
||||||
let fn_ty = func.ty(body, tcx);
|
let fn_ty = func.ty(body, tcx);
|
||||||
if let ty::FnDef(def_id, _) = fn_ty.kind {
|
if let ty::FnDef(def_id, _) = fn_ty.kind {
|
||||||
|
if !tcx.is_min_const_fn(def_id) {
|
||||||
// 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 => if !is_intrinsic_whitelisted(tcx, def_id) {
|
|
||||||
return Err((
|
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((
|
|
||||||
span,
|
span,
|
||||||
format!(
|
format!(
|
||||||
"can only call other `const fn` within a `const fn`, \
|
"can only call other `const fn` within a `const fn`, \
|
||||||
|
@ -375,14 +364,7 @@ fn check_terminator(
|
||||||
func,
|
func,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
)),
|
));
|
||||||
abi => return Err((
|
|
||||||
span,
|
|
||||||
format!(
|
|
||||||
"cannot call functions with `{}` abi in `min_const_fn`",
|
|
||||||
abi,
|
|
||||||
).into(),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check_operand(tcx, func, span, def_id, body)?;
|
check_operand(tcx, func, span, def_id, body)?;
|
||||||
|
@ -410,34 +392,3 @@ 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<'tcx>, def_id: DefId) -> bool {
|
|
||||||
match tcx.item_name(def_id) {
|
|
||||||
| sym::size_of
|
|
||||||
| sym::min_align_of
|
|
||||||
| sym::needs_drop
|
|
||||||
// Arithmetic:
|
|
||||||
| sym::add_with_overflow // ~> .overflowing_add
|
|
||||||
| sym::sub_with_overflow // ~> .overflowing_sub
|
|
||||||
| sym::mul_with_overflow // ~> .overflowing_mul
|
|
||||||
| sym::wrapping_add // ~> .wrapping_add
|
|
||||||
| sym::wrapping_sub // ~> .wrapping_sub
|
|
||||||
| sym::wrapping_mul // ~> .wrapping_mul
|
|
||||||
| sym::saturating_add // ~> .saturating_add
|
|
||||||
| sym::saturating_sub // ~> .saturating_sub
|
|
||||||
| sym::unchecked_shl // ~> .wrapping_shl
|
|
||||||
| sym::unchecked_shr // ~> .wrapping_shr
|
|
||||||
| sym::rotate_left // ~> .rotate_left
|
|
||||||
| sym::rotate_right // ~> .rotate_right
|
|
||||||
| sym::ctpop // ~> .count_ones
|
|
||||||
| sym::ctlz // ~> .leading_zeros
|
|
||||||
| sym::cttz // ~> .trailing_zeros
|
|
||||||
| sym::bswap // ~> .swap_bytes
|
|
||||||
| sym::bitreverse // ~> .reverse_bits
|
|
||||||
=> true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ extern "C" {
|
||||||
const extern fn bar() {
|
const extern fn bar() {
|
||||||
unsafe {
|
unsafe {
|
||||||
regular_in_block();
|
regular_in_block();
|
||||||
//~^ ERROR: cannot call functions with `"C"` abi in `min_const_fn`
|
//~^ ERROR: can only call other `const fn` within a `const fn`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ extern fn regular() {}
|
||||||
const extern fn foo() {
|
const extern fn foo() {
|
||||||
unsafe {
|
unsafe {
|
||||||
regular();
|
regular();
|
||||||
//~^ ERROR: cannot call functions with `"C"` abi in `min_const_fn`
|
//~^ ERROR: can only call other `const fn` within a `const fn`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0723]: cannot call functions with `"C"` abi in `min_const_fn`
|
error[E0723]: can only call other `const fn` within a `const fn`, but `const regular_in_block` is not stable as `const fn`
|
||||||
--> $DIR/const-extern-fn-call-extern-fn.rs:9:9
|
--> $DIR/const-extern-fn-call-extern-fn.rs:9:9
|
||||||
|
|
|
|
||||||
LL | regular_in_block();
|
LL | regular_in_block();
|
||||||
|
@ -7,7 +7,7 @@ LL | regular_in_block();
|
||||||
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
|
||||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0723]: cannot call functions with `"C"` abi in `min_const_fn`
|
error[E0723]: can only call other `const fn` within a `const fn`, but `const regular` is not stable as `const fn`
|
||||||
--> $DIR/const-extern-fn-call-extern-fn.rs:18:9
|
--> $DIR/const-extern-fn-call-extern-fn.rs:18:9
|
||||||
|
|
|
|
||||||
LL | regular();
|
LL | regular();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue