Skip to content

Commit 0c2a54d

Browse files
committed
Organize intrinsics promotion checks
1 parent e699ea0 commit 0c2a54d

File tree

4 files changed

+57
-70
lines changed

4 files changed

+57
-70
lines changed

src/libcore/intrinsics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,7 @@ extern "rust-intrinsic" {
913913
/// }
914914
/// ```
915915
#[stable(feature = "rust1", since = "1.0.0")]
916+
#[rustc_const_unstable(feature = "const_transmute")]
916917
pub fn transmute<T, U>(e: T) -> U;
917918

918919
/// Returns `true` if the actual type given as `T` requires drop

src/librustc/ty/constness.rs

+48-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ use crate::ty::query::Providers;
22
use crate::hir::def_id::DefId;
33
use crate::hir;
44
use crate::ty::TyCtxt;
5+
<<<<<<< HEAD
56
use syntax_pos::symbol::{sym, Symbol};
7+
=======
8+
use syntax_pos::symbol::Symbol;
9+
use rustc_target::spec::abi::Abi;
10+
>>>>>>> Organize intrinsics promotion checks
611
use crate::hir::map::blocks::FnLikeNode;
712
use syntax::attr;
813

@@ -68,16 +73,52 @@ impl<'tcx> TyCtxt<'tcx, 'tcx> {
6873

6974

7075
pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
71-
/// only checks whether the function has a `const` modifier
72-
fn is_const_fn_raw<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> bool {
76+
fn is_intrinsic_promotable(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
77+
// Intrinsics promotion whitelist is here to check const context at the top level beforehand.
78+
match tcx.fn_sig(def_id).abi() {
79+
Abi::RustIntrinsic |
80+
Abi::PlatformIntrinsic => {
81+
match &tcx.item_name(def_id).as_str()[..] {
82+
| "size_of"
83+
| "min_align_of"
84+
| "needs_drop"
85+
| "type_id"
86+
| "bswap"
87+
| "bitreverse"
88+
| "ctpop"
89+
| "cttz"
90+
| "cttz_nonzero"
91+
| "ctlz"
92+
| "ctlz_nonzero"
93+
| "overflowing_add"
94+
| "overflowing_sub"
95+
| "overflowing_mul"
96+
| "unchecked_shl"
97+
| "unchecked_shr"
98+
| "rotate_left"
99+
| "rotate_right"
100+
| "add_with_overflow"
101+
| "sub_with_overflow"
102+
| "mul_with_overflow"
103+
| "saturating_add"
104+
| "saturating_sub"
105+
| "transmute"
106+
=> true,
107+
108+
_ => false
109+
}
110+
}
111+
_ => false
112+
}
113+
}
114+
115+
/// Checks whether the function has a `const` modifier and intrinsics can be promotable in it
116+
fn is_const_fn_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
73117
let hir_id = tcx.hir().as_local_hir_id(def_id)
74118
.expect("Non-local call to local provider is_const_fn");
75119

76-
let node = tcx.hir().get_by_hir_id(hir_id);
77-
if let Some(fn_like) = FnLikeNode::from_node(node) {
78-
fn_like.constness() == hir::Constness::Const
79-
} else if let hir::Node::Ctor(_) = node {
80-
true
120+
if let Some(fn_like) = FnLikeNode::from_node(tcx.hir().get_by_hir_id(hir_id)) {
121+
(fn_like.constness() == hir::Constness::Const) || is_intrinsic_promotable(tcx, def_id)
81122
} else {
82123
false
83124
}

src/librustc_mir/transform/qualify_consts.rs

+8-60
Original file line numberDiff line numberDiff line change
@@ -489,49 +489,12 @@ impl Qualif for IsNotPromotable {
489489
let fn_ty = callee.ty(cx.body, cx.tcx);
490490
match fn_ty.sty {
491491
ty::FnDef(def_id, _) => {
492-
match cx.tcx.fn_sig(def_id).abi() {
493-
Abi::RustIntrinsic |
494-
Abi::PlatformIntrinsic => {
495-
assert!(!cx.tcx.is_const_fn(def_id));
496-
match &cx.tcx.item_name(def_id).as_str()[..] {
497-
| "size_of"
498-
| "min_align_of"
499-
| "needs_drop"
500-
| "type_id"
501-
| "bswap"
502-
| "bitreverse"
503-
| "ctpop"
504-
| "cttz"
505-
| "cttz_nonzero"
506-
| "ctlz"
507-
| "ctlz_nonzero"
508-
| "overflowing_add"
509-
| "overflowing_sub"
510-
| "overflowing_mul"
511-
| "unchecked_shl"
512-
| "unchecked_shr"
513-
| "rotate_left"
514-
| "rotate_right"
515-
| "add_with_overflow"
516-
| "sub_with_overflow"
517-
| "mul_with_overflow"
518-
| "saturating_add"
519-
| "saturating_sub"
520-
| "transmute"
521-
=> return true,
522-
523-
_ => {}
524-
}
525-
}
526-
_ => {
527-
let is_const_fn =
528-
cx.tcx.is_const_fn(def_id) ||
529-
cx.tcx.is_unstable_const_fn(def_id).is_some() ||
530-
cx.is_const_panic_fn(def_id);
531-
if !is_const_fn {
532-
return true;
533-
}
534-
}
492+
let is_const_fn =
493+
cx.tcx.is_const_fn(def_id) ||
494+
cx.tcx.is_unstable_const_fn(def_id).is_some() ||
495+
cx.is_const_panic_fn(def_id);
496+
if !is_const_fn {
497+
return true;
535498
}
536499
}
537500
_ => return true,
@@ -1251,21 +1214,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
12511214
Abi::PlatformIntrinsic => {
12521215
assert!(!self.tcx.is_const_fn(def_id));
12531216
match &self.tcx.item_name(def_id).as_str()[..] {
1254-
// special intrinsic that can be called diretly without an intrinsic
1255-
// feature gate needs a language feature gate
1256-
"transmute" => {
1257-
if self.mode.requires_const_checking() {
1258-
// const eval transmute calls only with the feature gate
1259-
if !self.tcx.features().const_transmute {
1260-
emit_feature_err(
1261-
&self.tcx.sess.parse_sess, sym::const_transmute,
1262-
self.span, GateIssue::Language,
1263-
&format!("The use of std::mem::transmute() \
1264-
is gated in {}s", self.mode));
1265-
}
1266-
}
1267-
}
1268-
12691217
name if name.starts_with("simd_shuffle") => {
12701218
is_shuffle = true;
12711219
}
@@ -1276,8 +1224,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
12761224
}
12771225
}
12781226
_ => {
1279-
// In normal functions no calls are feature-gated.
1280-
if self.mode.requires_const_checking() {
1227+
// Apply normal functions' rules which are not feature-gated.
1228+
if self.mode != Mode::Fn {
12811229
let unleash_miri = self
12821230
.tcx
12831231
.sess

src/libsyntax/feature_gate.rs

-3
Original file line numberDiff line numberDiff line change
@@ -489,9 +489,6 @@ declare_features! (
489489
// This will likely be removed prior to stabilization of async/await.
490490
(active, await_macro, "1.28.0", Some(50547), None),
491491

492-
// Allows reinterpretation of the bits of a value of one type as another type during const eval.
493-
(active, const_transmute, "1.29.0", Some(53605), None),
494-
495492
// Allows using `try {...}` expressions.
496493
(active, try_blocks, "1.29.0", Some(31436), None),
497494

0 commit comments

Comments
 (0)